Skip to content

Commit

Permalink
Add support python3.9 (#64)
Browse files Browse the repository at this point in the history
  • Loading branch information
tokusumi authored Jan 2, 2022
1 parent 104fe80 commit 190e55d
Show file tree
Hide file tree
Showing 9 changed files with 86 additions and 43 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: [3.6, 3.7, 3.8]
poetry-version: [1.0.0]
python-version: [3.6, 3.7, 3.8, 3.9]
poetry-version: [1.1.12]

steps:
- uses: actions/checkout@v2
Expand Down
7 changes: 6 additions & 1 deletion fastapi_cloudauth/cognito.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,12 @@ class CognitoCurrentUser(UserInfoAuth):
user_info = CognitoClaims

def __init__(
self, region: str, userPoolId: str, client_id: str, *args: Any, **kwargs: Any,
self,
region: str,
userPoolId: str,
client_id: str,
*args: Any,
**kwargs: Any,
):
url = f"https://cognito-idp.{region}.amazonaws.com/{userPoolId}/.well-known/jwks.json"
jwks = JWKS(url=url)
Expand Down
10 changes: 7 additions & 3 deletions fastapi_cloudauth/verification.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,9 @@ def __call__(self, claims: Dict[str, str], auto_error: bool = True) -> bool:

class JWKS:
def __init__(
self, url: str = "", fixed_keys: Optional[Dict[str, Key]] = None,
self,
url: str = "",
fixed_keys: Optional[Dict[str, Key]] = None,
):
"""Handle the JSON Web Key Set (JWKS), query and refresh ...
Args:
Expand Down Expand Up @@ -187,7 +189,8 @@ async def _get_publickey(
if not publickey:
if self.auto_error:
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED, detail=NO_PUBLICKEY,
status_code=status.HTTP_401_UNAUTHORIZED,
detail=NO_PUBLICKEY,
)
else:
return None
Expand Down Expand Up @@ -344,7 +347,8 @@ def _verify_scope(self, http_auth: HTTPAuthorizationCredentials) -> bool:
if not matched:
if self.auto_error:
raise HTTPException(
status_code=status.HTTP_403_FORBIDDEN, detail=SCOPE_NOT_MATCHED,
status_code=status.HTTP_403_FORBIDDEN,
detail=SCOPE_NOT_MATCHED,
)
return False
return True
Expand Down
36 changes: 19 additions & 17 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,37 +19,39 @@ classifiers = [
"Programming Language :: Python :: 3.6",
"Programming Language :: Python :: 3.7",
"Programming Language :: Python :: 3.8",
"Programming Language :: Python :: 3.9",
"Topic :: Security",
"Typing :: Typed",
]

[tool.poetry.dependencies]
python = "^3.6"
python = ">=3.6.2,<4.0"
fastapi = ">= 0.60.1, < 1.0"
python-jose = {version = ">=3.3.0,<4.0.0", extras = ["cryptography"]}
requests = "^2.24.0"
requests = ">=2.24.0,<3.0.0"

[tool.poetry.dev-dependencies]
pytest = "^5.4.3"
pytest-cov = "^2.10.0"
flake8 = "^3.8.3"
mypy = "^0.782"
black = "^19.10b0"
isort = "^5.7.0"
pytest = ">=6.2.4,<7.0.0"
pytest-cov = ">=2.12.0,<4.0.0"
flake8 = ">=3.8.3,<4.0.0"
mypy = "0.910"
black = "21.9b0"
isort = ">=5.0.6,<6.0.0"
uvicorn = ">=0.12.0,<0.14.0"
botocore = "^1.17.32"
boto3 = "^1.14.32"
authlib = "^0.15.2"
firebase-admin = "^4.4.0"
auth0-python = "^3.14.0"
pytest-mock = "^3.5.1"
pytest-asyncio = "^0.14.0"
autoflake = "^1.4"
botocore = ">=1.17.32"
boto3 = ">=1.14.32"
authlib = ">=0.15.2"
firebase-admin = ">=4.4.0"
auth0-python = ">=3.14.0"
pytest-mock = ">=3.5.1"
pytest-asyncio = ">=0.14.0"
autoflake = ">=1.4.0,<2.0.0"
types-requests = ">=2.26.3,<3.0.0"

[tool.isort]
profile = "black"
known_third_party = ["fastapi", "pydantic", "starlette"]

[build-system]
requires = ["poetry>=0.12"]
requires = ["poetry>=1.1.12"]
build-backend = "poetry.masonry.api"
10 changes: 7 additions & 3 deletions tests/test_auth0.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,9 @@ def init() -> Auth0sdk:
"""
get_token = GetToken(DOMAIN)
token = get_token.client_credentials(
MGMT_CLIENTID, MGMT_CLIENT_SECRET, f"https://{DOMAIN}/api/v2/",
MGMT_CLIENTID,
MGMT_CLIENT_SECRET,
f"https://{DOMAIN}/api/v2/",
)
mgmt_api_token = token["access_token"]

Expand Down Expand Up @@ -111,7 +113,8 @@ def delete_user(


def get_access_token(
username=f"test_user{info.major}{info.minor}@example.com", password="testPass1-",
username=f"test_user{info.major}{info.minor}@example.com",
password="testPass1-",
) -> Optional[str]:
"""
Requirements:
Expand Down Expand Up @@ -143,7 +146,8 @@ def get_access_token(


def get_id_token(
username=f"test_user{info.major}{info.minor}@example.com", password="testPass1-",
username=f"test_user{info.major}{info.minor}@example.com",
password="testPass1-",
) -> Optional[str]:
"""
Requirements:
Expand Down
9 changes: 6 additions & 3 deletions tests/test_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,8 @@ def test_validation_scope(mocker, scopes):
@pytest.mark.unittest
@pytest.mark.asyncio
@pytest.mark.parametrize(
"auth", [UserInfoAuth, ScopedAuth],
"auth",
[UserInfoAuth, ScopedAuth],
)
async def test_forget_def_user_info(auth):
dummy_http_auth = HTTPAuthorizationCredentials(
Expand All @@ -95,7 +96,8 @@ async def test_forget_def_user_info(auth):
@pytest.mark.unittest
@pytest.mark.asyncio
@pytest.mark.parametrize(
"auth", [UserInfoAuth, ScopedAuth],
"auth",
[UserInfoAuth, ScopedAuth],
)
async def test_assign_user_info(auth):
"""three way to set user info schema
Expand Down Expand Up @@ -133,7 +135,8 @@ class IatSchema(BaseModel):
@pytest.mark.unittest
@pytest.mark.asyncio
@pytest.mark.parametrize(
"auth", [UserInfoAuth, ScopedAuth],
"auth",
[UserInfoAuth, ScopedAuth],
)
async def test_extract_raw_user_info(auth):
dummy_http_auth = HTTPAuthorizationCredentials(
Expand Down
7 changes: 5 additions & 2 deletions tests/test_cognito.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,9 @@ def add_test_user(
except ClientError: # pragma: no cover
pass # pragma: no cover
client.admin_add_user_to_group(
UserPoolId=USERPOOLID, Username=username, GroupName=scope,
UserPoolId=USERPOOLID,
Username=username,
GroupName=scope,
)


Expand All @@ -85,7 +87,8 @@ def get_cognito_token(


def delete_cognito_user(
client, username=f"test_user{info.major}{info.minor}@example.com",
client,
username=f"test_user{info.major}{info.minor}@example.com",
):
try:
client.admin_delete_user(UserPoolId=USERPOOLID, Username=username)
Expand Down
5 changes: 4 additions & 1 deletion tests/test_firebase.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,10 @@ def initialize():

tmpdir = tempfile.TemporaryDirectory()
credentials_path = os.path.join(tmpdir.name, "sa.json")
with open(credentials_path, "w",) as f:
with open(
credentials_path,
"w",
) as f:
json.dump(credentials_json, f)

cred = credentials.Certificate(credentials_path)
Expand Down
41 changes: 30 additions & 11 deletions tests/test_verification.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,8 @@
@pytest.mark.asyncio
async def test_malformed_token_handling():
http_auth_with_malformed_token = HTTPAuthorizationCredentials(
scheme="a", credentials="malformed-token",
scheme="a",
credentials="malformed-token",
)

verifier = JWKsVerifier(jwks=JWKS.null())
Expand Down Expand Up @@ -89,7 +90,8 @@ def parse(t: datetime) -> datetime:
async def test_refresh_jwks(mocker):
too_short_exp = datetime.now()
mocker.patch(
"requests.get", return_value=DummyResp(too_short_exp),
"requests.get",
return_value=DummyResp(too_short_exp),
)
_jwks = DummyDecodeJWKS(url="http://")

Expand All @@ -99,7 +101,8 @@ async def test_refresh_jwks(mocker):
# time goes...
new_exp = too_short_exp + timedelta(days=10)
mocker.patch(
"requests.get", return_value=DummyResp(new_exp),
"requests.get",
return_value=DummyResp(new_exp),
)
await _jwks.get_publickey("")
# expired is refreshed
Expand Down Expand Up @@ -127,14 +130,16 @@ def _set_expiration(self, resp: Response) -> Optional[datetime]:
async def test_refresh_jwks_multiple(mocker):
too_short_exp = datetime.now()
mocker.patch(
"requests.get", return_value=DummyResp(too_short_exp),
"requests.get",
return_value=DummyResp(too_short_exp),
)
_jwks = DummyDecodeCntJWKS(url="http://")

# time goes...
new_exp = too_short_exp + timedelta(days=10)
mocker.patch(
"requests.get", return_value=DummyResp(new_exp),
"requests.get",
return_value=DummyResp(new_exp),
)
# multiple expired access
res = await asyncio.gather(
Expand All @@ -154,7 +159,10 @@ def test_verify_scope_exeption(mocker):
return_value={"dummy key": "read:test"},
)
scope_key = "dummy key"
http_auth = HTTPAuthorizationCredentials(scheme="a", credentials="dummy-token",)
http_auth = HTTPAuthorizationCredentials(
scheme="a",
credentials="dummy-token",
)

# trivial scope
verifier = ScopedJWKsVerifier(
Expand Down Expand Up @@ -184,11 +192,15 @@ def test_verify_scope_exeption(mocker):

@pytest.mark.unittest
@pytest.mark.parametrize(
"scopes", ["xxx:xxx yyy:yyy", ["xxx:xxx", "yyy:yyy"]],
"scopes",
["xxx:xxx yyy:yyy", ["xxx:xxx", "yyy:yyy"]],
)
def test_scope_match_all(mocker, scopes):
scope_key = "dummy key"
http_auth = HTTPAuthorizationCredentials(scheme="a", credentials="dummy-token",)
http_auth = HTTPAuthorizationCredentials(
scheme="a",
credentials="dummy-token",
)

# check scope logic
mocker.patch(
Expand All @@ -199,7 +211,10 @@ def test_scope_match_all(mocker, scopes):

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

Expand Down Expand Up @@ -233,11 +248,15 @@ def test_scope_match_all(mocker, scopes):

@pytest.mark.unittest
@pytest.mark.parametrize(
"scopes", ["xxx:xxx yyy:yyy", ["xxx:xxx", "yyy:yyy"]],
"scopes",
["xxx:xxx yyy:yyy", ["xxx:xxx", "yyy:yyy"]],
)
def test_scope_match_any(mocker, scopes):
scope_key = "dummy key"
http_auth = HTTPAuthorizationCredentials(scheme="a", credentials="dummy-token",)
http_auth = HTTPAuthorizationCredentials(
scheme="a",
credentials="dummy-token",
)

# check scope logic
mocker.patch(
Expand Down

0 comments on commit 190e55d

Please sign in to comment.