def realms(self, upstream_affordances=None, downstream_affordances=None): upstream_affordances, downstream_affordances = \ self._normalized_affordances(upstream_affordances, downstream_affordances) return _frozenuset(self._realms(upstream_affordances= upstream_affordances, downstream_affordances= downstream_affordances)) \ & upstream_affordances.realms \ & downstream_affordances.realms
def assert_cors_preflight_accepted_response(self, response, **kwargs): super(TestCorsPreflight, self)\ .assert_cors_preflight_accepted_response(response, **kwargs) response_allowed_origins_header = \ response.headers['Access-Control-Allow-Origin'] response_allowed_origins = \ _frozenuset('*' if response_allowed_origins_header == '*' else (token.strip() for token in response_allowed_origins_header .split(','))) self.assertIn(self.cors_origin, response_allowed_origins)
def ensure_auth(self, loc, realms='*', provisionsets='*', algorithms='*'): """Ensure authentication This method returns successfully if the request includes authentication information wherein the realm, security provisions, and algorithm satisfy the affordances of the authentication space defined for the given *loc*. If additional *realms*, *provisionsets*, or *algorithms* are given, then those are applied as additional constraints beyond those imposed by the authentication space's affordances. .. note:: Normally, the caller should not handle the :class:`bedframe.Unauthenticated <bedframe._exc.Unauthenticated>` exception or any of its subclasses (:class:`bedframe.AuthTokensNotGiven <bedframe._exc.AuthTokensNotGiven>` and :class:`bedframe.AuthTokensNotAccepted <bedframe._exc.AuthTokensNotAccepted>`). These exceptions should be handled by the :class:`bedframe.WebServiceImpl <bedframe._services.WebServiceImpl>` so that it can respond accordingly. To test whether the current request has appropriate authentication information, use :meth:`has_auth`. :param realms: Allowed realms. This should be a subset of the realms afforded by the authentication space defined for the given *loc*. :type realms: ~u{str} :param provisionsets: Allowed security provision sets. This should be a superset of the provision sets afforded by the authentication space defined for the given *loc*. :type provisionsets: ~\ :class:`~bedframe.auth._provisions.ProvisionSetSet` :param algorithms: Allowed algorithms. This should be a subset of the algorithms afforded by the authentication space defined for the given *loc*. :type algorithms: ~u{:class:`~bedframe.auth._algorithms.Algorithm`} :raise bedframe.AuthTokenNotGiven: Raised if the request does not include an authentication token. :raise bedframe.AuthTokenNotAccepted: Raised if the request includes an authentication token that was not accepted by the authenticator. """ if self.has_auth(loc=loc, realms=realms, provisionsets=provisionsets, algorithms=algorithms): return affordances = \ _affordances.AffordanceSet\ (realms=(realms if realms is not None else '*'), provisionsets=(provisionsets if provisionsets is not None else '*'), algorithms=(algorithms if algorithms is not None else '*')) space = self.spaces.get(loc, None) def logmessage(): message = 'authentication required at {}'.format(loc) if space: message += ' in space {}'.format(space) if affordances != _affordances.FrozenAffordanceSet.max(): message += ' with {}'.format(affordances) return message self.logger.cond((_logging.DEBUG, logmessage)) if algorithms: algorithms = _frozenuset(algorithms) & _frozenuset(self.algorithms) else: algorithms = _frozenuset(self.algorithms) clerks = _frozenuset(self.clerks) scanners = _frozenuset(self.scanners) supplicants = _frozenuset(self.supplicants) if space: algorithms = space.algorithms() & algorithms clerks = space.clerks & clerks scanners = space.scanners & scanners supplicants = space.supplicants & supplicants if space: affordances = space.affordances(upstream=affordances).unfrozen() else: affordances = _affordances.ProcessAffordanceSet.max() affordances.inputs = '*' affordances.outputs = '*' general_affordances = affordances.general general_affordances.require_nonempty() self.logger.cond((_logging.DEBUG, lambda: 'given affordances {}' .format(general_affordances))) # filter connectors by general affordances resolution_affordances = \ _affordances.ProcessProspectiveAffordanceSet\ .from_general(affordances) algorithms_list = \ [algorithm for algorithm in algorithms if algorithm.supports_affordances(upstream=affordances)] resolution_affordances.algorithms = algorithms_list resolution_affordances.clerks = \ [clerk for clerk in clerks if clerk.supports_affordances(upstream=affordances)] resolution_affordances.scanners = \ [scanner for scanner in scanners if scanner.supports_affordances(upstream=affordances)] resolution_affordances.supplicants = \ [supplicant for supplicant in supplicants if supplicant.supports_affordances(upstream=affordances)] for connector_type in ('algorithm', 'clerk', 'scanner', 'supplicant'): if not getattr(resolution_affordances, connector_type + 's'): raise _exc.Error('no {} meets the necessary affordances {}' .format(connector_type, affordances)) self.logger.cond((_logging.DEBUG, lambda: 'considering algorithms {}' .format(resolution_affordances.algorithms))) self.logger.cond((_logging.DEBUG, lambda: 'considering clerks {}' .format(resolution_affordances.clerks))) self.logger.cond((_logging.DEBUG, lambda: 'considering scanners {}' .format(resolution_affordances.scanners))) self.logger\ .cond((_logging.DEBUG, lambda: 'considering supplicants {}' .format(resolution_affordances.supplicants))) prospective_affordances = resolution_affordances.copy() prospective_affordances.outputs = ((),) prospective_affordances.scanners = \ resolution_affordances.scanners.copy() scanned_auth_info = None for scanner in resolution_affordances.scanners: try: scanned_auth_info = \ scanner.process_tokens(affordances=resolution_affordances) except _exc.NoValidTokensScanned: pass else: scanned_tokens = scanned_auth_info.tokens message = 'scanner {} recognized tokens {}' self.logger\ .cond((_logging.INSECURE, lambda: message.format(scanner, scanned_tokens)), (_logging.DEBUG, lambda: message.format(scanner, scanned_tokens.keys()))) prospective_affordances.outputs.add(scanned_tokens.frozen()) if not prospective_affordances.scanners: prospective_affordances.scanners = resolution_affordances.scanners if not prospective_affordances.outputs: prospective_affordances.outputs.add(()) prospective_affordances, phase = \ self._best_resolved_prospective_affordances_and_phase\ (prospective_affordances) if prospective_affordances is None: raise _exc.Error('cannot resolve an acceptable authentication' ' process') prospective_affordances.require_nonempty() if scanned_auth_info: auth_info = scanned_auth_info else: auth_info = _info.RequestAuthInfo() prospective_affordances = prospective_affordances.unfrozen() self._update_afforded_tokens_from_auth_info(prospective_affordances, auth_info) prospective_affordances.require_nonempty() prospective_affordances.require_finite(exceptions=('outputs')) realm = iter(prospective_affordances.realms).next() algorithm = iter(prospective_affordances.algorithms).next() clerk = iter(prospective_affordances.clerks).next() scanner = iter(prospective_affordances.scanners).next() supplicant = iter(prospective_affordances.supplicants).next() process_affordances = prospective_affordances.general auth_info.space = space auth_info.realm = realm auth_info.algorithm = algorithm auth_info.clerk = clerk auth_info.scanner = scanner auth_info.supplicant = supplicant self.logger.cond((_logging.DEBUG, lambda: 'chose realm {}'.format(realm))) self.logger.cond((_logging.DEBUG, lambda: 'chose algorithm {!r}'.format(algorithm))) self.logger.cond((_logging.DEBUG, lambda: 'chose clerk {!r}'.format(clerk))) self.logger.cond((_logging.DEBUG, lambda: 'chose scanner {!r}'.format(scanner))) self.logger.cond((_logging.DEBUG, lambda: 'chose supplicant {!r}'.format(supplicant))) self.logger.cond((_logging.DEBUG, lambda: 'starting authentication with phase {} and' ' affordances {}' .format(phase, process_affordances))) unauth_exc = None unauth_traceback = None try: auth_info = self._process_phase(phase, clerk=clerk, scanner=scanner, supplicant=supplicant, affordances=process_affordances, auth_info=auth_info) except _bedframe_exc.Unauthenticated as unauth_exc: unauth_traceback = _sys.exc_info()[2] self.current_auth_info = auth_info message = 'final info {}' self.logger\ .cond((_logging.INSECURE, lambda: message.format(auth_info.repr(insecure=True))), (_logging.DEBUG, lambda: message.format(auth_info.repr(insecure=False)))) if unauth_exc: raise unauth_exc, None, unauth_traceback affordances = process_affordances.general if auth_info.verified: clerk.confirm_auth_info(auth_info, affordances=affordances) if not auth_info.accepted: raise _bedframe_exc.AuthTokensNotAccepted(affordances=affordances) else: # FIXME raise _exc.Error