Skip to content

Commit 432f0b5

Browse files
authored
Merge pull request #149 from ahopkins/dev
Version 1.2.2 - 2019-03-14
2 parents 0b56cd6 + 5294d0d commit 432f0b5

11 files changed

+99
-35
lines changed

docs/source/conf.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@
5656
# The short X.Y version.
5757
version = u"1.2"
5858
# The full version, including alpha/beta/rc tags.
59-
release = u"1.2.1"
59+
release = u"1.2.2"
6060

6161
# The language for content autogenerated by Sphinx. Refer to documentation
6262
# for a list of supported languages.

docs/source/pages/changelog.rst

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,19 @@ Changelog
44

55
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>`_.
66

7+
++++++++++++++++++++++++++
8+
Version 1.2.2 - 2019-03-14
9+
++++++++++++++++++++++++++
10+
11+
| **Changed**
12+
| - `#148 <https://github.com/ahopkins/sanic-jwt/issues/148>`_. Exception message on refresh token intialization
13+
|
14+
15+
| **Fixed**
16+
| - `#147 <https://github.com/ahopkins/sanic-jwt/issues/147>`_. ``protected`` decorator properly applied to built in views when initialized on a blueprint
17+
|
18+
19+
720
++++++++++++++++++++++++++
821
Version 1.2.1 - 2018-12-04
922
++++++++++++++++++++++++++

sanic_jwt/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
__version__ = "1.2.1"
1+
__version__ = "1.2.2"
22
__author__ = "Adam Hopkins"
33
__credits__ = "Richard Kuesters"
44

sanic_jwt/endpoints.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,6 @@ async def post(self, request, *args, **kwargs):
7272

7373

7474
class RetrieveUserEndpoint(BaseEndpoint):
75-
decorators = [protected()]
7675

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

166167
user_id = await self.instance.auth._get_user_id(user)
167168
refresh_token = await utils.call(

sanic_jwt/initialization.py

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,9 @@
1717
_Handler = namedtuple(
1818
"_Handler", ["name", "keys", "exception", "outside_auth_mode"]
1919
)
20-
_EndpointMapping = namedtuple("_EndpointMapping", ["cls", "endpoint", "keys"])
20+
_EndpointMapping = namedtuple(
21+
"_EndpointMapping", ["cls", "endpoint", "keys", "is_protected"]
22+
)
2123

2224

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

3537
endpoint_mappings = (
3638
_EndpointMapping(
37-
endpoints.AuthenticateEndpoint, "authenticate", ["auth_mode"]
39+
endpoints.AuthenticateEndpoint, "authenticate", ["auth_mode"], False
3840
),
3941
_EndpointMapping(
40-
endpoints.RetrieveUserEndpoint, "retrieve_user", ["auth_mode"]
42+
endpoints.RetrieveUserEndpoint, "retrieve_user", ["auth_mode"], True
4143
),
42-
_EndpointMapping(endpoints.VerifyEndpoint, "verify", ["auth_mode"]),
44+
_EndpointMapping(endpoints.VerifyEndpoint, "verify", ["auth_mode"], False),
4345
_EndpointMapping(
4446
endpoints.RefreshEndpoint,
4547
"refresh",
4648
["auth_mode", "refresh_token_enabled"],
49+
False,
4750
),
4851
)
4952

@@ -148,7 +151,9 @@ def __add_endpoints(self):
148151
"""
149152
for mapping in endpoint_mappings:
150153
if all(map(self.config.get, mapping.keys)):
151-
self.__add_single_endpoint(mapping.cls, mapping.endpoint)
154+
self.__add_single_endpoint(
155+
mapping.cls, mapping.endpoint, mapping.is_protected
156+
)
152157

153158
self.bp.exception(exceptions.SanicJWTException)(
154159
self.responses.exception_response
@@ -272,8 +277,10 @@ def __load_configuration(self):
272277
def __load_responses(self):
273278
self.responses = self.responses_class(self.config, self.instance)
274279

275-
def __add_single_endpoint(self, endpoint_cls, path_name):
280+
def __add_single_endpoint(self, endpoint_cls, path_name, is_protected):
276281
path_name = getattr(self.config, "path_to_{}".format(path_name))()
282+
if is_protected:
283+
endpoint_cls.decorators = [self.protected()]
277284
if self.instance_is_blueprint:
278285
path_name = self._get_url_prefix() + path_name
279286
if self.instance.url_prefix:

setup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818

1919
setup(
2020
name="sanic-jwt",
21-
version="1.2.1",
21+
version="1.2.2",
2222
description="JWT oauth flow for Sanic",
2323
url="https://github.com/ahopkins/sanic-jwt",
2424
download_url="https://github.com/ahopkins/sanic-jwt/archive/master.zip",

tests/conftest.py

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -148,10 +148,8 @@ async def protected_request(request):
148148

149149

150150
@pytest.yield_fixture
151-
def app_with_bp(username_table, authenticate):
152-
151+
def app_with_bp_setup_without_init(username_table, authenticate):
153152
sanic_app = Sanic()
154-
sanic_jwt_init = Initialize(sanic_app, authenticate=authenticate)
155153

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

165163
sanic_bp = Blueprint("bp", url_prefix="/bp")
166-
sanic_app.blueprint(sanic_bp)
167-
168-
sanic_jwt_init_bp = Initialize(
169-
sanic_bp, app=sanic_app, authenticate=authenticate
170-
)
171164

172165
@sanic_bp.route("/")
173166
async def bp_helloworld(request):
@@ -178,6 +171,18 @@ async def bp_helloworld(request):
178171
async def bp_protected_request(request):
179172
return json({"protected": True})
180173

174+
yield (sanic_app, sanic_bp)
175+
176+
177+
@pytest.yield_fixture
178+
def app_with_bp(app_with_bp_setup_without_init):
179+
sanic_app, sanic_bp = app_with_bp_setup_without_init
180+
sanic_jwt_init = Initialize(sanic_app, authenticate=authenticate)
181+
sanic_jwt_init_bp = Initialize(
182+
sanic_bp, app=sanic_app, authenticate=authenticate
183+
)
184+
sanic_app.blueprint(sanic_bp)
185+
181186
yield (sanic_app, sanic_jwt_init, sanic_bp, sanic_jwt_init_bp)
182187

183188

tests/test_endpoints_basic.py

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -72,14 +72,14 @@ def test_auth_verify_missing_token_debug(app):
7272
assert "Authorization header not present." in response.json.get("reasons")
7373

7474

75-
def test_auth_verify_invalid_token(app):
76-
sanic_app, _ = app
77-
_, response = sanic_app.test_client.get(
78-
"/auth/verify", headers={"Authorization": "Bearer "}
79-
)
80-
assert response.status == 400
81-
assert response.json.get("exception") == "InvalidAuthorizationHeader"
82-
assert "Authorization header is invalid." in response.json.get("reasons")
75+
# def test_auth_verify_invalid_token(app):
76+
# sanic_app, _ = app
77+
# _, response = sanic_app.test_client.get(
78+
# "/auth/verify", headers={"Authorization": "Bearer "}
79+
# )
80+
# assert response.status == 400
81+
# assert response.json.get("exception") == "InvalidAuthorizationHeader"
82+
# assert "Authorization header is invalid." in response.json.get("reasons")
8383

8484

8585
def test_auth_verify_invalid_token(app):
@@ -117,8 +117,9 @@ def test_auth_refresh_not_enabled(app_with_refresh_token):
117117
"/auth/refresh",
118118
headers={"Authorization": "Bearer {}".format(access_token)},
119119
)
120+
message = "Refresh tokens have not been enabled properly."
121+
"Perhaps you forgot to initialize with a retrieve_user handler?"
122+
120123
assert response.status == 500
121124
assert response.json.get("exception") == "RefreshTokenNotImplemented"
122-
assert "Refresh tokens have not been enabled." in response.json.get(
123-
"reasons"
124-
)
125+
assert message in response.json.get("reasons")
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
from sanic_jwt import Initialize
2+
import pytest
3+
4+
5+
@pytest.fixture
6+
def app_with_retrieve_user_on_bp(
7+
authenticate, retrieve_user, app_with_bp_setup_without_init
8+
):
9+
app, bp = app_with_bp_setup_without_init
10+
sanicjwt = Initialize(
11+
bp,
12+
app=app,
13+
authenticate=authenticate,
14+
retrieve_user=retrieve_user,
15+
debug=True,
16+
)
17+
app.blueprint(bp)
18+
return app, sanicjwt, bp
19+
20+
21+
def test_me(app_with_retrieve_user_on_bp):
22+
app, sanicjwt, bp = app_with_retrieve_user_on_bp
23+
_, response = app.test_client.post(
24+
sanicjwt._get_url_prefix() + "/",
25+
json={"username": "user1", "password": "abcxyz"},
26+
)
27+
28+
assert response.status == 200
29+
30+
access_token = response.json.get(sanicjwt.config.access_token_name(), None)
31+
32+
_, response = app.test_client.get(
33+
sanicjwt._get_url_prefix() + "/me",
34+
headers={"Authorization": "Bearer {}".format(access_token)},
35+
)
36+
37+
assert response.status == 200
38+
assert response.json.get("me").get("user_id") == 1

tests/test_endpoints_multiple.py

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,11 @@ def access_tokens(app_with_bp):
88
app_int._get_url_prefix(),
99
json={"username": "user1", "password": "abcxyz"},
1010
)
11-
print("bp_init._get_url_prefix()", bp_init._get_url_prefix())
1211
_, response2 = app.test_client.post(
1312
bp_init._get_url_prefix() + "/",
1413
json={"username": "user2", "password": "abcxyz"},
1514
)
1615

17-
print(response2.body, response2.status)
18-
1916
token1 = response1.json.get(app_int.config.access_token_name(), None)
2017
token2 = response2.json.get(bp_init.config.access_token_name(), None)
2118

0 commit comments

Comments
 (0)