Skip to content

Commit

Permalink
Merge pull request #227 from ahopkins/v1.8
Browse files Browse the repository at this point in the history
  • Loading branch information
ahopkins committed Jun 28, 2022
2 parents 4f6ab07 + 11ce800 commit 74213de
Show file tree
Hide file tree
Showing 21 changed files with 265 additions and 230 deletions.
1 change: 1 addition & 0 deletions docs/requirements.txt
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
sphinx==3.1.2
sphinx_rtd_theme==0.4.2
Jinja2<3.1
4 changes: 2 additions & 2 deletions docs/source/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,9 +54,9 @@
# built documents.
#
# The short X.Y version.
version = u"1.6"
version = u"1.8"
# The full version, including alpha/beta/rc tags.
release = u"1.6.0"
release = u"1.8.0"

# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
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.7.0"
__version__ = "1.8.0"
__author__ = "Adam Hopkins"
__credits__ = "Richard Kuesters"

Expand Down
1 change: 0 additions & 1 deletion sanic_jwt/authentication.py
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,6 @@ async def _check_authentication(
raise e

args = e.args if isinstance(e, SanicJWTException) else []

raise exceptions.Unauthorized(*args)

return is_valid, status, reasons
Expand Down
2 changes: 1 addition & 1 deletion sanic_jwt/initialization.py
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,7 @@ def __add_endpoints(self):
mapping.protected_kwargs,
)

self.bp.exception(exceptions.SanicJWTException)(
self.app.exception(exceptions.SanicJWTException)(
self.responses.exception_response
)

Expand Down
8 changes: 5 additions & 3 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,21 +14,23 @@ def open_local(paths, mode="r", encoding="utf8"):

with open_local(["sanic_jwt", "__init__.py"], encoding="latin1") as fp:
try:
version = re.findall(r"^__version__ = \"([0-9\.]+)\"", fp.read(), re.M)[0]
version = re.findall(
r"^__version__ = \"([0-9\.]+)\"", fp.read(), re.M
)[0]
except IndexError:
raise RuntimeError("Unable to determine version.")

with open_local(["README.md"]) as rm:
long_description = rm.read()

extras_require = {"docs": ["Sphinx"]}
extras_require = {"docs": ["Sphinx", "Jinja2<3.1"]}

extras_require["all"] = []
for reqs in extras_require.values():
extras_require["all"].extend(reqs)

install_requires = [
"pyjwt~=2.1.0",
"pyjwt>=2.1.0,<3.0.0",
]

setup(
Expand Down
2 changes: 1 addition & 1 deletion tests/test_async_options.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ async def extend_payload(self, payload, user=None, *args, **kwargs):

@pytest.fixture
def app():
app = Sanic(__name__)
app = Sanic("Test")
app.config.SANIC_JWT_AUTHORIZATION_HEADER_PREFIX = "JWT"
app.config.SANIC_JWT_EXPIRATION_DELTA = 360000
app.config.SANIC_JWT_USER_ID = "username"
Expand Down
8 changes: 3 additions & 5 deletions tests/test_configuration.py
Original file line number Diff line number Diff line change
Expand Up @@ -364,13 +364,11 @@ def test_configuration_with_override_on_aliased():
def test_configuration_no_set_secret():
app = Sanic("sanic-jwt-test")

with pytest.warns(UserWarning) as record:
Initialize(app, authenticate=lambda: True)

assert len(record) == 1
assert record[0].message.args[0] == (
message = (
"Sanic JWT was initialized using the default secret available to the "
"public. DO NOT DEPLOY your application until you change it. "
"See https://sanic-jwt.readthedocs.io/en/latest/pages/configuration.html#secret "
"for more information."
)
with pytest.warns(UserWarning, match=message):
Initialize(app, authenticate=lambda: True)
29 changes: 17 additions & 12 deletions tests/test_endpoints_blueprint.py
Original file line number Diff line number Diff line change
@@ -1,31 +1,36 @@
import pytest
from sanic import Sanic
from sanic.blueprints import Blueprint
from sanic.response import json

from sanic_jwt import Initialize
from sanic_jwt.decorators import protected

blueprint = Blueprint("Test", "/test")

@pytest.fixture
def app():
blueprint = Blueprint("Test", "/test")

@blueprint.get("/", strict_slashes=True)
@protected()
def protected_hello_world(request):
return json({"message": "hello world"})
@blueprint.get("/", strict_slashes=True)
@protected()
def protected_hello_world(request):
return json({"message": "hello world"})

app = Sanic("sanic-jwt-test")
app.blueprint(blueprint)

async def authenticate(request, *args, **kwargs):
return {"user_id": 1}
return app


app = Sanic("sanic-jwt-test")
@pytest.fixture
def sanicjwt(app):
async def authenticate(request, *args, **kwargs):
return {"user_id": 1}

app.blueprint(blueprint)
return Initialize(app, authenticate=authenticate)

sanicjwt = Initialize(app, authenticate=authenticate)


def test_protected_blueprint():
def test_protected_blueprint(app, sanicjwt):
_, response = app.test_client.get("/test/")

assert response.status == 401
Expand Down
107 changes: 56 additions & 51 deletions tests/test_endpoints_cbv.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import jwt
import pytest
from sanic import Sanic
from sanic.response import json
from sanic.views import HTTPMethodView
Expand All @@ -7,84 +8,86 @@
from sanic_jwt.decorators import protected


class User(object):
def __init__(self, id, username, password):
self.id = id
self.username = username
self.password = password
@pytest.fixture
def fixtures():
class User(object):
def __init__(self, id, username, password):
self.id = id
self.username = username
self.password = password

def to_dict(self):
properties = ["user_id", "username"]
return {prop: getattr(self, prop, None) for prop in properties}
def to_dict(self):
properties = ["user_id", "username"]
return {prop: getattr(self, prop, None) for prop in properties}

users = [User(1, "user1", "abcxyz"), User(2, "user2", "abcxyz")]

users = [User(1, "user1", "abcxyz"), User(2, "user2", "abcxyz")]
username_table = {u.username: u for u in users}
# userid_table = {u.user_id: u for u in users}

username_table = {u.username: u for u in users}
# userid_table = {u.user_id: u for u in users}
async def authenticate(request, *args, **kwargs):
username = request.json.get("username", None)
password = request.json.get("password", None)

if not username or not password:
raise exceptions.AuthenticationFailed(
"Missing username or password."
)

async def authenticate(request, *args, **kwargs):
username = request.json.get("username", None)
password = request.json.get("password", None)
user = username_table.get(username, None)
if user is None:
raise exceptions.AuthenticationFailed("User not found.")

if not username or not password:
raise exceptions.AuthenticationFailed("Missing username or password.")
if password != user.password:
raise exceptions.AuthenticationFailed("Password is incorrect.")

user = username_table.get(username, None)
if user is None:
raise exceptions.AuthenticationFailed("User not found.")
return user

if password != user.password:
raise exceptions.AuthenticationFailed("Password is incorrect.")
sanic_app = Sanic("sanic-jwt-test")
sanic_jwt = Initialize(sanic_app, authenticate=authenticate)

return user
class PublicView(HTTPMethodView):
def get(self, request):
return json({"hello": "world"})

class ProtectedView(HTTPMethodView):
decorators = [protected()]

sanic_app = Sanic("sanic-jwt-test")
sanic_jwt = Initialize(sanic_app, authenticate=authenticate)
async def get(self, request):
return json({"protected": True})

class PartiallyProtectedView(HTTPMethodView):
async def get(self, request):
return json({"protected": True})

class PublicView(HTTPMethodView):
def get(self, request):
return json({"hello": "world"})
@protected()
async def patch(self, request):
return json({"protected": True})

sanic_app.add_route(PublicView.as_view(), "/")
sanic_app.add_route(ProtectedView.as_view(), "/protected")
sanic_app.add_route(PartiallyProtectedView.as_view(), "/partially")

class ProtectedView(HTTPMethodView):
decorators = [protected()]

async def get(self, request):
return json({"protected": True})


class PartiallyProtectedView(HTTPMethodView):
async def get(self, request):
return json({"protected": True})

@protected()
async def patch(self, request):
return json({"protected": True})


sanic_app.add_route(PublicView.as_view(), "/")
sanic_app.add_route(ProtectedView.as_view(), "/protected")
sanic_app.add_route(PartiallyProtectedView.as_view(), "/partially")
return sanic_app, sanic_jwt


class TestEndpointsCBV(object):
def test_unprotected(self):
def test_unprotected(self, fixtures):
sanic_app, sanic_jwt = fixtures
_, response = sanic_app.test_client.get("/")
assert response.status == 200

def test_protected(self):
def test_protected(self, fixtures):
sanic_app, sanic_jwt = fixtures
_, response = sanic_app.test_client.get("/protected")
assert response.status == 401
assert response.json.get("exception") == "Unauthorized"
assert "Authorization header not present." in response.json.get(
"reasons"
)

def test_partially_protected(self):
def test_partially_protected(self, fixtures):
sanic_app, sanic_jwt = fixtures
_, response = sanic_app.test_client.get("/partially")
assert response.status == 200

Expand All @@ -95,12 +98,14 @@ def test_partially_protected(self):
"reasons"
)

def test_auth_invalid_method(self):
def test_auth_invalid_method(self, fixtures):
sanic_app, sanic_jwt = fixtures
_, response = sanic_app.test_client.get("/auth")
assert response.status == 405
assert b"Method GET not allowed for URL /auth" in response.body

def test_auth_proper_credentials(self):
def test_auth_proper_credentials(self, fixtures):
sanic_app, sanic_jwt = fixtures
_, response = sanic_app.test_client.post(
"/auth", json={"username": "user1", "password": "abcxyz"}
)
Expand Down
33 changes: 19 additions & 14 deletions tests/test_endpoints_extra.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import pytest
from sanic import response, Sanic
from sanic.response import json

Expand All @@ -15,23 +16,26 @@ async def post(self, request):
return json(response)


app = Sanic("sanic-jwt-test")
initialize(
app,
authenticate=lambda: True,
class_views=[
(
"/magic-login",
MagicLoginHandler,
) # The path will be relative to the url prefix
# (which defaults to /auth)
],
)
@pytest.fixture
def app():
app = Sanic("sanic-jwt-test")
initialize(
app,
authenticate=lambda: True,
class_views=[
(
"/magic-login",
MagicLoginHandler,
) # The path will be relative to the url prefix
# (which defaults to /auth)
],
)
return app


class TestEndpointsExtra(object):
def dispatch(self, path, method):
method = getattr(app.test_client, method)
method = getattr(self.app.test_client, method)
request, response = method(path)
return request, response

Expand All @@ -44,7 +48,8 @@ def post(self, path):
def options(self, path):
return self.dispatch(path, "options")

def test_verify_token(self):
def test_verify_token(self, app):
self.app = app
_, response = self.options("/auth/magic-login")
assert response.status == 204

Expand Down

0 comments on commit 74213de

Please sign in to comment.