async def handle_oauth_callback( identity_provider_input: str, request: web.Request ) -> Tuple[str, str]: """Callback handler for oauth protocol""" if identity_provider_input not in identity_providers.BACKENDS: raise web.HTTPBadRequest(reason="Identity provider not implemented") identity_provider_path = identity_providers.BACKENDS[identity_provider_input] identity_provider_settings = request.app["settings"]["idps"][ identity_provider_input ] identity_provider = import_class(identity_provider_path)(identity_provider_settings) idp_claims = await identity_provider.authenticate_user( { "oauth_verifier": request.rel_url.query.get("oauth_verifier"), "oauth_token": request.rel_url.query.get("oauth_token"), }, step=2, ) sub = f"{identity_provider_input}-{idp_claims['sub']}" if not await request.app["storage_backend"].user_exists(sub): await request.app["storage_backend"].create_user(sub) groups = await request.app["storage_backend"].get_authorizations_for_user(sub) pasee_claims = { "iss": request.app["settings"]["jwt"]["iss"], "sub": sub, "groups": groups, } return generate_access_token_and_refresh_token_pairs( pasee_claims, request.app["settings"]["private_key"], algorithm=request.app["settings"]["algorithm"], )
def test_import_storage_backend(): """Test importing authorization backend""" with pytest.raises(ImportError): import_class("helloworldxddd~~~") with pytest.raises(ImportError): import_class("my.dummy.path") with pytest.raises(ImportError): import_class("pasee.storage_backend.test_backend.UnknownClass") with pytest.raises(ImportError): import_class( "pasee.storage_backend.demo_backend.sqlite.UnknownClassName")
async def authenticate_with_identity_provider(request: web.Request) -> Claims: """Use identity provider provided by user to authenticate.""" try: input_data = await request.json() except json.decoder.JSONDecodeError: input_data = {} identity_provider_input = request.rel_url.query.get("idp", None) if not identity_provider_input: raise web.HTTPBadRequest( reason="Identity provider not provided in query string" ) if identity_provider_input not in request.app["settings"]["idps"]: raise web.HTTPBadRequest(reason="Identity provider not implemented") identity_provider_path = request.app["settings"]["idps"][identity_provider_input][ "implementation" ] identity_provider_settings = request.app["settings"]["idps"][ identity_provider_input ] identity_provider = import_class(identity_provider_path)(identity_provider_settings) return await identity_provider.authenticate_user(input_data)
def get_identity_provider_with_capability(settings, capability): """Returns an identity provider with capability passed in argument""" for idp in settings["identity_providers"]: if capability in idp.get("capabilities", set()): return import_class(idp["implementation"])(idp) return None
def identification_app(settings, ): """Identification provider entry point: builds and run a webserver.""" app = web.Application(middlewares=[ verify_input_body_is_json, transform_unauthorized, coreapi_error_middleware, security_headers, ]) app["settings"] = settings app["storage_backend"] = import_class( settings["storage_backend"]["class"])( settings["storage_backend"]["options"]) async def on_startup_wrapper(app): """Wrapper to call __aenter__.""" await app["storage_backend"].__aenter__() async def on_cleanup_wrapper(app): """Wrapper to call __exit__.""" await app["storage_backend"].__aexit__(None, None, None) app.on_startup.append(on_startup_wrapper) app.on_cleanup.append(on_cleanup_wrapper) app.add_routes([ web.get("/", views.get_root, name="get_root"), web.get("/public-key/", views.get_public_key, name="get_public_key"), web.get("/tokens/", token_views.get_tokens, name="get_tokens"), web.post("/tokens/", token_views.post_token, name="post_tokens"), web.get("/users/", user_views.get_users), web.get("/users/{username}", user_views.get_user), web.delete("/users/{username}", user_views.delete_user), web.patch("/users/{username}", user_views.patch_user), web.get("/groups/", group_views.get_groups), web.post("/groups/", group_views.post_groups), web.get("/groups/{group_uid}/", group_views.get_group), web.delete("/groups/{group_uid}/", group_views.delete_group), web.post("/groups/{group_uid}/", group_views.post_group), web.delete("/groups/{group_uid}/{username}/", group_views.delete_group_member), ]) cors = aiohttp_cors.setup( app, defaults={ "*": aiohttp_cors.ResourceOptions( allow_credentials=True, expose_headers="*", allow_headers="*", allow_methods=[ "GET", "OPTIONS", "PUT", "POST", "DELETE", "PATCH" ], ) }, ) for route in list(app.router.routes()): cors.add(route) return app