def _addChair(conf, chair, grantManager, grantSubmission): conf.addChair(chair) if grantManager and chair.getEmail(): conf.as_event.update_principal(EmailPrincipal(chair.getEmail()), full_access=True) if grantSubmission and chair.getEmail(): conf.as_event.update_principal(EmailPrincipal(chair.getEmail()), add_roles={'submit'})
def test_update_principal_resolve_email(create_event, create_user): event = create_event() user = create_user(123, email='*****@*****.**') # add email that belongs to a user entry = event.update_principal(EmailPrincipal('*****@*****.**'), full_access=True) assert entry.principal == user assert entry.type == PrincipalType.user # add email that has no user associated entry = event.update_principal(EmailPrincipal('*****@*****.**'), full_access=True) assert entry.principal == EmailPrincipal('*****@*****.**') assert entry.type == PrincipalType.email
def test_update_principal_resolve_email(create_event, create_user, smtp): event = create_event() user = create_user(123, email='*****@*****.**') # add email that belongs to a user entry = event.update_principal(EmailPrincipal('*****@*****.**'), full_access=True) assert entry.principal == user assert entry.type == PrincipalType.user extract_emails(smtp, required=False, count=0) # add email that has no user associated entry = event.update_principal(EmailPrincipal('*****@*****.**'), full_access=True) assert entry.principal == EmailPrincipal('*****@*****.**') assert entry.type == PrincipalType.email extract_emails(smtp, required=True, count=1)
def _process_principal(self, principal_cls, principals, legacy_principal, name, read_access=None, full_access=None, roles=None, allow_emails=True): if legacy_principal is None: return elif isinstance(legacy_principal, basestring): user = self.global_ns.users_by_email.get(legacy_principal) principal = user or EmailPrincipal(legacy_principal) else: principal = self._convert_principal(legacy_principal) if principal is None: self.print_warning('%[yellow]{} does not exist:%[reset] {}' .format(name, legacy_principal), always=False) return elif not allow_emails and isinstance(principal, EmailPrincipal): self.print_warning('%[yellow]{} cannot be an email principal:%[reset] {}' .format(name, legacy_principal), always=False) return try: entry = principals[principal] except KeyError: entry = principal_cls(principal=principal, full_access=False, roles=[]) principals[principal] = entry if read_access: entry.read_access = True if full_access: entry.full_access = True if roles: entry.roles = sorted(set(entry.roles) | set(roles)) if not self.quiet: self.print_info(' - [{}] {}'.format(name.lower(), principal))
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_update_principal_email(create_event, smtp): event = create_event() principal = EmailPrincipal('*****@*****.**') event.update_principal(principal, roles={'submit'}) email = extract_emails(smtp, required=True, one=True, to=principal.email) assert email['Subject'] == '[Indico] Please register' # adding more privs to the user should not send another email event.update_principal(principal, full_access=True) extract_emails(smtp, required=False, count=0)
def test_convert_email_principals_merge(db, create_event, create_user): event = create_event() user = create_user(123, email='*****@*****.**') principal = EmailPrincipal('*****@*****.**') entry1 = event.update_principal(user, full_access=True, roles={'foo', 'foobar'}) entry2 = event.update_principal(principal, read_access=True, roles={'foo', 'bar'}) # different emails for now -> nothing updated assert not EventPrincipal.replace_email_with_user(user, 'event_new') assert set(event.acl_entries) == {entry1, entry2} user.secondary_emails.add(principal.email) assert EventPrincipal.replace_email_with_user(user, 'event_new') == {event} assert len(event.acl_entries) == 1 entry = list(event.acl_entries)[0] assert entry.full_access assert entry.read_access assert set(entry.roles) == {'foo', 'bar', 'foobar'}
def test_convert_email_principals(db, create_event, create_user, dummy_user): event = create_event() user = create_user(123, email='*****@*****.**') principal = EmailPrincipal('*****@*****.**') other_entry = event.update_principal(dummy_user, full_access=True, roles={'foo', 'foobar'}) entry = event.update_principal(principal, read_access=True, roles={'foo', 'bar'}) other_entry_data = other_entry.current_data entry_data = entry.current_data # different emails for now -> nothing updated assert not EventPrincipal.replace_email_with_user(user, 'event_new') assert set(event.acl_entries) == {entry, other_entry} user.secondary_emails.add(principal.email) assert EventPrincipal.replace_email_with_user(user, 'event_new') == {event} assert set(event.acl_entries) == {entry, other_entry} assert all(x.type == PrincipalType.user for x in event.acl_entries) db.session.expire(other_entry) db.session.expire(entry) assert entry.current_data == entry_data assert other_entry.current_data == other_entry_data
def process_principal(self, event, principals, legacy_principal, name, color, full_access=None, roles=None): if isinstance(legacy_principal, basestring): user = self.all_users_by_email.get(legacy_principal) principal = user or EmailPrincipal(legacy_principal) else: principal = self.convert_principal(legacy_principal) if principal is None: self.print_warning(cformat('%%{%s}{}%%{reset}%%{yellow} does not exist:%%{reset} {}' % color) .format(name, legacy_principal), event_id=event.id) return try: entry = principals[principal] except KeyError: entry = EventPrincipal(event_id=event.id, principal=principal, full_access=False, roles=[]) principals[principal] = entry if full_access: entry.full_access = True if roles: entry.roles = sorted(set(entry.roles) | set(roles)) if not self.quiet: self.print_msg(cformat(' - %%{%s}[{}]%%{reset} {}' % color).format(name.lower(), principal)) return principal
def process_principal(self, principals, legacy_principal, name, color, full_access=None, roles=None, read_access=None): if isinstance(legacy_principal, basestring): user = self.global_ns.users_by_email.get(legacy_principal) principal = user or EmailPrincipal(legacy_principal) else: principal = self.convert_principal(legacy_principal) if principal is None: self.print_warning( ('%%[%s]{}%%[reset]%%[yellow] does not exist:%%[reset] {} ({})' % color).format(name, legacy_principal, getattr(legacy_principal, 'id', '-'))) return try: entry = principals[principal] except KeyError: entry = EventPrincipal(event_id=self.event.id, principal=principal, full_access=False, roles=[]) principals[principal] = entry if full_access: entry.full_access = True if read_access: entry.read_access = True if roles: entry.roles = sorted(set(entry.roles) | set(roles)) if not self.quiet: self.print_log(' %%[%s][{}]%%[reset] {}' % color.format(name.lower(), principal)) return principal
def principal(self): if self.user is not None: return self.user elif self.email: return EmailPrincipal(self.email) return None
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_))
if not allow_registration_forms: raise ValueError('Registration forms are not allowed') try: reg_form_id = int(data) except ValueError: raise ValueError('Invalid data') registration_form = RegistrationForm.get( reg_form_id, is_deleted=(None if soft_fail else False)) if registration_form is None or registration_form.event_id != event_id: raise ValueError(f'Invalid registration form: {reg_form_id}') return registration_form elif type_ == 'Email': if not allow_emails: raise ValueError('Emails are not allowed') return EmailPrincipal(data) elif type_ == 'IPNetworkGroup': if not allow_networks: raise ValueError('Network groups are not allowed') try: netgroup_id = int(data) except ValueError: raise ValueError('Invalid data') netgroup = IPNetworkGroup.get(netgroup_id) if netgroup is None or (netgroup.hidden and not soft_fail): raise ValueError(f'Invalid network group: {netgroup_id}') return netgroup else: raise ValueError('Invalid data')
def principal_from_identifier(identifier, allow_groups=False, allow_external_users=False, allow_event_roles=False, allow_category_roles=False, allow_registration_forms=False, allow_emails=False, event_id=None, soft_fail=False): from indico.modules.events.models.events import Event from indico.modules.events.models.roles import EventRole from indico.modules.categories.models.roles import CategoryRole from indico.modules.events.registration.models.forms import RegistrationForm 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=(None if soft_fail else 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 not soft_fail and group.group is None: raise ValueError('Invalid group: {}'.format(data)) return group elif type_ == 'EventRole': if not allow_event_roles: raise ValueError('Event roles are not allowed') try: event_role_id = int(data) except ValueError: raise ValueError('Invalid data') event_role = EventRole.get(event_role_id) if event_role is None or event_role.event_id != event_id: raise ValueError('Invalid event role: {}'.format(event_role_id)) return event_role elif type_ == 'CategoryRole': if not allow_category_roles: raise ValueError('Category roles are not allowed') event = Event.get(event_id) if event is None: raise ValueError('Invalid event id: {}'.format(event_id)) try: category_role_id = int(data) except ValueError: raise ValueError('Invalid data') if soft_fail: category_role = CategoryRole.get(category_role_id) else: category_role = CategoryRole.get_category_role_by_id(event.category, category_role_id) if category_role is None: raise ValueError('Invalid category role: {}'.format(category_role_id)) return category_role elif type_ == 'RegistrationForm': if not allow_registration_forms: raise ValueError('Registration forms are not allowed') try: reg_form_id = int(data) except ValueError: raise ValueError('Invalid data') registration_form = RegistrationForm.get(reg_form_id, is_deleted=(None if soft_fail else False)) if registration_form is None or registration_form.event_id != event_id: raise ValueError('Invalid registration form: {}'.format(reg_form_id)) return registration_form elif type_ == 'Email': if not allow_emails: raise ValueError('Emails are not allowed') return EmailPrincipal(data) else: raise ValueError('Invalid data')