Skip to content

Commit

Permalink
Override fideslib.oauth.api.deps.verify_oauth_client to pass in the c…
Browse files Browse the repository at this point in the history
…onfig instead of overriding fideslib.oauth.oauth_util.verify_oauth_client.
  • Loading branch information
pattisdr committed Oct 22, 2022
1 parent 0061b11 commit 5751fd7
Show file tree
Hide file tree
Showing 4 changed files with 15 additions and 54 deletions.
2 changes: 1 addition & 1 deletion noxfiles/dev_nox.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@
START_APP_EXTERNAL,
)
from docker_nox import build
from utils_nox import COMPOSE_DOWN_VOLUMES
from run_infrastructure import ALL_DATASTORES, run_infrastructure
from utils_nox import COMPOSE_DOWN_VOLUMES


@nox.session()
Expand Down
60 changes: 8 additions & 52 deletions src/fides/api/ops/util/oauth_util.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,23 +5,19 @@

from fastapi import Depends, HTTPException, Security
from fastapi.security import SecurityScopes
from fideslib.cryptography.schemas.jwt import (
JWE_ISSUED_AT,
JWE_PAYLOAD_CLIENT_ID,
JWE_PAYLOAD_SCOPES,
)
from fideslib.cryptography.schemas.jwt import JWE_PAYLOAD_SCOPES
from fideslib.exceptions import AuthenticationError, AuthorizationError
from fideslib.models.client import ClientDetail
from fideslib.models.fides_user import FidesUser
from fideslib.oauth.oauth_util import extract_payload, is_token_expired
from fideslib.oauth.oauth_util import extract_payload
from fideslib.oauth.oauth_util import verify_oauth_client as verify
from fideslib.oauth.schemas.oauth import OAuth2ClientCredentialsBearer
from jose.constants import ALGORITHMS
from pydantic import ValidationError
from sqlalchemy.orm import Session
from starlette.status import HTTP_404_NOT_FOUND

from fides.api.ops.api.deps import get_db
from fides.api.ops.api.v1.scope_registry import SCOPE_REGISTRY
from fides.api.ops.api.v1.urn_registry import TOKEN, V1_URL_PREFIX
from fides.api.ops.models.policy import PolicyPreWebhook
from fides.api.ops.schemas.external_https import WebhookJWE
Expand All @@ -31,8 +27,6 @@
JWT_ENCRYPTION_ALGORITHM = ALGORITHMS.A256GCM


# TODO: include list of all scopes in the docs via the scopes={} dict
# (see https://fastapi.tiangolo.com/advanced/security/oauth2-scopes/)
oauth2_scheme = OAuth2ClientCredentialsBearer(
tokenUrl=(V1_URL_PREFIX + TOKEN),
)
Expand Down Expand Up @@ -105,51 +99,13 @@ def verify_callback_oauth(
return webhook


async def verify_oauth_client(
def verify_oauth_client(
security_scopes: SecurityScopes,
authorization: str = Security(oauth2_scheme),
db: Session = Depends(get_db),
) -> ClientDetail:
"""
Verifies that the access token provided in the authorization header contains
the necessary scopes specified by the caller. Yields a 403 forbidden error
if not
"""
if authorization is None:
raise AuthenticationError(detail="Authentication Failure")

token_data = json.loads(
extract_payload(authorization, CONFIG.security.app_encryption_key)
)

issued_at = token_data.get(JWE_ISSUED_AT, None)
if not issued_at:
raise AuthorizationError(detail="Not Authorized for this action")

if is_token_expired(
datetime.fromisoformat(issued_at),
CONFIG.security.oauth_access_token_expire_minutes,
):
raise AuthorizationError(detail="Not Authorized for this action")

assigned_scopes = token_data[JWE_PAYLOAD_SCOPES]
if not set(security_scopes.scopes).issubset(assigned_scopes):
raise AuthorizationError(detail="Not Authorized for this action")

client_id = token_data.get(JWE_PAYLOAD_CLIENT_ID)
if not client_id:
raise AuthorizationError(detail="Not Authorized for this action")
"""Calls fideslib oauth_util.verify_oauth_client.
# scopes param is only used if client is root client, otherwise we use the client's associated scopes
client = ClientDetail.get(
db, object_id=client_id, config=CONFIG, scopes=SCOPE_REGISTRY
)

if not client:
raise AuthorizationError(detail="Not Authorized for this action")

if not set(assigned_scopes).issubset(set(client.scopes)):
# If the scopes on the token are not a subset of the scopes available
# to the associated oauth client, this token is not valid
raise AuthorizationError(detail="Not Authorized for this action")
return client
This override is needed because we have to pass in the config.
"""
return verify(security_scopes, authorization, db=db, config=CONFIG)
2 changes: 1 addition & 1 deletion src/fides/ctl/core/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@
import re
from functools import partial
from json.decoder import JSONDecodeError
from typing import Dict, Iterator, List
from os.path import isfile
from typing import Dict, Iterator, List

import click
import jwt
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,11 @@ def test_patch_connections_not_authenticated(
response = api_client.patch(url, headers={}, json=payload)
assert 401 == response.status_code

def test_malformed_token_is_forbidden(self, api_client: TestClient, url, payload):
auth_header = {"Authorization": "Bearer invalid"}
response = api_client.patch(url, headers=auth_header, json=payload)
assert 403 == response.status_code

def test_patch_connections_incorrect_scope(
self, api_client: TestClient, generate_auth_header, url, payload
) -> None:
Expand Down

0 comments on commit 5751fd7

Please sign in to comment.