diff --git a/apps/account/migrations/0029_auto_20200109_1354.py b/apps/account/migrations/0029_auto_20200109_1354.py new file mode 100644 index 00000000..79134663 --- /dev/null +++ b/apps/account/migrations/0029_auto_20200109_1354.py @@ -0,0 +1,18 @@ +# Generated by Django 2.2.7 on 2020-01-09 13:54 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('account', '0028_merge_20191217_1127'), + ] + + operations = [ + migrations.AlterField( + model_name='user', + name='username', + field=models.CharField(blank=True, default=None, error_messages={'unique': 'A user with that username already exists.'}, help_text='Required. 150 characters or fewer. Letters, digits and ./+/-/_ only.', max_length=150, null=True, verbose_name='username'), + ), + ] diff --git a/apps/account/models.py b/apps/account/models.py index 8abefedc..88969b15 100644 --- a/apps/account/models.py +++ b/apps/account/models.py @@ -69,11 +69,11 @@ class UserManager(BaseUserManager): use_in_migrations = False - def make(self, username: str, email: str, password: str, newsletter: bool) -> object: + def make(self, email: str, password: str, newsletter: bool, username: str = '') -> object: """Register new user""" obj = self.model( username=username, - email=email, + email=email.lower(), newsletter=newsletter) obj.set_password(password) obj.save() @@ -112,6 +112,15 @@ class UserQuerySet(models.QuerySet): class User(AbstractUser): """Base user model.""" + username = models.CharField( + _('username'), + max_length=150, + blank=True, null=True, default=None, + help_text=_('Required. 150 characters or fewer. Letters, digits and ./+/-/_ only.'), + error_messages={ + 'unique': _("A user with that username already exists."), + }, + ) image_url = models.URLField(verbose_name=_('Image URL path'), blank=True, null=True, default=None, max_length=500) diff --git a/apps/account/serializers/common.py b/apps/account/serializers/common.py index 62113d9b..bee3f7ac 100644 --- a/apps/account/serializers/common.py +++ b/apps/account/serializers/common.py @@ -17,21 +17,15 @@ from utils import methods as utils_methods class UserSerializer(serializers.ModelSerializer): """User serializer.""" # RESPONSE - email_confirmed = serializers.BooleanField(read_only=True) fullname = serializers.CharField(source='get_full_name', read_only=True) # REQUEST username = serializers.CharField( validators=(rest_validators.UniqueValidator(queryset=models.User.objects.all()),), required=False) - first_name = serializers.CharField(required=False, write_only=True) - last_name = serializers.CharField(required=False, write_only=True) - image_url = serializers.URLField(required=False) - cropped_image_url = serializers.URLField(required=False) email = serializers.EmailField( validators=(rest_validators.UniqueValidator(queryset=models.User.objects.all()),), required=False) - newsletter = serializers.BooleanField(required=False) class Meta: model = models.User @@ -46,6 +40,14 @@ class UserSerializer(serializers.ModelSerializer): 'email_confirmed', 'newsletter', ] + extra_kwargs = { + 'first_name': {'required': False, 'write_only': True, }, + 'last_name': {'required': False, 'write_only': True, }, + 'email_confirmed': {'read_only': True, }, + 'image_url': {'required': False, }, + 'cropped_image_url': {'required': False, }, + 'newsletter': {'required': False, }, + } def create(self, validated_data): user = super(UserSerializer, self).create(validated_data) diff --git a/apps/account/tasks.py b/apps/account/tasks.py index 8afe1545..528cb35e 100644 --- a/apps/account/tasks.py +++ b/apps/account/tasks.py @@ -10,6 +10,7 @@ from account.models import User logging.basicConfig(format='[%(levelname)s] %(message)s', level=logging.INFO) logger = logging.getLogger(__name__) + def send_email(user_id: int, subject: str, message_prop: str, country_code: str, emails=None): try: user = User.objects.get(id=user_id) diff --git a/apps/authorization/serializers/common.py b/apps/authorization/serializers/common.py index 1d61c573..e6a9bdc7 100644 --- a/apps/authorization/serializers/common.py +++ b/apps/authorization/serializers/common.py @@ -58,11 +58,11 @@ class SignupSerializer(serializers.ModelSerializer): return value def create(self, validated_data): - """Override create method""" + """Overridden create method""" obj = account_models.User.objects.make( username=validated_data.get('username'), password=validated_data.get('password'), - email=validated_data.get('email').lower(), + email=validated_data.get('email'), newsletter=validated_data.get('newsletter')) # Send verification link on user email if settings.USE_CELERY: @@ -110,16 +110,18 @@ class LoginByUsernameOrEmailSerializer(SourceSerializerMixin, password = attrs.pop('password') user_qs = account_models.User.objects.filter(Q(username=username_or_email) | Q(email=username_or_email)) + if not user_qs.exists(): raise utils_exceptions.WrongAuthCredentials() - else: - user = user_qs.first() - authentication = authenticate(username=user.get_username(), - password=password) - if not authentication: - raise utils_exceptions.WrongAuthCredentials() - self.instance = user - return attrs + + user = user_qs.first() + password_is_valid = user.check_password(password) + + if not password_is_valid: + raise utils_exceptions.WrongAuthCredentials() + + self.instance = user + return attrs def to_representation(self, instance): """Override to_representation method""" diff --git a/apps/utils/methods.py b/apps/utils/methods.py index 7bf97222..e06881e5 100644 --- a/apps/utils/methods.py +++ b/apps/utils/methods.py @@ -46,7 +46,7 @@ def get_token_from_request(request): def username_validator(username: str) -> bool: """Validate given username""" - pattern = r'[@,]+' + pattern = r'[\s@,]' if re.search(pattern=pattern, string=username): return False else: