def decorated_function(*args, **kwargs): if not current_user.is_authenticated: flash('Please log in to access that page.') return redirect(url_for('home.index')) g.user_permissions = get_user_permissions( current_user.id, current_app.config['CLIENT_ID']) if not any(s in g.user_permissions for s in scope): flash('You do not have permission to access that page.', category='warning') return redirect(request.referrer or url_for('home.index')) try: # call the view function return f(*args, **kwargs) except ODPAPIError as e: if response := handle_error(e): return response if e.status_code == 503: # avoid redirect loops when the API is unavailable return redirect(url_for('home.index')) if fallback_to_referrer and request.referrer: return redirect(request.referrer) # fall back to the index page return redirect(url_for('.index'))
def test_platform_roles(): scopes = ScopeFactory.create_batch(8, type='odp') client = ClientFactory(scopes=scopes[1:7]) role1 = RoleFactory(scopes=scopes[:3]) role2 = RoleFactory(scopes=scopes[5:]) user = UserFactory(roles=(role1, role2)) actual_user_perm = get_user_permissions(user.id, client.id) expected_user_perm = { scope.id: '*' for n, scope in enumerate(scopes) if n in (1, 2, 5, 6) } assert_compare(expected_user_perm, actual_user_perm) actual_client_perm = get_client_permissions(client.id) expected_client_perm = {scope.id: '*' for scope in scopes[1:7]} assert_compare(expected_client_perm, actual_client_perm)
def consent(): """ Implements the consent provider component of the Hydra consent workflow. Hydra redirects to this endpoint based on the ``URLS_CONSENT`` environment variable configured on the Hydra server. """ challenge = request.args.get('consent_challenge') try: consent_request = hydra_admin.get_consent_request(challenge) user_id = consent_request['subject'] client_id = consent_request['client']['client_id'] try: user_permissions = get_user_permissions(user_id, client_id) user_info = get_user_info(user_id, client_id) grant_scope = [ requested_scope_id for requested_scope_id in consent_request['requested_scope'] if requested_scope_id in user_permissions or requested_scope_id not in ODPScope.__members__.values() ] consent_params = { 'grant_scope': grant_scope, 'grant_audience': consent_request['requested_access_token_audience'], 'access_token_data': user_permissions, 'id_token_data': asdict(user_info), } redirect_to = hydra_admin.accept_consent_request( challenge, **consent_params) return redirect(redirect_to) except x.ODPIdentityError as e: redirect_to = hydra_admin.reject_consent_request( challenge, e.error_code, e.error_description) return redirect(redirect_to) except x.HydraAdminError as e: return hydra_error_page(e)
def test_collection_client_platform_collection_role_mix(): scopes = ScopeFactory.create_batch(8, type='odp') client = ClientFactory(scopes=scopes[1:7], is_collection_client=True) role1 = RoleFactory(scopes=scopes[:3]) role2 = RoleFactory(scopes=scopes[3:5], is_collection_role=True) role3 = RoleFactory(scopes=scopes[5:], collection=client.collection) user = UserFactory(roles=(role1, role2, role3)) actual_user_perm = get_user_permissions(user.id, client.id) expected_user_perm = { scope.id: [client.collection_id] for n, scope in enumerate(scopes) if n in (1, 2, 5, 6) } assert_compare(expected_user_perm, actual_user_perm) actual_client_perm = get_client_permissions(client.id) expected_client_perm = { scope.id: [client.collection_id] for scope in scopes[1:7] } assert_compare(expected_client_perm, actual_client_perm)
def _authorize_request(request: Request, required_scope_id: str) -> Authorized: auth_header = request.headers.get('Authorization') scheme, access_token = get_authorization_scheme_param(auth_header) if not auth_header or scheme.lower() != 'bearer': raise HTTPException( status_code=HTTP_401_UNAUTHORIZED, headers={'WWW-Authenticate': 'Bearer'}, ) token: OAuth2TokenIntrospection = hydra_admin_api.introspect_token( access_token, [required_scope_id], ) if not token.active: raise HTTPException(HTTP_403_FORBIDDEN) # if sub == client_id it's an API call from a client, # using a client credentials grant if token.sub == token.client_id: client_permissions = get_client_permissions(token.client_id) if required_scope_id not in client_permissions: raise HTTPException(HTTP_403_FORBIDDEN) return Authorized( client_id=token.client_id, user_id=None, collection_ids=client_permissions[required_scope_id], ) # user-initiated API call user_permissions = get_user_permissions(token.sub, token.client_id) if required_scope_id not in user_permissions: raise HTTPException(HTTP_403_FORBIDDEN) return Authorized( client_id=token.client_id, user_id=token.sub, collection_ids=user_permissions[required_scope_id], )
def test_collection_roles(): scopes = ScopeFactory.create_batch(8, type='odp') client = ClientFactory(scopes=scopes[1:7]) role1 = RoleFactory(scopes=scopes[:5], is_collection_role=True) role2 = RoleFactory(scopes=scopes[3:], is_collection_role=True) user = UserFactory(roles=(role1, role2)) actual_user_perm = get_user_permissions(user.id, client.id) expected_user_perm = { scope.id: [role1.collection_id] for n, scope in enumerate(scopes) if n in (1, 2) } | { scope.id: [role1.collection_id, role2.collection_id] for n, scope in enumerate(scopes) if n in (3, 4) } | { scope.id: [role2.collection_id] for n, scope in enumerate(scopes) if n in (5, 6) } assert_compare(expected_user_perm, actual_user_perm) actual_client_perm = get_client_permissions(client.id) expected_client_perm = {scope.id: '*' for scope in scopes[1:7]} assert_compare(expected_client_perm, actual_client_perm)