diff options
author | Ramón M. Gómez <ramongomez@us.es> | 2019-05-16 08:14:14 +0200 |
---|---|---|
committer | Ramón M. Gómez <ramongomez@us.es> | 2019-05-16 08:14:14 +0200 |
commit | e848ab462bf599171a87e24e10f365fa7fe9d643 (patch) | |
tree | ba5421a3a5d17e161ac60a469c5e3ad880b28372 | |
parent | 85db11d8588b69ed6e56cd952df43ade5d511c59 (diff) |
#908: OGAgent uses a new Python decorator to check the REST access token.
-rw-r--r-- | admin/Sources/Clients/ogagent/src/opengnsys/modules/server/OpenGnSys/__init__.py | 104 |
1 files changed, 70 insertions, 34 deletions
diff --git a/admin/Sources/Clients/ogagent/src/opengnsys/modules/server/OpenGnSys/__init__.py b/admin/Sources/Clients/ogagent/src/opengnsys/modules/server/OpenGnSys/__init__.py index 04c7ebc5..6e729046 100644 --- a/admin/Sources/Clients/ogagent/src/opengnsys/modules/server/OpenGnSys/__init__.py +++ b/admin/Sources/Clients/ogagent/src/opengnsys/modules/server/OpenGnSys/__init__.py @@ -47,6 +47,25 @@ from opengnsys.workers import ServerWorker from six.moves.urllib import parse +# Check authorization header decorator +def check_secret(fnc): + """ + Decorator to check for received secret key and raise exception if it isn't valid. + """ + def wrapper(*args, **kwargs): + try: + this, path, get_params, post_params, server = args # @UnusedVariable + if this.random == server.headers['Authorization']: + fnc(*args, **kwargs) + else: + raise Exception('Unauthorized operation') + except Exception as e: + logger.error(e) + raise Exception(e) + + return wrapper + + # Error handler decorator. def catch_background_error(fnc): def wrapper(*args, **kwargs): @@ -93,7 +112,6 @@ class OpenGnSysWorker(ServerWorker): interface = None # Bound interface for OpenGnsys REST = None # REST object loggedin = False # User session flag - locked = {} # Locked partitions browser = {} # Browser info commands = [] # Running commands random = None # Random string for secure connections @@ -101,17 +119,6 @@ class OpenGnSysWorker(ServerWorker): access_token = refresh_token = None # Server authorization tokens grant_type = 'http://opengnsys.es/grants/og_client' - def _check_secret(self, server): - """ - Checks for received secret key and raise exception if it isn't valid. - """ - try: - if self.random != server.headers['Authorization']: - raise Exception('Unauthorized operation') - except Exception as e: - logger.error(e) - raise Exception(e) - def _launch_browser(self, url): """ Launchs the Browser with specified URL @@ -238,7 +245,7 @@ class OpenGnSysWorker(ServerWorker): <html> <head></head> <body> -<h1>Initializing...</h1> +<h1 style="margin: 5em; font-size: xx-large;">OpenGnsys 3</h1> </body> </html>""" f = open('/tmp/init.html', 'w') @@ -319,7 +326,12 @@ class OpenGnSysWorker(ServerWorker): def process_status(self, path, get_params, post_params, server): """ - Returns client status (OS type and login status). + Returns client status (OS type or execution status) and login status. + :param path: + :param get_params: + :param post_params: + :param server: + :return: JSON object {"status": "status_code", "loggedin": boolean} """ res = {'loggedin': self.loggedin} try: @@ -327,32 +339,42 @@ class OpenGnSysWorker(ServerWorker): except KeyError: res['status'] = '' # Check if OpenGnsys Client is busy - if res['status'] == 'oglive' and self.locked: + if res['status'] == 'oglive' and len(self.commands) > 0: res['status'] = 'busy' return res + @check_secret def process_reboot(self, path, get_params, post_params, server): """ Launches a system reboot operation. + :param path: + :param get_params: + :param post_params: + :param server: authorization header + :return: JSON object {"op": "launched"} """ logger.debug('Received reboot operation') - self._check_secret(server) - # Rebooting thread. + # Rebooting thread def rebt(): operations.reboot() threading.Thread(target=rebt).start() return {'op': 'launched'} + @check_secret def process_poweroff(self, path, get_params, post_params, server): """ Launches a system power off operation. + :param path: + :param get_params: + :param post_params: + :param server: authorization header + :return: JSON object {"op": "launched"} """ logger.debug('Received poweroff operation') - self._check_secret(server) - # Powering off thread. + # Powering off thread def pwoff(): time.sleep(2) operations.poweroff() @@ -360,18 +382,23 @@ class OpenGnSysWorker(ServerWorker): threading.Thread(target=pwoff).start() return {'op': 'launched'} + @check_secret def process_script(self, path, get_params, post_params, server): """ Processes an script execution (script should be encoded in base64) + :param path: + :param get_params: + :param post_params: JSON object {"redirect_uri, "uri", "script": "commands", "id": trace_id} + :param server: authorization header + :return: JSON object {"op": "launched"} or {"error": "message"} """ logger.debug('Processing script request') - self._check_secret(server) # Processing data try: script = urllib.unquote(post_params.get('script').decode('base64')).decode('utf8') op_id = post_params.get('id') route = post_params.get('redirect_uri') - # Checking if the thread id. exists + # Check if the thread id. exists for c in self.commands: if c.getName() == str(op_id): raise Exception('Task id. already exists: {}'.format(op_id)) @@ -388,43 +415,43 @@ class OpenGnSysWorker(ServerWorker): return {'error': e} return {'op': 'launched'} + @check_secret def process_logoff(self, path, get_params, post_params, server): """ Closes user session. """ logger.debug('Received logoff operation') - self._check_secret(server) - # Sending log off message to OGAgent client. + # Send log off message to OGAgent client. self.sendClientMessage('logoff', {}) return {'op': 'sent to client'} + @check_secret def process_popup(self, path, get_params, post_params, server): """ Shows a message popup on the user's session. """ logger.debug('Received message operation') - self._check_secret(server) - # Sending popup message to OGAgent client. + # Send popup message to OGAgent client. self.sendClientMessage('popup', post_params) return {'op': 'launched'} def process_client_popup(self, params): self.REST.sendMessage('popup_done', params) + @check_secret def process_config(self, path, get_params, post_params, server): """ Returns client configuration :param path: :param get_params: :param post_params: - :param server: - :return: object + :param server: authorization header + :return: JSON object """ serialno = '' # Serial number storage = [] # Storage configuration warnings = 0 # Number of warnings logger.debug('Received getconfig operation') - # self._check_secret(server) # Processing data for row in operations.get_configuration().split(';'): cols = row.split(':') @@ -450,33 +477,42 @@ class OpenGnSysWorker(ServerWorker): logger.warn('Configuration parameter error: {}'.format(cols)) warnings += 1 else: - # Logging warnings + # Log warnings logger.warn('Configuration data error: {}'.format(cols)) warnings += 1 # Return configuration data and count of warnings return {'serialno': serialno, 'storage': storage, 'warnings': warnings} + @check_secret def process_execinfo(self, path, get_params, post_params, server): """ Returns running commands information :param path: :param get_params: :param post_params: - :param server: - :return: object + :param server: authorization header + :return: JSON array: [["callback_url", "commands", trace_id], ...] """ data = [] logger.debug('Received execinfo operation') - self._check_secret(server) - # Returning the arguments of all running threads + # Return the arguments of all running threads for c in self.commands: if c.is_alive(): data.append(c.__dict__['_Thread__args']) return data + @check_secret def process_stopcmd(self, path, get_params, post_params, server): + """ + Stops a running process identified by its trace id. + :param path: + :param get_params: + :param post_params: JSON object {"trace": trace_id} + :param server: authorization header + :return: JSON object: {"stopped": trace_id} + """ logger.debug('Received stopcmd operation with params {}:'.format(post_params)) - self._check_secret(server) + # Find operation id. and stop the thread op_id = post_params.get('trace') for c in self.commands: if c.is_alive() and c.getName() == str(op_id): |