forked from platypush/platypush
Basic support for token authentication on request level
This commit is contained in:
parent
7ad0724f0e
commit
81a81312e3
6 changed files with 39 additions and 20 deletions
|
@ -78,7 +78,11 @@ class Daemon(object):
|
|||
msg -- platypush.message.Message instance """
|
||||
|
||||
if isinstance(msg, Request):
|
||||
try:
|
||||
msg.execute(n_tries=self.n_tries)
|
||||
except PermissionError:
|
||||
logger.info('Dropped unauthorized request: {}'.format(msg))
|
||||
|
||||
self.processed_requests += 1
|
||||
if self.requests_to_process \
|
||||
and self.processed_requests >= self.requests_to_process:
|
||||
|
|
|
@ -180,7 +180,11 @@ class HttpBackend(Backend):
|
|||
self.logger.info('Received message on the HTTP backend: {}'.format(msg))
|
||||
|
||||
if isinstance(msg, Request):
|
||||
try:
|
||||
response = msg.execute(async=False)
|
||||
except PermissionError:
|
||||
abort(401)
|
||||
|
||||
self.logger.info('Processing response on the HTTP backend: {}'.format(msg))
|
||||
return str(response)
|
||||
elif isinstance(msg, Event):
|
||||
|
|
|
@ -6,6 +6,7 @@ import sys
|
|||
import time
|
||||
import yaml
|
||||
|
||||
from platypush.utils import get_hash
|
||||
|
||||
""" Config singleton instance """
|
||||
_default_config_instance = None
|
||||
|
@ -18,8 +19,6 @@ class Config(object):
|
|||
Config.init()
|
||||
- Initialize config from a custom path
|
||||
Config.init(config_file_path)
|
||||
- Set a value
|
||||
Config.set('foo', 'bar')
|
||||
- Get a value
|
||||
Config.get('foo')
|
||||
"""
|
||||
|
@ -60,6 +59,9 @@ class Config(object):
|
|||
self._cfgfile = cfgfile
|
||||
self._config = self._read_config_file(self._cfgfile)
|
||||
|
||||
if 'token' in self._config:
|
||||
self._config['token_hash'] = get_hash(self._config['token'])
|
||||
|
||||
if 'workdir' not in self._config:
|
||||
self._config['workdir'] = self._workdir_location
|
||||
os.makedirs(self._config['workdir'], exist_ok=True)
|
||||
|
@ -242,20 +244,7 @@ class Config(object):
|
|||
"""
|
||||
global _default_config_instance
|
||||
if _default_config_instance is None: _default_config_instance = Config()
|
||||
return _default_config_instance._config[key]
|
||||
|
||||
@staticmethod
|
||||
def set(key, value):
|
||||
"""
|
||||
Sets a config value
|
||||
Params:
|
||||
key -- Config key to set
|
||||
value -- Value for key
|
||||
"""
|
||||
global _default_config_instance
|
||||
if _default_config_instance is None: _default_config_instance = Config()
|
||||
_default_config_instance._config[key] = key
|
||||
|
||||
return _default_config_instance._config.get(key)
|
||||
|
||||
|
||||
# vim:sw=4:ts=4:et:
|
||||
|
|
|
@ -8,10 +8,11 @@ import traceback
|
|||
|
||||
from threading import Thread
|
||||
|
||||
from platypush.config import Config
|
||||
from platypush.context import get_plugin
|
||||
from platypush.message import Message
|
||||
from platypush.message.response import Response
|
||||
from platypush.utils import get_module_and_method_from_action
|
||||
from platypush.utils import get_hash, get_module_and_method_from_action
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
@ -19,7 +20,8 @@ logger = logging.getLogger(__name__)
|
|||
class Request(Message):
|
||||
""" Request message class """
|
||||
|
||||
def __init__(self, target, action, origin=None, id=None, backend=None, args=None):
|
||||
def __init__(self, target, action, origin=None, id=None, backend=None,
|
||||
args=None, token=None):
|
||||
"""
|
||||
Params:
|
||||
target -- Target node [String]
|
||||
|
@ -28,6 +30,7 @@ class Request(Message):
|
|||
id -- Message ID, or None to get it auto-generated
|
||||
backend -- Backend connected to the request, where the response will be delivered
|
||||
args -- Additional arguments for the action [Dict]
|
||||
token -- Authorization token, if required on the server [Str]
|
||||
"""
|
||||
|
||||
self.id = id if id else self._generate_id()
|
||||
|
@ -36,6 +39,7 @@ class Request(Message):
|
|||
self.origin = origin
|
||||
self.args = args if args else {}
|
||||
self.backend = backend
|
||||
self.token = token
|
||||
|
||||
@classmethod
|
||||
def build(cls, msg):
|
||||
|
@ -48,6 +52,7 @@ class Request(Message):
|
|||
|
||||
args['id'] = msg['id'] if 'id' in msg else cls._generate_id()
|
||||
if 'origin' in msg: args['origin'] = msg['origin']
|
||||
if 'token' in msg: args['token'] = msg['token']
|
||||
return cls(**args)
|
||||
|
||||
@staticmethod
|
||||
|
@ -201,6 +206,12 @@ class Request(Message):
|
|||
self._send_response(response)
|
||||
return response
|
||||
|
||||
token_hash = Config.get('token_hash')
|
||||
|
||||
if token_hash:
|
||||
if self.token is None or get_hash(self.token) != token_hash:
|
||||
raise PermissionError()
|
||||
|
||||
if async:
|
||||
Thread(target=_thread_func, args=(n_tries,)).start()
|
||||
else:
|
||||
|
|
|
@ -5,6 +5,12 @@ from platypush.config import Config
|
|||
from platypush.message.response import Response
|
||||
|
||||
|
||||
def action(f):
|
||||
def _execute_action(*args, **kwargs):
|
||||
return f(*args, **kwargs)
|
||||
return _execute_action
|
||||
|
||||
|
||||
class Plugin(object):
|
||||
""" Base plugin class """
|
||||
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import errno
|
||||
import hashlib
|
||||
import importlib
|
||||
import logging
|
||||
import os
|
||||
|
@ -65,5 +66,9 @@ def clear_timeout():
|
|||
signal.alarm(0)
|
||||
|
||||
|
||||
def get_hash(s):
|
||||
return hashlib.sha256(s.encode('utf-8')).hexdigest()
|
||||
|
||||
|
||||
# vim:sw=4:ts=4:et:
|
||||
|
||||
|
|
Loading…
Reference in a new issue