def test_validate_context_ok_noscopes(self): '''This test case ensures a security context is valid when no required scopes are necessary.''' access_token = Token({"scopes": ["scope1"]}) security_ctx = SecurityContext(access_token) self.assertTrue(security_ctx.validate_context())
def test_validate_context_ok_noscopes(self): """This test case ensures a security context is valid when no required scopes are necessary.""" access_token = Token({"scopes": ["scope1"]}) security_ctx = SecurityContext(access_token) self.assertTrue(security_ctx.validate_context())
def test_validate_context_invalid(self): """This test case ensures a security context is invalid when required scopes are not found in access_token scopes.""" for attr_scope in self._ATTR_SCOPES: access_token = Token({"scopes": []}) required_scopes = ["scope1", "scope2"] required_scopes_obj = self._mock_required_scopes_obj(attr_scope, required_scopes) security_ctx = SecurityContext(access_token, required_scopes_obj) self.assertFalse(security_ctx.validate_context(attr_scope))
def test_validate_context_invalid(self): '''This test case ensures a security context is invalid when required scopes are not found in access_token scopes.''' for attr_scope in self._ATTR_SCOPES: access_token = Token({"scopes": []}) required_scopes = ["scope1", "scope2"] required_scopes_obj = self._mock_required_scopes_obj( attr_scope, required_scopes) security_ctx = SecurityContext(access_token, required_scopes_obj) self.assertFalse(security_ctx.validate_context(attr_scope))
def __call__(self, environ, start_response, conn_manager=mvc): '''This method is invoked automatically during middleware pipeline execution. For tokens middleware, this is the place where oauth2 access tokens are decrypted and validated.''' request = environ.get("fantastico.request") if not request: raise FantasticoNoRequestError( "OAuth2TokensMiddleware must execute after RequestMiddleware.") if not conn_manager.CONN_MANAGER: raise FantasticoDbError( msg= "OAuth2TokensMiddleware must execute after ModelSessionMiddleware." ) db_conn = conn_manager.CONN_MANAGER.get_connection(request.request_id) encrypted_token = request.params.get( self.TOKEN_QPARAM, self._get_token_from_header(request)) if not encrypted_token: request.context.security = SecurityContext(None) return self._app(environ, start_response) request.context.security = self._build_security_context( encrypted_token, db_conn) return self._app(environ, start_response)
def _build_security_context(self, encrypted_token, db_conn): '''This method builds a security context using the current encrypted token and the currently opened db connection.''' tokens_service = self._tokens_service_cls(db_conn) token = tokens_service.decrypt(encrypted_token) tokens_service.validate(token) return SecurityContext(token)
def inject_scopes_in_security(self, request): '''This method injects the request scopes into request security context.''' security_ctx = request.context.security ctx = SecurityContext(access_token=security_ctx.access_token, required_scopes=self) request.context.security = ctx
def test_required_scopes_unauthorized(self): '''This test case ensures a concrete exception is raised if the requested scopes are not available in the current security context.''' access_token = Token({"scopes": []}) request = Mock() request.context = Mock() request.context.security = SecurityContext(access_token) mock_controller = MockController(Mock()) self.assertRaises(OAuth2UnauthorizedError, lambda: mock_controller.do_stuff(request))
def _test_required_scopes_method(self, method, expected_scopes): '''This method provides a template test case for invoking and asserting result of a method decorated with @RequiredScopes.''' expected_scopes = sorted(expected_scopes) access_token = Token({"scopes": expected_scopes}) request = Mock() request.context = Mock() request.context.security = SecurityContext(access_token) self.assertIsNone(method(request)) security_ctx = request.context.security self.assertEqual(access_token, security_ctx.access_token) self.assertEqual(expected_scopes, security_ctx.required_scopes.scopes)
def _test_validate_owned_by_user(self, resource, user_id, person_id): '''This method provides a template for testing validation for scenarios where resource belongs / does not belong to expected user.''' token = Token({"user_id": user_id, "scopes": []}) request = Mock() request.request_id = 1 request.context = Mock() request.context.security = SecurityContext(token) self._model_facade.find_by_pk = Mock(return_value=User(person_id=1)) self._validator.validate(resource, request, person_id) self._conn_manager.get_connection.assert_called_once_with( request.request_id) self._model_facade_cls.assert_called_once_with(User, self._db_conn) self._model_facade.find_by_pk.assert_called_once_with( {User.user_id: token.user_id})