Merge pull request #528 from taigaio/Enabling-lowercase-for-username-or-email-when-allowed

Enabling lowercase for username or email when allowed
remotes/origin/logger
David Barragán Merino 2015-11-17 18:02:35 +01:00
commit 14fc5f35d2
4 changed files with 87 additions and 15 deletions

View File

@ -7,6 +7,8 @@
- [CSV Reports] Add fields "created_date", "modified_date", "finished_date" to issues CSV report. - [CSV Reports] Add fields "created_date", "modified_date", "finished_date" to issues CSV report.
### Misc ### Misc
- Improve login and forgot password: allow username or email case-insensitive if the query only
match with one user.
- Improve the django admin panel, now it is more usable and all the selector fields works properly. - Improve the django admin panel, now it is more usable and all the selector fields works properly.
- [API] Performance improvements for project stats. - [API] Performance improvements for project stats.
- Lots of small and not so small bugfixes. - Lots of small and not so small bugfixes.

View File

@ -35,7 +35,7 @@ from taiga.base.api.utils import get_object_or_404
from taiga.base.filters import MembersFilterBackend from taiga.base.filters import MembersFilterBackend
from taiga.base.mails import mail_builder from taiga.base.mails import mail_builder
from taiga.projects.votes import services as votes_service from taiga.projects.votes import services as votes_service
from taiga.users.services import get_user_by_username_or_email
from easy_thumbnails.source_generators import pil_image from easy_thumbnails.source_generators import pil_image
from . import models from . import models
@ -145,13 +145,7 @@ class UsersViewSet(ModelCrudViewSet):
if not username_or_email: if not username_or_email:
raise exc.WrongArguments(_("Invalid username or email")) raise exc.WrongArguments(_("Invalid username or email"))
try: user = get_user_by_username_or_email(username_or_email)
queryset = models.User.objects.all()
user = queryset.get(Q(username=username_or_email) |
Q(email=username_or_email))
except models.User.DoesNotExist:
raise exc.WrongArguments(_("Invalid username or email"))
user.token = str(uuid.uuid1()) user.token = str(uuid.uuid1())
user.save(update_fields=["token"]) user.save(update_fields=["token"])

View File

@ -37,6 +37,24 @@ from .gravatar import get_gravatar_url
from django.conf import settings from django.conf import settings
def get_user_by_username_or_email(username_or_email):
user_model = apps.get_model("users", "User")
qs = user_model.objects.filter(Q(username__iexact=username_or_email) |
Q(email__iexact=username_or_email))
if len(qs) > 1:
qs = qs.filter(Q(username=username_or_email) |
Q(email=username_or_email))
if len(qs) == 0:
raise exc.WrongArguments(_("Username or password does not matches user."))
user = qs[0]
return user
def get_and_validate_user(*, username:str, password:str) -> bool: def get_and_validate_user(*, username:str, password:str) -> bool:
""" """
Check if user with username/email exists and specified Check if user with username/email exists and specified
@ -46,13 +64,7 @@ def get_and_validate_user(*, username:str, password:str) -> bool:
exception is raised. exception is raised.
""" """
user_model = apps.get_model("users", "User") user = get_user_by_username_or_email(username)
qs = user_model.objects.filter(Q(username=username) |
Q(email=username))
if len(qs) == 0:
raise exc.WrongArguments(_("Username or password does not matches user."))
user = qs[0]
if not user.check_password(password): if not user.check_password(password):
raise exc.WrongArguments(_("Username or password does not matches user.")) raise exc.WrongArguments(_("Username or password does not matches user."))

View File

@ -106,3 +106,67 @@ def test_respond_400_if_username_or_email_is_duplicate(client, settings, registe
register_form["email"] = "ff@dd.com" register_form["email"] = "ff@dd.com"
response = client.post(reverse("auth-register"), register_form) response = client.post(reverse("auth-register"), register_form)
assert response.status_code == 400 assert response.status_code == 400
def test_auth_uppercase_ignore(client, settings):
settings.PUBLIC_REGISTER_ENABLED = True
register_form = {"username": "Username",
"password": "password",
"full_name": "fname",
"email": "User@email.com",
"type": "public"}
response = client.post(reverse("auth-register"), register_form)
#Only exists one user with the same lowercase version of username/password
login_form = {"type": "normal",
"username": "Username",
"password": "password"}
response = client.post(reverse("auth-list"), login_form)
assert response.status_code == 200
login_form = {"type": "normal",
"username": "User@email.com",
"password": "password"}
response = client.post(reverse("auth-list"), login_form)
assert response.status_code == 200
#Now we have two users with the same lowercase version of username/password
# 1.- The capitalized version works
register_form = {"username": "username",
"password": "password",
"full_name": "fname",
"email": "user@email.com",
"type": "public"}
response = client.post(reverse("auth-register"), register_form)
login_form = {"type": "normal",
"username": "Username",
"password": "password"}
response = client.post(reverse("auth-list"), login_form)
assert response.status_code == 200
login_form = {"type": "normal",
"username": "User@email.com",
"password": "password"}
response = client.post(reverse("auth-list"), login_form)
assert response.status_code == 200
# 2.- If we capitalize a new version it doesn't
login_form = {"type": "normal",
"username": "uSername",
"password": "password"}
response = client.post(reverse("auth-list"), login_form)
assert response.status_code == 400
login_form = {"type": "normal",
"username": "uSer@email.com",
"password": "password"}
response = client.post(reverse("auth-list"), login_form)
assert response.status_code == 400