def _merge_users(target, source, **kwargs): from indico.modules.events.models.persons import EventPerson from indico.modules.events.models.principals import EventPrincipal EventPerson.merge_users(target, source) EventPrincipal.merge_users(target, source, 'event') target.event_roles |= source.event_roles source.event_roles.clear()
def _clone_persons(self, new_event): attrs = get_simple_column_attrs(EventPerson) | {'user'} for old_person in self.old_event.persons: person = EventPerson(event=new_event) person.populate_from_attrs(old_person, attrs) assert person not in db.session self._person_map[old_person] = person
def _clone_persons(self, new_event): attrs = get_simple_column_attrs(EventPerson) | {"user"} for old_person in self.old_event.persons: person = EventPerson(event_new=new_event) person.populate_from_attrs(old_person, attrs) assert person not in db.session self._person_map[old_person] = person
def test_get_registered_event_persons(dummy_event, dummy_user, dummy_regform): create_registration(dummy_regform, { 'email': '*****@*****.**', 'first_name': 'John', 'last_name': 'Doe', }, notify_user=False) user_person = EventPerson.create_from_user(dummy_user, dummy_event) no_user_person = EventPerson(email='*****@*****.**', first_name='John', last_name='Doe') create_registration(dummy_regform, { 'email': '*****@*****.**', 'first_name': 'Jane', 'last_name': 'Doe', }, notify_user=False) no_user_no_reg = EventPerson(email='*****@*****.**', first_name='No', last_name='Show') dummy_event.persons.append(user_person) dummy_event.persons.append(no_user_person) dummy_event.persons.append(no_user_no_reg) db.session.flush() registered_persons = get_registered_event_persons(dummy_event) assert registered_persons == {user_person, no_user_person}
def test_dump_event(db, dummy_user, dummy_event): from indico.modules.search.schemas import EventSchema schema = EventSchema() dummy_event.description = 'A dummy event' dummy_event.keywords = ['foo', 'bar'] person = EventPerson.create_from_user(dummy_user, dummy_event) person2 = EventPerson(event=dummy_event, first_name='Admin', last_name='Saurus', affiliation='Indico') dummy_event.person_links.append(EventPersonLink(person=person)) dummy_event.person_links.append(EventPersonLink(person=person2)) db.session.flush() category_id = dummy_event.category_id assert schema.dump(dummy_event) == { 'description': 'A dummy event', 'keywords': ['foo', 'bar'], 'location': { 'address': '', 'room_name': '', 'venue_name': '' }, 'persons': [{ 'affiliation': None, 'name': 'Guinea Pig' }, { 'affiliation': 'Indico', 'name': 'Admin Saurus' }], 'title': 'dummy#0', 'category_id': category_id, 'category_path': [ { 'id': 0, 'title': 'Home', 'url': '/' }, { 'id': category_id, 'title': 'dummy', 'url': f'/category/{category_id}/' }, ], 'end_dt': dummy_event.end_dt.isoformat(), 'event_id': 0, 'start_dt': dummy_event.start_dt.isoformat(), 'type': 'event', 'event_type': 'meeting', 'url': '/event/0/', }
def create_event_person(event, create_untrusted_persons=False, **data): """Create an event person from data passed as kwargs.""" from indico.modules.events.persons.schemas import EventPersonSchema event_person = EventPerson(event=event, is_untrusted=create_untrusted_persons) event_person.populate_from_dict( EventPersonSchema(unknown=EXCLUDE).load(data)) return event_person
def person_from_data(person_data, event): user = User.find_first(~User.is_deleted, User.all_emails.contains(person_data['email'].lower())) if user: return EventPerson.for_user(user, event) person = EventPerson.find_first(event_new=event, email=person_data['email'].lower()) if not person: person = EventPerson(event_new=event, **person_data) return person
def _event_person_from_legacy(self, old_person): data = dict(first_name=convert_to_unicode(old_person._firstName), last_name=convert_to_unicode(old_person._surName), _title=self.USER_TITLE_MAP.get( getattr(old_person, '_title', ''), UserTitle.none), affiliation=convert_to_unicode(old_person._affilliation), address=convert_to_unicode(old_person._address), phone=convert_to_unicode(old_person._telephone)) email = strict_sanitize_email(old_person._email) if email: person = (self.event_persons_by_email.get(email) or self.event_persons_by_user.get( self.importer.all_users_by_email.get(email))) else: person = self.event_persons_noemail_by_data.get( (data['first_name'], data['last_name'], data['affiliation'])) if not person: user = self.importer.all_users_by_email.get(email) person = EventPerson(event_new=self.event, user=user, email=email, **data) if email: self.event_persons_by_email[email] = person if user: self.event_persons_by_user[user] = person if not email and not user: self.event_persons_noemail_by_data[( person.first_name, person.last_name, person.affiliation)] = person person_link = AbstractPersonLink(person=person) person_link.populate_from_dict(data) return person_link
def event_person_from_legacy(self, old_person, skip_empty_email=False, skip_empty_names=False): """Translate an old participation-like (or avatar) object to an EventPerson.""" data = self._get_person_data(old_person) if skip_empty_names and not data['first_name'] and not data[ 'last_name']: self.print_warning('%[yellow!]Skipping nameless event person', always=False) return None # retrieve e-mail in both Avatar and Participation objects email = strict_sanitize_email( getattr(old_person, '_email', None) or getattr(old_person, 'email', None)) if email: person = (self.event_ns.event_persons_by_email.get(email) or self.event_ns.event_persons_by_user.get( self.global_ns.users_by_email.get(email))) elif skip_empty_email: return None else: person = self.event_ns.event_persons_by_data.get( (data['first_name'], data['last_name'], data['affiliation'])) if not person: user = self.global_ns.users_by_email.get(email) person = EventPerson(event=self.event, user=user, email=email, **data) self.add_event_person(person) return person
def create_event_person(event, create_untrusted_persons=False, **data): """Create an event person from data passed as kwargs.""" title = next((x.value for x in UserTitle if data.get('title') == x.title), None) return EventPerson(event=event, email=data.get('email', '').lower(), _title=title, first_name=data.get('firstName'), last_name=data['familyName'], affiliation=data.get('affiliation'), address=data.get('address'), phone=data.get('phone'), is_untrusted=create_untrusted_persons)
def _create_event_person(self, data): title = next((x.value for x in UserTitle if data.get('title') == x.title), None) person = EventPerson(event_new=self.event, email=data.get('email', '').lower(), _title=title, first_name=data.get('firstName'), last_name=data['familyName'], affiliation=data.get('affiliation'), address=data.get('address'), phone=data.get('phone')) # Keep the original data to cancel the conversion if the person is not persisted to the db self.event_person_conversions[person] = data return person
def test_access_everyone(dummy_contribution, dummy_user, dummy_event): menu_entry = MenuEntry(event=dummy_event, type=MenuEntryType.page, access=MenuEntryAccess.everyone) person = EventPerson.create_from_user(dummy_user, dummy_event) assert menu_entry.can_access(dummy_user) contrib_person_link = ContributionPersonLink(person=person) dummy_contribution.person_links.append(contrib_person_link) assert menu_entry.can_access(dummy_user) contrib_person_link.is_speaker = True assert menu_entry.can_access(dummy_user)
def _create(event, user=None, first_name=None, last_name=None, email=None, affiliation=None, title=None): person = EventPerson(event_new=event, user=user, first_name=first_name or user.first_name, last_name=last_name or user.last_name, email=email or user.email, affiliation=affiliation or user.affiliation, title=title or user.title) db.session.add(person) db.session.flush() return person
def _copy_person_link_data(link_data): # Copy person link data since we would otherwise end up # adding the EventPersons of the first event in all other # events of the series. for link, submitter in link_data.items(): link_copy = EventPersonLink(**{col: getattr(link, col) for col in get_simple_column_attrs(EventPersonLink)}) link_copy.person = EventPerson(**{col: getattr(link.person, col) for col in get_simple_column_attrs(EventPerson)}) link_copy.person.user = link.person.user yield link_copy, submitter
def test_unused_event_person(db, dummy_user, dummy_event, create_contribution, create_subcontribution, create_abstract): person = EventPerson.create_from_user(dummy_user, event=dummy_event) assert not person.has_links dummy_event.person_links.append(EventPersonLink(person=person)) db.session.flush() assert person.has_links dummy_event.person_links.clear() db.session.flush() assert not person.has_links set_feature_enabled(dummy_event, 'abstracts', True) abstract = create_abstract(dummy_event, 'Dummy abstract', submitter=dummy_user, person_links=[ AbstractPersonLink( person=person, is_speaker=True, author_type=AuthorType.primary) ]) assert person.has_links abstract.is_deleted = True assert not person.has_links contrib = create_contribution( dummy_event, 'Dummy contribution', person_links=[ContributionPersonLink(person=person, is_speaker=True)]) assert person.has_links contrib.is_deleted = True assert not person.has_links db.session.delete(contrib) contrib = create_contribution(dummy_event, 'Dummy contribution', person_links=[]) assert not person.has_links create_subcontribution(contrib, 'Dummy subcontribution', person_links=[ SubContributionPersonLink(person=person, is_speaker=True) ]) assert person.has_links contrib.is_deleted = True assert not person.has_links db.session.delete(contrib) assert not person.has_links
def test_access_participants_not_registered(dummy_contribution, dummy_user, dummy_event): menu_entry = MenuEntry(event=dummy_event, type=MenuEntryType.page, access=MenuEntryAccess.registered_participants) person = EventPerson.create_from_user(dummy_user, dummy_event) assert not menu_entry.can_access(dummy_user) contrib_person_link = ContributionPersonLink(person=person) dummy_contribution.person_links.append(contrib_person_link) assert not menu_entry.can_access(dummy_user) contrib_person_link.is_speaker = True assert not menu_entry.can_access(dummy_user)
def test_access_speakers_contrib(dummy_contribution, dummy_user, dummy_event): set_feature_enabled(dummy_event, 'registration', True) menu_entry = MenuEntry(event=dummy_event, type=MenuEntryType.page, access=MenuEntryAccess.speakers) person = EventPerson.create_from_user(dummy_user, dummy_event) assert not menu_entry.can_access(dummy_user) contrib_person_link = ContributionPersonLink(person=person) dummy_contribution.person_links.append(contrib_person_link) assert not menu_entry.can_access(dummy_user) contrib_person_link.is_speaker = True assert menu_entry.can_access(dummy_user) dummy_contribution.is_deleted = True assert not menu_entry.can_access(dummy_user)
def test_serialize_principal(app, dummy_event, dummy_user): from indico.modules.events.persons.schemas import EventPersonSchema with app.test_request_context(): form = MockForm(event=dummy_event) dummy_user.phone = '91' dummy_user.address = 'My street' dummy_user.affiliation = 'Test' person = EventPerson.create_from_user(dummy_user, dummy_event) persons = EventPersonSchema( only=EventPersonSchema.Meta.public_fields).dumps([person], many=True) form.person_link_data.process_formdata([persons]) del form.person_link_data._submitted_data result = form.person_link_data._value() assert result[0].get('phone') == '' assert result[0].get('address') == '' assert result[0].get('affiliation') == 'Test'
def _migrate_event_persons(self): all_persons = defaultdict(list) old_people = [] for chairperson in getattr(self.conf, '_chairs', []): old_people.append(chairperson) for old_contrib in self.conf.contributions.itervalues(): for speaker in getattr(old_contrib, '_speakers', []): old_people.append(speaker) for author in getattr(old_contrib, '_primaryAuthors', []): old_people.append(author) for coauthor in getattr(old_contrib, '_coAuthors', []): old_people.append(coauthor) for old_subcontrib in old_contrib._subConts: for speaker in getattr(old_subcontrib, 'speakers', []): old_people.append(speaker) schedule = self.conf._Conference__schedule if schedule: for old_entry in schedule._entries: entry_type = old_entry.__class__.__name__ if entry_type == 'LinkedTimeSchEntry': old_block = old_entry._LinkedTimeSchEntry__owner for convener in getattr(old_block, '_conveners', []): old_people.append(convener) for old_person in old_people: person = self.event_person_from_legacy(old_person, skip_empty_email=True, skip_empty_names=True) if person: user = self.global_ns.users_by_email.get(person.email) email = user.email if user else person.email all_persons[email].append(person) for email, persons in all_persons.iteritems(): person = self.get_event_person_by_email(email) if not person: person = EventPerson(email=email, event_new=self.event, user=self.global_ns.users_by_email.get(email), first_name=most_common(persons, key=attrgetter('first_name')), last_name=most_common(persons, key=attrgetter('last_name')), _title=most_common(persons, key=attrgetter('_title')), affiliation=most_common(persons, key=attrgetter('affiliation')), address=most_common(persons, key=attrgetter('address')), phone=most_common(persons, key=attrgetter('phone'))) self.add_event_person(person) if not self.quiet: self.print_info('%[magenta!]Event Person%[reset] {}({})'.format(person.full_name, person.email))
def test_access_speakers_subcontrib(dummy_contribution, dummy_user, dummy_event): set_feature_enabled(dummy_event, 'registration', True) menu_entry = MenuEntry(event=dummy_event, type=MenuEntryType.page, access=MenuEntryAccess.speakers) person = EventPerson.create_from_user(dummy_user, dummy_event) assert not menu_entry.can_access(dummy_user) subcontrib = SubContribution(contribution=dummy_contribution, title='sc', duration=timedelta(minutes=10)) subcontrib_person_link = SubContributionPersonLink(person=person) subcontrib.person_links.append(subcontrib_person_link) assert menu_entry.can_access(dummy_user) dummy_contribution.is_deleted = True assert not menu_entry.can_access(dummy_user) dummy_contribution.is_deleted = False subcontrib.is_deleted = True assert not menu_entry.can_access(dummy_user)
def test_submitter_permissions(app, db, dummy_event, dummy_user): from indico.modules.events.persons.schemas import PersonLinkSchema person = EventPerson.create_from_user(dummy_user, dummy_event) person_link = EventPersonLink(person=person) dummy_event.person_links = [person_link] dummy_event.update_principal(person_link.person.principal, add_permissions={'submit'}) with app.test_request_context(): form = MockForm(event=dummy_event) form.person_link_data.data = dummy_event.person_links # Remove all persons form.person_link_data.process_formdata(['[]']) dummy_event.person_link_data = form.person_link_data.data db.session.flush() assert person.has_role('submit', dummy_event) is False # Serialize a person_link with a submitter role input_person = PersonLinkSchema().dump(person_link) input_person['roles'] = ['submitter'] form.person_link_data.process_formdata([json.dumps([input_person])]) dummy_event.person_link_data = form.person_link_data.data db.session.flush() assert person.has_role('submit', dummy_event) is True
def test_dump_contribution(db, dummy_user, dummy_event, dummy_contribution, create_entry, scheduled): from indico.modules.search.schemas import ContributionSchema person = EventPerson.create_from_user(dummy_user, dummy_event) dummy_contribution.person_links.append( ContributionPersonLink(person=person)) dummy_contribution.description = 'A dummy contribution' extra = {'start_dt': None, 'end_dt': None} if scheduled: create_entry(dummy_contribution, utc.localize(datetime(2020, 4, 20, 4, 20))) extra = { 'start_dt': dummy_contribution.start_dt.isoformat(), 'end_dt': dummy_contribution.end_dt.isoformat(), } db.session.flush() category_id = dummy_contribution.event.category_id schema = ContributionSchema() assert schema.dump(dummy_contribution) == { 'description': 'A dummy contribution', 'location': { 'address': '', 'room_name': '', 'venue_name': '' }, 'persons': [{ 'affiliation': None, 'name': 'Guinea Pig' }], 'title': 'Dummy Contribution', 'category_id': category_id, 'category_path': [ { 'id': 0, 'title': 'Home', 'url': '/' }, { 'id': category_id, 'title': 'dummy', 'url': f'/category/{category_id}/' }, ], 'contribution_id': dummy_contribution.id, 'duration': 20, 'event_id': 0, 'type': 'contribution', 'url': f'/event/0/contributions/{dummy_contribution.id}/', **extra }
def _get_event_person_for_user(self, user): person = EventPerson.for_user( user, self.event, is_untrusted=self.create_untrusted_persons) # Keep a reference to the user to cancel the conversion if the person is not persisted to the db self.event_person_conversions[person] = user return person
def _get_event_person_for_user(self, user): person = EventPerson.for_user(user, self.event, is_untrusted=self.create_untrusted_persons) # Keep a reference to the user to cancel the conversion if the person is not persisted to the db self.event_person_conversions[person] = user return person
def test_filter_contrib_entries(app, db, dummy_event, create_user, create_contribution, create_registration): registered_user = create_user(1) registered_speaker = create_user(2) unregistered_user = create_user(3) dummy_regform = RegistrationForm(event=dummy_event, title='Registration Form', currency='USD') dummy_event.registrations.append( create_registration(registered_user, dummy_regform)) dummy_event.registrations.append( create_registration(registered_speaker, dummy_regform)) registered_speaker_contribution = create_contribution( dummy_event, 'Registered Speaker', person_links=[ ContributionPersonLink(person=EventPerson.create_from_user( registered_speaker, dummy_event), is_speaker=True) ]) registered_speaker_author_contribution = create_contribution( dummy_event, 'Registered Speaker Author', person_links=[ ContributionPersonLink(person=EventPerson.for_user( registered_speaker, dummy_event), is_speaker=True, author_type=AuthorType.primary) ]) unregistered_speaker_registered_author_contribution = create_contribution( dummy_event, 'Unregistered Speaker, Registered Author', person_links=[ ContributionPersonLink(person=EventPerson.for_user( unregistered_user, dummy_event), is_speaker=True), ContributionPersonLink(person=EventPerson.for_user( registered_user, dummy_event), author_type=AuthorType.primary) ]) registered_speaker_unregistered_author_contribution = create_contribution( dummy_event, 'Registered Speaker, Unregistered Author', person_links=[ ContributionPersonLink(person=EventPerson.for_user( registered_user, dummy_event), is_speaker=True), ContributionPersonLink(person=EventPerson.for_user( unregistered_user, dummy_event), author_type=AuthorType.primary) ]) # Filter contributions with registered users with app.test_request_context(): list_gen = ContributionListGenerator(dummy_event) list_gen.list_config['filters'] = {'items': {'people': {'registered'}}} result = list_gen.get_list_kwargs() assert result['contribs'] == [ registered_speaker_contribution, registered_speaker_author_contribution, unregistered_speaker_registered_author_contribution, registered_speaker_unregistered_author_contribution ] # Filter contributions with registered speakers list_gen.list_config['filters'] = {'items': {'speakers': {'registered'}}} with app.test_request_context(): result = list_gen.get_list_kwargs() assert result['contribs'] == [ registered_speaker_contribution, registered_speaker_author_contribution, registered_speaker_unregistered_author_contribution ] # Filter contributions with unregistered speakers and registered users list_gen.list_config['filters'] = { 'items': { 'speakers': {'not_registered'}, 'people': {'registered'} } } with app.test_request_context(): result = list_gen.get_list_kwargs() assert result['contribs'] == [ unregistered_speaker_registered_author_contribution ]
def get_event_person_for_user(event, user, create_untrusted_persons=False): """Return the event person that links to a given User/Event (if any).""" return EventPerson.for_user(user, event, is_untrusted=create_untrusted_persons)
def test_dump_event(db, dummy_user, dummy_event): from .schemas import EventRecordSchema schema = EventRecordSchema(context={'schema': 'test-events'}) dummy_event.description = 'A dummy <strong>event</strong>' dummy_event.keywords = ['foo', 'bar'] person = EventPerson.create_from_user(dummy_user, dummy_event) person2 = EventPerson(event=dummy_event, first_name='Admin', last_name='Saurus', affiliation='Indico') dummy_event.person_links.append(EventPersonLink(person=person)) dummy_event.person_links.append(EventPersonLink(person=person2)) db.session.flush() category_id = dummy_event.category_id assert schema.dump(dummy_event) == { '$schema': 'test-events', '_access': { 'delete': ['IndicoAdmin'], 'owner': ['IndicoAdmin'], 'update': ['IndicoAdmin'], }, '_data': { 'description': 'A dummy event', 'keywords': ['foo', 'bar'], 'location': { 'address': '', 'room_name': '', 'venue_name': '' }, 'persons': [{ 'name': 'Guinea Pig' }, { 'affiliation': 'Indico', 'name': 'Admin Saurus' }], 'site': 'http://localhost', 'title': 'dummy#0' }, 'category_id': 1, 'category_path': [ { 'id': 0, 'title': 'Home', 'url': '/' }, { 'id': category_id, 'title': 'dummy', 'url': f'/category/{category_id}/' }, ], 'end_dt': dummy_event.end_dt.isoformat(), 'event_id': 0, 'start_dt': dummy_event.start_dt.isoformat(), 'type': 'event', 'type_format': 'meeting', 'url': 'http://localhost/event/0/', }
def test_dump_contribution(db, dummy_user, dummy_event, dummy_contribution, create_entry, scheduled): from .schemas import ContributionRecordSchema person = EventPerson.create_from_user(dummy_user, dummy_event) dummy_contribution.person_links.append( ContributionPersonLink(person=person)) dummy_contribution.description = 'A dummy <strong>contribution</strong>' extra = {} if scheduled: create_entry(dummy_contribution, utc.localize(datetime(2020, 4, 20, 4, 20))) extra = { 'start_dt': dummy_contribution.start_dt.isoformat(), 'end_dt': dummy_contribution.end_dt.isoformat(), } db.session.flush() category_id = dummy_contribution.event.category_id schema = ContributionRecordSchema(context={'schema': 'test-contribs'}) assert schema.dump(dummy_contribution) == { '$schema': 'test-contribs', '_access': { 'delete': ['IndicoAdmin'], 'owner': ['IndicoAdmin'], 'update': ['IndicoAdmin'], }, '_data': { 'description': 'A dummy contribution', 'location': { 'address': '', 'room_name': '', 'venue_name': '' }, 'persons': [{ 'name': 'Guinea Pig' }], 'site': 'http://localhost', 'title': 'Dummy Contribution', }, 'category_id': category_id, 'category_path': [ { 'id': 0, 'title': 'Home', 'url': '/' }, { 'id': category_id, 'title': 'dummy', 'url': f'/category/{category_id}/' }, ], 'contribution_id': dummy_contribution.id, 'duration': 20, 'event_id': 0, 'type': 'contribution', 'url': f'http://localhost/event/0/contributions/{dummy_contribution.id}/', **extra }
def _merge_users(target, source, **kwargs): from indico.modules.events.models.persons import EventPerson from indico.modules.events.models.principals import EventPrincipal EventPerson.merge_users(target, source) EventPrincipal.merge_users(target, source, 'event_new')
def _convert_email_person_links(user, **kwargs): from indico.modules.events.models.persons import EventPerson EventPerson.link_user_by_email(user)