예제 #1
0
async def test_assign_user_info(auth):
    """three way to set user info schema
    1. pass it to arguments when create instance
    2. call `.claim` method and pass it to that arguments
    3. assign with `=` statements
    """
    class SubSchema(BaseModel):
        sub: str

    class NameSchema(BaseModel):
        name: str

    class IatSchema(BaseModel):
        iat: int

    # authorized token
    dummy_http_auth = HTTPAuthorizationCredentials(
        scheme="a",
        credentials=
        "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6Im5hbWUiLCJpYXQiOjE1MTYyMzkwMjJ9.3ZEDmhWNZWDbJDPDlZX_I3oaalNYXdoT-bKLxIxQK4U",
    )

    user = auth(jwks=JWKS.null(), user_info=IatSchema)
    assert await user.call(dummy_http_auth) == IatSchema(iat=1516239022)

    assert await user.claim(SubSchema).call(dummy_http_auth) == SubSchema(
        sub="1234567890")

    user.user_info = NameSchema
    assert await user.call(dummy_http_auth) == NameSchema(name="name")
예제 #2
0
파일: sso.py 프로젝트: Yodo1Games/py-yodo1
 async def __call__(
         self, request: Request) -> Optional[HTTPAuthorizationCredentials]:
     authorization_in_request: str = request.headers.get("Authorization")
     authorization_in_cookie: str = request.cookies.get("Authorization")
     if authorization_in_request:
         scheme, credentials = get_authorization_scheme_param(
             authorization_in_request)
     elif authorization_in_cookie:
         scheme, credentials = get_authorization_scheme_param(
             authorization_in_cookie)
     else:
         scheme, credentials = None, None
     if not (scheme and credentials):
         if self.auto_error:
             raise HTTPException(status_code=HTTP_401_UNAUTHORIZED,
                                 detail="Not authenticated")
         else:
             return None
     if scheme.lower() != "bearer":
         if self.auto_error:
             raise HTTPException(
                 status_code=HTTP_401_UNAUTHORIZED,
                 detail="Invalid authentication credentials",
             )
         else:
             return None
     return HTTPAuthorizationCredentials(scheme=scheme,
                                         credentials=credentials)
예제 #3
0
async def test_malformed_token_handling():
    http_auth_with_malformed_token = HTTPAuthorizationCredentials(
        scheme="a",
        credentials="malformed-token",
    )

    verifier = JWKsVerifier(jwks=JWKS.null())
    with pytest.raises(HTTPException):
        await verifier._get_publickey(http_auth_with_malformed_token)
    with pytest.raises(HTTPException):
        await verifier.verify_token(http_auth_with_malformed_token)

    verifier = JWKsVerifier(jwks=JWKS.null(), auto_error=False)
    assert not await verifier._get_publickey(http_auth_with_malformed_token)
    assert not await verifier.verify_token(http_auth_with_malformed_token)

    verifier = ScopedJWKsVerifier(jwks=JWKS.null())
    with pytest.raises(HTTPException):
        verifier._verify_scope(http_auth_with_malformed_token)
    with pytest.raises(HTTPException):
        await verifier.verify_token(http_auth_with_malformed_token)

    verifier = ScopedJWKsVerifier(jwks=JWKS.null(), auto_error=False)
    assert not verifier._verify_scope(http_auth_with_malformed_token)
    assert not await verifier.verify_token(http_auth_with_malformed_token)
예제 #4
0
def test_verify_scope_exeption(mocker):
    mocker.patch(
        "fastapi_cloudauth.verification.jwt.get_unverified_claims",
        return_value={"dummy key": "read:test"},
    )
    scope_key = "dummy key"
    http_auth = HTTPAuthorizationCredentials(
        scheme="a",
        credentials="dummy-token",
    )

    # trivial scope
    verifier = ScopedJWKsVerifier(jwks=JWKS.null(),
                                  scope_key=scope_key,
                                  scope_name=None)
    assert verifier._verify_scope(http_auth)

    # invalid incoming scope format
    mocker.patch(
        "fastapi_cloudauth.verification.jwt.get_unverified_claims",
        return_value={"dummy key": 100},
    )
    verifier = ScopedJWKsVerifier(jwks=JWKS.null(),
                                  scope_key=scope_key,
                                  scope_name=["read:test"])
    with pytest.raises(HTTPException):
        verifier._verify_scope(http_auth)
    # auto_error is False
    verifier = ScopedJWKsVerifier(
        jwks=JWKS.null(),
        scope_key=scope_key,
        scope_name=["read:test"],
        auto_error=False,
    )
    assert not verifier._verify_scope(http_auth)
예제 #5
0
async def test_forget_def_user_info(auth):
    dummy_http_auth = HTTPAuthorizationCredentials(
        scheme="a",
        credentials=
        "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6Im5hbWUiLCJpYXQiOjE1MTYyMzkwMjJ9.3ZEDmhWNZWDbJDPDlZX_I3oaalNYXdoT-bKLxIxQK4U",
    )
    """If `.user_info` is None, return raw payload"""
    get_current_user = auth(jwks=JWKS.null())
    assert get_current_user.user_info is None
    res = await get_current_user.call(dummy_http_auth)
    assert res == {"sub": "1234567890", "name": "name", "iat": 1516239022}
예제 #6
0
def test_validation_scope(mocker, scopes):
    mocker.patch(
        "fastapi_cloudauth.verification.jwt.get_unverified_claims",
        return_value={"dummy key": scopes},
    )
    verifier = ScopedAuth(jwks=JWKS.null())
    scope_key = "dummy key"
    verifier.scope_key = scope_key

    scope_name = "user-assigned-scope"
    obj = verifier.scope(scope_name)
    assert obj.verifier._verify_scope(
        HTTPAuthorizationCredentials(scheme="", credentials=""))

    scope_name = "user-assigned-scope-invalid"
    obj = verifier.scope(scope_name)
    with pytest.raises(HTTPException):
        obj.verifier._verify_scope(
            HTTPAuthorizationCredentials(scheme="", credentials=""))

    obj.verifier.auto_error = False
    assert not obj.verifier._verify_scope(
        HTTPAuthorizationCredentials(scheme="", credentials=""))
예제 #7
0
def test_scope_match_all(mocker, scopes):
    scope_key = "dummy key"
    http_auth = HTTPAuthorizationCredentials(
        scheme="a",
        credentials="dummy-token",
    )

    # check scope logic
    mocker.patch(
        "fastapi_cloudauth.verification.jwt.get_unverified_claims",
        return_value={"dummy key": scopes},
    )
    jwks = JWKS.null()

    # api scope < user scope
    verifier = ScopedJWKsVerifier(
        scope_name=["xxx:xxx"],
        jwks=jwks,
        scope_key=scope_key,
        auto_error=False,
    )
    assert verifier._verify_scope(http_auth)

    # api scope == user scope (in order)
    verifier = ScopedJWKsVerifier(
        scope_name=["xxx:xxx", "yyy:yyy"],
        jwks=jwks,
        scope_key=scope_key,
        auto_error=False,
    )
    assert verifier._verify_scope(http_auth)

    # api scope == user scope (disorder)
    verifier = ScopedJWKsVerifier(
        scope_name=["yyy:yyy", "xxx:xxx"],
        jwks=jwks,
        scope_key=scope_key,
        auto_error=False,
    )
    assert verifier._verify_scope(http_auth)

    # api scope > user scope
    verifier = ScopedJWKsVerifier(
        scope_name=["yyy:yyy", "xxx:xxx", "zzz:zzz"],
        jwks=jwks,
        scope_key=scope_key,
        auto_error=False,
    )
    assert not verifier._verify_scope(http_auth)
예제 #8
0
async def test_extract_raw_user_info(auth):
    dummy_http_auth = HTTPAuthorizationCredentials(
        scheme="a",
        credentials=
        "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6Im5hbWUiLCJpYXQiOjE1MTYyMzkwMjJ9.3ZEDmhWNZWDbJDPDlZX_I3oaalNYXdoT-bKLxIxQK4U",
    )

    class NameSchema(BaseModel):
        name: str

    get_current_user = auth(jwks=JWKS.null(), user_info=NameSchema)
    get_current_user.user_info = None
    res = await get_current_user.call(dummy_http_auth)
    assert res == {"sub": "1234567890", "name": "name", "iat": 1516239022}

    get_current_user = auth(jwks=JWKS.null(), user_info=NameSchema)
    res = await get_current_user.claim(None).call(dummy_http_auth)
    assert res == {"sub": "1234567890", "name": "name", "iat": 1516239022}
예제 #9
0
async def test_bearer_auth() -> None:
    """Check bearer auth return user id from scope."""
    request = Request(
        scope={
            "type": "http",
            "method": "GET",
            "headers": [],
            "token_data": {
                "user_id": str(USER_UUID),
            }
        })
    credentials: HTTPAuthorizationCredentials = HTTPAuthorizationCredentials(
        scheme="test",
        credentials="test",
    )

    user_id: Optional[str] = await bearer_auth(request=request,
                                               http_credentials=credentials)

    AssertThat(user_id).IsEqualTo(str(USER_UUID))
예제 #10
0
def _assert_verifier_no_error(token, verifier: JWKsVerifier) -> None:
    http_auth = HTTPAuthorizationCredentials(scheme="a", credentials=token)
    assert verifier._verify_claims(http_auth) is False
예제 #11
0
def _assert_verifier(token, verifier: JWKsVerifier) -> HTTPException:
    http_auth = HTTPAuthorizationCredentials(scheme="a", credentials=token)
    with pytest.raises(HTTPException) as e:
        verifier._verify_claims(http_auth)
    return e.value
예제 #12
0
def test_verify_token():
    verifier = JWKsVerifier(jwks=JWKS.null())
    verifier_no_error = JWKsVerifier(jwks=JWKS.null(), auto_error=False)

    # correct
    token = jwt.encode(
        {
            "sub": "dummy-ID",
            "exp": datetime.utcnow() + timedelta(hours=10),
            "iat": datetime.utcnow(),
        },
        "dummy_secret",
        headers={
            "alg": "HS256",
            "typ": "JWT",
            "kid": "dummy-kid"
        },
    )
    verifier._verify_claims(
        HTTPAuthorizationCredentials(scheme="a", credentials=token))
    verifier_no_error._verify_claims(
        HTTPAuthorizationCredentials(scheme="a", credentials=token))

    # token expired
    token = jwt.encode(
        {
            "sub": "dummy-ID",
            "exp": datetime.utcnow() - timedelta(hours=10),  # 10h before
            "iat": datetime.utcnow(),
        },
        "dummy_secret",
        headers={
            "alg": "HS256",
            "typ": "JWT",
            "kid": "dummy-kid"
        },
    )
    e = _assert_verifier(token, verifier)
    assert e.status_code == HTTP_401_UNAUTHORIZED and e.detail == messages.NOT_VERIFIED
    _assert_verifier_no_error(token, verifier_no_error)

    # token created at future
    token = jwt.encode(
        {
            "sub": "dummy-ID",
            "exp": datetime.utcnow() + timedelta(hours=10),
            "iat": datetime.utcnow() + timedelta(hours=10),
        },
        "dummy_secret",
        headers={
            "alg": "HS256",
            "typ": "JWT",
            "kid": "dummy-kid"
        },
    )
    e = _assert_verifier(token, verifier)
    assert e.status_code == HTTP_401_UNAUTHORIZED and e.detail == messages.NOT_VERIFIED
    _assert_verifier_no_error(token, verifier_no_error)

    # invalid format
    token = jwt.encode(
        {
            "sub": "dummy-ID",
            "exp": datetime.utcnow() + timedelta(hours=10),
            "iat": datetime.utcnow(),
        },
        "dummy_secret",
        headers={
            "alg": "HS256",
            "typ": "JWT",
            "kid": "dummy-kid"
        },
    )
    token = token.split(".")[0]
    e = _assert_verifier(token, verifier)
    assert (e.status_code == HTTP_401_UNAUTHORIZED
            and e.detail == messages.NOT_AUTHENTICATED)
    _assert_verifier_no_error(token, verifier_no_error)
예제 #13
0
async def test_get_user_id(auth_token):
    creds = HTTPAuthorizationCredentials(scheme="Bearer",
                                         credentials=auth_token)
    user_id = await auth.get_user_id(creds)
    assert user_id.startswith("auth0")
예제 #14
0
async def test_get_user_id_invalid(token):
    creds = HTTPAuthorizationCredentials(scheme="Bearer", credentials=token)
    with pytest.raises(HTTPException) as err:
        await auth.get_user_id(creds)
    assert err.value.status_code == 401