Source code for docker_leash.processor

# vim:set ts=4 sw=4 et:
'''
Processor
=========
'''

import json
import os

import yaml

from . import app, checks
from .config import Config
from .exceptions import NoSuchCheckModuleException
from .payload import Payload


[docs]class Processor(object): """The :class:`Processor` class is responsible for launching all the :mod:`docker_leash.checks` defined in the configuration for the triplet `User`, `RequestMethod` and `RequestUri`. """ #: The currently loaded rules. config = None def __init__(self): self.config = Config()
[docs] def load_config(self): """Load rules from defined files in the global configuration. Look for path in that order: path in config file, `/etc/docker-leash/`, `/config/` and docker-leash module directory. """ groups_files = [ app.config['GROUPS_FILE'], '/etc/docker-leash/groups.yml', '/config/groups.yml', os.path.abspath( os.path.dirname(os.path.abspath(__file__)) + '/../groups.yml' ), ] policies_files = [ app.config['POLICIES_FILE'], '/etc/docker-leash/policies.yml', '/config/policies.yml', os.path.abspath( os.path.dirname(os.path.abspath(__file__)) + '/../policies.yml' ), ] groups = None for groups_file in groups_files: if os.path.isfile(groups_file): app.logger.info("Found groups config at: %s", groups_file) with open(groups_file) as groups_yml: groups = yaml.safe_load(groups_yml) break policies = None for policies_file in policies_files: if os.path.isfile(policies_file): app.logger.info("Found policies config at: %s", policies_file) with open(policies_file) as policies_yml: policies = yaml.safe_load(policies_yml) break self.config.update(groups, policies)
[docs] def run(self, body=None): """Check if the request is `accepted` or `denied`. The request will be passed to all configured :mod:`docker_leash.checks` for the triplet :attr:`docker_leash.payload.Payload.user` + :attr:`docker_leash.payload.Payload.method` + :attr:`docker_leash.payload.Payload.uri`. If one :mod:`docker_leash.checks` sub-modules deny the action, then the whole request is declared as `denied`. :param body: The HTTP request body :type body: str or dict or None :raises UnauthorizedException: if the check denied the request. :raises NoSuchCheckModuleException: if the check doesn't exists. """ data = json.loads(body) if isinstance(body, str) else body payload = Payload(data) checks_for_user = self.config.get_rules(payload) for check in checks_for_user: self._process(payload, check)
[docs] @staticmethod def _process(payload, check): """Instanciate the requested action and launch :meth:`docker_leash.checks.base.BaseCheck.run` :param Payload payload: The request payload object. :param str check: The check name to run. :raises UnauthorizedException: if the check denied the request. :raises NoSuchCheckModuleException: if the check doesn't exists. """ try: check_action = getattr(checks, check['name'])() except AttributeError: raise NoSuchCheckModuleException( "Check module '%s' does not exists or not autoloadable." % check['name'] ) check_action.run(check['args'], payload)