Skip to content

Commit

Permalink
fix tests for login and registration auto login
Browse files Browse the repository at this point in the history
  • Loading branch information
Sascha Dobbelaere committed Dec 12, 2023
1 parent 230794e commit d38e49f
Show file tree
Hide file tree
Showing 9 changed files with 64 additions and 54 deletions.
2 changes: 1 addition & 1 deletion OneSila/core/decorators.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ def deco(f):
@wraps(f)
def f_wrap(self, *args, **kwargs):
is_dirty_field = False
if self.is_dirty_field(field):
if self.is_dirty_field(dirty_field):
is_dirty_field = True
signal_pre.send(sender=self.__class__, instance=self)

Expand Down
5 changes: 5 additions & 0 deletions OneSila/core/factories/multi_tenant.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
from django.db import transaction
from core.models.multi_tenant import MultiTenantUser
from django.core.exceptions import ValidationError
from django.contrib.auth.password_validation import validate_password

from core.signals import registered, invite_sent, invite_accepted, \
disabled, enabled
Expand All @@ -18,6 +19,9 @@ def __init__(self, *, username, password, language, first_name="", last_name="")
self.first_name = first_name
self.last_name = last_name

def validate_password(self):
validate_password(password=self.password)

def create_user(self):
user = self.model(
username=self.username,
Expand All @@ -42,6 +46,7 @@ def send_signal(self):

@transaction.atomic
def run(self):
self.validate_password()
self.create_user()
self.send_signal()

Expand Down
4 changes: 2 additions & 2 deletions OneSila/core/models/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@ def save(self, *args, force_save=False, **kwargs):
if self.is_dirty(check_relationship=True) or force_save:
super().save(*args, **kwargs)

def is_dirty_field(field):
return field in self.dirty_fields.keys()
def is_dirty_field(self, field):
return field in self.get_dirty_fields().keys()

class Meta:
abstract = True
Expand Down
13 changes: 7 additions & 6 deletions OneSila/core/schema/multi_tenant/mutations/fields.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,11 @@
from core.schema.core.mutations import IsAuthenticated, default_extensions
from .mutation_classes import MyMultiTenantCompanyCreateMutation, \
MyMultiTentantCompanyUpdateMutation, UpdateMeMutation, \
RegisterUserMutation, InviteUserMutation, AcceptInvitationMutation, \
InviteUserMutation, AcceptInvitationMutation, \
EnableUserMutation, DisableUserMutation
import functools
import strawberry
from .resolvers import resolve_register_user


def register_my_multi_tenant_company():
Expand All @@ -24,11 +27,6 @@ def update_me():
return UpdateMeMutation(MultiTenantUserPartialInput, extensions=extensions)


def register_user():
extensions = []
return RegisterUserMutation(MultiTenantUserInput, extensions=extensions)


def invite_user():
extensions = default_extensions
return InviteUserMutation(MultiTenantInviteUserInput, extensions=extensions)
Expand All @@ -47,3 +45,6 @@ def disable_user():
def enable_user():
extensions = default_extensions
return EnableUserMutation(MultiTenantUserStatusInput, extensions=extensions)


register_user = functools.partial(strawberry.mutation, resolver=resolve_register_user)
42 changes: 0 additions & 42 deletions OneSila/core/schema/multi_tenant/mutations/mutation_classes.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@

from django.db import transaction
from django.contrib import auth
from django.contrib.auth.password_validation import validate_password
from django.core.exceptions import ValidationError
from django.conf import settings

Expand All @@ -33,47 +32,6 @@ def cleanup_data(self, data):
return data


class RegisterUserMutation(CleanupDataMixin, DjangoCreateMutation):
AUTO_LOGIN = settings.STRAWBERRY_DJANGO_REGISTER_USER_AUTO_LOGIN

def create_user(self, data):
data = self.cleanup_data(data)
fac = RegisterUserFactory(**data)
fac.run()

return fac.user

def login_user(self, info, username, password):
request = get_request(info)
user = auth.authenticate(request, username=username, password=password)

if user is None:
raise ValidationError("User is not logged in.")

scope = request.consumer.scope
async_to_sync(channels_auth.login)(scope, user)
# Channels docs, you must save the session, or no user will be logged in.
scope["session"].save()

return user

def create(self, data: dict[str, Any], *, info: Info):
password = data.get("password")
username = data.get('username')
validate_password(password)

with DjangoOptimizerExtension.disabled():
user = self.create_user(data)

if self.AUTO_LOGIN:
# FIXME: Using auto-login seems to break:
# https://stackoverflow.com/questions/77557246/django-channels-login-connection-already-closed
# breaks on async_to_sync(channels_auth.login) section.
self.login_user(info, username, password)

return user


class InviteUserMutation(CleanupDataMixin, GetMultiTenantCompanyMixin, DjangoCreateMutation):
def create(self, data: dict[str, Any], *, info: Info):
multi_tenant_company = self.get_multi_tenant_company(info)
Expand Down
5 changes: 3 additions & 2 deletions OneSila/core/schema/multi_tenant/mutations/mutation_type.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
from core.schema.core.mutations import type
from strawberry_django import auth as strawberry_auth
from .fields import register_user, register_my_multi_tenant_company, \
from .fields import register_my_multi_tenant_company, \
update_me, update_my_multi_tenant_company, invite_user, \
accept_user_invitation, disable_user, enable_user
accept_user_invitation, disable_user, enable_user, \
register_user

from core.schema.multi_tenant.types.types import MultiTenantUserType, \
MultiTenantCompanyType
Expand Down
43 changes: 43 additions & 0 deletions OneSila/core/schema/multi_tenant/mutations/resolvers.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
from strawberry_django.resolvers import django_resolver
from asgiref.sync import async_to_sync
from core.factories.multi_tenant import RegisterUserFactory
from strawberry_django.utils.requests import get_request
from channels import auth as channels_auth
from django.contrib import auth

from .mutation_classes import CleanupDataMixin


@django_resolver
def resolve_register_user(info, username: str, password: str, language: str):
request = get_request(info)

fac = RegisterUserFactory(username=username, password=password, language=language)
fac.run()

user = fac.user

try:
# We dont have any need for the classic django-auth outside of the
# tests. So this is why this try except clause exists.
auth.login(request, user)
except AttributeError:
# ASGI in combo with websockets needs the channels login functionality.
# to ensure we're talking about channels, let's veriy that our
# request is actually channelsrequest
try:
scope = request.consumer.scope # type: ignore
async_to_sync(channels_auth.login)(scope, user) # type: ignore
# According to channels docs you must save the session
scope["session"].save()
except (AttributeError, NameError):
# When Django-channels is not installed,
# this code will be non-existing
pass

# scope = request.consumer.scope
# async_to_sync(channels_auth.login)(scope, user)
# # According to channels docs you must save the session
# scope["session"].save()

return user
2 changes: 1 addition & 1 deletion OneSila/core/tests/tests_schemas/mutations.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@

REGISTER_USER_MUTATION = """
mutation registerUser($username: String!, $password: String!, $language: String!) {
registerUser(data: {username: $username, password: $password, language: $language}) {
registerUser(username: $username, password: $password, language: $language) {
username
password
invitationAccepted
Expand Down
2 changes: 2 additions & 0 deletions OneSila/core/tests/tests_schemas/tests_mutations.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@ def test_register_flow(self):
variables={"username": username, "password": password, 'language': language}
)

print(resp)

self.assertTrue(resp.errors is None)
self.assertTrue(resp.data is not None)

Expand Down

0 comments on commit d38e49f

Please sign in to comment.