コード例 #1
0
class PostalAddress(colander.MappingSchema):
    address = colander.SchemaNode(
        colander.String(),
        validator=MaliciousInputValidator(),
        title=_('Address'),
        widget=deform.widget.TextInputWidget(error_class='text-danger',
                                             css_class='form-control'),
    )
    locality = colander.SchemaNode(
        colander.String(),
        validator=MaliciousInputValidator(),
        title=_('City'),
        widget=deform.widget.TextInputWidget(error_class='text-danger',
                                             css_class='form-control'),
    )
    postalCode = colander.SchemaNode(
        colander.String(),
        validator=colander.All(colander.Length(min=5, max=6),
                               MaliciousInputValidator()),
        title=_('Postal code'),
        widget=deform.widget.TextInputWidget(error_class='text-danger',
                                             css_class='form-control'))
    country = colander.SchemaNode(colander.String(),
                                  validator=MaliciousInputValidator(),
                                  title=_('Country'),
                                  widget=deform.widget.TextInputWidget(
                                      error_class='text-danger',
                                      css_class='form-control'),
                                  default=postal_address_default_country)
コード例 #2
0
    def remove_action(self, index, post_data):
        emails = self.user.get_mail_aliases()
        if len(emails) == 1:
            message = _('Error: You only have one email address and it  '
                        'can not be removed')
            return {
                'result': 'error',
                'message': get_localizer(self.request).translate(message),
            }
        remove_email = emails[index]['email']
        emails.remove(emails[index])

        self.user.set_mail_aliases(emails)
        primary_email = self.user.get_mail()

        if not primary_email or primary_email == remove_email:
            self.user.set_mail(emails[0]['email'])

        try:
            self.user.save(self.request)
        except UserOutOfSync:
            return self.sync_user()

        self.request.stats.count('dashboard/email_removed', 1)
        message = _('Email address was successfully removed')
        return {
            'result': 'success',
            'message': get_localizer(self.request).translate(message),
        }
コード例 #3
0
class Person(CSRFTokenSchema):
    givenName = colander.SchemaNode(colander.String(),
                                    validator=MaliciousInputValidator(),
                                    widget=deform.widget.TextInputWidget(
                                        error_class='text-danger',
                                        css_class='form-control'),
                                    readonly=True,
                                    title=_('Given name'))
    surname = colander.SchemaNode(colander.String(),
                                  validator=MaliciousInputValidator(),
                                  widget=deform.widget.TextInputWidget(
                                      error_class='text-danger',
                                      css_class='form-control'),
                                  title=_('Surname'))
    displayName = colander.SchemaNode(colander.String(),
                                      validator=MaliciousInputValidator(),
                                      widget=deform.widget.TextInputWidget(
                                          error_class='text-danger',
                                          css_class='form-control'),
                                      title=_('Display name'))
    preferredLanguage = colander.SchemaNode(
        colander.String(),
        validator=MaliciousInputValidator(),
        title=_('Preferred language'),
        missing='',
        widget=preferred_language_widget)
コード例 #4
0
    def add_success(self, mobileform):
        mobile_number = self.schema.serialize(mobileform)['mobile']
        mobile_number = normalize_to_e_164(self.request, mobile_number)
        mobile = PhoneNumber(
            data={
                'number': mobile_number,
                'verified': False,
                'primary': False,
                'created_ts': datetime.utcnow()
            })
        self.user = get_session_user(self.request)
        self.user.phone_numbers.add(mobile)
        try:
            self.context.save_dashboard_user(self.user)
        except UserOutOfSync:
            self.sync_user()

        else:
            send_verification_code(self.request, self.user, mobile_number)

            self.request.session.flash(_('Changes saved'), queue='forms')
            msg = _(
                'A confirmation code has been sent to your mobile phone. '
                'Please click on the "Pending confirmation" link below and enter your confirmation code.'
            )
            msg = get_localizer(self.request).translate(msg)
            self.request.session.flash(msg, queue='forms')
コード例 #5
0
    def add_success(self, emailform):
        newemail = self.schema.serialize(emailform)

        # We need to add the new email to the emails list

        emails = self.user.get_mail_aliases()

        mailsubdoc = {
            'email': newemail['mail'],
            'verified': False,
            'added_timestamp': datetime.utcnow()
        }

        emails.append(mailsubdoc)

        self.user.set_mail_aliases(emails)
        try:
            self.user.save(self.request)
        except UserOutOfSync:
            self.sync_user()

        else:
            message = _('Changes saved')
            self.request.session.flash(get_localizer(self.request).translate(message), queue='forms')

            send_verification_mail(self.request, newemail['mail'])

            second_msg = _('A confirmation email has been sent to your email '
                    'address. Please enter your confirmation code '
                    '<a href="#" class="verifycode" '
                    'data-identifier="${id}">here</a>.', mapping={'id': len(emails)})
            self.request.session.flash(get_localizer(self.request).translate(second_msg), queue='forms')
コード例 #6
0
ファイル: nins.py プロジェクト: digideskio/eduid-dashboard
def send_letter(request, user, nin):

    settings = request.registry.settings
    letter_url = settings.get('letter_service_url')
    send_letter_url = urlparse.urljoin(letter_url, 'send-letter')

    data = {'eppn': user.eppn, 'nin': nin}
    response = requests.post(send_letter_url, data=data)
    result = 'error'
    msg = _('There was a problem with the letter service. '
            'Please try again later.')
    if response.status_code == 200:
        logger.info("Letter sent to user {!r}.".format(user))  # This log line moved here from letter_status function
        expires = response.json()['letter_expires']
        expires = datetime.utcfromtimestamp(int(expires))
        expires = expires.strftime('%Y-%m-%d')
        result = 'success'
        msg = _('A letter with a verification code has been sent to your '
                'official postal address. Please return to this page once you receive it.'
                ' The code will be valid until ${expires}.',
                mapping={'expires': expires})
    return {
        'result': result,
        'message': get_localizer(request).translate(msg),
    }
コード例 #7
0
ファイル: mobiles.py プロジェクト: SUNET/eduid-dashboard
    def add_success(self, mobileform):
        mobile_number = self.schema.serialize(mobileform)['mobile']
        mobile_number = normalize_to_e_164(self.request, mobile_number)
        mobile = PhoneNumber(data={'number':  mobile_number,
                                   'verified': False,
                                   'primary': False,
                                   'created_ts': datetime.utcnow()
                                   })
        self.user = get_session_user(self.request)
        self.user.phone_numbers.add(mobile)
        try:
            self.context.save_dashboard_user(self.user)
        except UserOutOfSync:
            self.sync_user()

        else:
            send_verification_code(self.request, self.user, mobile_number)

            self.request.session.flash(_('Changes saved'),
                                   queue='forms')
            msg = _('A confirmation code has been sent to your mobile phone. '
                'Please click on the "Pending confirmation" link below and enter your confirmation code.')
            msg = get_localizer(self.request).translate(msg)
            self.request.session.flash(msg,
                                   queue='forms')
コード例 #8
0
ファイル: mobiles.py プロジェクト: SUNET/eduid-dashboard
    def setprimary_action(self, index, post_data):
        self.user = get_session_user(self.request)
        mobiles = self.user.phone_numbers.to_list()

        try:
            mobile = mobiles[index]
        except IndexError:
            return self.sync_user()

        if not mobile.is_verified:
            message = _('You need to confirm your mobile number '
                        'before it can become primary')
            return {
                'result': 'bad',
                'message': get_localizer(self.request).translate(message),
            }

        self.user.phone_numbers.primary = mobile.number
        try:
            self.context.save_dashboard_user(self.user)
        except UserOutOfSync:
            return self.sync_user()

        self.request.stats.count('mobile_number_set_primary')
        message = _('Mobile phone number was successfully made primary')
        return {
            'result': 'success',
            'message': get_localizer(self.request).translate(message),
        }
コード例 #9
0
class ResetPasswordStep2(CSRFTokenSchema):
    use_custom_password = colander.SchemaNode(
        colander.Boolean(),
        widget=deform.widget.CheckboxWidget(),
        title=_('Use my own password'),
        missing='false')

    suggested_password = colander.SchemaNode(
        colander.String(),
        title=_('Suggested password'),
        widget=deform.widget.TextInputWidget(
            readonly=True, css_class='suggested-password form-control'),
        missing=password_readonly)

    custom_password = colander.SchemaNode(
        colander.String(),
        widget=deform.widget.PasswordWidget(
            size=20,
            error_class='text-danger',
            css_class='form-control custom-password'),
        validator=PasswordValidator(),
        title=_("New Password"),
        missing='')
    repeated_password = colander.SchemaNode(
        colander.String(),
        widget=deform.widget.PasswordWidget(
            size=20,
            error_class='text-danger',
            css_class='form-control custom-password'),
        title=_("Confirm New Password"),
        missing='')

    def validator(self, node, data):
        if data['custom_password'] != data['repeated_password']:
            raise colander.Invalid(node, _("Passwords doesn't match"))
コード例 #10
0
    def remove_action(self, index, post_data):
        self.user = get_session_user(self.request)
        emails = self.user.mail_addresses.to_list()
        if len(emails) == 1:
            message = _('Error: You only have one email address and it  '
                        'can not be removed')
            return {
                'result': 'error',
                'message': get_localizer(self.request).translate(message),
            }

        try:
            remove_email = emails[index].email
        except IndexError:
            return self.sync_user()

        try:
            self.user.mail_addresses.remove(remove_email)
        except PrimaryElementViolation:
            new_index = 0 if index != 0 else 1
            self.user.mail_addresses.primary = emails[new_index].email
            self.user.mail_addresses.remove(remove_email)

        try:
            self.context.save_dashboard_user(self.user)
        except UserOutOfSync:
            return self.sync_user()

        self.request.stats.count('email_removed')
        message = _('Email address was successfully removed')
        return {
            'result': 'success',
            'message': get_localizer(self.request).translate(message),
        }
コード例 #11
0
ファイル: validators.py プロジェクト: SUNET/eduid-dashboard
    def __call__(self, node, value):
        """
        Validator which makes sure that:
        1. the NiN has not already been added by the user
        2. the user does not already have a confirmed NiN.
        """

        from eduiddashboard.models import normalize_nin
        value = normalize_nin(copy(value))

        request = node.bindings.get('request')
        user = request.context.user
        user_nins = user.nins

        unverified_user_nins = request.db.verifications.find({
            'obj_id': value,
            'model_name': 'norEduPersonNIN',
            'user_oid': user.user_id,
            'verified': False
        })

        # Search the request.POST for any post that starts with "add".
        for post_value in request.POST:
            if post_value.startswith('add') and (
                    user_nins.find(value) or unverified_user_nins.count() > 0):
                err = _('National identity number already added')
                raise colander.Invalid(node,
                                       get_localizer(request).translate(err))

            elif post_value.startswith('add') and user_nins.count > 0:
                err = _(
                    'You already have a confirmed national identity number')
                raise colander.Invalid(node,
                                       get_localizer(request).translate(err))
コード例 #12
0
ファイル: security.py プロジェクト: Ratler/eduid-dashboard
    def save_success(self, passwordform):
        passwords_data = self.schema.serialize(passwordform)
        user = self.request.session['user']

        if passwords_data.get('use_custom_password') == 'true':
            # The user has entered his own password and it was verified by
            # validators
            log.debug("Password change for user {!r} (custom password).".format(user.get_id()))
            new_password = passwords_data.get('custom_password')

        else:
            # If the user has selected the suggested password, then it should
            # be in session
            log.debug("Password change for user {!r} (suggested password).".format(user.get_id()))
            new_password = self.get_suggested_password()

        new_password = new_password.replace(' ', '')

        old_password = passwords_data['old_password']

        # Load user from database to ensure we are working on an up-to-date set of credentials.
        # XXX this refresh is a bit redundant with the same thing being done in OldPasswordValidator.
        user = self.request.userdb.get_user_by_oid(user.get_id())

        self.changed = change_password(self.request, user, old_password, new_password)
        if self.changed:
            self.message = _('Your password has been successfully updated')
        else:
            self.message = _('An error has occured while updating your password, '
                             'please try again or contact support if the problem persists.')
コード例 #13
0
ファイル: emails.py プロジェクト: digideskio/eduid-dashboard
    def add_success(self, emailform):
        newemail = self.schema.serialize(emailform)

        new_email = MailAddress(email=newemail['mail'],
                application='dashboard',
                verified=False, primary=False)

        self.user = get_session_user(self.request)
        self.user.mail_addresses.add(new_email)
        try:
            self.context.save_dashboard_user(self.user)
        except UserOutOfSync:
            self.sync_user()

        else:
            message = _('Changes saved')
            self.request.session.flash(get_localizer(self.request).translate(message), queue='forms')

            send_verification_mail(self.request, newemail['mail'])

            second_msg = _('A confirmation email has been sent to your email '
                    'address. Please enter your confirmation code '
                    '<a href="#" class="verifycode" '
                    'data-identifier="${id}">here</a>.', mapping={'id': self.user.mail_addresses.count})
            self.request.session.flash(get_localizer(self.request).translate(second_msg), queue='forms')
コード例 #14
0
ファイル: emails.py プロジェクト: digideskio/eduid-dashboard
    def setprimary_action(self, index, post_data):

        self.user = get_session_user(self.request)
        try:
            mail = self.user.mail_addresses.to_list()[index]
        except IndexError:
            return self.sync_user()

        if not mail.is_verified:
            message = _('You need to confirm your email address '
                        'before it can become primary')
            return {
                'result': 'bad',
                'message': get_localizer(self.request).translate(message),
            }

        self.user.mail_addresses.primary = mail.email
        try:
            self.context.save_dashboard_user(self.user)
        except UserOutOfSync:
            return self.sync_user()

        self.request.stats.count('dashboard/email_set_primary', 1)
        message = _('Your primary email address was '
                    'successfully changed')
        return {'result': 'success',
                'message': get_localizer(self.request).translate(message)}
コード例 #15
0
    def __call__(self, node, value):
        """
        Validator which makes sure that:
        1. the NiN has not already been added by the user
        2. the user does not already have a confirmed NiN.
        """

        from eduiddashboard.models import normalize_nin
        value = normalize_nin(copy(value))

        request = node.bindings.get('request')
        user = get_session_user(request)
        user_nins = user.nins

        unverified_user_nins = request.db.verifications.find({
            'obj_id': value,
            'model_name': 'norEduPersonNIN',
            'user_oid': user.user_id,
            'verified': False
        })

        # Search the request.POST for any post that starts with "add".
        for post_value in request.POST:
            if post_value.startswith('add') and (user_nins.find(value) or
                                      unverified_user_nins.count() > 0):
                err = _('National identity number already added')
                raise colander.Invalid(node, get_localizer(request).translate(err))

            elif post_value.startswith('add') and user_nins.count > 0:
                err = _('You already have a confirmed national identity number')
                raise colander.Invalid(node, get_localizer(request).translate(err))
コード例 #16
0
ファイル: emails.py プロジェクト: digideskio/eduid-dashboard
    def remove_action(self, index, post_data):
        self.user = get_session_user(self.request)
        emails = self.user.mail_addresses.to_list()
        if len(emails) == 1:
            message = _('Error: You only have one email address and it  '
                        'can not be removed')
            return {
                'result': 'error',
                'message': get_localizer(self.request).translate(message),
            }

        try:
            remove_email = emails[index].email
        except IndexError:
            return self.sync_user()

        try:
            self.user.mail_addresses.remove(remove_email)
        except PrimaryElementViolation:
            new_index = 0 if index != 0 else 1
            self.user.mail_addresses.primary = emails[new_index].email
            self.user.mail_addresses.remove(remove_email)

        try:
            self.context.save_dashboard_user(self.user)
        except UserOutOfSync:
            return self.sync_user()

        self.request.stats.count('dashboard/email_removed', 1)
        message = _('Email address was successfully removed')
        return {
            'result': 'success',
            'message': get_localizer(self.request).translate(message),
        }
コード例 #17
0
ファイル: emails.py プロジェクト: Ratler/eduid-dashboard
    def add_success(self, emailform):
        newemail = self.schema.serialize(emailform)

        # We need to add the new email to the emails list

        emails = self.user.get_mail_aliases()

        mailsubdoc = {
            'email': newemail['mail'],
            'verified': False,
        }

        emails.append(mailsubdoc)

        self.user.set_mail_aliases(emails)
        self.user.save(self.request)

        self.request.session.flash(_('Changes saved'),
                                   queue='forms')

        send_verification_mail(self.request, newemail['mail'])

        self.request.session.flash(_('A confirmation email has been sent to your email address. '
                                     'Please enter your confirmation code <a href="#" class="verifycode" data-identifier="${id}">here</a>.',
                                     mapping={'id': len(emails)}),
                                   queue='forms')
コード例 #18
0
    def setprimary_action(self, index, post_data):

        self.user = get_session_user(self.request)
        try:
            mail = self.user.mail_addresses.to_list()[index]
        except IndexError:
            return self.sync_user()

        if not mail.is_verified:
            message = _('You need to confirm your email address '
                        'before it can become primary')
            return {
                'result': 'bad',
                'message': get_localizer(self.request).translate(message),
            }

        self.user.mail_addresses.primary = mail.email
        try:
            self.context.save_dashboard_user(self.user)
        except UserOutOfSync:
            return self.sync_user()

        self.request.stats.count('email_set_primary')
        message = _('Your primary email address was ' 'successfully changed')
        return {
            'result': 'success',
            'message': get_localizer(self.request).translate(message)
        }
コード例 #19
0
    def add_success(self, emailform):
        newemail = self.schema.serialize(emailform)

        new_email = MailAddress(email=newemail['mail'],
                                application='dashboard',
                                verified=False,
                                primary=False)

        self.user = get_session_user(self.request)
        self.user.mail_addresses.add(new_email)
        try:
            self.context.save_dashboard_user(self.user)
        except UserOutOfSync:
            self.sync_user()

        else:
            message = _('Changes saved')
            self.request.session.flash(get_localizer(
                self.request).translate(message),
                                       queue='forms')

            send_verification_mail(self.request, newemail['mail'])

            second_msg = _(
                'A confirmation email has been sent to your email '
                'address. Please enter your confirmation code '
                '<a href="#" class="verifycode" '
                'data-identifier="${id}">here</a>.',
                mapping={'id': self.user.mail_addresses.count})
            self.request.session.flash(get_localizer(
                self.request).translate(second_msg),
                                       queue='forms')
コード例 #20
0
ファイル: mobiles.py プロジェクト: Ratler/eduid-dashboard
    def setprimary_action(self, index, post_data):
        mobiles = self.user.get_mobiles()

        if index > len(mobiles):
            return {
                'result': 'bad',
                'message': _("That mobile phone number doesn't exists"),
            }

        if index > len(mobiles):
            return {
                'result': 'bad',
                'message': _("You need to verify that mobile phone number "
                             "before be able to set as primary"),
            }

        # set all to False, and then set the new primary to True using the index
        for mobile in mobiles:
            mobile['primary'] = False

        assert(mobiles[index]['verified'])  # double check
        mobiles[index]['primary'] = True

        self.user.set_mobiles(mobiles)
        self.user.save(self.request)

        return {
            'result': 'ok',
            'message': _('Mobile phone number was successfully made primary'),
        }
コード例 #21
0
 def __call__(self, node, value):
     request = node.bindings.get('request')
     is_email = '@' in value
     localizer = get_localizer(request)
     if not is_email:
         try:
             request.userdb.get_user_by_username(value)
         except UserDB.UserDoesNotExist:
             err = _("Username does not exist")
             raise colander.Invalid(node, localizer.translate(err))
         except UserDB.MultipleUsersReturned:
             err = _("There is more than one user for that username")
             raise colander.Invalid(node, localizer.translate(err))
     else:
         try:
             request.userdb.get_user_by_email(value)
         except UserDoesNotExist as e:
             if e.args:
                 msg = e.args[0]
             else:
                 msg = _("email address ${val} does not exist "
                         "or is unverified")
                 msg = localizer.translate(msg, mapping={'val': value})
             raise colander.Invalid(node, msg)
         except MultipleUsersReturned:
             msg = _("There is more than one user for that email")
             raise colander.Invalid(node, localizer.translate(msg))
コード例 #22
0
ファイル: validators.py プロジェクト: SUNET/eduid-dashboard
 def __call__(self, node, value):
     request = node.bindings.get('request')
     is_email = '@' in value
     localizer = get_localizer(request)
     if not is_email:
         try:
             request.userdb.get_user_by_username(value)
         except UserDB.UserDoesNotExist:
             err = _("Username does not exist")
             raise colander.Invalid(node, localizer.translate(err))
         except UserDB.MultipleUsersReturned:
             err = _("There is more than one user for that username")
             raise colander.Invalid(node, localizer.translate(err))
     else:
         try:
             request.userdb.get_user_by_email(value)
         except UserDoesNotExist as e:
             if e.args:
                 msg = e.args[0]
             else:
                 msg = _("email address ${val} does not exist "
                         "or is unverified")
                 msg = localizer.translate(msg, mapping={'val': value})
             raise colander.Invalid(node, msg)
         except MultipleUsersReturned:
             msg = _("There is more than one user for that email")
             raise colander.Invalid(node, localizer.translate(msg))
コード例 #23
0
    def setprimary_action(self, index, post_data):
        self.user = get_session_user(self.request)
        mobiles = self.user.phone_numbers.to_list()

        try:
            mobile = mobiles[index]
        except IndexError:
            return self.sync_user()

        if not mobile.is_verified:
            message = _('You need to confirm your mobile number '
                        'before it can become primary')
            return {
                'result': 'bad',
                'message': get_localizer(self.request).translate(message),
            }

        self.user.phone_numbers.primary = mobile.number
        try:
            self.context.save_dashboard_user(self.user)
        except UserOutOfSync:
            return self.sync_user()

        self.request.stats.count('mobile_number_set_primary')
        message = _('Mobile phone number was successfully made primary')
        return {
            'result': 'success',
            'message': get_localizer(self.request).translate(message),
        }
コード例 #24
0
def verifications(context, request):
    model_name = request.matchdict['model']
    code = request.matchdict['code']

    verification = get_verification_code(request, model_name, code=code)
    if verification and verification['expired']:
        log.debug("Verification code is expired: {!r}".format(verification))
        raise HTTPNotFound()  # the code is expired

    if code not in request.session.get('verifications', []):
        log.debug("Code {!r} not found in active sessions verifications: {!r}".format(
            code, request.session.get('verifications', [])))
        raise HTTPNotFound(_("Can't locate the code in the active session"))
    try:
        obj_id = verify_code(request, model_name, code)
    except UserOutOfSync:
        msg = _('Your user profile is out of sync. Please '
                'reload the page and try again.')
        msg = get_localizer(request).translate(msg)
        request.session.flash(msg),
        raise HTTPFound(request.context.route_url('profile-editor'))

    if obj_id is not None:
        request.stats.count('verification_{!s}_ok'.format(model_name))
        return HTTPFound(location=request.route_url('home'))
    else:
        log.debug("Incorrect verification code {!r} for model {!r}".format(code, model_name))
        request.stats.count('verification_{!s}_fail'.format(model_name))
        raise HTTPNotFound()
コード例 #25
0
class UserSearcher(colander.MappingSchema):
    query = colander.SchemaNode(
        colander.String(),
        validator=MaliciousInputValidator(),
        description=_('Search for users'),
        title=_('query'),
        widget=deform.widget.TextInputWidget(error_class='text-danger'))
コード例 #26
0
def verifications(context, request):
    model_name = request.matchdict['model']
    code = request.matchdict['code']

    verification = get_verification_code(request, model_name, code=code)
    if verification and verification['expired']:
        log.debug("Verification code is expired: {!r}".format(verification))
        raise HTTPNotFound()  # the code is expired

    if code not in request.session.get('verifications', []):
        log.debug("Code {!r} not found in active sessions verifications: {!r}".
                  format(code, request.session.get('verifications', [])))
        raise HTTPNotFound(_("Can't locate the code in the active session"))
    try:
        obj_id = verify_code(request, model_name, code)
    except UserOutOfSync:
        msg = _('Your user profile is out of sync. Please '
                'reload the page and try again.')
        msg = get_localizer(request).translate(msg)
        request.session.flash(msg),
        raise HTTPFound(request.context.route_url('profile-editor'))

    if obj_id is not None:
        request.stats.count('verification_{!s}_ok'.format(model_name))
        return HTTPFound(location=request.route_url('home'))
    else:
        log.debug("Incorrect verification code {!r} for model {!r}".format(
            code, model_name))
        request.stats.count('verification_{!s}_fail'.format(model_name))
        raise HTTPNotFound()
コード例 #27
0
ファイル: mobiles.py プロジェクト: Ratler/eduid-dashboard
def get_status(request, user):
    """
    Check if all mobiles are verified already

    return msg and icon
    """
    mobiles = user.get_mobiles()
    pending_actions = None
    pending_action_type = ''
    verification_needed = -1

    if not mobiles:
        pending_actions = _('Add mobile phone number')
    else:
        for n, mobile in enumerate(mobiles):
            if not mobile['verified']:
                verification_needed = n
                pending_action_type = 'verify'
                pending_actions = _('A mobile phone number is pending confirmation')

    if pending_actions:
        return {
            'icon': get_icon_string('warning-sign'),
            'pending_actions': pending_actions,
            'pending_action_type': pending_action_type,
            'completed': (0, 1),
            'verification_needed': verification_needed,
        }
    return {
        'completed': (1, 1),
    }
コード例 #28
0
ファイル: nins.py プロジェクト: SUNET/eduid-dashboard
def send_letter(request, user, nin):

    settings = request.registry.settings
    letter_url = settings.get('letter_service_url')
    send_letter_url = urlappend(letter_url, 'send-letter')

    data = {'eppn': user.eppn, 'nin': nin}
    response = requests.post(send_letter_url, data=data)
    result = 'error'
    msg = _('There was a problem with the letter service. '
            'Please try again later.')
    if response.status_code == 200:
        logger.info("Letter sent to user {!r}.".format(user))  # This log line moved here from letter_status function
        expires = response.json()['letter_expires']
        expires = datetime.utcfromtimestamp(int(expires))
        expires = expires.strftime('%Y-%m-%d')
        result = 'success'
        msg = _('A letter with a verification code has been sent to your '
                'official postal address. Please return to this page once you receive it.'
                ' The code will be valid until ${expires}.',
                mapping={'expires': expires})
    return {
        'result': result,
        'message': get_localizer(request).translate(msg),
    }
コード例 #29
0
ファイル: validators.py プロジェクト: SUNET/eduid-dashboard
    def __call__(self, node, value):
        """
            Check is the NIN is reachable by eduid_msg service through
            Mina Meddelanden service
        """

        from eduiddashboard.models import normalize_nin

        value = normalize_nin(copy(value))
        request = node.bindings.get('request')
        settings = request.registry.settings

        if settings.get('developer_mode', False):
            return

        msg = None
        try:
            reachable = request.msgrelay.nin_reachable(value)
        except request.msgrelay.TaskFailed:
            msg = _('Sorry, we are experiencing temporary technical '
                    'problem with ${service_name}, please try again '
                    'later.')
            reachable = 'Failed'

        if reachable is False:
            msg = _(
                'This national identity number is '
                'not registered with "${service_name}". Please register '
                'at <a href="${service_url}" target="_blank">${service_name}</a>.'
            )

        elif reachable is 'Anonymous':
            msg = _(
                'Your registration process with '
                '"${service_name}" is not complete. Please visit <a href='
                '"${service_url}" target="_blank">${service_name}</a> to complete your registration.'
            )

        elif reachable is 'Sender_not':
            msg = _(
                'According to "${service_name}"'
                ' you have opted out to receive messages from SUNET (eduID). In'
                ' order to receive a confirmation code from us, you need to'
                ' accept SUNET (eduID) as a sender at <a href="${service_url}" target="_blank">'
                '${service_name}</a>.')

        if msg:
            localizer = get_localizer(request)
            raise colander.Invalid(
                node,
                localizer.translate(msg,
                                    mapping={
                                        'service_name':
                                        settings.get('nin_service_name'),
                                        'service_url':
                                        settings.get('nin_service_url'),
                                    }))
コード例 #30
0
class Email(CSRFTokenSchema):
    mail = colander.SchemaNode(
        colander.String(),
        preparer=EmailNormalizer(),
        validator=colander.All(colander.Email(), MaliciousInputValidator(),
                               EmailUniqueValidator()),
        title=_('email'),
        widget=deform.widget.TextInputWidget(mask=_('Email address'),
                                             error_class='text-danger',
                                             css_class='form-control'))
コード例 #31
0
class Mobile(CSRFTokenSchema):
    mobile = colander.SchemaNode(
        colander.String(),
        validator=colander.All(MobileFormatValidator,
                               MaliciousInputValidator(),
                               MobilePhoneUniqueValidator()),
        title=_('mobile'),
        widget=deform.widget.TextInputWidget(mask=_('Mobile phone number'),
                                             error_class='text-danger',
                                             css_class='form-control'))
コード例 #32
0
    def save_success(self, passwordform):
        authn_ts = self.request.session.get('reauthn-for-chpass', None)
        if authn_ts is None:
            raise HTTPBadRequest(_('No authentication info'))
        now = datetime.utcnow()
        delta = now - datetime.fromtimestamp(authn_ts)
        # XXX put the reauthn timeout in the settings
        if int(delta.total_seconds()) > 600:
            msg = _('Stale authentication info. Please try again.')
            self.request.session.flash('error|' + msg)
            raise HTTPFound(self.context.route_url('profile-editor'))
        user = get_session_user(self.request)
        log.debug('Removing Authn ts for user {!r} before'
                  ' changing the password'.format(user))
        del self.request.session['reauthn-for-chpass']
        passwords_data = self.schema.serialize(passwordform)

        if passwords_data.get('use_custom_password') == 'true':
            # The user has entered his own password and it was verified by
            # validators
            log.debug(
                "Password change for user {!r} (custom password).".format(
                    user))
            new_password = passwords_data.get('custom_password')

        else:
            # If the user has selected the suggested password, then it should
            # be in session
            log.debug(
                "Password change for user {!r} (suggested password).".format(
                    user))
            new_password = self.get_suggested_password()

        new_password = new_password.replace(' ', '')

        old_password = passwords_data['old_password']

        # Load user from database to ensure we are working on an up-to-date set of credentials.
        # XXX this refresh is a bit redundant with the same thing being done in OldPasswordValidator.
        user = self.request.userdb_new.get_user_by_id(user.user_id)
        log.debug("Refreshed user {!s} from {!s}".format(
            user, self.request.userdb_new))
        retrieve_modified_ts(user, self.request.dashboard_userdb)

        self.changed = change_password(self.request, user, old_password,
                                       new_password)
        if self.changed:
            message = 'success|' + _(
                'Your password has been successfully updated')
        else:
            message = 'error|' + _(
                'An error has occured while updating your password, '
                'please try again or contact support if the problem persists.')
        self.request.session.flash(message)
        raise HTTPFound(self.context.route_url('profile-editor'))
コード例 #33
0
ファイル: emails.py プロジェクト: Ratler/eduid-dashboard
    def setprimary_action(self, index, post_data):
        mail = self.user.get_mail_aliases()[index]
        if not mail.get('verified', False):
            return {
                'result': 'bad',
                'message': _("You need to confirm your email address before it can become primary"),
            }

        self.user.set_mail(mail['email'])
        self.user.save(self.request)

        return {'result': 'ok', 'message': _('Your primary email address was '
                                             'successfully changed')}
コード例 #34
0
ファイル: portal.py プロジェクト: SUNET/eduid-dashboard
def home(context, request):
    """
    If workmode is not personal mode, then show an admin or helpdesk interface

    """

    if context.workmode == 'personal':
        raise HTTPFound(context.route_url('profile-editor'))

    searcher_schema = UserSearcher()
    buttons = (deform.Button(name='search', title=_('Search')),)
    searcher_form = Form(searcher_schema, buttons=buttons,
                         method='get', formid='user-searcher')

    users = None
    showresults = False

    if sanitize_get(request, 'query') is not None:
        controls = request.GET.items()
        try:
            searcher_data = searcher_form.validate(controls)
        except deform.ValidationFailure as form:
            return {
                'form': form,
                'users': [],
                'showresults': False,
            }
        query_text = re.escape(searcher_data['query'])
        filter_dict = {'$or': []}
        field_filter = {'$regex': '.*%s.*' % query_text, '$options': 'i'}
        for field in SEARCHER_FIELDS:
            filter_dict['$or'].append({field: field_filter})

        users = request.userdb.get_users(filter_dict)

        showresults = True

    if users and users.count() > SEARCH_RESULT_LIMIT:
        request.session.flash(_('error|More than %d users returned. Please refine your search.' % SEARCH_RESULT_LIMIT))
        users.limit(SEARCH_RESULT_LIMIT)

    # if users and users.count() == 1:
    #    raise HTTPFound(request.route_url('profile-editor',
    #                    userid=users[0][context.main_attribute]))

    return {
        'form': searcher_form,
        'users': users,
        'showresults': showresults,
    }
コード例 #35
0
ファイル: permissions.py プロジェクト: SUNET/eduid-dashboard
    def authorize(self):
        if not has_logged_in_user(self.request):
            raise HTTPForbidden(_('Not logged in'))
        is_authorized = super(BaseCredentialsFactory, self).authorize()

        # Verify that session loa is equal than the max reached
        # loa
        max_user_loa = self.get_max_loa()
        session_loa = self.get_loa()

        if session_loa != max_user_loa:
            raise HTTPForbidden(_('You must be logged in with {user_AL} '
                                  'to manage your credentials',
                                  mapping={'user_AL': max_user_loa}))
        return is_authorized
コード例 #36
0
ファイル: portal.py プロジェクト: SUNET/eduid-dashboard
def account_terminated(context, request):
    """
    The account termination action,
    removes all credentials for the terminated account
    from the VCCS service,
    flags the account as terminated,
    sends an email to the address in the terminated account,
    and logs out the session.

    :type user: eduid_userdb.dashboard.DashboardLegacyUser
    """
    settings = request.registry.settings

    authn_ts = request.session.get('reauthn-for-termination', None)
    if authn_ts is None:
        raise HTTPBadRequest(_('No authentication info'))
    now = datetime.utcnow()
    delta = now - datetime.fromtimestamp(authn_ts)
    # XXX put the reauthn timeout in the settings
    if int(delta.total_seconds()) > 600:
        msg = _('Stale authentication info. Please try again.')
        request.session.flash('error|' + msg)
        raise HTTPFound(context.route_url('profile-editor'))

    user = get_session_user(request)
    logger.debug('Removing Authn ts for user {!r} before'
            ' changing the password'.format(user))
    del request.session['reauthn-for-termination']

    logged_user = get_logged_in_user(request, legacy_user = False)
    if logged_user.user_id != user.user_id:
        raise HTTPUnauthorized("Wrong user")

    logger.info("Terminating user {!s}".format(user))

    # revoke all user credentials
    revoke_all_credentials(settings.get('vccs_url'), user)
    for p in logged_user.credentials.filter(Password).to_list():
        logged_user.passwords.remove(p.key)

    # flag account as terminated
    logged_user.terminated = True
    request.context.save_dashboard_user(logged_user)

    # email the user
    send_termination_mail(request, logged_user)

    return {}
コード例 #37
0
ファイル: security.py プロジェクト: Ratler/eduid-dashboard
    def reset_success(self, passwordform):
        passwords_data = self.schema.serialize(passwordform)
        email_or_username = passwords_data['email_or_username']

        # If input is a mail address we need to normalize it (ie lower case etc)
        if validate_email_format(email_or_username):
            email_or_username = normalize_email(email_or_username)
        elif email_or_username.startswith(u'0'):
            email_or_username = normalize_to_e_164(self.request, email_or_username)

        try:
            filter_dict = {'$or': []}
            for field in self.SEARCH_FIELDS:
                filter_dict['$or'].append({field: email_or_username})

            user = self.request.userdb.get_user_by_filter(filter_dict)
        except self.request.userdb.exceptions.UserDoesNotExist:
            log.debug("User {!r} does not exist".format(email_or_username))
            user = None

        if user is not None:
            nin = None
            nins = user.get_nins()
            if nins:
                nin = nins[-1]
            if nin is not None:
                reset_password_link = new_reset_password_code(self.request, user, mechanism='govmailbox')
                send_reset_password_gov_message(self.request, nin, user, reset_password_link)

        self.request.session['_reset_type'] = _('Myndighetspost')
        return HTTPFound(location=self.request.route_url('reset-password-sent'))
コード例 #38
0
    def reset_success(self, passwordform):
        passwords_data = self.schema.serialize(passwordform)
        email_or_username = passwords_data['email_or_username']

        try:
            user = self._search_user(email_or_username)
            log.debug(
                "Reset password via email initiated for user {!r}".format(
                    user))
            self.request.stats.count('pwreset_email_init')
        except UserDoesNotExist:
            log.debug(
                "Tried to initiate reset password via email but user {!r} does not exist"
                .format(email_or_username))
            self.request.stats.count('pwreset_email_init_unknown_user')
            user = None

        if user is not None:
            reference, reset_password_link = new_reset_password_code(
                self.request, user)
            send_reset_password_mail(self.request, user, reset_password_link)

        self.request.session['_reset_type'] = _('email')
        return HTTPFound(
            location=self.request.route_url('reset-password-sent'))
コード例 #39
0
def get_tab(request):
    label = _('Mobile phone numbers')
    return {
        'status': get_status,
        'label': get_localizer(request).translate(label),
        'id': 'mobiles',
    }
コード例 #40
0
    def reset_success(self, passwordform):
        passwords_data = self.schema.serialize(passwordform)
        email_or_username = passwords_data['email_or_username']

        try:
            user = self._search_user(email_or_username)
            log.debug(
                "Reset password via mm initiated for user {!r}.".format(user))
            self.request.stats.count('pwreset_mm_init')
        except UserDoesNotExist:
            log.debug(
                "Tried to initiate reset password via mm but user {!r} does not exist"
                .format(email_or_username))
            self.request.stats.count('pwreset_mm_init_unknown_user')
            user = None

        if user is not None:
            nin = None
            nins = user.nins.to_list()
            if nins:
                nin = nins[-1]
            if nin is not None:
                reference, reset_password_link = new_reset_password_code(
                    self.request, user, mechanism='govmailbox')
                send_reset_password_gov_message(self.request, reference, nin,
                                                user, reset_password_link)

        self.request.session['_reset_type'] = _('Myndighetspost')
        return HTTPFound(
            location=self.request.route_url('reset-password-sent'))
コード例 #41
0
    def __call__(self, node, value):

        request = node.bindings.get('request')
        user = get_session_user(request)
        mobile = normalize_to_e_164(request, value)

        # The debug logs below were added to help figure out how a user
        # managed to get by past this function with a duplicated phone number,
        # which was caught by userdb while saving the user.

        log.debug("User {!r} tried to add a phone number {!r}: "
                  "entering 1st code-section that will verify that it's unique."
                  .format(user.eppn, mobile))

        if sanitize_post_key(request, 'add') is not None:
            log.debug("User {!r} tried to add a phone number {!r}: "
                      "1st code-section evaluated, POST request OK."
                      .format(user.eppn, mobile))

            if user.phone_numbers.find(mobile):
                log.debug("User {!r} tried to add a phone number {!r}: "
                          "2nd code-section evaluated, the user had already "
                          "added the phone number."
                          .format(user.eppn, mobile))

                err = _("This mobile phone was already registered")
                raise colander.Invalid(node, get_localizer(request).translate(err))

            else:
                log.debug("User {!r} tried to add a phone number {!r}: "
                          "2nd code-section evaluated, the phone number "
                          "has not previously been added by the user."
                          .format(user.eppn, mobile))
コード例 #42
0
def get_tab(request):
    label = _('Postal address')
    return {
        'status': get_status,
        'label': get_localizer(request).translate(label),
        'id': 'postaladdress',
    }
コード例 #43
0
    def __call__(self, node, value):
        """
            Check if the NIN was not already registered and verified by any user
            Check if the NIN was not already registered by the present user in the
                verifications process.
        """

        from eduiddashboard.models import normalize_nin
        value = normalize_nin(copy(value))

        request = node.bindings.get('request')
        user = request.context.user
        user_nins = user.get_nins()

        unverified_user_nins = request.db.verifications.find({
            'obj_id': value,
            'model_name': 'norEduPersonNIN',
            'user_oid': user.get_id(),
            'verified': False
        })

        # Search the request.POST for any post that starts with "add"
        for post_value in request.POST:
            if post_value.startswith('add'):
                if unverified_user_nins.count() > 0 or value in user_nins:
                    err = _("This national identity number is already in use")
                    raise colander.Invalid(node,
                            get_localizer(request).translate(err))
コード例 #44
0
    def __call__(self, node, value):

        request = node.bindings.get('request')

        if not request.registry.settings.get('use_vccs', True):
            return

        old_password = value
        old_password = old_password.replace(" ", "")

        if 'edit-user' in request.session:
            userid = request.session['edit-user'].get_id()
        else:
            userid = request.session['user'].get_id()
        # Load user from database to ensure we are working on an up-to-date set of credentials.
        user = request.userdb.get_user_by_oid(userid)
        # XXX if we saved user['passwords'] to node.bindings.request['user']['passwords'] here,
        # we could possibly avoid doing the same refresh again when changing passwords
        # (in PasswordsView.save_success()).

        vccs_url = request.registry.settings.get('vccs_url')
        password = check_password(vccs_url, old_password, user)
        if not password:
            err = _('Current password is incorrect')
            localizer = get_localizer(request)
            raise colander.Invalid(node, localizer.translate(err))
コード例 #45
0
def get_tab(request):
    label = _('Postal address')
    return {
        'status': get_status,
        'label': get_localizer(request).translate(label),
        'id': 'postaladdress',
    }
コード例 #46
0
    def save_success(self, addressform):
        address = self.schema.serialize(addressform)
        address['verified'] = False
        address['type'] = 'alternative'

        addresses = self.user.get_addresses()
        if len(addresses) > 0 and addresses[0].get('type') == 'official':
            if len(addresses) == 1:
                addresses.append(address)
            else:
                addresses[1] = address
        else:
            addresses = [address]

        # update the session data
        self.user.set_addresses(addresses)
        try:
            self.user.save(self.request)
        except UserOutOfSync:
            self.sync_user()
        else:
            message = _('Changes saved.')
            self.request.session.flash(get_localizer(
                self.request).translate(message),
                                       queue='forms')
            self.request.stats.count('postal_address_saved')
コード例 #47
0
def set_phone_verified(request, user, new_number):
    """
    Mark a phone number as verified on a user.

    This process also includes *removing* the phone number from any other user
    that had it as a verified phone number.

    :param request: The HTTP request
    :param user: The user
    :param new_number: The phone number to mark as verified

    :type request: pyramid.request.Request
    :type user: User
    :type new_number: str | unicode

    :return: Status message
    :rtype: str | unicode
    """
    log.info('Trying to verify phone number for user {!r}.'.format(user))
    log.debug('Phone number: {!s}.'.format(new_number))
    # Start by removing mobile number from any other user
    old_user = request.userdb_new.get_user_by_phone(new_number, raise_on_missing=False)
    steal_count = 0
    if old_user and old_user.user_id != user.user_id:
        retrieve_modified_ts(old_user, request.dashboard_userdb)
        _remove_phone_from_user(new_number, old_user)
        request.context.save_dashboard_user(old_user)
        log.info('Removed phone number from user {!r}.'.format(old_user))
        steal_count = 1
    # Add the verified mobile number to the requesting user
    _add_phone_to_user(new_number, user)
    log.info('Phone number verified for user {!r}.'.format(user))
    request.stats.count('verify_mobile_stolen', steal_count)
    request.stats.count('verify_mobile_completed')
    return _('Phone {obj} verified')
コード例 #48
0
def set_email_verified(request, user, new_mail):
    """
    Mark an e-mail address as verified on a user.

    This process also includes *removing* the e-mail address from any other user
    that had it as a verified e-mail address.

    :param request: The HTTP request
    :param user: The user
    :param new_mail: The e-mail address to mark as verified

    :type request: pyramid.request.Request
    :type user: User
    :type new_mail: str | unicode

    :return: Status message
    :rtype: str | unicode
    """
    log.info('Trying to verify mail address for user {!r}.'.format(user))
    log.debug('Mail address: {!s}.'.format(new_mail))
    # Start by removing the email address from any other user that currently has it (verified)
    old_user = request.userdb_new.get_user_by_mail(new_mail, raise_on_missing=False)
    steal_count = 0
    if old_user and old_user.user_id != user.user_id:
        retrieve_modified_ts(old_user, request.dashboard_userdb)
        old_user = _remove_mail_from_user(new_mail, old_user)
        request.context.save_dashboard_user(old_user)
        steal_count = 1
    # Add the verified mail address to the requesting user
    _add_mail_to_user(new_mail, user)
    log.info('Mail address verified for user {!r}.'.format(user))
    request.stats.count('verify_mail_stolen', steal_count)
    request.stats.count('verify_mail_completed')
    return _('Email {obj} verified')
コード例 #49
0
ファイル: validators.py プロジェクト: SUNET/eduid-dashboard
 def __call__(self, node, value):
     request = node.bindings.get('request')
     try:
         request.userdb.get_user_by_email(value)
     except UserDoesNotExist:
         err = _("Email address does not exist")
         raise colander.Invalid(node, get_localizer(request).translate(err))
コード例 #50
0
ファイル: security.py プロジェクト: Ratler/eduid-dashboard
def send_reset_password_mail(request, user, reset_password_link):
    """ Send an email with the instructions for resetting password """
    mailer = get_mailer(request)

    site_name = request.registry.settings.get("site.name", "eduID")
    password_reset_timeout = int(request.registry.settings.get("password_reset_timeout", "120")) / 60
    email = user.get_mail()

    context = {
        "email": email,
        "reset_password_link": reset_password_link,
        "password_reset_timeout": password_reset_timeout,
        "site_url": request.route_url("home"),
        "site_name": site_name,
    }

    message = Message(
        subject=_("Reset your {site_name} password").format(
            site_name=site_name),
        sender=request.registry.settings.get("mail.default_sender"),
        recipients=[email],
        body=render(
            "templates/reset-password-email.txt.jinja2",
            context,
            request,
        ),
        html=render(
            "templates/reset-password-email.html.jinja2",
            context,
            request,
        ),
    )
    mailer.send(message)
コード例 #51
0
    def save_success(self, addressform):
        address = self.schema.serialize(addressform)
        address['verified'] = False
        address['type'] = 'alternative'

        addresses = self.user.get_addresses()
        if len(addresses) > 0 and addresses[0].get('type') == 'official':
            if len(addresses) == 1:
                addresses.append(address)
            else:
                addresses[1] = address
        else:
            addresses = [address]

        # update the session data
        self.user.set_addresses(addresses)
        try:
            self.user.save(self.request)
        except UserOutOfSync:
            self.sync_user()
        else:
            message = _('Changes saved.')
            self.request.session.flash(
                    get_localizer(self.request).translate(message),
                    queue='forms')
            self.request.stats.count('dashboard/postal_address_saved', 1)
コード例 #52
0
ファイル: nins.py プロジェクト: SUNET/eduid-dashboard
    def remove_action(self, data, post_data):
        """ Only not verified nins can be removed """
        raise HTTPNotImplemented  # Temporary remove the functionality
        self.user = get_session_user(self.request)

        nin, index = data.split()
        index = int(index)
        nins = get_not_verified_nins_list(self.request, self.user)

        if len(nins) > index:
            remove_nin = nins[index]
            if remove_nin != nin:
                return self.sync_user()
        else:
            return self.sync_user()

        verifications = self.request.db.verifications
        verifications.remove({
            'model_name': self.data_attribute,
            'obj_id': remove_nin,
            'user_oid': self.user.user_id,
            'verified': False,
        })

        self.request.stats.count('nin_remove')
        message = _('National identity number has been removed')
        return {
            'result': 'success',
            'message': get_localizer(self.request).translate(message),
        }
コード例 #53
0
 def __call__(self, node, value):
     request = node.bindings.get('request')
     try:
         request.userdb.get_user_by_email(value)
     except UserDoesNotExist:
         err = _("Email address does not exist")
         raise colander.Invalid(node, get_localizer(request).translate(err))
コード例 #54
0
ファイル: nins.py プロジェクト: SUNET/eduid-dashboard
    def __init__(self, *args, **kwargs):
        super(NinsView, self).__init__(*args, **kwargs)

        # All buttons for adding a nin, must have a name that starts with "add". This because the POST message, sent
        # from the button, must trigger the "add" validation part of a nin.
        self.buttons = ()
        if self.request.registry.settings.get('enable_mm_verification'):

            self.buttons += (deform.Button(name='add',
                                           title=_('Mina Meddelanden')),)
        self.buttons += (deform.Button(name='add_by_mobile',
                                       title=_('Phone subscription'),
                                       css_class='btn btn-primary'),)
        self.buttons += (deform.Button(name='add_by_letter',
                                       title=_('Physical letter'),
                                       css_class='btn btn-primary'),)
コード例 #55
0
def get_tab(request):
    label = _('Permissions')
    return {
        'status': get_dummy_status,
        'label': get_localizer(request).translate(label),
        'id': 'permissions',
    }
コード例 #56
0
ファイル: validators.py プロジェクト: SUNET/eduid-dashboard
    def __call__(self, node, value):

        request = node.bindings.get('request')
        user = request.context.user
        mobile = normalize_to_e_164(request, value)

        # The debug logs below were added to help figure out how a user
        # managed to get by past this function with a duplicated phone number,
        # which was caught by userdb while saving the user.

        log.debug(
            "User {!r} tried to add a phone number {!r}: "
            "entering 1st code-section that will verify that it's unique.".
            format(user.eppn, mobile))

        if sanitize_post_key(request, 'add') is not None:
            log.debug("User {!r} tried to add a phone number {!r}: "
                      "1st code-section evaluated, POST request OK.".format(
                          user.eppn, mobile))

            if user.phone_numbers.find(mobile):
                log.debug("User {!r} tried to add a phone number {!r}: "
                          "2nd code-section evaluated, the user had already "
                          "added the phone number.".format(user.eppn, mobile))

                err = _("This mobile phone was already registered")
                raise colander.Invalid(node,
                                       get_localizer(request).translate(err))

            else:
                log.debug("User {!r} tried to add a phone number {!r}: "
                          "2nd code-section evaluated, the phone number "
                          "has not previously been added by the user.".format(
                              user.eppn, mobile))
コード例 #57
0
    def __call__(self, node, value):
        request = node.bindings.get('request')
        localizer = get_localizer(request)
        settings = request.registry.settings
        value = value.replace(" ", "")
        password_min_entropy = int(settings.get('password_entropy', 60))

        # We accept a 10% of variance in password_min_entropy because
        # we have calculated the entropy by javascript too and the results
        # may vary.
        password_min_entropy = (0.90 * password_min_entropy)

        generated_password = request.session.get('last_generated_password', '')
        if len(generated_password) > 0 and generated_password == value:
            # Don't validate the password if it is the generated password
            # That is, the user has filled out the form with the suggested
            # password
            return

        # Get a users e-mail addresses to make sure a user does not use one of those as password
        user = get_session_user(request, raise_on_not_logged_in = False)
        if not user:
            # User is resetting a forgotten password
            hash_code = request.matchdict['code']
            password_reset = request.db.reset_passwords.find_one({'hash_code': hash_code})
            user = request.userdb_new.get_user_by_mail(password_reset['email'])
        mail_addresses = [item.email for item in user.mail_addresses.to_list()]

        veredict = zxcvbn.password_strength(value, user_inputs=mail_addresses)

        if veredict.get('entropy', 0) < password_min_entropy:
            err = _('The password complexity is too weak.')
            raise colander.Invalid(node, localizer.translate(err))
コード例 #58
0
ファイル: nins.py プロジェクト: Ratler/eduid-dashboard
    def add_success_other(self, ninform):
        newnin = self.schema.serialize(ninform)
        newnin = newnin['norEduPersonNIN']

        newnin = normalize_nin(newnin)

        old_user = self.request.db.profiles.find_one({
            'norEduPersonNIN': newnin
            })

        if old_user:
            old_user = User(old_user)
            nins = [nin for nin in old_user.get_nins() if nin != newnin]
            old_user.set_nins(nins)
            addresses = [a for a in old_user.get_addresses() if not a['verified']]
            old_user.set_addresses(addresses)
            old_user.save(self.request)

        nins = self.user.get_nins()
        nins.append(newnin)
        self.user.set_nins(nins)

        # Save the state in the verifications collection
        save_as_verificated(self.request, 'norEduPersonNIN',
                            self.user.get_id(), newnin)

        self.user.save(self.request)
        self.request.session.flash(_('Changes saved'),
                                   queue='forms')
コード例 #59
0
    def authorize(self):
        """You must overwrite this method is you want to get another
           authorization access method no based in the ACLs.
           If you want to unauthorized the acces to this resource you must
           raise a HTTPForbidden exception
        """

        ### This block enable the requirent of the user must have more loa
        # # that the loa from edited user
        # if self.user is not None:
        #     # Verify that session loa is iqual or bigger than the edited user
        #     max_user_loa = self.get_max_loa()
        #     max_user_loa = self.loa_to_int(loa=max_user_loa)
        #     session_loa = self.loa_to_int()
        #     if session_loa < max_user_loa:
        #         raise HTTPForbidden(_('You do not have sufficient AL to edit this user'))

        required_loa = self.request.registry.settings.get('required_loa', {})
        required_loa = required_loa.get(self.workmode, '')

        user_loa_int = self.loa_to_int()
        required_loa_int = self.loa_to_int(loa=required_loa)

        if user_loa_int < required_loa_int:
            logger.info(
                'User AL too low for workmode {!r} ({!r} < {!r})'.format(
                    self.workmode, self.get_loa(), required_loa))
            raise HTTPForbidden(
                _('You do not have sufficient AL to access to this '
                  'workmode'))

        return True
コード例 #60
0
ファイル: nins.py プロジェクト: SUNET/eduid-dashboard
def get_tab(request):
    label = _('Confirm Identity')
    return {
        'status': get_status,
        'label': get_localizer(request).translate(label),
        'id': 'nins',
    }