Пример #1
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')
Пример #2
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_))
Пример #3
0
def convert_principal(principal):
    """Converts a legacy principal to PrincipalMixin style"""
    if isinstance(principal, AvatarUserWrapper):
        return principal.user
    elif isinstance(principal, GroupWrapper):
        return principal.group
    elif principal.__class__.__name__ == 'Avatar':
        return AvatarUserWrapper(principal.id).user
    elif principal.__class__.__name__ == 'Group':
        return GroupProxy(principal.id)
    elif principal.__class__.__name__ in {'CERNGroup', 'LDAPGroup', 'NiceGroup'}:
        return GroupProxy(principal.id, multipass.default_group_provider.name)
Пример #4
0
def get_user_access(user, admin_override_enabled=False):
    if not user:
        return []
    if admin_override_enabled and user.is_admin:
        return ['IndicoAdmin']
    access = [user.identifier] + [u.identifier for u in user.get_merged_from_users_recursive()]
    access += [GroupProxy(x.id, _group=x).identifier for x in user.local_groups]
    if user.can_get_all_multipass_groups:
        multipass_groups = [GroupProxy(x.name, x.provider.name, x)
                            for x in user.iter_all_multipass_groups()]
        access += _include_capitalized_groups(multipass_groups)
    return access
Пример #5
0
def retrieve_principal(principal, allow_groups=True, legacy=True):
    """Retrieves principal object from a `(type, id)` tuple.

    Valid principal types are 'Avatar', 'User' and 'Group'.

    :param principal: The principal (a tuple/list)
    :param allow_groups: If group principals are allowed
    :param legacy: If legacy wrappers or new objects should be returned.
    """
    from indico.modules.groups import GroupProxy
    from indico.modules.groups.legacy import LocalGroupWrapper, LDAPGroupWrapper
    from indico.modules.users import User

    type_, id_ = principal
    if type_ in {'Avatar', 'User'}:
        user = User.get(int(id_))
        if not user:
            return None
        return user.as_avatar if legacy else user
    elif type_ == 'Group' and allow_groups:
        if isinstance(id_, (int, basestring)):  # legacy group
            group = LocalGroupWrapper(id_) if unicode(
                id_).isdigit() else LDAPGroupWrapper(id_)
            return group if legacy else group.group
        else:  # new group
            provider, name_or_id = id_
            group = GroupProxy(name_or_id, provider)
            return group.as_legacy_group if legacy else group
    else:
        raise ValueError('Unexpected type: {}'.format(type_))
Пример #6
0
 def _process(self):
     query = LocalGroup.query.options(joinedload(LocalGroup.members)).order_by(db.func.lower(LocalGroup.name))
     groups = [g.proxy for g in query]
     providers = [p for p in multipass.identity_providers.itervalues() if p.supports_groups]
     form = SearchForm(obj=FormDefaults(exact=True))
     groups_enabled = True
     if not providers and not config.LOCAL_GROUPS:
         groups_enabled = False
     elif not providers:
         del form.provider
     else:
         choices = [('', _('All'))]
         if config.LOCAL_GROUPS:
             choices.append(('indico', _('Local Groups')))
         choices += [(p.name, p.title) for p in sorted(providers, key=attrgetter('title'))]
         form.provider.choices = choices
     search_results = None
     if groups_enabled and form.validate_on_submit():
         search_providers = None if not providers or not form.provider.data else {form.provider.data}
         search_results = GroupProxy.search(form.name.data, exact=form.exact.data, providers=search_providers)
         search_results.sort(key=attrgetter('provider', 'name'))
     provider_titles = {p.name: p.title for p in multipass.identity_providers.itervalues()}
     provider_titles[None] = _('Local')
     return WPGroupsAdmin.render_template('groups.html', groups=groups, providers=providers, form=form,
                                          search_results=search_results, provider_titles=provider_titles,
                                          groups_enabled=groups_enabled)
Пример #7
0
 def _process(self):
     query = LocalGroup.query.options(joinedload(LocalGroup.members)).order_by(db.func.lower(LocalGroup.name))
     groups = [g.proxy for g in query]
     providers = [p for p in multipass.identity_providers.itervalues() if p.supports_groups]
     form = SearchForm(obj=FormDefaults(exact=True))
     if not providers:
         del form.provider
     else:
         form.provider.choices = [("", _("All")), ("indico", _("Local Groups"))] + [
             (p.name, p.title) for p in sorted(providers, key=attrgetter("title"))
         ]
     search_results = None
     if form.validate_on_submit():
         search_providers = None if not providers or not form.provider.data else {form.provider.data}
         search_results = GroupProxy.search(form.name.data, exact=form.exact.data, providers=search_providers)
         search_results.sort(key=attrgetter("provider", "name"))
     provider_titles = {p.name: p.title for p in multipass.identity_providers.itervalues()}
     provider_titles[None] = _("Local")
     return WPGroupsAdmin.render_template(
         "groups.html",
         groups=groups,
         providers=providers,
         form=form,
         search_results=search_results,
         provider_titles=provider_titles,
     )
Пример #8
0
def _populate_blocking(blocking, room_ids, allowed_principals, reason):
    blocking.blocked_rooms = [BlockedRoom(room_id=room.id) for room in Room.query.filter(Room.id.in_(room_ids))]
    blocking.reason = reason
    blocking.allowed = [GroupProxy(_group_id_or_name(pr), provider=pr['provider'])
                        if pr.get('is_group')
                        else User.get_one(pr['id'])
                        for pr in allowed_principals]
Пример #9
0
 def _create_group(id_):
     group = LocalGroup()
     group.id = id_
     group.name = u'dummy-{}'.format(id_)
     db.session.add(group)
     db.session.flush()
     _groups.add(group)
     return GroupProxy(group.id, _group=group)
Пример #10
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
    ]
Пример #11
0
 def is_owned_by(self, user):
     """Checks if the user is managing the room (owner or manager)"""
     if self.owner == user:
         return True
     manager_group = self.get_attribute_value('manager-group')
     if not manager_group:
         return False
     return user in GroupProxy.get_named_default_group(manager_group)
Пример #12
0
 def _checkParams(self):
     try:
         group = GroupProxy(request.view_args['group_id'], request.view_args['provider'])
     except ValueError:
         group = None
     if group is None or group.group is None:
         raise NotFound
     self.group = group
Пример #13
0
 def _process(self, name):
     groups = GroupProxy.search(name)
     return jsonify([{
         'is_group': True,
         'name': group.name,
         'id': getattr(group, 'id', group.name),
         'provider': group.provider
     } for group in groups])
Пример #14
0
 def _getAnswer(self):
     results = [
         g.as_legacy_group
         for g in GroupProxy.search(self._group, exact=self._exactMatch)
     ]
     fossilized_results = fossilize(results, IGroupFossil)
     for fossilizedGroup in fossilized_results:
         fossilizedGroup["isGroup"] = True
     return fossilized_results
Пример #15
0
 def _process(self):
     query = LocalGroup.query.options(joinedload(LocalGroup.members)).order_by(db.func.lower(LocalGroup.name))
     groups = [GroupProxy(g.id, _group=g) for g in query]
     providers = [p for p in multipass.identity_providers.itervalues() if p.supports_groups]
     form = SearchForm(obj=FormDefaults(exact=True))
     if not providers:
         del form.provider
     else:
         form.provider.choices = ([('', _('All')), ('indico', _('Local Groups'))] +
                                  [(p.name, p.title) for p in sorted(providers, key=attrgetter('title'))])
     search_results = None
     if form.validate_on_submit():
         search_providers = None if not providers or not form.provider.data else {form.provider.data}
         search_results = GroupProxy.search(form.name.data, exact=form.exact.data, providers=search_providers)
         search_results.sort(key=attrgetter('provider', 'name'))
     provider_titles = {p.name: p.title for p in multipass.auth_providers.itervalues()}
     provider_titles[None] = _('Local')
     return WPGroupsAdmin.render_template('groups.html', groups=groups, providers=providers, form=form,
                                          search_results=search_results, provider_titles=provider_titles)
Пример #16
0
def get_principal(name):
    if '@' in name:
        return get_user(name)

    # otherwise we assume it's a group's name
    group = group_cache.setdefault(name, GroupProxy(name, provider='cern-ldap'))
    if not group or not group.group:
        group = None
        print(cformat("%{red}!%{reset} Group %{cyan}{}%{reset} doesn't seem to exist!").format(name))
    return group
Пример #17
0
 def _process_args(self):
     try:
         group = GroupProxy(request.view_args['group_id'], request.view_args['provider'])
     except ValueError:
         group = None
     if group is None or group.group is None:
         raise NotFound
     if not config.LOCAL_GROUPS and group.is_local:
         raise Forbidden('Local groups are disabled.')
     self.group = group
Пример #18
0
def principal_from_identifier(identifier, allow_groups=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_ == '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')
Пример #19
0
def _populate_blocking(blocking, room_ids, allowed_principals, reason):
    blocking.reason = reason
    principals = {
        GroupProxy(_group_id_or_name(pr), provider=pr['provider'])
        if pr.get('is_group') else User.get_one(pr['id'])
        for pr in allowed_principals
    }
    # We don't use `=` here to prevent SQLAlchemy from deleting and re-adding unchanged entries
    blocking.allowed |= principals  # add new
    blocking.allowed &= principals  # remove deleted
    _update_blocked_rooms(blocking, room_ids)
Пример #20
0
 def principal(self):
     from indico.modules.groups import GroupProxy
     if self.type == PrincipalType.user:
         return self.user
     elif self.type == PrincipalType.local_group:
         return self.local_group.proxy
     elif self.type == PrincipalType.multipass_group:
         return GroupProxy(self.multipass_group_name,
                           self.multipass_group_provider)
     elif self.type == PrincipalType.email:
         return EmailPrincipal(self.email)
Пример #21
0
    def _can_be_booked(self, user, prebook=False, ignore_admin=False):
        if not user or not rb_check_user_access(user):
            return False

        if (not ignore_admin and rb_is_admin(user)) or (self.is_owned_by(user) and self.is_active):
            return True

        if self.is_active and self.is_reservable and (prebook or not self.reservations_need_confirmation):
            group_name = self.get_attribute_value('allowed-booking-group')
            if not group_name or user in GroupProxy.get_named_default_group(group_name):
                return True

        return False
Пример #22
0
 def _process(self, room_ids, start_date, end_date, reason,
              allowed_principals):
     rooms = Room.query.filter(Room.id.in_(room_ids)).all()
     allowed = []
     for obj in allowed_principals:
         if obj.get('is_group'):
             allowed.append(GroupProxy(obj['id'], provider=obj['provider']))
         else:
             allowed.append(User.query.filter(User.id == obj['id']).one())
     blocking = create_blocking(rooms, start_date, end_date, reason,
                                allowed)
     approve_or_request_blocking(blocking)
     return jsonify_data(flash=False)
Пример #23
0
 def convert_principal(self, old_principal):
     """Converts a legacy principal to PrincipalMixin style"""
     if old_principal.__class__.__name__ == 'Avatar':
         principal = self.global_ns.avatar_merged_user.get(old_principal.id)
         if not principal and 'email' in old_principal.__dict__:
             email = convert_to_unicode(
                 old_principal.__dict__['email']).lower()
             principal = self.global_ns.users_by_primary_email.get(
                 email, self.global_ns.users_by_secondary_email.get(email))
             if principal is not None:
                 self.print_warning(
                     'Using {} for {} (matched via {})'.format(
                         principal, old_principal, email))
         if not principal:
             self.print_error("User {} doesn't exist".format(
                 old_principal.id))
         return principal
     elif old_principal.__class__.__name__ == 'Group':
         assert int(old_principal.id) in self.global_ns.all_groups
         return GroupProxy(int(old_principal.id))
     elif old_principal.__class__.__name__ in {
             'CERNGroup', 'LDAPGroup', 'NiceGroup'
     }:
         return GroupProxy(old_principal.id, self.default_group_provider)
Пример #24
0
 def principal(self):
     from indico.modules.groups import GroupProxy
     if self.type == PrincipalType.user:
         return self.user
     elif self.type == PrincipalType.local_group:
         return self.local_group.proxy
     elif self.type == PrincipalType.multipass_group:
         return GroupProxy(self.multipass_group_name, self.multipass_group_provider)
     elif self.type == PrincipalType.email:
         return EmailPrincipal(self.email)
     elif self.type == PrincipalType.network:
         return self.ip_network_group
     elif self.type == PrincipalType.event_role:
         return self.event_role
     elif self.type == PrincipalType.category_role:
         return self.category_role
Пример #25
0
 def manager_emails(self):
     manager_group = self.get_attribute_value('manager-group')
     if not manager_group:
         return set()
     group = GroupProxy.get_named_default_group(manager_group)
     return {u.email for u in group.get_members()}
Пример #26
0
 def _process(self, name, exact):
     groups = GroupProxy.search(name, exact=exact)
     total = len(groups)
     return jsonify(
         groups=[serialize_group(group) for group in groups[:10]],
         total=total)
Пример #27
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_))
Пример #28
0
 def _process(self, name, exact):
     groups = GroupProxy.search(name, exact=exact)
     total = len(groups)
     return jsonify(groups=[serialize_group(group) for group in groups[:10]], total=total)
Пример #29
0
 def _getAnswer(self):
     results = [g.as_legacy_group for g in GroupProxy.search(self._group, exact=self._exactMatch)]
     fossilized_results = fossilize(results, IGroupFossil)
     for fossilizedGroup in fossilized_results:
         fossilizedGroup["isGroup"] = True
     return fossilized_results
Пример #30
0
 def _process(self, name):
     groups = GroupProxy.search(name)
     return jsonify([serialize_group(group) for group in groups])
Пример #31
0
 def is_member_of_group(self, group_name):
     group_provider = multipass.default_group_provider
     group = GroupProxy(group_name, group_provider.name if group_provider else None)
     return group.has_member(self.user)
Пример #32
0
 def proxy(self):
     """Return a GroupProxy wrapping this group."""
     from indico.modules.groups import GroupProxy
     return GroupProxy(self.id, _group=self)
Пример #33
0
 def group(self):
     return GroupProxy(self.id, self.provider)
Пример #34
0
 def getName(self):
     return GroupProxy(self.id).name
Пример #35
0
 def group(self):
     return GroupProxy(self.id)