summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRamón M. Gómez <ramongomez@us.es>2019-05-16 08:14:14 +0200
committerRamón M. Gómez <ramongomez@us.es>2019-05-16 08:14:14 +0200
commite848ab462bf599171a87e24e10f365fa7fe9d643 (patch)
treeba5421a3a5d17e161ac60a469c5e3ad880b28372
parent85db11d8588b69ed6e56cd952df43ade5d511c59 (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__.py104
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):