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 == {'*****@*****.**', '*****@*****.**'}
Example #2
0
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
Example #4
0
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()
Example #5
0
    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())
Example #6
0
    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())
Example #7
0
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')
Example #8
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.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
Example #9
0
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)
Example #10
0
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_))
Example #11
0
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
Example #12
0
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)
Example #13
0
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)
Example #14
0
 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')
Example #15
0
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 == {'*****@*****.**', '*****@*****.**'}
Example #16
0
 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)
Example #17
0
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 == {'*****@*****.**', '*****@*****.**'}
Example #18
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()
    # 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
Example #19
0
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
Example #20
0
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 == {'*****@*****.**', '*****@*****.**'}
Example #21
0
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}'
Example #22
0
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
    ]
Example #23
0
 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
Example #24
0
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()
Example #25
0
 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
Example #26
0
 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
Example #27
0
    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()
Example #28
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, 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_))
Example #29
0
def test_full_name():
    assert User(first_name='Guinea', last_name='Pig', title=UserTitle.prof).full_name == 'Guinea Pig'
Example #30
0
def test_no_names_pending(db):
    db.session.add(User(first_name='', last_name='', is_pending=True))
    db.session.flush()