Skip to content

Commit

Permalink
Merge pull request #149 from ahopkins/dev
Browse files Browse the repository at this point in the history
Version 1.2.2 - 2019-03-14
  • Loading branch information
ahopkins authored Mar 14, 2019
2 parents 0b56cd6 + 5294d0d commit 432f0b5
Show file tree
Hide file tree
Showing 11 changed files with 99 additions and 35 deletions.
2 changes: 1 addition & 1 deletion docs/source/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@
# The short X.Y version.
version = u"1.2"
# The full version, including alpha/beta/rc tags.
release = u"1.2.1"
release = u"1.2.2"

# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
Expand Down
13 changes: 13 additions & 0 deletions docs/source/pages/changelog.rst
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,19 @@ Changelog

The format is based on `Keep a Changelog <http://keepachangelog.com/en/1.0.0/>`_ and this project adheres to `Semantic Versioning <http://semver.org/spec/v2.0.0.html>`_.

++++++++++++++++++++++++++
Version 1.2.2 - 2019-03-14
++++++++++++++++++++++++++

| **Changed**
| - `#148 <https://github.com/ahopkins/sanic-jwt/issues/148>`_. Exception message on refresh token intialization
|
| **Fixed**
| - `#147 <https://github.com/ahopkins/sanic-jwt/issues/147>`_. ``protected`` decorator properly applied to built in views when initialized on a blueprint
|

++++++++++++++++++++++++++
Version 1.2.1 - 2018-12-04
++++++++++++++++++++++++++
Expand Down
2 changes: 1 addition & 1 deletion sanic_jwt/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
__version__ = "1.2.1"
__version__ = "1.2.2"
__author__ = "Adam Hopkins"
__credits__ = "Richard Kuesters"

Expand Down
5 changes: 3 additions & 2 deletions sanic_jwt/endpoints.py
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,6 @@ async def post(self, request, *args, **kwargs):


class RetrieveUserEndpoint(BaseEndpoint):
decorators = [protected()]

async def get(self, request, *args, **kwargs):
request, args, kwargs = await self.do_incoming(request, args, kwargs)
Expand Down Expand Up @@ -161,7 +160,9 @@ async def post(self, request, *args, **kwargs):
self.instance.auth.retrieve_user, request, payload=payload
)
except exceptions.MeEndpointNotSetup:
raise exceptions.RefreshTokenNotImplemented
message = "Refresh tokens have not been enabled properly."
"Perhaps you forgot to initialize with a retrieve_user handler?"
raise exceptions.RefreshTokenNotImplemented(message=message)

user_id = await self.instance.auth._get_user_id(user)
refresh_token = await utils.call(
Expand Down
19 changes: 13 additions & 6 deletions sanic_jwt/initialization.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,9 @@
_Handler = namedtuple(
"_Handler", ["name", "keys", "exception", "outside_auth_mode"]
)
_EndpointMapping = namedtuple("_EndpointMapping", ["cls", "endpoint", "keys"])
_EndpointMapping = namedtuple(
"_EndpointMapping", ["cls", "endpoint", "keys", "is_protected"]
)


def initialize(*args, **kwargs):
Expand All @@ -34,16 +36,17 @@ def initialize(*args, **kwargs):

endpoint_mappings = (
_EndpointMapping(
endpoints.AuthenticateEndpoint, "authenticate", ["auth_mode"]
endpoints.AuthenticateEndpoint, "authenticate", ["auth_mode"], False
),
_EndpointMapping(
endpoints.RetrieveUserEndpoint, "retrieve_user", ["auth_mode"]
endpoints.RetrieveUserEndpoint, "retrieve_user", ["auth_mode"], True
),
_EndpointMapping(endpoints.VerifyEndpoint, "verify", ["auth_mode"]),
_EndpointMapping(endpoints.VerifyEndpoint, "verify", ["auth_mode"], False),
_EndpointMapping(
endpoints.RefreshEndpoint,
"refresh",
["auth_mode", "refresh_token_enabled"],
False,
),
)

Expand Down Expand Up @@ -148,7 +151,9 @@ def __add_endpoints(self):
"""
for mapping in endpoint_mappings:
if all(map(self.config.get, mapping.keys)):
self.__add_single_endpoint(mapping.cls, mapping.endpoint)
self.__add_single_endpoint(
mapping.cls, mapping.endpoint, mapping.is_protected
)

self.bp.exception(exceptions.SanicJWTException)(
self.responses.exception_response
Expand Down Expand Up @@ -272,8 +277,10 @@ def __load_configuration(self):
def __load_responses(self):
self.responses = self.responses_class(self.config, self.instance)

def __add_single_endpoint(self, endpoint_cls, path_name):
def __add_single_endpoint(self, endpoint_cls, path_name, is_protected):
path_name = getattr(self.config, "path_to_{}".format(path_name))()
if is_protected:
endpoint_cls.decorators = [self.protected()]
if self.instance_is_blueprint:
path_name = self._get_url_prefix() + path_name
if self.instance.url_prefix:
Expand Down
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@

setup(
name="sanic-jwt",
version="1.2.1",
version="1.2.2",
description="JWT oauth flow for Sanic",
url="https://github.com/ahopkins/sanic-jwt",
download_url="https://github.com/ahopkins/sanic-jwt/archive/master.zip",
Expand Down
21 changes: 13 additions & 8 deletions tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -148,10 +148,8 @@ async def protected_request(request):


@pytest.yield_fixture
def app_with_bp(username_table, authenticate):

def app_with_bp_setup_without_init(username_table, authenticate):
sanic_app = Sanic()
sanic_jwt_init = Initialize(sanic_app, authenticate=authenticate)

@sanic_app.route("/")
async def helloworld(request):
Expand All @@ -163,11 +161,6 @@ async def protected_request(request):
return json({"protected": True})

sanic_bp = Blueprint("bp", url_prefix="/bp")
sanic_app.blueprint(sanic_bp)

sanic_jwt_init_bp = Initialize(
sanic_bp, app=sanic_app, authenticate=authenticate
)

@sanic_bp.route("/")
async def bp_helloworld(request):
Expand All @@ -178,6 +171,18 @@ async def bp_helloworld(request):
async def bp_protected_request(request):
return json({"protected": True})

yield (sanic_app, sanic_bp)


@pytest.yield_fixture
def app_with_bp(app_with_bp_setup_without_init):
sanic_app, sanic_bp = app_with_bp_setup_without_init
sanic_jwt_init = Initialize(sanic_app, authenticate=authenticate)
sanic_jwt_init_bp = Initialize(
sanic_bp, app=sanic_app, authenticate=authenticate
)
sanic_app.blueprint(sanic_bp)

yield (sanic_app, sanic_jwt_init, sanic_bp, sanic_jwt_init_bp)


Expand Down
23 changes: 12 additions & 11 deletions tests/test_endpoints_basic.py
Original file line number Diff line number Diff line change
Expand Up @@ -72,14 +72,14 @@ def test_auth_verify_missing_token_debug(app):
assert "Authorization header not present." in response.json.get("reasons")


def test_auth_verify_invalid_token(app):
sanic_app, _ = app
_, response = sanic_app.test_client.get(
"/auth/verify", headers={"Authorization": "Bearer "}
)
assert response.status == 400
assert response.json.get("exception") == "InvalidAuthorizationHeader"
assert "Authorization header is invalid." in response.json.get("reasons")
# def test_auth_verify_invalid_token(app):
# sanic_app, _ = app
# _, response = sanic_app.test_client.get(
# "/auth/verify", headers={"Authorization": "Bearer "}
# )
# assert response.status == 400
# assert response.json.get("exception") == "InvalidAuthorizationHeader"
# assert "Authorization header is invalid." in response.json.get("reasons")


def test_auth_verify_invalid_token(app):
Expand Down Expand Up @@ -117,8 +117,9 @@ def test_auth_refresh_not_enabled(app_with_refresh_token):
"/auth/refresh",
headers={"Authorization": "Bearer {}".format(access_token)},
)
message = "Refresh tokens have not been enabled properly."
"Perhaps you forgot to initialize with a retrieve_user handler?"

assert response.status == 500
assert response.json.get("exception") == "RefreshTokenNotImplemented"
assert "Refresh tokens have not been enabled." in response.json.get(
"reasons"
)
assert message in response.json.get("reasons")
38 changes: 38 additions & 0 deletions tests/test_endpoints_init_on_bp_retrieve_user.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
from sanic_jwt import Initialize
import pytest


@pytest.fixture
def app_with_retrieve_user_on_bp(
authenticate, retrieve_user, app_with_bp_setup_without_init
):
app, bp = app_with_bp_setup_without_init
sanicjwt = Initialize(
bp,
app=app,
authenticate=authenticate,
retrieve_user=retrieve_user,
debug=True,
)
app.blueprint(bp)
return app, sanicjwt, bp


def test_me(app_with_retrieve_user_on_bp):
app, sanicjwt, bp = app_with_retrieve_user_on_bp
_, response = app.test_client.post(
sanicjwt._get_url_prefix() + "/",
json={"username": "user1", "password": "abcxyz"},
)

assert response.status == 200

access_token = response.json.get(sanicjwt.config.access_token_name(), None)

_, response = app.test_client.get(
sanicjwt._get_url_prefix() + "/me",
headers={"Authorization": "Bearer {}".format(access_token)},
)

assert response.status == 200
assert response.json.get("me").get("user_id") == 1
3 changes: 0 additions & 3 deletions tests/test_endpoints_multiple.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,11 @@ def access_tokens(app_with_bp):
app_int._get_url_prefix(),
json={"username": "user1", "password": "abcxyz"},
)
print("bp_init._get_url_prefix()", bp_init._get_url_prefix())
_, response2 = app.test_client.post(
bp_init._get_url_prefix() + "/",
json={"username": "user2", "password": "abcxyz"},
)

print(response2.body, response2.status)

token1 = response1.json.get(app_int.config.access_token_name(), None)
token2 = response2.json.get(bp_init.config.access_token_name(), None)

Expand Down
6 changes: 4 additions & 2 deletions tests/test_initialize.py
Original file line number Diff line number Diff line change
Expand Up @@ -233,8 +233,10 @@ def test_initialize_app_and_bp():
Initialize(instance=bp, app=app, authenticate=lambda: True)

app.blueprint(bp)
print("app", app.router.routes_all.keys())
print("bp", [x.uri for x in bp.routes])


# print("app", app.router.routes_all.keys())
# print("bp", [x.uri for x in bp.routes])


# Result:
Expand Down

0 comments on commit 432f0b5

Please sign in to comment.