Exemplo n.º 1
0
 def _original_user(self):
     # A proper user, with an id that can be mapped directly to sqlalchemy
     if isinstance(self.id, int) or self.id.isdigit():
         return User.get(int(self.id))
     # A user who had no real fossir account but an ldap identifier/email.
     # In this case we try to find his real user and replace the ID of this object
     # with that user's ID.
     data = self.id.split(':')
     # TODO: Once everything is in SQLAlchemy this whole thing needs to go away!
     user = None
     if data[0] == 'LDAP':
         identifier = data[1]
         email = data[2]
         # You better have only one ldap provider or at least different identifiers ;)
         identity = Identity.find_first(Identity.provider != 'fossir',
                                        Identity.identifier == identifier)
         if identity:
             user = identity.user
     elif data[0] == 'Nice':
         email = data[1]
     else:
         return None
     if not user:
         user = User.find_first(User.all_emails.contains(email))
     if user:
         self._old_id = self.id
         self.id = str(user.id)
         logger.info("Updated legacy user id (%s => %s)", self._old_id,
                     self.id)
     return user
Exemplo n.º 2
0
def create_user(email,
                data,
                identity=None,
                settings=None,
                other_emails=None,
                from_moderation=True):
    """Create a new user.

    This may also convert a pending user to a proper user in case the
    email address matches such a user.

    :param email: The primary email address of the user.
    :param data: The data used to populate the user.
    :param identity: An `Identity` to associate with the user.
    :param settings: A dict containing user settings.
    :param other_emails: A set of email addresses that are also used
                         to check for a pending user. They will also
                         be added as secondary emails to the user.
    :param from_moderation: Whether the user was created through the
                            moderation process or manually by an admin.
    """
    if other_emails is None:
        other_emails = set()
    if settings is None:
        settings = {}
    settings.setdefault('timezone', config.DEFAULT_TIMEZONE)
    settings.setdefault('lang', config.DEFAULT_LOCALE)
    settings.setdefault('suggest_categories', False)
    # Get a pending user if there is one
    user = User.find_first(
        ~User.is_deleted, User.is_pending,
        User.all_emails.contains(db.func.any(list({email}
                                                  | set(other_emails)))))
    if not user:
        user = User()

    if email in user.secondary_emails:
        # This can happen if there's a pending user who has a secondary email
        # for some weird reason which should now become the primary email...
        user.make_email_primary(email)
    else:
        user.email = email
    user.populate_from_dict(data)
    user.is_pending = False
    user.secondary_emails |= other_emails
    user.favorite_users.add(user)
    if identity is not None:
        user.identities.add(identity)
    db.session.add(user)
    user.settings.set_multi(settings)
    db.session.flush()
    signals.users.registered.send(user,
                                  from_moderation=from_moderation,
                                  identity=identity)
    db.session.flush()
    return user
Exemplo n.º 3
0
 def _get_user_data(self):
     user_id = request.args.get('user')
     if user_id is None:
         return {}
     elif user_id.isdigit():
         # existing fossir user
         user = User.find_first(id=user_id, is_deleted=False)
         user_data = {t.name: getattr(user, t.name, None) if user else '' for t in PersonalDataType}
     else:
         # non-fossir user
         data = GenericCache('pending_identities').get(user_id, {})
         user_data = {t.name: data.get(t.name) for t in PersonalDataType}
     user_data['title'] = get_title_uuid(self.regform, user_data['title'])
     return user_data
    def _process(self):
        if session.user:
            return redirect(url_for_index())

        handler = MultipassRegistrationHandler(self) if self.identity_info else LocalRegistrationHandler(self)
        verified_email, prevalidated = self._get_verified_email()
        if verified_email is not None:
            handler.email_verified(verified_email)
            if prevalidated:
                flash(_("You may change your email address after finishing the registration process."), 'info')
            else:
                flash(_('You have successfully validated your email address and can now proceeed with the '
                        'registration.'), 'success')
            return redirect(url_for('.register', provider=self.provider_name))

        form = handler.create_form()
        if not handler.moderate_registrations and not handler.must_verify_email:
            del form.comment
        # Check for pending users if we have verified emails
        pending = None
        if not handler.must_verify_email:
            pending = User.find_first(~User.is_deleted, User.is_pending,
                                      User.all_emails.contains(db.func.any(list(handler.get_all_emails(form)))))
        if form.validate_on_submit():
            if handler.must_verify_email:
                return self._send_confirmation(form.email.data)
            elif handler.moderate_registrations:
                return self._create_registration_request(form, handler)
            else:
                return self._create_user(form, handler)
        elif not form.is_submitted() and pending:
            # If we have a pending user, populate empty fields with data from that user
            for field in form:
                value = getattr(pending, field.short_name, '')
                if value and not field.data:
                    field.data = value
        if pending:
            flash(_("There is already some information in fossir that concerns you. "
                    "We are going to link it automatically."), 'info')
        return WPAuth.render_template('register.html', form=form, local=(not self.identity_info),
                                      must_verify_email=handler.must_verify_email, widget_attrs=handler.widget_attrs,
                                      email_sent=session.pop('register_verification_email_sent', False),
                                      moderate_accounts=handler.moderate_registrations)
Exemplo n.º 5
0
 def _get_event_person(self, data):
     person_type = data.get('_type')
     if person_type is None:
         if data.get('email'):
             email = data['email'].lower()
             user = User.find_first(~User.is_deleted,
                                    User.all_emails.contains(email))
             if user:
                 return self._get_event_person_for_user(user)
             elif self.event:
                 person = self.event.persons.filter_by(email=email).first()
                 if person:
                     return person
         # We have no way to identify an existing event person with the provided information
         return self._create_event_person(data)
     elif person_type == 'Avatar':
         return self._get_event_person_for_user(
             self._convert_principal(data))
     elif person_type == 'EventPerson':
         return self.event.persons.filter_by(id=data['id']).one()
     elif person_type == 'PersonLink':
         return self.event.persons.filter_by(id=data['personId']).one()
     else:
         raise ValueError(_("Unknown person type '{}'").format(person_type))
Exemplo n.º 6
0
 def user(self):
     if not self.is_submitted() or not self.email.data:
         return None
     return User.find_first(~User.is_deleted, ~User.is_blocked,
                            ~User.is_pending,
                            User.all_emails.contains(self.email.data))
Exemplo n.º 7
0
def principal_from_fossil(fossil,
                          allow_pending=False,
                          allow_groups=True,
                          allow_missing_groups=False,
                          allow_emails=False,
                          allow_networks=False,
                          existing_data=None):
    from fossir.modules.networks.models.networks import IPNetworkGroup
    from fossir.modules.groups import GroupProxy
    from fossir.modules.users import User

    if existing_data is None:
        existing_data = set()

    type_ = fossil['_type']
    id_ = fossil['id']
    if type_ == 'Avatar':
        if isinstance(id_, int) or id_.isdigit():
            # regular user
            user = User.get(int(id_))
        elif allow_pending:
            data = GenericCache('pending_identities').get(id_)
            if not data:
                raise ValueError("Cannot find user '{}' in cache".format(id_))

            data = {k: '' if v is None else v for k, v in data.items()}
            email = data['email'].lower()

            # check if there is not already a (pending) user with that e-mail
            # we need to check for non-pending users too since the search may
            # show a user from external results even though the email belongs
            # to an fossir account in case some of the search criteria did not
            # match the fossir account
            user = User.find_first(User.all_emails.contains(email),
                                   ~User.is_deleted)
            if not user:
                user = User(first_name=data.get('first_name') or '',
                            last_name=data.get('last_name') or '',
                            email=email,
                            address=data.get('address', ''),
                            phone=data.get('phone', ''),
                            affiliation=data.get('affiliation', ''),
                            is_pending=True)
                db.session.add(user)
                db.session.flush()
        else:
            raise ValueError(
                "Id '{}' is not a number and allow_pending=False".format(id_))
        if user is None:
            raise ValueError('User does not exist: {}'.format(id_))
        return user
    elif allow_emails and type_ == 'Email':
        return EmailPrincipal(id_)
    elif allow_networks and type_ == 'IPNetworkGroup':
        group = IPNetworkGroup.get(int(id_))
        if group is None or (group.hidden and group not in existing_data):
            raise ValueError('IP network group does not exist: {}'.format(id_))
        return group
    elif allow_groups and type_ in {'LocalGroupWrapper', 'LocalGroup'}:
        group = GroupProxy(int(id_))
        if group.group is None:
            raise ValueError('Local group does not exist: {}'.format(id_))
        return group
    elif allow_groups and type_ in {'LDAPGroupWrapper', 'MultipassGroup'}:
        provider = fossil['provider']
        group = GroupProxy(id_, provider)
        if group.group is None and not allow_missing_groups:
            raise ValueError('Multipass group does not exist: {}:{}'.format(
                provider, id_))
        return group
    else:
        raise ValueError('Unexpected fossil type: {}'.format(type_))
Exemplo n.º 8
0
 def user(self):
     from fossir.modules.users import User
     return User.find_first(~User.is_deleted,
                            User.all_emails.contains(self.email))