def _discovery(request): """Returns a JSON file listing the services supported by the server.""" services = request.registry.settings['tokenserver.applications'] discovery = {} discovery["services"] = services discovery["auth"] = request.url.rstrip("/") try: verifier = get_browserid_verifier(request.registry) except ComponentLookupError: pass else: discovery["browserid"] = { "allowed_issuers": verifier.allowed_issuers, "trusted_issuers": verifier.trusted_issuers, } try: verifier = get_oauth_verifier(request.registry) except ComponentLookupError: pass else: discovery["oauth"] = { "default_issuer": verifier.default_issuer, "scope": verifier.scope, "server_url": verifier.server_url, } return discovery
def _valid_browserid_assertion(request, assertion): try: verifier = get_browserid_verifier(request.registry) with metrics_timer('tokenserver.assertion.verify', request): assertion = verifier.verify(assertion) except browserid.errors.Error as e: # Convert CamelCase to under_scores for reporting. error_type = e.__class__.__name__ error_type = re.sub('(?<=.)([A-Z])', r'_\1', error_type).lower() request.metrics['token.assertion.verify_failure'] = 1 request.metrics['token.assertion.%s' % error_type] = 1 # Log a full traceback for errors that are not a simple # "your assertion was bad and we dont trust it". if not isinstance(e, browserid.errors.TrustError): logger.exception("Unexpected verification error") # Report an appropriate error code. if isinstance(e, browserid.errors.ConnectionError): raise json_error(503, description="Resource is not available") if isinstance(e, browserid.errors.ExpiredSignatureError): raise _unauthorized("invalid-timestamp") raise _unauthorized("invalid-credentials") # FxA sign-in confirmation introduced the notion of unverified tokens. # The default value is True to preserve backwards compatibility. try: tokenVerified = assertion['idpClaims']['fxa-tokenVerified'] except KeyError: tokenVerified = True if not tokenVerified: raise _unauthorized("invalid-credentials") # everything sounds good, add the assertion to the list of validated fields # and continue request.metrics['token.assertion.verify_success'] = 1 request.validated['authorization'] = assertion id_key = request.registry.settings.get("fxa.metrics_uid_secret_key") if id_key is None: id_key = 'insecure' email = assertion['email'] fxa_uid_full = fxa_metrics_hash(email, id_key) # "legacy" key used by heka active_counts.lua request.metrics['uid'] = fxa_uid_full request.metrics['email'] = email # "new" keys use shorter values fxa_uid = fxa_uid_full[:32] request.validated['fxa_uid'] = fxa_uid request.metrics['fxa_uid'] = fxa_uid try: device = assertion['idpClaims']['fxa-deviceId'] if device is None: device = 'none' except KeyError: device = 'none' device_id = fxa_metrics_hash(fxa_uid + device, id_key)[:32] request.validated['device_id'] = device_id request.metrics['device_id'] = device_id
def _discovery(request): """Returns a JSON file listing the services supported by the server.""" services = request.registry.settings['tokenserver.applications'] discovery = {} discovery["services"] = services discovery["auth"] = request.url.rstrip("/") verifier = get_browserid_verifier(request.registry) discovery["browserid"] = { "allowed_issuers": verifier.allowed_issuers, "trusted_issuers": verifier.trusted_issuers, } verifier = get_oauth_verifier(request.registry) discovery["oauth"] = { "default_issuer": verifier.default_issuer, "scope": verifier.scope, "server_url": verifier.server_url, } return discovery
def mock_browserid_verifier(self, response=None, exc=None): def mock_verify_method(assertion): if exc is not None: raise exc if response is not None: return response return { "status": "okay", "email": get_assertion_info(assertion)["principal"]["email"], } verifier = get_browserid_verifier(self.config.registry) orig_verify_method = verifier.__dict__.get("verify", None) verifier.__dict__["verify"] = mock_verify_method try: yield None finally: if orig_verify_method is None: del verifier.__dict__["verify"] else: verifier.__dict__["verify"] = orig_verify_method
def mock_browserid_verifier(self, response=None, exc=None): def mock_verify_method(assertion): if exc is not None: raise exc if response is not None: return response return { "status": "okay", "email": get_assertion_info(assertion)["principal"]["email"], } verifier = get_browserid_verifier(self.config.registry) orig_verify_method = verifier.__dict__.get("verify", None) verifier.__dict__["verify"] = mock_verify_method try: yield None finally: if orig_verify_method is None: del verifier.__dict__["verify"] else: verifier.__dict__["verify"] = orig_verify_method
def _validate_browserid_assertion(request, assertion): try: verifier = get_browserid_verifier(request.registry) except ComponentLookupError: raise _unauthorized(description='Unsupported') try: with metrics_timer('tokenserver.assertion.verify', request): assertion = verifier.verify(assertion) except browserid.errors.Error as e: # Convert CamelCase to under_scores for reporting. error_type = e.__class__.__name__ error_type = re.sub('(?<=.)([A-Z])', r'_\1', error_type).lower() request.metrics['token.assertion.verify_failure'] = 1 request.metrics['token.assertion.%s' % error_type] = 1 # Log a full traceback for errors that are not a simple # "your assertion was bad and we dont trust it". if not isinstance(e, browserid.errors.TrustError): logger.exception("Unexpected verification error") # Report an appropriate error code. if isinstance(e, browserid.errors.ConnectionError): raise json_error(503, description="Resource is not available") if isinstance(e, browserid.errors.ExpiredSignatureError): raise _unauthorized("invalid-timestamp") raise _unauthorized("invalid-credentials") # FxA sign-in confirmation introduced the notion of unverified tokens. # The default value is True to preserve backwards compatibility. try: tokenVerified = assertion['idpClaims']['fxa-tokenVerified'] except KeyError: tokenVerified = True if not tokenVerified: raise _unauthorized("invalid-credentials") # everything sounds good, add the assertion to the list of validated fields # and continue request.metrics['token.assertion.verify_success'] = 1 request.validated['authorization'] = assertion
def _validate_browserid_assertion(request, assertion): try: verifier = get_browserid_verifier(request.registry) except ComponentLookupError: raise _unauthorized(description='Unsupported') try: with metrics_timer('tokenserver.assertion.verify', request): assertion = verifier.verify(assertion) except browserid.errors.Error as e: # Convert CamelCase to under_scores for reporting. error_type = e.__class__.__name__ error_type = re.sub('(?<=.)([A-Z])', r'_\1', error_type).lower() request.metrics['token.assertion.verify_failure'] = 1 request.metrics['token.assertion.%s' % error_type] = 1 # Log a full traceback for errors that are not a simple # "your assertion was bad and we dont trust it". if not isinstance(e, browserid.errors.TrustError): logger.exception("Unexpected verification error") # Report an appropriate error code. if isinstance(e, browserid.errors.ConnectionError): raise json_error(503, description="Resource is not available") if isinstance(e, browserid.errors.ExpiredSignatureError): raise _unauthorized("invalid-timestamp") raise _unauthorized("invalid-credentials") # FxA sign-in confirmation introduced the notion of unverified tokens. # The default value is True to preserve backwards compatibility. try: tokenVerified = assertion['idpClaims']['fxa-tokenVerified'] except KeyError: tokenVerified = True if not tokenVerified: raise _unauthorized("invalid-credentials") # everything sounds good, add the assertion to the list of validated fields # and continue request.metrics['token.assertion.verify_success'] = 1 request.validated['authorization'] = assertion