Skip to content
Merged
Show file tree
Hide file tree
Changes from 13 commits
Commits
Show all changes
76 commits
Select commit Hold shift + click to select a range
abba205
feat: Add primitive claim and its tests for session grants
KShivendu Jul 14, 2022
349596a
feat: Add more functions related to session claims
KShivendu Jul 17, 2022
ed3a1cb
test: Add more tests for session claim features
KShivendu Jul 18, 2022
6d297b0
feat: Wrap up features and tests related to basic session claims
KShivendu Jul 21, 2022
9a0886c
feat: Refactor session claims and tests
KShivendu Jul 22, 2022
ef1b610
Merge pull request #211 from supertokens/feat/session-grants-refactor
KShivendu Jul 25, 2022
b984f64
test: Implement AsyncMock if not available and fix failing tests
KShivendu Jul 26, 2022
597415c
test: Fix minor bug in @min_api_version test wrapper
KShivendu Jul 26, 2022
f74e97b
ci: Add debugging support in GH actions using tmate
KShivendu Jul 26, 2022
4950367
ci: Run tmate only if tests fail
KShivendu Jul 26, 2022
ccf3dc6
fix: Import missing SessionRecipe to fix test failures
KShivendu Jul 26, 2022
0dc1819
ci: Trigger tmate for debugging before tests if debug mode is enabled
KShivendu Jul 26, 2022
1493aeb
test: Fix session claims test failures
KShivendu Jul 27, 2022
76b1cc3
fix: Fix test failures for python3.7, use fixtures, and fix bugs
KShivendu Jul 28, 2022
f084a51
refactor: Extract SessionClaim related classes for easier inheritance…
KShivendu Jul 28, 2022
583e820
refactor: Clean up session claims tests
KShivendu Jul 28, 2022
45abb80
fix: Add pytest-mock to dev-requirements.txt
KShivendu Jul 28, 2022
9f981c9
fix: Changes suggested in PR feedback
KShivendu Jul 31, 2022
e932be8
refactor: Make ClaimValidationResult an object instead of dict
KShivendu Aug 2, 2022
54e2736
feat: Changes suggested in feedback
KShivendu Aug 3, 2022
a7e4b6a
feat: Add and use email verification claim
KShivendu Aug 7, 2022
918e15f
feat: Add and use email verification claim
KShivendu Aug 7, 2022
07fe952
fix: Fix lint errors and make email verification claims usable
KShivendu Aug 8, 2022
29d7cee
refactor: Use email veriifcation claim in thirdparty recipe
KShivendu Aug 9, 2022
6957000
refactor: Run black on tp recipe and use ev claim in pless recipe
KShivendu Aug 9, 2022
44d0f3a
refactor: Remove email verification features from thirdpartyemailpass…
KShivendu Aug 9, 2022
720f593
refactor: Remove email verification features from thirdpartypasswordl…
KShivendu Aug 9, 2022
e31b60d
refactor: Clean up usages of email verification in other recipes in f…
KShivendu Aug 10, 2022
0834fe5
refactor: Fix circular dependency error in emailverification recipe a…
KShivendu Aug 10, 2022
34e492a
test: Fix test failures related to tpep recipe
KShivendu Aug 10, 2022
1586251
refactor: Allow emailverification init without directly using ParentR…
KShivendu Aug 10, 2022
10395c4
tests: Fix test failures in tppless email delivery
KShivendu Aug 10, 2022
c26242e
feat: Changes suggested in feedback
KShivendu Aug 11, 2022
e77328e
feat: Apply claims on access_token_payload when calling create_new_se…
KShivendu Aug 11, 2022
27282d4
changes based on feedback
KShivendu Aug 17, 2022
3df9f16
Remove get_link_domain_and_path function and ev logic from other recipes
KShivendu Aug 17, 2022
dc9c3be
changes suggested in PR feedback
KShivendu Aug 17, 2022
0ac965c
test invalid claims response with and without reason
KShivendu Aug 17, 2022
3663a1d
fix test failure
KShivendu Aug 17, 2022
e58cb87
feat: Changes suggested in feedback
KShivendu Sep 1, 2022
63eb59b
Merge branch 'feat/session-grants' into feat/ev-claim
KShivendu Sep 1, 2022
619ac25
feat: Changes suggested in feedback
KShivendu Sep 1, 2022
5b36b16
refactor: Remove ParentRecipeEmailVerificationConfig
KShivendu Sep 1, 2022
01c2609
test: Fix failing tests
KShivendu Sep 1, 2022
6fc90c6
refactor: Remove irrelevant comment
KShivendu Sep 1, 2022
a038414
Merge pull request #215 from supertokens/feat/ev-claim
rishabhpoddar Sep 5, 2022
200e4c6
feat: Most of requested changes except the last two
KShivendu Sep 5, 2022
dac30f0
Merge branch 'feat/session-claim-remaining' into feat/session-grants
KShivendu Sep 5, 2022
28392ee
feat: More of requested changes
KShivendu Sep 5, 2022
2dca9c0
refactor:remaining changes
KShivendu Sep 6, 2022
5eac706
feat: complete remaining items
KShivendu Sep 6, 2022
b103949
feat: changes suggested in feedback
KShivendu Sep 7, 2022
c18ba05
feat: More of requested changes
KShivendu Sep 9, 2022
58255c1
feat: requested changes
KShivendu Sep 9, 2022
f35003c
feat: last changes
KShivendu Sep 9, 2022
aa37fe3
feat: remove commet
KShivendu Sep 9, 2022
e438cdf
feat: remove commet
KShivendu Sep 9, 2022
9879067
Merge branch '0.10' into feat/session-grants
rishabhpoddar Sep 10, 2022
b013a5d
makes user context optional in syncio exposed functions for user roles
rishabhpoddar Sep 10, 2022
0322472
feat: last changes
KShivendu Sep 12, 2022
1c395a7
refactor: Serialize ClaimValidationError in default implementation of…
KShivendu Sep 12, 2022
9138a41
test: Fix failing tests
KShivendu Sep 12, 2022
0e3fd33
fix: emailverification syncio
KShivendu Sep 12, 2022
a000d3c
Merge pull request #221 from supertokens/feat/session-grants-new
rishabhpoddar Sep 12, 2022
8f21297
test: session claims fix failing tests
KShivendu Sep 12, 2022
23aacfc
test: Fix failing tests
KShivendu Sep 13, 2022
dc7390d
test: add tests for userroles claims
KShivendu Sep 13, 2022
af39f58
test: Fix failing tests
KShivendu Sep 13, 2022
87595a4
feat: CHANGELOG
KShivendu Sep 13, 2022
7065aed
fix: fix changelog
KShivendu Sep 13, 2022
aa1d35f
feat: update fdi version
KShivendu Sep 13, 2022
ba3f774
test: Add tests for primitive array claim
KShivendu Sep 13, 2022
e3fd8c9
feat: update fdi version
KShivendu Sep 13, 2022
984dfc4
test: Fix failing tests
KShivendu Sep 14, 2022
0283c00
feat: example app update for emailverification
KShivendu Sep 14, 2022
df5994f
Merge pull request #223 from supertokens/test/session-claims
rishabhpoddar Sep 14, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -51,5 +51,10 @@ jobs:
run: cd ../supertokens-root && ./loadModules
- name: Setting up supertokens-root test environment
run: cd ../supertokens-root && bash ./utils/setupTestEnvLocal
- name: Debugging with tmate
if: ${{ github.event_name == 'workflow_dispatch' && inputs.debug_enabled }}
uses: mxschmitt/[email protected]
with:
sudo: false
- name: Run tests
run: make test
run: make test
34 changes: 31 additions & 3 deletions supertokens_python/recipe/session/api/implementation.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,17 @@
# under the License.
from __future__ import annotations

from typing import TYPE_CHECKING, Union
from typing import TYPE_CHECKING, Union, List, Callable, Optional

from supertokens_python.normalised_url_path import NormalisedURLPath
from supertokens_python.recipe.session.interfaces import (
APIInterface,
SignOutOkayResponse,
SessionClaimValidator,
)
from supertokens_python.types import MaybeAwaitable
from supertokens_python.utils import normalise_http_method
from ..utils import get_required_claim_validators

if TYPE_CHECKING:
from supertokens_python.recipe.session.interfaces import APIOptions
Expand Down Expand Up @@ -48,6 +51,7 @@ async def signout_post(
user_context=user_context,
anti_csrf_check=None,
session_required=True,
override_global_claim_validators=lambda _, __, ___: [],
)
except UnauthorisedError:
return SignOutOkayResponse()
Expand All @@ -62,6 +66,12 @@ async def verify_session(
api_options: APIOptions,
anti_csrf_check: Union[bool, None],
session_required: bool,
override_global_claim_validators: Optional[
Callable[
[List[SessionClaimValidator], SessionContainer, Dict[str, Any]],
MaybeAwaitable[List[SessionClaimValidator]],
]
],
user_context: Dict[str, Any],
) -> Union[SessionContainer, None]:
method = normalise_http_method(api_options.request.method())
Expand All @@ -73,6 +83,24 @@ async def verify_session(
return await api_options.recipe_implementation.refresh_session(
api_options.request, user_context
)
return await api_options.recipe_implementation.get_session(
api_options.request, anti_csrf_check, session_required, user_context
session = await api_options.recipe_implementation.get_session(
api_options.request,
anti_csrf_check,
session_required,
override_global_claim_validators,
user_context,
)

if session is not None:
claim_validators = await get_required_claim_validators(
session,
override_global_claim_validators,
user_context,
)
await api_options.recipe_implementation.assert_claims(
session,
claim_validators,
user_context,
)

return session
183 changes: 178 additions & 5 deletions supertokens_python/recipe/session/asyncio/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
from typing import Any, Dict, List, Union
from typing import Any, Dict, List, Union, TypeVar, Callable, Optional

from supertokens_python.recipe.openid.interfaces import (
GetOpenIdDiscoveryConfigurationResult,
Expand All @@ -20,16 +20,25 @@
RegenerateAccessTokenOkResult,
SessionContainer,
SessionInformationResult,
SessionClaim,
SessionClaimValidator,
SessionDoesntExistError,
ValidateClaimsOkResult,
JSONObject,
GetClaimValueOkResult,
)
from supertokens_python.recipe.session.recipe import SessionRecipe
from supertokens_python.utils import FRAMEWORKS

from supertokens_python.types import MaybeAwaitable
from supertokens_python.utils import FRAMEWORKS, resolve
from ..utils import get_required_claim_validators
from ...jwt.interfaces import (
CreateJwtOkResult,
CreateJwtResultUnsupportedAlgorithm,
GetJWKSResult,
)

_T = TypeVar("_T")


async def create_new_session(
request: Any,
Expand All @@ -49,10 +58,160 @@ async def create_new_session(
)


async def validate_claims_for_session_handle(
session_handle: str,
override_global_claim_validators: Optional[
Callable[
[
List[SessionClaimValidator],
SessionInformationResult,
Dict[str, Any],
], # Prev. 2nd arg was SessionContainer
MaybeAwaitable[List[SessionClaimValidator]],
]
] = None,
user_context: Union[None, Dict[str, Any]] = None,
) -> Union[SessionDoesntExistError, ValidateClaimsOkResult]:
if user_context is None:
user_context = {}

recipe_impl = SessionRecipe.get_instance().recipe_implementation
session_info = await recipe_impl.get_session_information(
session_handle, user_context
)

if session_info is None:
return SessionDoesntExistError()

claim_validators_added_by_other_recipes = (
SessionRecipe.get_claim_validators_added_by_other_recipes()
)
global_claim_validators = await resolve(
recipe_impl.get_global_claim_validators(
session_info.user_id,
claim_validators_added_by_other_recipes,
user_context,
)
)

if override_global_claim_validators is not None:
claim_validators = await resolve(
override_global_claim_validators(
global_claim_validators, session_info, user_context
)
)
else:
claim_validators = global_claim_validators

return await recipe_impl.validate_claims_for_session_handle(
session_info, claim_validators, user_context
)


async def validate_claims_in_jwt_payload(
user_id: str,
jwt_payload: JSONObject,
override_global_claim_validators: Optional[
Callable[
[
List[SessionClaimValidator],
str,
Dict[str, Any],
], # Prev. 2nd arg was SessionContainer
MaybeAwaitable[List[SessionClaimValidator]],
]
] = None,
user_context: Union[None, Dict[str, Any]] = None,
):
if user_context is None:
user_context = {}

recipe_impl = SessionRecipe.get_instance().recipe_implementation

claim_validators_added_by_other_recipes = (
SessionRecipe.get_claim_validators_added_by_other_recipes()
)
global_claim_validators = await resolve(
recipe_impl.get_global_claim_validators(
user_id,
claim_validators_added_by_other_recipes,
user_context,
)
)

if override_global_claim_validators is not None:
claim_validators = await resolve(
override_global_claim_validators(
global_claim_validators, user_id, user_context
)
)
else:
claim_validators = global_claim_validators

return await recipe_impl.validate_claims_in_jwt_payload(
user_id, jwt_payload, claim_validators, user_context
)


async def fetch_and_set_claim(
session_handle: str,
claim: SessionClaim[Any],
user_context: Union[None, Dict[str, Any]] = None,
) -> bool:
if user_context is None:
user_context = {}
return await SessionRecipe.get_instance().recipe_implementation.fetch_and_set_claim(
session_handle, claim, user_context
)


async def get_claim_value(
session_handle: str,
claim: SessionClaim[_T],
user_context: Union[None, Dict[str, Any]] = None,
) -> Union[SessionDoesntExistError, GetClaimValueOkResult[_T]]:
if user_context is None:
user_context = {}
return await SessionRecipe.get_instance().recipe_implementation.get_claim_value(
session_handle, claim, user_context
)


async def set_claim_value(
session_handle: str,
claim: SessionClaim[_T],
value: _T,
user_context: Union[None, Dict[str, Any]] = None,
) -> bool:
if user_context is None:
user_context = {}
return await SessionRecipe.get_instance().recipe_implementation.set_claim_value(
session_handle, claim, value, user_context
)


async def remove_claim(
session_handle: str,
claim: SessionClaim[Any],
user_context: Union[None, Dict[str, Any]] = None,
) -> bool:
if user_context is None:
user_context = {}
return await SessionRecipe.get_instance().recipe_implementation.remove_claim(
session_handle, claim, user_context
)


async def get_session(
request: Any,
anti_csrf_check: Union[bool, None] = None,
session_required: bool = True,
override_global_claim_validators: Optional[
Callable[
[List[SessionClaimValidator], SessionContainer, Dict[str, Any]],
MaybeAwaitable[List[SessionClaimValidator]],
]
] = None,
user_context: Union[None, Dict[str, Any]] = None,
) -> Union[SessionContainer, None]:
if user_context is None:
Expand All @@ -61,10 +220,24 @@ async def get_session(
request = FRAMEWORKS[
SessionRecipe.get_instance().app_info.framework
].wrap_request(request)
return await SessionRecipe.get_instance().recipe_implementation.get_session(
request, anti_csrf_check, session_required, user_context

session_recipe_impl = SessionRecipe.get_instance().recipe_implementation
session = await session_recipe_impl.get_session(
request,
anti_csrf_check,
session_required,
override_global_claim_validators,
user_context,
)

if session is not None:
claim_validators = await get_required_claim_validators(
session, override_global_claim_validators, user_context
)
await session_recipe_impl.assert_claims(session, claim_validators, user_context)

return session


async def refresh_session(
request: Any, user_context: Union[None, Dict[str, Any]] = None
Expand Down
13 changes: 13 additions & 0 deletions supertokens_python/recipe/session/claim_base_classes/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# Copyright (c) 2021, VRAI Labs and/or its affiliates. All rights reserved.
#
# This software is licensed under the Apache License, Version 2.0 (the
# "License") as published by the Apache Software Foundation.
#
# You may not use this file except in compliance with the License. You may
# obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# Copyright (c) 2021, VRAI Labs and/or its affiliates. All rights reserved.
#
# This software is licensed under the Apache License, Version 2.0 (the
# "License") as published by the Apache Software Foundation.
#
# You may not use this file except in compliance with the License. You may
# obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.

from .primitive_claim import PrimitiveClaim


class BooleanClaim(PrimitiveClaim):
pass
Loading