Ejemplo n.º 1
0
 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
Ejemplo n.º 2
0
    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
Ejemplo n.º 3
0
    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
Ejemplo n.º 4
0
 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)
Ejemplo n.º 5
0
    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
Ejemplo n.º 6
0
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()
Ejemplo n.º 7
0
 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
Ejemplo n.º 8
0
 def clean(self):
     # Skip the AbstractUser.clean as this tries to set self.email
     AbstractBaseUser.clean(self)
Ejemplo n.º 9
0
 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)
Ejemplo n.º 10
0
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
Ejemplo n.º 11
0
 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)
Ejemplo n.º 12
0
 def delete(self, using=None, keep_parents=False):              
     return AbstractBaseUser.delete(self, using=using, keep_parents=keep_parents)