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