def login_user(user, identity=None, admin_impersonation=False): """Set the session user and performs on-login logic. When specifying `identity`, the provider/identitifer information is saved in the session so the identity management page can prevent the user from removing the identity he used to login. :param user: The :class:`~indico.modules.users.User` to log in to. :param identity: The :class:`Identity` instance used to log in. :param admin_impersonation: Whether the login is an admin impersonating the user and thus should not be considered a login by the user. """ if user.settings.get('force_timezone'): session.timezone = user.settings.get('timezone', config.DEFAULT_TIMEZONE) else: session.timezone = 'LOCAL' session.set_session_user(user) session.lang = user.settings.get('lang') if not admin_impersonation: if identity: identity.register_login(request.remote_addr) session['login_identity'] = identity.id else: session.pop('login_identity', None) user.synchronize_data() signals.users.logged_in.send(user, identity=identity, admin_impersonation=admin_impersonation)
def test_RHRegistrationForm_can_register(db, dummy_regform, dummy_reg, dummy_user, create_user): invitation = RegistrationInvitation(registration_form=dummy_regform, email='*****@*****.**', first_name='foo', last_name='bar', affiliation='test') db.session.flush() request.view_args = {'reg_form_id': dummy_regform.id, 'event_id': dummy_regform.event_id} request.args = {'invitation': invitation.uuid} rh = RHRegistrationForm() rh._process_args() assert rh._can_register() # invited rh.invitation = None assert not rh._can_register() # not open dummy_regform.start_dt = now_utc(False) assert rh._can_register() session.set_session_user(dummy_user) # registered in dummy_reg assert not rh._can_register() dummy_reg.state = RegistrationState.rejected assert not rh._can_register() # being rejected does not allow registering again dummy_reg.state = RegistrationState.withdrawn assert not rh._can_register() # being withdrawn does not allow registering again session.set_session_user(create_user(123, email='*****@*****.**')) assert rh._can_register() dummy_regform.registration_limit = 1 assert rh._can_register() # withdrawn/rejected do not count against limit dummy_reg.state = RegistrationState.complete assert not rh._can_register() # exceeding limit
def test_lookup_request_user_session_oauth(dummy_user, mocker): assert _lookup_request_user() == (None, None) session.set_session_user(dummy_user) mocker.patch('indico.web.util.get_oauth_user').return_value = dummy_user with pytest.raises(BadRequest) as exc_info: _lookup_request_user() assert 'OAuth tokens and session cookies cannot be mixed' in str(exc_info.value)
def undo_impersonate_user(): """Undo an admin impersonation login and revert to the old user.""" from indico.modules.auth import logger from indico.modules.users import User try: entry = session.pop('login_as_orig_user') except KeyError: # The user probably already switched back from another tab return user = User.get_or_404(entry['user_id']) logger.info('Admin %r stopped impersonating user %r', user, session.user) session.set_session_user(user) session.update(entry['session_data'])
def test_event_key_access(create_user, create_event): """ Ensure the event doesn't reject the user if an access key is required. """ rh = RHDisplayEventBase() rh.event = create_event(2, protection_mode=ProtectionMode.protected, access_key='abc') with pytest.raises(AccessKeyRequired): rh._check_access() user = create_user(1) rh.event.update_principal(user, read_access=True) session.set_session_user(user) rh._check_access()
def test_event_protected_access(db, create_user, create_event): """ Ensure a null user cannot access a protected event. Ensure a user with respective ACL entry can access a protected event. """ rh = RHProtectedEventBase() rh.event = create_event(2, protection_mode=ProtectionMode.protected) with pytest.raises(Forbidden): rh._check_access() user = create_user(1) session.set_session_user(user) with pytest.raises(Forbidden): rh._check_access() rh.event.update_principal(user, read_access=True) rh._check_access()
def mock_access_request(dummy_event, dummy_regform, dummy_user, app, request): data = { 'email': dummy_user.email, 'first_name': dummy_user.first_name, 'last_name': dummy_user.last_name, 'affiliation': dummy_user.affiliation, 'phone': dummy_user.phone, 'position': 'Business Relationship Manager', 'user': dummy_user } data.update(request.param.get('personal_data', {})) with app.test_request_context(method='POST', data=data): session.set_session_user(dummy_user) session.lang = 'en_GB' CERNAccessPlugin.settings.acls.add_principal('authorized_users', dummy_user) g.rh = RHRegistrationForm() g.rh.regform = dummy_regform req = Request(event=dummy_event, definition=CERNAccessRequestDefinition(), created_by_user=dummy_user, data={ 'comment': 'no comments', 'regforms': [dummy_regform.id], 'during_registration': request.param['during_registration'], 'during_registration_required': request.param['during_registration_required'], 'start_dt_override': None, 'end_dt_override': None }) CERNAccessRequestDefinition.send(req, { 'start_dt_override': None, 'end_dt_override': None }) yield
def test_move_event(app, dummy_event, dummy_user, dummy_category, target_category): dummy_event.category = dummy_category dummy_event.update_principal(dummy_user, full_access=True) target_category.event_creation_mode = EventCreationMode.open target_category.update_principal(dummy_user, read_access=True, permissions={'create'}) assert dummy_event.pending_move_request is None rh = RHMoveEvent() rh.comment = '' rh.event = dummy_event rh.target_category = target_category with app.test_request_context(): session.set_session_user(dummy_user) rh._check_access() rh._process() assert dummy_event.category == target_category assert dummy_event.pending_move_request is None
def attachment_access_test_env(request_context, dummy_user, dummy_event, dummy_session, create_contribution): session.set_session_user(dummy_user) session_contrib = create_contribution(dummy_event, 'Session Contrib', session=dummy_session) standalone_contrib = create_contribution(dummy_event, 'Standalone Contrib') event_attachment = _make_attachment(dummy_user, dummy_event) session_attachment = _make_attachment(dummy_user, dummy_session) session_contrib_attachment = _make_attachment(dummy_user, session_contrib) standalone_contrib_attachment = _make_attachment(dummy_user, standalone_contrib) rh = RHDownloadEventAttachment() rh.event = dummy_event def assert_access_check(attachment, accessible=True, expected_exc=Forbidden): __tracebackhide__ = True rh.attachment = attachment if accessible: rh._check_access() else: with pytest.raises(expected_exc) as exc_info: rh._check_access() assert exc_info.type is expected_exc yield type( 'AttachmentAccessTestEnv', (object, ), { 'event': dummy_event, 'session': dummy_session, 'standalone_contrib': standalone_contrib, 'session_contrib': session_contrib, 'event_attachment': event_attachment, 'session_attachment': session_attachment, 'session_contrib_attachment': session_contrib_attachment, 'standalone_contrib_attachment': standalone_contrib_attachment, 'assert_access_check': staticmethod(assert_access_check), })
def test_move_event_request(db, app, creation_mode, permissions, dummy_user, dummy_event, dummy_category, target_category): dummy_event.category = dummy_category dummy_event.update_principal(dummy_user, full_access=True) target_category.event_creation_mode = creation_mode target_category.update_principal(dummy_user, read_access=True, permissions=permissions) assert dummy_event.pending_move_request is None rh = RHMoveEvent() rh.comment = 'foo' rh.event = dummy_event rh.target_category = target_category with app.test_request_context(): session.set_session_user(dummy_user) rh._check_access() rh._process() db.session.expire(dummy_event, ['pending_move_request']) assert dummy_event.category == dummy_category assert dummy_event.pending_move_request is not None assert dummy_event.pending_move_request.category == target_category assert dummy_event.pending_move_request.requestor_comment == rh.comment
def test_search_for_rooms_with_entities(dummy_room, dummy_user): session.set_session_user(dummy_user) assert search_for_rooms({}).with_entities( Room.id, Room.full_name).one() == (dummy_room.id, '1/2-3')
def test_search_for_rooms(dummy_room, dummy_user): session.set_session_user(dummy_user) assert search_for_rooms({}).one() == dummy_room
def test_lookup_request_user_signed_url(create_user, dummy_user, mocker): assert _lookup_request_user(True) == (None, None) mocker.patch('indico.web.util.verify_signed_user_url').return_value = dummy_user session.set_session_user(create_user(123)) # should be ignored assert _lookup_request_user(True) == (dummy_user, 'signed_url')
def test_lookup_request_user_session(dummy_user): assert _lookup_request_user() == (None, None) session.set_session_user(dummy_user) assert _lookup_request_user() == (dummy_user, 'session')
def test_get_user_data(monkeypatch, dummy_event, dummy_user, dummy_regform): monkeypatch.setattr( 'indico.modules.events.registration.util.notify_invitation', lambda *args, **kwargs: None) session.set_session_user(dummy_user) assert get_user_data(dummy_regform, None) == {} expected = { 'email': '*****@*****.**', 'first_name': 'Guinea', 'last_name': 'Pig' } user_data = get_user_data(dummy_regform, dummy_user) assert user_data == expected user_data = get_user_data(dummy_regform, session.user) assert user_data == expected dummy_user.title = UserTitle.mr dummy_user.phone = '+1 22 50 14' dummy_user.address = 'Geneva' user_data = get_user_data(dummy_regform, dummy_user) assert type(user_data['title']) is dict assert user_data['phone'] == '+1 22 50 14' # Check that data is taken from the invitation invitation = RegistrationInvitation(skip_moderation=True, email='*****@*****.**', first_name='Amy', last_name='Wang', affiliation='ACME Inc.') dummy_regform.invitations.append(invitation) dummy_user.title = None user_data = get_user_data(dummy_regform, dummy_user, invitation) assert user_data == { 'email': '*****@*****.**', 'first_name': 'Amy', 'last_name': 'Wang', 'phone': '+1 22 50 14', 'address': 'Geneva', 'affiliation': 'ACME Inc.' } # Check that data is taken from the invitation when user is missing user_data = get_user_data(dummy_regform, None, invitation) assert user_data == { 'email': '*****@*****.**', 'first_name': 'Amy', 'last_name': 'Wang', 'affiliation': 'ACME Inc.' } # Check that data from disabled/deleted fields is not used title_field = next(item for item in dummy_regform.active_fields if item.type == RegistrationFormItemType.field_pd and item.personal_data_type.name == 'title') title_field.is_enabled = False dummy_user.title = UserTitle.dr user_data = get_user_data(dummy_regform, dummy_user) assert 'title' not in user_data phone_field = next(item for item in dummy_regform.active_fields if item.type == RegistrationFormItemType.field_pd and item.personal_data_type.name == 'phone') phone_field.is_deleted = True user_data = get_user_data(dummy_regform, dummy_user) assert 'title' not in user_data assert 'phone' not in user_data assert user_data == { 'email': '*****@*****.**', 'first_name': 'Guinea', 'last_name': 'Pig', 'address': 'Geneva' } for item in dummy_regform.active_fields: item.is_enabled = False assert get_user_data(dummy_regform, dummy_user) == {} assert get_user_data(dummy_regform, dummy_user, invitation) == {}
def test_modify_registration(monkeypatch, dummy_event, dummy_user, dummy_regform): session.set_session_user(dummy_user) monkeypatch.setattr('indico.modules.users.util.get_user_by_email', lambda *args, **kwargs: dummy_user) # Extend the dummy_regform with more sections and fields user_section = RegistrationFormSection(registration_form=dummy_regform, title='dummy_section', is_manager_only=False) db.session.add(user_section) db.session.flush() boolean_field = RegistrationFormField(parent_id=user_section.id, registration_form=dummy_regform) _fill_form_field_with_data(boolean_field, { 'input_type': 'bool', 'default_value': False, 'title': 'Yes/No' }) db.session.add(boolean_field) multi_choice_field = RegistrationFormField(parent_id=user_section.id, registration_form=dummy_regform) _fill_form_field_with_data( multi_choice_field, { 'input_type': 'multi_choice', 'with_extra_slots': False, 'title': 'Multi Choice', 'choices': [ { 'caption': 'A', 'id': 'new:test1', 'is_enabled': True }, { 'caption': 'B', 'id': 'new:test2', 'is_enabled': True }, ] }) choice_uuid = next(k for k, v in multi_choice_field.data['captions'].items() if v == 'A') db.session.add(multi_choice_field) db.session.flush() # Add a manager-only section management_section = RegistrationFormSection( registration_form=dummy_regform, title='manager_section', is_manager_only=True) db.session.add(management_section) db.session.flush() checkbox_field = RegistrationFormField(parent_id=management_section.id, registration_form=dummy_regform) _fill_form_field_with_data(checkbox_field, { 'input_type': 'checkbox', 'is_required': True, 'title': 'Checkbox' }) db.session.add(checkbox_field) db.session.flush() # Create a registration data = { boolean_field.html_field_name: True, multi_choice_field.html_field_name: { choice_uuid: 2 }, checkbox_field.html_field_name: True, 'email': dummy_user.email, 'first_name': dummy_user.first_name, 'last_name': dummy_user.last_name } reg = create_registration(dummy_regform, data, invitation=None, management=True, notify_user=False) assert reg.data_by_field[boolean_field.id].data assert reg.data_by_field[multi_choice_field.id].data == {choice_uuid: 2} assert reg.data_by_field[checkbox_field.id].data # Modify the registration data = { boolean_field.html_field_name: True, multi_choice_field.html_field_name: { choice_uuid: 1 }, checkbox_field.html_field_name: False, } modify_registration(reg, data, management=False, notify_user=False) assert reg.data_by_field[boolean_field.id].data assert reg.data_by_field[multi_choice_field.id].data == {choice_uuid: 1} # Assert that the manager field is not changed assert reg.data_by_field[checkbox_field.id].data # Modify as a manager data = { multi_choice_field.html_field_name: { choice_uuid: 3 }, checkbox_field.html_field_name: False, } modify_registration(reg, data, management=True, notify_user=False) assert reg.data_by_field[boolean_field.id].data assert reg.data_by_field[multi_choice_field.id].data == {choice_uuid: 3} assert not reg.data_by_field[checkbox_field.id].data # Add a new field after registering new_multi_choice_field = RegistrationFormField( parent_id=user_section.id, registration_form=dummy_regform) _fill_form_field_with_data( new_multi_choice_field, { 'input_type': 'multi_choice', 'with_extra_slots': False, 'title': 'Multi Choice', 'choices': [ { 'caption': 'A', 'id': 'new:test3', 'is_enabled': True }, ] }) db.session.add(new_multi_choice_field) db.session.flush() modify_registration(reg, {}, management=False, notify_user=False) assert reg.data_by_field[boolean_field.id].data assert reg.data_by_field[multi_choice_field.id].data == {choice_uuid: 3} assert not reg.data_by_field[checkbox_field.id].data # Assert that the new field got a default value assert reg.data_by_field[new_multi_choice_field.id].data == {} # Remove a field after registering multi_choice_field.is_deleted = True db.session.flush() data = { multi_choice_field.html_field_name: { choice_uuid: 7 }, } modify_registration(reg, data, management=True, notify_user=False) assert reg.data_by_field[boolean_field.id].data # Assert that the removed field keeps its old value assert reg.data_by_field[multi_choice_field.id].data == {choice_uuid: 3} assert not reg.data_by_field[checkbox_field.id].data assert reg.data_by_field[new_multi_choice_field.id].data == {}