-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
merge quality of life changes (#141)
- Loading branch information
Showing
15 changed files
with
166 additions
and
31 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,15 +1,14 @@ | ||
*.pyc | ||
__pycache__ | ||
__pycache__/ | ||
/demo/db.sqlite3 | ||
/demo/.env | ||
|
||
# Test artifacts | ||
/.pytest_cache/ | ||
/.coverage | ||
/htmlcov/ | ||
/.tox/ | ||
/venv/ | ||
|
||
# Packaging litter | ||
/*.egg-info | ||
# Packaging artifacts | ||
/build/ | ||
/dist/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,16 @@ | ||
from django.apps import AppConfig | ||
from django.db import models | ||
|
||
from rest_framework.serializers import ModelSerializer | ||
|
||
|
||
class AccountsConfig(AppConfig): | ||
name = 'demo.accounts' | ||
label = 'accounts' | ||
|
||
def ready(self): | ||
from rest_auth_toolkit.fields import CustomEmailField | ||
|
||
ModelSerializer.serializer_field_mapping.update({ | ||
models.EmailField: CustomEmailField, | ||
}) |
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
from rest_framework.authentication import TokenAuthentication | ||
|
||
from .utils import get_object_from_setting | ||
|
||
|
||
Token = get_object_from_setting("api_token_class") | ||
|
||
|
||
class TokenAuthentication(TokenAuthentication): | ||
"""DRF authentication backend for API requests. | ||
Parses headers like "Authorization: Bearer user-api-token". | ||
Override authenticate_credentials in a subclass if you need | ||
special behaviour to get a Token object from a string value. | ||
Default behaviour is to fetch a token via "key" field and | ||
check that token.user.is_active is true. | ||
""" | ||
|
||
keyword = "Bearer" | ||
model = Token |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
from django.contrib.auth import get_user_model | ||
|
||
from rest_framework.fields import EmailField, empty | ||
|
||
|
||
User = get_user_model() | ||
|
||
|
||
class CustomEmailField(EmailField): | ||
"""Subclass of EmailField that adds normalization.""" | ||
|
||
def run_validation(self, data=empty): | ||
if data != empty: | ||
data = User.objects.normalize_email(data) | ||
return super().run_validation(data) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,12 +1,21 @@ | ||
from datetime import datetime | ||
|
||
from django.urls import reverse | ||
|
||
import pytest | ||
|
||
from demo.accounts.models import User, APIToken | ||
|
||
|
||
def test_signup(db, django_app, mailoutbox): | ||
params = {"email": "[email protected]", "password": "correct battery horse staple"} | ||
django_app.post_json(reverse("auth:signup"), params=params, status=201) | ||
@pytest.mark.parametrize("email", [ | ||
"[email protected]", | ||
"[email protected]", | ||
]) | ||
def test_signup(db, django_app, mailoutbox, email): | ||
params = {"email": email, "password": "correct battery horse staple"} | ||
resp = django_app.post_json(reverse("auth:signup"), params=params, status=201) | ||
|
||
assert resp.json == {"email": "[email protected]"} | ||
user = User.objects.last() | ||
assert user.email == "[email protected]" | ||
assert user.has_usable_password() | ||
|
@@ -22,25 +31,64 @@ def test_signup_same_as_password(db, django_app): | |
assert "password" in resp.json | ||
|
||
|
||
def test_signup_missing_email(db, django_app): | ||
params = {"password": "little bobby passwords"} | ||
resp = django_app.post_json(reverse("auth:signup"), params=params, status=400) | ||
|
||
assert "email" in resp.json | ||
|
||
|
||
def test_signup_invalid_email(db, django_app): | ||
params = {"email": "bobby", "password": "[email protected]"} | ||
resp = django_app.post_json(reverse("auth:signup"), params=params, status=400) | ||
|
||
assert "email" in resp.json | ||
|
||
|
||
def test_signup_already_exists(db, django_app, user0): | ||
params = {"email": "[email protected]", "password": "pass123"} | ||
@pytest.mark.parametrize("email", [ | ||
"[email protected]", | ||
"[email protected]", | ||
]) | ||
def test_signup_already_exists(db, django_app, user0, email): | ||
params = {"email": email, "password": "pass123"} | ||
resp = django_app.post_json(reverse("auth:signup"), params=params, status=400) | ||
|
||
assert "email" in resp.json | ||
|
||
|
||
def test_login(db, django_app, user0): | ||
params = {"email": "[email protected]", "password": "pass123"} | ||
def test_signup_different_address(db, django_app, user0): | ||
params = {"email": "[email protected]", "password": "goodpass"} | ||
resp = django_app.post_json(reverse("auth:signup"), params=params, status=201) | ||
|
||
assert resp.json == {"email": "[email protected]"} | ||
|
||
|
||
def test_confirm_email(db, django_app, user0, emailconfirmation0): | ||
assert not user0.is_active | ||
assert emailconfirmation0.confirmed is None | ||
|
||
django_app.get(reverse("app-auth:email-confirmation", | ||
kwargs={"external_id": emailconfirmation0.external_id})) | ||
|
||
user0.refresh_from_db() | ||
emailconfirmation0.refresh_from_db() | ||
assert user0.is_active | ||
assert isinstance(emailconfirmation0.confirmed, datetime) | ||
|
||
|
||
@pytest.mark.parametrize("email", [ | ||
"[email protected]", | ||
"[email protected]", | ||
]) | ||
def test_login(db, django_app, user0, email): | ||
assert user0.last_login is None | ||
|
||
params = {"email": email, "password": "pass123"} | ||
resp = django_app.post_json(reverse("auth:login"), params=params, status=200) | ||
|
||
assert "token" in resp.json | ||
user0.refresh_from_db() | ||
assert isinstance(user0.last_login, datetime) | ||
|
||
|
||
def test_login_unknown_user(db, django_app): | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters