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
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
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)
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))
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))
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_))
def user(self): from fossir.modules.users import User return User.find_first(~User.is_deleted, User.all_emails.contains(self.email))