Skip to content

Commit

Permalink
Add some inline documentation and missing OPTIONS check in scoped dec…
Browse files Browse the repository at this point in the history
…orator
  • Loading branch information
ahopkins committed Apr 24, 2018
1 parent 7110022 commit 74d1671
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 1 deletion.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ htmlcov/
.coverage
.coverage.*
.cache
.pytest_cache/
nosetests.xml
coverage.xml
*.cover
Expand Down
32 changes: 31 additions & 1 deletion sanic_jwt/authentication.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,10 @@ async def add_scopes_to_payload(self, *args, **kwargs):
class Authentication(BaseAuthentication):

def _decode(self, token, verify=True):
"""
Take a JWT and return a decoded payload. Optionally, will verify
the claims on the token.
"""
secret = self._get_secret()
algorithm = self._get_algorithm()
kwargs = {}
Expand All @@ -82,19 +86,24 @@ def _decode(self, token, verify=True):
kwargs["audience"] = self.config.claim_aud()
if "claim_iss" in self.config:
kwargs["issuer"] = self.config.claim_iss()
return jwt.decode(

decoded = jwt.decode(
token,
secret,
algorithms=[algorithm],
verify=verify,
options={"verify_exp": self.config.verify_exp()},
**kwargs
)
return decoded

def _get_algorithm(self):
return self.config.algorithm()

async def _get_payload(self, user):
"""
Given a user object, create a payload and extend it as configured.
"""
payload = await utils.call(self.build_payload, user)

if (
Expand Down Expand Up @@ -136,6 +145,9 @@ def _get_secret(self, encode=False):
return self.config.secret()

def _get_token(self, request, refresh_token=False):
"""
Extract a token from a request object.
"""
if self.config.cookie_set():
cookie_token_name_key = "cookie_access_token_name" if refresh_token is False else "cookie_refresh_token_name"
cookie_token_name = getattr(self.config, cookie_token_name_key)
Expand Down Expand Up @@ -168,6 +180,9 @@ def _get_token(self, request, refresh_token=False):
raise exceptions.MissingAuthorizationHeader()

async def _get_refresh_token(self, request):
"""
Extract a refresh token from a request object.
"""
return self._get_token(request, refresh_token=True)

async def _get_user_id(self, user):
Expand All @@ -183,13 +198,19 @@ async def _get_user_id(self, user):
return user_id

async def get_access_token(self, user):
"""
Generate an access token for a given user.
"""
payload = await self._get_payload(user)
secret = self._get_secret(True)
algorithm = self._get_algorithm()

return jwt.encode(payload, secret, algorithm=algorithm).decode("utf-8")

async def get_refresh_token(self, request, user):
"""
Generate a refresh token for a given user.
"""
refresh_token = await utils.call(self.config.generate_refresh_token())
user_id = await self._get_user_id(user)
await utils.call(
Expand All @@ -215,6 +236,9 @@ def is_authenticated(self, request, *args, **kwargs):
def verify(
self, request, return_payload=False, verify=True, *args, **kwargs
):
"""
Verify that a request object is authenticated.
"""
token = self._get_token(request)
is_valid = True
reason = None
Expand Down Expand Up @@ -244,11 +268,17 @@ async def retrieve_refresh_token_from_request(self, request):
return await self._get_refresh_token(request)

def retrieve_scopes(self, request):
"""
Extract scopes from a request object.
"""
payload = self.extract_payload(request)
scopes_attribute = self.config.scopes_name()
return payload.get(scopes_attribute, None)

def extract_payload(self, request, verify=True, *args, **kwargs):
"""
Extract a payload from a request object.
"""
payload = self.verify(
request, return_payload=True, verify=verify, *args, **kwargs
)
Expand Down
6 changes: 6 additions & 0 deletions sanic_jwt/decorators.py
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,12 @@ async def decorated_function(request, *args, **kwargs):
instance = request.app

with instant_config(instance, request=request, **kw):
if request.method == "OPTIONS":
response = f(request, *args, **kwargs)
if isawaitable(response):
response = await response
return response

try:
is_authenticated, status, reasons = instance.auth.is_authenticated(
request, *args, **kwargs
Expand Down

0 comments on commit 74d1671

Please sign in to comment.