# HG changeset patch # User Oliver Maurhart # Date 1398852382 -7200 # Node ID ac117cd7bab14e5543cb94ae785e81bfc7b407fb # Parent c9499f5166c78155208f3ded8d2a54688641f885 trayicon starts client rest server diff -r c9499f5166c7 -r ac117cd7bab1 .hgignore --- a/.hgignore Tue Apr 29 15:40:48 2014 +0100 +++ b/.hgignore Wed Apr 30 12:06:22 2014 +0200 @@ -4,6 +4,12 @@ # no python compiles *.pyc +# no VIM swap files +*.swp + +# no VM image +*.ova + # no generated setup files OpenSecurity?Setup?*.exe OpenSecurity?Setup?Manifest.txt diff -r c9499f5166c7 -r ac117cd7bab1 OpenSecurity/bin/opensecurity_client_restful_server.py --- a/OpenSecurity/bin/opensecurity_client_restful_server.py Tue Apr 29 15:40:48 2014 +0100 +++ b/OpenSecurity/bin/opensecurity_client_restful_server.py Wed Apr 30 12:06:22 2014 +0200 @@ -35,6 +35,7 @@ import json import os import os.path +import socket import subprocess import sys import urllib @@ -65,6 +66,14 @@ # ------------------------------------------------------------ +# vars + + +"""The REST server object""" +server = None + + +# ------------------------------------------------------------ # code @@ -95,7 +104,7 @@ process = subprocess.Popen(process_command, shell = False, stdout = subprocess.PIPE) # run process result handling in seprate thread (not to block main one) - bouncer = UserResultBouncer(process, remote_ip, '/credentials') + bouncer = ProcessResultBouncer(process, remote_ip, '/credentials') bouncer.start() return 'user queried for credentials' @@ -128,7 +137,7 @@ process = subprocess.Popen(process_command, shell = False, stdout = subprocess.PIPE) # run process result handling in seprate thread (not to block main one) - bouncer = UserResultBouncer(process, remote_ip, '/keyfile') + bouncer = ProcessResultBouncer(process, remote_ip, '/keyfile') bouncer.start() return 'user queried for password and keyfile' @@ -193,7 +202,7 @@ process = subprocess.Popen(process_command, shell = False, stdout = subprocess.PIPE) # run process result handling in seprate thread (not to block main one) - bouncer = UserResultBouncer(process, remote_ip, '/password') + bouncer = ProcessResultBouncer(process, remote_ip, '/password') bouncer.start() return 'user queried for password' @@ -250,9 +259,9 @@ return res -class UserResultBouncer(threading.Thread): +class ProcessResultBouncer(threading.Thread): - """A class to spawn off user I/O waiting and push the data back to the requesting services.""" + """A class to post the result of a given process - assuming it to be in JSON - to a REST Api.""" def __init__(self, process, remote_ip, resource): @@ -299,8 +308,78 @@ return -# start -if __name__ == "__main__": +class RESTServerThread(threading.Thread): + + """Thread for serving the REST API.""" + + def __init__(self, port): + + """ctor""" + threading.Thread.__init__(self) + self._port = port + + def stop(self): + + """stop thread""" + self.running = False + + + def run(self): + + """run the thread""" + _serve(self._port) + + + +def is_already_running(port = 8090): + + """check if this is started twice""" + + try: + s = socket.create_connection(('127.0.0.1', port), 0.5) + except: + return False + + return True + + +def _serve(port): + + """Start the REST server""" + + global server + + # trick the web.py server + sys.argv = [__file__, str(port)] server = web.application(opensecurity_urls, globals()) server.run() + +def serve(port = 8090, background = False): + + """Start serving the REST Api + port ... port number to listen on + background ... cease into background (spawn thread) and return immediately""" + + # start threaded or direct version + if background == True: + t = RESTServerThread(port) + t.start() + else: + _serve(port) + +def stop(): + + """Stop serving the REST Api""" + + global server + if server is None: + return + + server.stop() + + +# start +if __name__ == "__main__": + serve() + diff -r c9499f5166c7 -r ac117cd7bab1 OpenSecurity/bin/opensecurity_tray.pyw --- a/OpenSecurity/bin/opensecurity_tray.pyw Tue Apr 29 15:40:48 2014 +0100 +++ b/OpenSecurity/bin/opensecurity_tray.pyw Wed Apr 30 12:06:22 2014 +0200 @@ -45,6 +45,7 @@ if sys.platform == 'win32' or sys.platform == 'cygwin': from cygwin import Cygwin +import opensecurity_client_restful_server from ui import AboutDialog from ui import ConfigureDialog from ui import opensecurity_rc @@ -136,6 +137,7 @@ def clicked_exit(self): """clicked exit""" + opensecurity_client_restful_server.stop() sys.exit(0) @@ -186,16 +188,32 @@ self.acAbout.triggered.connect(self.clicked_about) self.acExit.triggered.connect(self.clicked_exit) - + def main(): + # parse arguments + parser = argparse.ArgumentParser(description = 'OpenSecurity Tray Icon.') + parser.add_argument('-p', '--port', type=int, default=8090, help='port number of the REST API this instance will listen on.') + args = parser.parse_args() + + # get up Qt a = QtGui.QApplication(sys.argv) + # enforce singelton process + if opensecurity_client_restful_server.is_already_running(args.port): + QtGui.QMessageBox.critical(None, 'OpenSecurity Error', 'OpenSecurity Tray Instance already launched.\nClose previous instance first.') + sys.exit(1) + + # start serving + opensecurity_client_restful_server.serve(args.port, True) + + # init tray icon widget w = QtGui.QWidget() icon = QtGui.QIcon() icon.addPixmap(QtGui.QPixmap(QtCore.QString.fromUtf8(":/opensecurity/gfx/opensecurity_icon_64.png")), QtGui.QIcon.Normal, QtGui.QIcon.Off) trayIcon = OpenSecurityTrayIcon(icon) + # go! trayIcon.show() a.setQuitOnLastWindowClosed(False) sys.exit(a.exec_())