def _create_user(self, username, password, **extra_fields): if not username: raise ValueError('The given username must be set') username = AbstractBaseUser.normalize_username(username) user = self.model(username=username, **extra_fields) user.set_password(password) user.save() return user
def create_user(self, username, password, **kwargs): if not username: raise ValueError("Account must have username") username = AbstractBaseUser.normalize_username(username) user = self.model(username=username, **kwargs) user.set_password(password) user.save() return user
def create_user(self, username, email=None, password=None, **kwargs): if not username: raise ValueError('User must have username') username = AbstractBaseUser.normalize_username(username) email = self.normalize_email(email) user = self.model(username=username, email=email, **kwargs) user.set_password(password) user.save() return user
def save(self, force_insert=False, force_update=False, using=None, update_fields=None): if not self.pk: self.invite_code = random_str(5) + str(MyUser.objects.count()) return AbstractBaseUser.save(self, force_insert=force_insert, force_update=force_update, using=using, update_fields=update_fields)
def create_user(self, username, email, password=None): if not username: raise ValueError('Username required') if not email: raise ValueError('Email required') user = self.model( username=AbstractBaseUser.normalize_username(username), email=self.normalize_email(email)) user.set_password(password) user.save() return user
class BaseAbstractUser(AbstractBaseUser): is_active = models.BooleanField(default=True) created_at = models.DateTimeField(auto_now_add=True, auto_now=False) modified_at = models.DateTimeField(auto_now=True, auto_now_add=False, null=True) is_deleted = models.BooleanField(default=False) deleted_at = models.DateTimeField(default=None, null=True) class Meta: abstract = True objects = AbstractBaseUser()
def update_user(self, user: AbstractBaseUser, claims: Dict) -> None: """update the django user with data from the claims""" if callable(settings.OIDC_EMAIL_CLAIM): user.email = settings.OIDC_EMAIL_CLAIM(claims) else: email_claim_name = settings.OIDC_EMAIL_CLAIM if not email_claim_name: email_claim_name = settings.OIDC_OP_EXPECTED_EMAIL_CLAIM user.email = claims.get(email_claim_name, '') if callable(settings.OIDC_FIRSTNAME_CLAIM): user.first_name = settings.OIDC_FIRSTNAME_CLAIM(claims) else: user.first_name = claims.get(settings.OIDC_FIRSTNAME_CLAIM, '') if callable(settings.OIDC_LASTNAME_CLAIM): user.last_name = settings.OIDC_LASTNAME_CLAIM(claims) else: user.last_name = claims.get(settings.OIDC_LASTNAME_CLAIM, '') if callable(settings.OIDC_EXTEND_USER): settings.OIDC_EXTEND_USER(user, claims) user.is_active = True
def clean(self): # Skip the AbstractUser.clean as this tries to set self.email AbstractBaseUser.clean(self)
def save(self, force_insert=False, force_update=False, using=None, update_fields=None): if not self.pk: self.invite_code = random_str(5) + str(MyUser.objects.count()) return AbstractBaseUser.save(self, force_insert=force_insert, force_update=force_update, using=using, update_fields=update_fields)
class Member( SimpleEmailConfirmationUserMixin, AbstractBaseUser, PermissionsMixin): """This class describes a member""" objects = MelosUserManager() username_validator = UnicodeUsernameValidator() EMAIL_FIELD = 'email' USERNAME_FIELD = 'username' REQUIRED_FIELDS = [ AbstractBaseUser.get_email_field_name(), "phone_number", "melos_id" ] # ---- Necessary fields --- username = models.CharField( _('username'), max_length=150, unique=True, help_text=_( 'Required. 150 characters or fewer. ' 'Letters, digits and @/./+/-/_ only.' ), validators=[username_validator], error_messages={ 'unique': _("A user with that username already exists."), }, ) is_staff = models.BooleanField( _('staff status'), default=False, help_text=_( 'Designates whether the user can log into this admin site.' ), ) is_active = models.BooleanField( _('active'), default=True, help_text=_( 'Designates whether this user should be treated as active. ' 'Unselect this instead of deleting accounts.' ), ) date_joined = models.DateTimeField(_('date joined'), default=timezone.now) # ----- Fields for caching user information from melos name = models.CharField( max_length=254, verbose_name=_('Name'), ) person_nr = models.CharField( max_length=13, verbose_name=_('Person number'), ) # ---- Membership information ------ MEMBERSHIP_CHOICES = ( ('unknown', _('Unknown')), ('nonmember', _('Nonmember')), ('member', _('Member')), ('alumnus', _('Alumnus')), ) status = models.CharField( max_length=20, choices=MEMBERSHIP_CHOICES, verbose_name=_('Membership status'), blank=False, default='unknown' ) status_changed = models.DateTimeField( default=status_changed_default, null=False, ) # ---- Contact information ------ phone_number = models.CharField( max_length=20, verbose_name=_('Phone number'), help_text=_('Enter a phone number so UTN may reach you'), ) email = models.EmailField( max_length=255, verbose_name=_('email'), help_text=_('Enter an email address so UTN may reach you') ) # ---- University information ------ registration_year = models.CharField( max_length=4, verbose_name=_('Registration year'), help_text=_('Enter the year you started studying at the TakNat ' 'faculty'), validators=[validators.RegexValidator( regex=r'^\d{4}$', message=_('Please enter a valid year') )], blank=True, ) study = models.ForeignKey( 'StudyProgram', verbose_name=_('Study program'), on_delete=models.SET_NULL, null=True, blank=True, ) section = models.ForeignKey( 'Section', verbose_name=_('Member of section'), on_delete=models.SET_NULL, null=True, blank=True, ) # ---- Melos ------ melos_id = models.IntegerField( blank=True, editable=False, null=True, unique=True, ) melos_user_data = None class Meta: verbose_name = _('user') verbose_name_plural = _('users') def __str__(self) -> str: return self.username @property def teams(self): Team = apps.get_model('involvement', 'Team') return Team.objects.filter( roles__positions__term_from__lte=date.today(), roles__positions__term_to__gte=date.today(), roles__positions__applications__applicant=self, roles__positions__applications__status='appointed', ) @property def roles(self): Role = apps.get_model('involvement', 'Role') return Role.objects.filter( positions__term_from__lte=date.today(), positions__term_to__gte=date.today(), positions__applications__applicant=self, positions__applications__status='appointed', ) @property def get_status(self): self.update_status() return self.status def get_full_name(self): return self.name def fetch_and_save_melos_info(self): melos_data = self.get_melos_user_data() if melos_data is not None: self.name = "{} {}".format( melos_data['first_name'].strip(), melos_data['last_name'].strip() ) self.person_nr = melos_data['person_number'] self.save() return True return False @property def get_phone_formatted(self): try: parsed_number = parse(self.phone_number, "SE") number_format = \ PhoneNumberFormat.NATIONAL \ if parsed_number.country_code == 46 \ else PhoneNumberFormat.INTERNATIONAL return format_number( parsed_number, number_format ) except Exception: return self.phone_number @property def get_ssn(self): return self.person_nr @property def get_email(self): if not self.email: data = self.get_melos_user_data() if data | data['email']: self.email = data['email'] self.save() return self.email def person_number(self) -> str: return self.get_ssn def update_status(self, data=None, save=True): if data is None: # Prevent updating this value to often if timezone.now() - self.status_changed < timedelta(days=1): return melos_user_data = self.get_melos_user_data() if melos_user_data is None: return is_member = MelosClient.is_member(melos_user_data['person_number']) data = "member" if is_member else "nonmember" if data == 'member': self.status = 'member' elif data == 'nonmember': if self.status not in ['member', 'alumnus']: self.status = 'nonmember' else: self.status = 'alumnus' self.status_changed = timezone.now() if save: self.save() def remove_old_email(self): for email in self.get_unconfirmed_emails() or []: self.remove_email(email) for email in self.get_confirmed_emails(): if email != self.email: self.remove_email(email) def get_status_text(self, status): status = _('Member') if status == 'member' else _('Nonmember') return status def sync_user_groups(self): current_groups = self.groups.all() wanted_groups = list(map(lambda role: role.group, self.roles.filter( positions__applications__removed=False ).all())) # Remove unavailable groups for group in current_groups: if group not in wanted_groups: group.user_set.remove(self) # Add missing groups for group in wanted_groups: if (group not in current_groups): group.user_set.add(self) def get_melos_user_data(self): if self.melos_user_data is None: self.melos_user_data = MelosClient.get_user_data(self.melos_id) return self.melos_user_data @staticmethod def find_by_melos_id(melos_id): if melos_id: return Member.objects.filter(melos_id=int(melos_id)).first() return None @staticmethod def find_by_ssn(ssn): try: ssn = ssn.strip() SSNValidator()(ssn) user = Member.objects.filter(person_nr=ssn).first() if user is None: melos_id = MelosClient.get_melos_id(ssn) return Member.find_by_melos_id(melos_id), melos_id else: return user, user.melos_id except Exception: pass return None, None
def validate_username(self, value): user = usr.objects.filter(username=value) if user: raise serializers.ValidationError("Username is already taken") return AbstractBaseUser.normalize_username(value)
def delete(self, using=None, keep_parents=False): return AbstractBaseUser.delete(self, using=using, keep_parents=keep_parents)