def test_make_email_primary(db): signal_called = False def _signal_fn(sender, old, new): nonlocal signal_called signal_called = True assert sender is user assert old == '*****@*****.**' assert new == '*****@*****.**' with signals.users.primary_email_changed.connected_to(_signal_fn): user = User(first_name='Guinea', last_name='Pig', email='*****@*****.**') db.session.add(user) db.session.flush() with pytest.raises(ValueError): user.make_email_primary('*****@*****.**') user.secondary_emails = {'*****@*****.**', '*****@*****.**'} db.session.flush() assert not signal_called user.make_email_primary('*****@*****.**') assert signal_called db.session.expire(user) assert user.email == '*****@*****.**' assert user.secondary_emails == {'*****@*****.**', '*****@*****.**'}
def get_user_by_email(email, create_pending=False): """finds a user based on his email address. :param email: The email address of the user. :param create_pending: If True, this function searches for external users and creates a new pending User in case no existing user was found. :return: A :class:`.User` instance or ``None`` if not exactly one user was found. """ email = email.lower().strip() if not email: return None if not create_pending: res = User.find_all(~User.is_deleted, User.all_emails.contains(email)) else: res = search_users(exact=True, include_pending=True, external=True, email=email) if len(res) != 1: return None user_or_identity = next(iter(res)) if isinstance(user_or_identity, User): return user_or_identity elif not create_pending: return None # Create a new pending user data = user_or_identity.data user = User(first_name=data.get('first_name') or '', last_name=data.get('last_name') or '', email=data['email'], address=data.get('address', ''), phone=data.get('phone', ''), affiliation=data.get('affiliation', ''), is_pending=True) db.session.add(user) db.session.flush() return user
def test_deletion_no_primary_email(): # this tests setting the is_deleted property on a user with no primary email # very unlikely case but let's make sure we never try to set the deleted # flag on a None primary email. user = User() assert user.email is None user.is_deleted = True
def create_all_tables(db, verbose=False, add_initial_data=True): """Create all tables and required initial objects""" from indico.modules.categories import Category from indico.modules.designer import TemplateType from indico.modules.designer.models.templates import DesignerTemplate from indico.modules.oauth.models.applications import OAuthApplication, SystemAppType from indico.modules.users import User if verbose: print(cformat('%{green}Creating tables')) db.create_all() if add_initial_data: if verbose: print(cformat('%{green}Creating system user')) db.session.add(User(id=0, is_system=True, first_name='Indico', last_name='System')) if verbose: print(cformat('%{green}Creating root category')) cat = Category(id=0, title='Home', protection_mode=ProtectionMode.public) db.session.add(cat) db.session.flush() if verbose: print(cformat('%{green}Creating default ticket template for root category ')) dt = DesignerTemplate(category_id=0, title='Default ticket', type=TemplateType.badge, data=DEFAULT_TEMPLATE_DATA, is_system_template=True) cat.default_ticket_template = dt db.session.add(dt) if verbose: print(cformat('%{green}Creating system oauth apps')) for sat in SystemAppType: if sat != SystemAppType.none: db.session.add(OAuthApplication(system_app_type=sat, **sat.default_data)) db.session.commit()
def _process_POST(self): if User.query.has_rows(): return redirect(url_for_index()) setup_form = BootstrapForm(request.form) if not setup_form.validate(): flash(_("Some fields are invalid. Please, correct them and submit the form again."), 'error') return redirect(url_for('bootstrap.index')) # Creating new user user = User() user.first_name = to_unicode(setup_form.first_name.data) user.last_name = to_unicode(setup_form.last_name.data) user.affiliation = to_unicode(setup_form.affiliation.data) user.email = to_unicode(setup_form.email.data) user.is_admin = True identity = Identity(provider='indico', identifier=setup_form.username.data, password=setup_form.password.data) user.identities.add(identity) db.session.add(user) db.session.flush() user.settings.set('timezone', Config.getInstance().getDefaultTimezone()) user.settings.set('lang', session.lang or Config.getInstance().getDefaultLocale()) login_user(user, identity) full_name = user.full_name # needed after the session closes transaction.commit() # Configuring server's settings minfo = HelperMaKaCInfo.getMaKaCInfoInstance() minfo.setOrganisation(setup_form.affiliation.data) message = get_template_module('bootstrap/flash_messages.html').bootstrap_success(name=full_name) flash(Markup(message), 'success') # Activate instance tracking if setup_form.enable_tracking.data: contact_name = setup_form.contact_name.data contact_email = setup_form.contact_email.data try: register_instance(contact_name, contact_email) except (HTTPError, ValueError) as err: message = get_template_module('bootstrap/flash_messages.html').community_error(err=err) category = 'error' except Timeout: message = get_template_module('bootstrap/flash_messages.html').community_timeout() category = 'error' except RequestException as exc: message = get_template_module('bootstrap/flash_messages.html').community_exception(exc=exc) category = 'error' else: message = get_template_module('bootstrap/flash_messages.html').community_success() category = 'success' flash(Markup(message), category) return redirect(url_for_index())
def _handle_submit(self, setup_form): # Creating new user user = User() user.first_name = setup_form.first_name.data user.last_name = setup_form.last_name.data user.affiliation = setup_form.affiliation.data user.email = setup_form.email.data user.is_admin = True identity = Identity(provider='indico', identifier=setup_form.username.data, password=setup_form.password.data) user.identities.add(identity) db.session.add(user) db.session.flush() user.settings.set('timezone', config.DEFAULT_TIMEZONE) user.settings.set('lang', session.lang or config.DEFAULT_LOCALE) login_user(user, identity) full_name = user.full_name # needed after the session closes db.session.commit() # Configuring server's settings core_settings.set('site_organization', setup_form.affiliation.data) message = get_template_module( 'bootstrap/flash_messages.html').bootstrap_success(name=full_name) flash(Markup(message), 'success') # Activate instance tracking if setup_form.enable_tracking.data: contact_name = setup_form.contact_name.data contact_email = setup_form.contact_email.data try: register_instance(contact_name, contact_email) except (HTTPError, ValueError) as err: message = get_template_module('bootstrap/flash_messages.html' ).community_error(err=str(err)) category = 'error' except Timeout: message = get_template_module( 'bootstrap/flash_messages.html').community_timeout() category = 'error' except RequestException as exc: message = get_template_module( 'bootstrap/flash_messages.html').community_exception( err=str(exc)) category = 'error' else: message = get_template_module( 'bootstrap/flash_messages.html').community_success() category = 'success' flash(Markup(message), category) return redirect(url_for_index())
def principal_from_identifier(identifier, allow_groups=False, allow_external_users=False): # XXX: this is currently only used in PrincipalList # if we ever need to support more than just users and groups, # make sure to add it in here as well from indico.modules.groups import GroupProxy from indico.modules.users import User try: type_, data = identifier.split(':', 1) except ValueError: raise ValueError('Invalid data') if type_ == 'User': try: user_id = int(data) except ValueError: raise ValueError('Invalid data') user = User.get(user_id, is_deleted=False) if user is None: raise ValueError('Invalid user: {}'.format(user_id)) return user elif type_ == 'ExternalUser': if not allow_external_users: raise ValueError('External users are not allowed') cache = GenericCache('external-user') external_user_data = cache.get(data) if not external_user_data: raise ValueError('Invalid data') user = User.query.filter(User.all_emails == external_user_data['email'], ~User.is_deleted).first() if user: return user # create a pending user. this user isn't sent to the DB unless it gets added # to the sqlalchemy session somehow (e.g. by adding it to an ACL). # like this processing form data does not result in something being stored in # the database, which is good! return User(first_name=external_user_data['first_name'], last_name=external_user_data['last_name'], email=external_user_data['email'], affiliation=external_user_data['affiliation'], address=external_user_data['address'], phone=external_user_data['phone'], is_pending=True) elif type_ == 'Group': if not allow_groups: raise ValueError('Groups are not allowed') try: provider, name = data.split(':', 1) except ValueError: raise ValueError('Invalid data') if not provider: # local group try: group_id = int(name) except ValueError: raise ValueError('Invalid data') group = GroupProxy(group_id) else: # multipass group group = GroupProxy(name, provider) if group.group is None: raise ValueError('Invalid group: {}'.format(data)) return group else: raise ValueError('Invalid data')
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.query.filter(~User.is_deleted, User.is_pending, User.all_emails.in_({email} | set(other_emails))).first() 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, skip={'synced_fields'}) 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) db.session.flush() user.populate_from_dict(data, keys={ 'synced_fields' }) # this is a setting, so the user must have an ID 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 test_get_full_name_empty_names(first_name, last_name): user = User(first_name=first_name, last_name=last_name, title=UserTitle.none) for last_name_first, last_name_upper, abbrev_first_name in itertools.product((True, False), repeat=3): # Just make sure it doesn't fail. We don't really care about the output. # It's only allowed for pending users so in most cases it only shows up # in the ``repr`` of such a user. user.get_full_name(last_name_first=last_name_first, last_name_upper=last_name_upper, abbrev_first_name=abbrev_first_name)
def principal_from_fossil(fossil, allow_pending=False, allow_groups=True, legacy=True, allow_missing_groups=False, allow_emails=False): """Gets a GroupWrapper or AvatarUserWrapper from a fossil""" from indico.modules.groups import GroupProxy from indico.modules.users import User 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 user = User.find_first(email=email, is_pending=True) 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.as_avatar if legacy else user elif allow_emails and type_ == 'Email': return EmailPrincipal(id_) 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.as_legacy_group if legacy else 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.as_legacy_group if legacy else group else: raise ValueError('Unexpected fossil type: {}'.format(type_))
def test_title(db): user = User(first_name='Guinea', last_name='Pig') db.session.add(user) db.session.flush() assert user.title == '' user.title = UserTitle.prof assert user.title == UserTitle.prof.title assert is_lazy_string(user.title) assert User.find_one(title=UserTitle.prof) == user
def test_deletion(db): user = User(first_name='Guinea', last_name='Pig', email='*****@*****.**', secondary_emails=['[email protected]']) db.session.add(user) db.session.flush() assert not user.is_deleted assert all(not ue.is_user_deleted for ue in user._all_emails) user.is_deleted = True db.session.flush() assert all(ue.is_user_deleted for ue in user._all_emails)
def test_acls_invalid(): user = User() proxy = SettingsProxy('foo', {'reg': None}, acls={'acl'}) pytest.raises(ValueError, proxy.get, 'acl') pytest.raises(ValueError, proxy.set, 'acl', 'foo') pytest.raises(ValueError, proxy.acls.get, 'reg') pytest.raises(ValueError, proxy.acls.set, 'reg', {user}) pytest.raises(ValueError, proxy.acls.contains_user, 'reg', user) pytest.raises(ValueError, proxy.acls.add_principal, 'reg', user) pytest.raises(ValueError, proxy.acls.remove_principal, 'reg', user)
def _load_users(self, data): if not data['users']: return missing = {} for uuid, userdata in data['users'].iteritems(): if userdata is None: self.user_map[uuid] = self.system_user_id continue user = (User.query .filter(User.all_emails.in_(userdata['all_emails']), ~User.is_deleted) .first()) if user is None: missing[uuid] = userdata else: self.user_map[uuid] = user.id if missing: click.secho('The following users from the import data could not be mapped to existing users:', fg='yellow') table_data = [['First Name', 'Last Name', 'Email', 'Affiliation']] for userdata in sorted(missing.itervalues(), key=itemgetter('first_name', 'last_name', 'email')): table_data.append([userdata['first_name'], userdata['last_name'], userdata['email'], userdata['affiliation']]) table = AsciiTable(table_data) click.echo(table.table) if self.create_users is None: click.echo('Do you want to create these users now?') click.echo('If you choose to not create them, the behavior depends on where the user would be used:') click.echo('- If the user is not required, it will be omitted.') click.echo('- If a user is required but using the system user will not cause any problems or look ' 'weird, the system user will be used.') click.echo('- In case neither is possible, e.g. in abstract reviews or ACLs, these objects will ' 'be skipped altogether!') create_users = click.confirm('Create the missing users?', default=True) else: create_users = self.create_users if create_users: click.secho('Creating missing users', fg='magenta') for uuid, userdata in missing.iteritems(): user = User(first_name=userdata['first_name'], last_name=userdata['last_name'], email=userdata['email'], secondary_emails=set(userdata['all_emails']) - {userdata['email']}, address=userdata['address'], phone=userdata['phone'], affiliation=userdata['affiliation'], title=userdata['title'], is_pending=True) db.session.add(user) db.session.flush() self.user_map[uuid] = user.id if self.verbose: click.echo(cformat("- %{cyan}User%{blue!} '{}' ({})").format(user.full_name, user.email)) else: click.secho('Skipping missing users', fg='magenta')
def test_emails(db): user = User(first_name='Guinea', last_name='Pig') db.session.add(user) db.session.flush() assert user.email is None assert not user.secondary_emails user.email = '*****@*****.**' db.session.flush() assert user.all_emails == {'*****@*****.**'} user.secondary_emails.add('*****@*****.**') db.session.flush() assert user.all_emails == {'*****@*****.**', '*****@*****.**'}
def migrate_system_user(self): if self.system_user_id is not None: user = User.get(self.system_user_id, is_deleted=False) if not user: raise Exception('Invalid system_user user id') user.is_system = True self.print_success('Using existing system user: {}'.format(user), always=True) return user_id = 0 if not User.get(0) else None db.session.add(User(id=user_id, is_system=True, first_name='Indico', last_name='System')) db.session.flush() self.print_success('Added new system user: {}'.format(User.get_system_user()), always=True)
def test_make_email_primary(db): user = User(first_name='Guinea', last_name='Pig', email='*****@*****.**') db.session.add(user) db.session.flush() with pytest.raises(ValueError): user.make_email_primary('*****@*****.**') user.secondary_emails = {'*****@*****.**', '*****@*****.**'} db.session.flush() user.make_email_primary('*****@*****.**') db.session.expire(user) assert user.email == '*****@*****.**' assert user.secondary_emails == {'*****@*****.**', '*****@*****.**'}
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() # 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) if settings: 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 create_mock_abstract(event): """Create a mock abstract that can be used in previews. Brace for geek references. """ User = namedtuple('Author', ['first_name', 'last_name', 'title', 'full_name']) Track = namedtuple('Track', ['title']) Session = namedtuple('Session', ['title']) ContributionType = namedtuple('ContributionType', ['name']) Contribution = namedtuple('Contribution', ['title', 'track', 'session', 'type', 'locator']) Abstract = namedtuple('Abstract', ['friendly_id', 'title', 'event_new', 'submitter', 'contribution', 'primary_authors', 'secondary_authors', 'locator', 'judgment_comment', 'accepted_track', 'accepted_contrib_type', 'state', 'merged_into']) englert = User(full_name="Fran\xe7ois Englert", first_name="Fran\xe7ois", last_name="Englert", title="Prof.") brout = User(full_name="Robert Brout", first_name="Robert", last_name="Brout", title="Prof.") guralnik = User(full_name="Gerald Guralnik", first_name="Gerald", last_name="Guralnik", title="Prof.") hagen = User(full_name="Carl Hagen", first_name="Carl", last_name="Hagen", title="Prof.") kibble = User(full_name="Tom Kibble", first_name="Tom", last_name="Kibble", title="Prof.") higgs = User(full_name="Peter Higgs", first_name="Peter", last_name="Higgs", title="Prof.") track = Track(title=_("Higgs Fields")) session = Session(title=_("Higgs Fields Posters")) contribution_type = ContributionType(name=_("Poster")) contribution = Contribution(title="Broken Symmetry and the Mass of Gauge Vector Mesons", track=track, session=session, type=contribution_type, locator={'confId': -314, 'contrib_id': 1234}) target_abstract = Abstract(friendly_id=315, title="Broken Symmetry", accepted_track=track, accepted_contrib_type=contribution_type, event_new=event, submitter=brout, state=AbstractState.accepted, contribution=contribution, primary_authors=[englert, brout], secondary_authors=[guralnik, hagen, kibble, higgs], locator={'confId': -314, 'abstract_id': 1235}, judgment_comment='Vague but interesting!', merged_into=None) abstract = Abstract(friendly_id=314, title="Broken Symmetry and the Mass of Gauge Vector Mesons", accepted_track=track, accepted_contrib_type=contribution_type, event_new=event, submitter=brout, state=AbstractState.accepted, contribution=contribution, primary_authors=[englert, brout], secondary_authors=[guralnik, hagen, kibble, higgs], locator={'confId': -314, 'abstract_id': 1234}, judgment_comment='Vague but interesting!', merged_into=target_abstract) return abstract
def test_emails(db): user = User(first_name='Guinea', last_name='Pig') db.session.add(user) db.session.flush() assert user.email is None assert not user.secondary_emails user.email = '*****@*****.**' db.session.flush() assert user.all_emails == {'*****@*****.**'} user.secondary_emails.add('*****@*****.**') db.session.flush() db.session.expire(user) # all_emails is only updated after expire (or commit) assert user.all_emails == {'*****@*****.**', '*****@*****.**'}
def test_get_full_name(last_name_first, last_name_upper, abbrev_first_name, expected): user = User(first_name='Guinea', last_name='Pig', title=UserTitle.none) name = user.get_full_name(last_name_first=last_name_first, last_name_upper=last_name_upper, abbrev_first_name=abbrev_first_name, show_title=False) assert name == expected # titled name with no title is the same titled_name = user.get_full_name(last_name_first=last_name_first, last_name_upper=last_name_upper, abbrev_first_name=abbrev_first_name, show_title=True) assert titled_name == expected # titled name with a non-empty title user.title = UserTitle.mr titled_name = user.get_full_name(last_name_first=last_name_first, last_name_upper=last_name_upper, abbrev_first_name=abbrev_first_name, show_title=True) assert titled_name == f'Mr {expected}'
def test_iter_acl(): user = User() user_p = MagicMock(principal=user, spec=['principal']) ipn = IPNetworkGroup() ipn_p = MagicMock(principal=ipn, spec=['principal']) local_group = GroupProxy(123, _group=MagicMock()) local_group_p = MagicMock(principal=local_group, spec=['principal']) remote_group = GroupProxy('foo', 'bar') remote_group_p = MagicMock(principal=remote_group, spec=['principal']) acl = [ ipn, user_p, remote_group, local_group_p, user, local_group, remote_group_p, ipn_p ] assert list(iter_acl(iter(acl))) == [ user_p, user, ipn, ipn_p, local_group_p, local_group, remote_group, remote_group_p ]
def _create_user(id_, first_name=u'Guinea', last_name=u'Pig', rb_admin=False, admin=False, email=None, groups=None, legacy=False): user = User.get(id_) if user: return user.as_avatar if legacy else user user = User() user.id = id_ user.first_name = first_name user.last_name = last_name user.email = email or u'{}@example.com'.format(id_) user.is_admin = admin user.local_groups = {g.group for g in (groups or ())} db.session.add(user) db.session.flush() if rb_admin: rb_settings.acls.add_principal('admin_principals', user) db.session.flush() return user.as_avatar if legacy else user
def create_all_tables(db, verbose=False, add_initial_data=True): """Create all tables and required initial objects""" from indico.modules.categories import Category from indico.modules.users import User if verbose: print cformat('%{green}Creating tables') db.create_all() if add_initial_data: if verbose: print cformat('%{green}Creating system user') db.session.add( User(id=0, is_system=True, first_name='Indico', last_name='System')) if verbose: print cformat('%{green}Creating root category') db.session.add( Category(id=0, title='Home', protection_mode=ProtectionMode.public)) db.session.commit()
def _create_user(id_, name=u'Pig', surname=u'Guinea', rb_admin=False, email=None, groups=None): user = User.get(id_) if user: return user.as_avatar user = User() user.id = id_ user.first_name = name user.last_name = surname user.email = email or u'{}@example.com'.format(id_) user.local_groups = {g.group for g in (groups or ())} db.session.add(user) db.session.flush() if rb_admin: rb_settings.set('admin_principals', rb_settings.get('admin_principals') + [user.as_principal]) db.session.flush() _users.add(user) avatar = user.as_avatar avatar.email = user.email return avatar
def _user_from_avatar(self, avatar, **kwargs): email = sanitize_email(convert_to_unicode(avatar.email).lower().strip()) secondary_emails = {sanitize_email(convert_to_unicode(x).lower().strip()) for x in avatar.secondaryEmails} secondary_emails = {x for x in secondary_emails if x and is_valid_mail(x, False) and x != email} # we handle deletion later. otherwise it might be set before secondary_emails which would # result in those emails not being marked as deleted is_deleted = kwargs.pop('is_deleted', False) user = User(id=int(avatar.id), email=email, first_name=convert_to_unicode(avatar.name).strip() or 'UNKNOWN', last_name=convert_to_unicode(avatar.surName).strip() or 'UNKNOWN', title=USER_TITLE_MAP.get(avatar.title, UserTitle.none), phone=convert_to_unicode(avatar.telephone[0]).strip(), affiliation=convert_to_unicode(avatar.organisation[0]).strip(), address=convert_to_unicode(avatar.address[0]).strip(), secondary_emails=secondary_emails, is_blocked=avatar.status == 'disabled', **kwargs) if is_deleted or not is_valid_mail(user.email): user.is_deleted = True return user
def _create_user(self, form, handler, pending_user): data = form.data if pending_user: user = pending_user user.is_pending = False else: user = User() form.populate_obj(user, skip={'email'}) if form.email.data 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(form.email.data) else: user.email = form.email.data identity = handler.create_identity(data) user.identities.add(identity) user.secondary_emails |= handler.get_all_emails(form) - {user.email} user.favorite_users.add(user) db.session.add(user) minfo = HelperMaKaCInfo.getMaKaCInfoInstance() timezone = session.timezone if timezone == 'LOCAL': timezone = Config.getInstance().getDefaultTimezone() user.settings.set('timezone', timezone) user.settings.set('lang', session.lang or minfo.getLang()) handler.update_user(user, form) db.session.flush() # notify everyone of user creation signals.users.registered.send(user) login_user(user, identity) msg = _('You have sucessfully registered your Indico profile. ' 'Check <a href="{url}">your profile</a> for further details and settings.') flash(Markup(msg).format(url=url_for('users.user_profile')), 'success') db.session.flush() return handler.redirect_success()
def principal_from_fossil(fossil, allow_pending=False, allow_groups=True, allow_missing_groups=False, allow_emails=False, allow_networks=False, existing_data=None, event=None): from indico.modules.networks.models.networks import IPNetworkGroup from indico.modules.events.models.roles import EventRole from indico.modules.groups import GroupProxy from indico.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 indico account in case some of the search criteria did not # match the indico account user = User.query.filter(User.all_emails == email, ~User.is_deleted).first() 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 elif event and type_ == 'EventRole': role = EventRole.get(id_) role_name = fossil.get('name') if role is None: raise ValueError('Role does not exist: {}:{}'.format(role_name, id_)) if role.event != event: raise ValueError('Role does not belong to provided event: {}:{} - {}'.format(role_name, id_, event)) return role else: raise ValueError('Unexpected fossil type: {}'.format(type_))
def test_full_name(): assert User(first_name='Guinea', last_name='Pig', title=UserTitle.prof).full_name == 'Guinea Pig'
def test_no_names_pending(db): db.session.add(User(first_name='', last_name='', is_pending=True)) db.session.flush()