# -*- coding: utf-8 -*- from __future__ import absolute_import """ Registers and loads Processor classes from settings. """ import base64 import logging import warnings import zlib from flask import g from importlib import import_module from . import base from . import exceptions from . import xml_render from .app import saml_app class SSOProcessor(base.Processor): """SAML processor for the Ruby omniauth saml gem.""" def _validate_request(self): super(SSOProcessor, self)._validate_request() #url = self._request_params['ACS_URL'] #if 'blah' not in url: # raise exceptions.CannotHandleAssertion('ACS is not a supported URL') def _decode_request(self): self._request_xml = zlib.decompress(base64.b64decode(self._saml_request), -15) def _determine_audience(self): self._audience = self._request_params.get('ISSUER', None) if not self._audience: super(SSOProcessor, self)._determine_audience() def _format_assertion(self): # Add attributes that gitlab needs (?). self._assertion_params['ATTRIBUTES'] = { 'name': self._subject, 'email': g.user_email, } self._assertion_xml = xml_render.get_assertion_salesforce_xml(self._assertion_params, signed=True) def get_processor(name, config): return SSOProcessor(config, name) def old_get_processor(name, config): """ Get an instance of the processor with config. """ dottedpath = config['processor'] try: dot = dottedpath.rindex('.') except ValueError: raise exceptions.ImproperlyConfigured('%s isn\'t a processors module' % dottedpath) sp_module, sp_classname = dottedpath[:dot], dottedpath[dot+1:] try: mod = import_module(sp_module) except ImportError as exc: raise exceptions.ImproperlyConfigured( 'Error importing processors {0}: "{1}"'.format(sp_module, exc)) try: sp_class = getattr(mod, sp_classname) except AttributeError: raise exceptions.ImproperlyConfigured( 'processors module "{0}" does not define a "{1}" class'.format( sp_module, sp_classname)) try: instance = sp_class(name=name, config=config) except TypeError: warnings.warn( "the new version of the Processor class expects a 'name' argument " "to be passed in. The use of old processors is deprecated and will " "be removed in the future.", DeprecationWarning) instance = sp_class(config=config) instance.name = name return instance def find_processor(): """ Returns the Processor instance that is willing to handle the current request. """ for name, sp_config in saml_app.config['SAML2IDP_REMOTES'].items(): proc = get_processor(name, sp_config) try: if proc.can_handle(): return proc except exceptions.CannotHandleAssertion as exc: # Log these, but keep looking. logging.debug('%s %s' % (proc, exc)) raise exceptions.CannotHandleAssertion( 'None of the processors in SAML2IDP_REMOTES could handle this request.')