def test_register_from_invite_when_user_registers_in_another_browser(
    client,
    api_user_active,
    mock_get_user_by_email,
    mock_accept_invite,
):
    invited_user = InvitedUser(api_user_active.id, api_user_active.id, "",
                               api_user_active.email_address,
                               ["manage_users"],
                               "pending",
                               datetime.utcnow(),
                               'sms_auth',
                               [])
    with client.session_transaction() as session:
        session['invited_user'] = invited_user.serialize()
    response = client.post(
        url_for('main.register_from_invite'),
        data={
            'name': 'Registered in another Browser',
            'email_address': api_user_active.email_address,
            'mobile_number': api_user_active.mobile_number,
            'service': str(api_user_active.id),
            'password': '******',
            'auth_type': 'sms_auth'
        }
    )
    assert response.status_code == 302
    assert response.location == url_for('main.verify', _external=True)
def test_invite_goes_in_session(
    client_request,
    mocker,
    sample_invite,
    mock_get_service,
    api_user_active,
    mock_check_invite_token,
    mock_get_user_by_email,
    mock_get_users_by_service,
    mock_add_user_to_service,
    mock_accept_invite,
):
    invite = InvitedUser(**sample_invite)
    invite.email_address = '*****@*****.**'
    mocker.patch('app.invite_api_client.check_token', return_value=invite)

    client_request.get(
        'main.accept_invite',
        token='thisisnotarealtoken',
        _expected_status=302,
        _expected_redirect=url_for(
            'main.service_dashboard',
            service_id=SERVICE_ONE_ID,
            _external=True,
        ),
        _follow_redirects=False,
    )

    with client_request.session_transaction() as session:
        assert session['invited_user']['email_address'] == invite.email_address
예제 #3
0
def test_register_from_invite_when_user_registers_in_another_browser(
    client,
    api_user_active,
    mock_get_user_by_email,
    mock_accept_invite,
):
    invited_user = InvitedUser(
        {
            'id': api_user_active['id'],
            'service': api_user_active['id'],
            'from_user': "",
            'email_address': api_user_active['email_address'],
            'permissions': ["manage_users"],
            'status': "pending",
            'created_at': datetime.utcnow(),
            'auth_type': 'sms_auth',
            'folder_permissions': [],
            'blocked': False
        }
    )
    with client.session_transaction() as session:
        session['invited_user'] = invited_user.serialize()
    response = client.post(
        url_for('main.register_from_invite'),
        data={
            'name': 'Registered in another Browser',
            'email_address': api_user_active['email_address'],
            'mobile_number': api_user_active['mobile_number'],
            'service': str(api_user_active['id']),
            'password': '******',
            'auth_type': 'sms_auth'
        }
    )
    assert response.status_code == 302
    assert response.location == url_for('main.verify', _external=True)
예제 #4
0
def test_invite_user_with_email_auth_service(
    client_request,
    service_one,
    active_user_with_permissions,
    sample_invite,
    email_address,
    gov_user,
    mocker,
    auth_type,
    mock_get_template_folders,
):
    service_one['permissions'].append('email_auth')
    sample_invite['email_address'] = '*****@*****.**'

    data = [InvitedUser(**sample_invite)]
    assert is_gov_user(email_address) == gov_user
    mocker.patch('app.invite_api_client.get_invites_for_service',
                 return_value=data)
    mocker.patch('app.user_api_client.get_users_for_service',
                 return_value=[active_user_with_permissions])
    mocker.patch('app.invite_api_client.create_invite',
                 return_value=InvitedUser(**sample_invite))
    page = client_request.post(
        'main.invite_user',
        service_id=SERVICE_ONE_ID,
        _data={
            'email_address': email_address,
            'view_activity': 'y',
            'send_messages': 'y',
            'manage_templates': 'y',
            'manage_service': 'y',
            'manage_api_keys': 'y',
            'login_authentication': auth_type,
        },
        _follow_redirects=True,
        _expected_status=200,
    )

    assert page.h1.string.strip() == 'Team members'
    flash_banner = page.find('div',
                             class_='banner-default-with-tick').string.strip()
    assert flash_banner == 'Invite sent to [email protected]'

    expected_permissions = {
        'manage_api_keys', 'manage_service', 'manage_templates',
        'send_messages', 'view_activity'
    }

    app.invite_api_client.create_invite.assert_called_once_with(
        sample_invite['from_user'], sample_invite['service'], email_address,
        expected_permissions, auth_type, [])
def activate_user(user_id):
    user = User.from_id(user_id)
    # the user will have a new current_session_id set by the API - store it in the cookie for future requests
    session['current_session_id'] = user.current_session_id
    organisation_id = session.get('organisation_id')
    activated_user = user.activate()
    activated_user.login()

    invited_user = InvitedUser.from_session()
    if invited_user:
        service_id = _add_invited_user_to_service(invited_user)
        service = Service.from_id(service_id)
        if service.has_permission('broadcast'):
            return redirect(
                url_for('main.broadcast_tour',
                        service_id=service.id,
                        step_index=1))
        return redirect(
            url_for('main.service_dashboard', service_id=service_id))

    invited_org_user = InvitedOrgUser.from_session()
    if invited_org_user:
        user_api_client.add_user_to_organisation(invited_org_user.organisation,
                                                 session['user_details']['id'])

    if organisation_id:
        return redirect(
            url_for('main.organisation_dashboard', org_id=organisation_id))
    else:
        return redirect(url_for('main.add_service', first='first'))
def test_existing_email_auth_user_with_phone_can_set_sms_auth(
    client_request,
    api_user_active,
    service_one,
    sample_invite,
    mock_get_users_by_service,
    mock_get_unknown_user_by_email,
    mock_accept_invite,
    mock_update_user_attribute,
    mock_add_user_to_service,
    mocker
):
    sample_invite['email_address'] = api_user_active.email_address
    service_one['permissions'].append('email_auth')
    sample_invite['auth_type'] = 'sms_auth'

    mocker.patch('app.invite_api_client.check_token', return_value=InvitedUser(**sample_invite))

    client_request.get(
        'main.accept_invite',
        token='thisisnotarealtoken',
        _expected_status=302,
        _expected_redirect=url_for('main.service_dashboard', service_id=service_one['id'], _external=True),
    )

    mock_get_unknown_user_by_email.assert_called_once_with(sample_invite['email_address'])
    mock_update_user_attribute.assert_called_once_with(USER_ONE_ID, auth_type='sms_auth')
def test_existing_email_auth_user_without_phone_cannot_set_sms_auth(
    client_request,
    api_user_active,
    service_one,
    sample_invite,
    mock_get_users_by_service,
    mock_accept_invite,
    mock_update_user_attribute,
    mock_add_user_to_service,
    mocker
):
    sample_invite['email_address'] = api_user_active.email_address

    service_one['permissions'].append('email_auth')

    api_user_active.auth_type = 'email_auth'
    api_user_active.mobile_number = None
    sample_invite['auth_type'] = 'sms_auth'

    mocker.patch('app.main.views.invites.user_api_client.get_user_by_email', return_value=api_user_active)
    mocker.patch('app.main.views.invites.service_api_client.get_service', return_value={'data': service_one})
    mocker.patch('app.invite_api_client.check_token', return_value=InvitedUser(**sample_invite))

    client_request.get(
        'main.accept_invite',
        token='thisisnotarealtoken',
        _expected_status=302,
        _expected_redirect=url_for('main.service_dashboard', service_id=service_one['id'], _external=True),
    )

    assert not mock_update_user_attribute.called
def test_existing_user_doesnt_get_auth_changed_by_service_without_permission(
    client_request,
    api_user_active,
    service_one,
    sample_invite,
    mock_get_user_by_email,
    mock_get_users_by_service,
    mock_accept_invite,
    mock_update_user_attribute,
    mock_add_user_to_service,
    mocker
):
    sample_invite['email_address'] = api_user_active.email_address

    assert 'email_auth' not in service_one['permissions']

    sample_invite['auth_type'] = 'email_auth'
    mocker.patch('app.main.views.invites.service_api_client.get_service', return_value={'data': service_one})
    mocker.patch('app.invite_api_client.check_token', return_value=InvitedUser(**sample_invite))

    client_request.get(
        'main.accept_invite',
        token='thisisnotarealtoken',
        _expected_status=302,
        _expected_redirect=url_for('main.service_dashboard', service_id=service_one['id'], _external=True),
    )

    assert not mock_update_user_attribute.called
def test_signed_in_existing_user_cannot_use_anothers_invite(
    client_request,
    mocker,
    api_user_active,
    sample_invite,
    mock_get_user,
    mock_accept_invite,
    mock_get_service,
):
    invite = InvitedUser(**sample_invite)
    mocker.patch('app.invite_api_client.check_token', return_value=invite)
    mocker.patch('app.user_api_client.get_users_for_service', return_value=[api_user_active])

    page = client_request.get(
        'main.accept_invite',
        token='thisisnotarealtoken',
        _follow_redirects=True,
        _expected_status=403,
    )
    assert page.h1.string.strip() == '403'
    flash_banners = page.find_all('div', class_='banner-dangerous')
    assert len(flash_banners) == 1
    banner_contents = flash_banners[0].text.strip()
    assert "You’re signed in as [email protected]." in banner_contents
    assert "This invite is for another email address." in banner_contents
    assert "Sign out and click the link again to accept this invite." in banner_contents
    assert mock_accept_invite.call_count == 0
def test_existing_user_of_service_get_redirected_to_signin(
    client,
    mocker,
    api_user_active,
    sample_invite,
    mock_get_service,
    mock_get_user_by_email,
    mock_accept_invite,
):
    sample_invite['email_address'] = api_user_active.email_address
    invite = InvitedUser(**sample_invite)
    mocker.patch('app.invite_api_client.check_token', return_value=invite)
    mocker.patch('app.user_api_client.get_users_for_service', return_value=[api_user_active])

    response = client.get(url_for('main.accept_invite', token='thisisnotarealtoken'), follow_redirects=True)
    assert response.status_code == 200
    page = BeautifulSoup(response.data.decode('utf-8'), 'html.parser')
    assert (
        page.h1.string,
        page.select('main p')[0].text.strip(),
    ) == (
        'You need to sign in again',
        'We signed you out because you haven’t used Notify for a while.',
    )
    assert mock_accept_invite.call_count == 1
예제 #11
0
def accept_invite(token):
    try:
        invited_user = InvitedUser.from_token(token)
    except InviteTokenError as exception:
        flash(_(str(exception)))
        return redirect(url_for("main.sign_in"))

    if not current_user.is_anonymous and current_user.email_address.lower() != invited_user.email_address.lower():
        message = Markup(
            _(
                "You’re signed in as %(email)s. This invite is for another email address. "
                + "<a href=%(href)s>Sign out</a> and click the link again to accept this invite.",
                email=current_user.email_address,
                href=url_for("main.sign_out", _external=True),
            )
        )
        flash(message=message)

        abort(403)

    if invited_user.status == "cancelled":
        service = Service.from_id(invited_user.service)
        return render_template(
            "views/cancelled-invitation.html",
            from_user=invited_user.from_user.name,
            service_name=service.name,
        )

    if invited_user.status == "accepted":
        session.pop("invited_user", None)
        return redirect(url_for("main.service_dashboard", service_id=invited_user.service))

    session["invited_user"] = invited_user.serialize()

    existing_user = User.from_email_address_or_none(invited_user.email_address)

    if existing_user:
        invited_user.accept_invite()
        if existing_user in Users(invited_user.service):
            return redirect(url_for("main.service_dashboard", service_id=invited_user.service))
        else:
            service = Service.from_id(invited_user.service)
            # if the service you're being added to can modify auth type, then check if this is relevant
            if service.has_permission("email_auth") and (
                # they have a phone number, we want them to start using it. if they dont have a mobile we just
                # ignore that option of the invite
                (existing_user.mobile_number and invited_user.auth_type == "sms_auth")
                or
                # we want them to start sending emails. it's always valid, so lets always update
                invited_user.auth_type == "email_auth"
            ):
                existing_user.update(auth_type=invited_user.auth_type)
            existing_user.add_to_service(
                service_id=invited_user.service,
                permissions=invited_user.permissions,
                folder_permissions=invited_user.folder_permissions,
            )
            return redirect(url_for("main.service_dashboard", service_id=service.id))
    else:
        return redirect(url_for("main.register_from_invite"))
예제 #12
0
def invite_user(service_id):

    form = InviteUserForm(
        invalid_email_address=current_user.email_address,
        all_template_folders=current_service.all_template_folders,
        folder_permissions=[
            f['id'] for f in current_service.all_template_folders
        ])

    service_has_email_auth = current_service.has_permission('email_auth')
    if not service_has_email_auth:
        form.login_authentication.data = 'sms_auth'

    if form.validate_on_submit():
        email_address = form.email_address.data
        invited_user = InvitedUser.create(
            current_user.id,
            service_id,
            email_address,
            form.permissions,
            form.login_authentication.data,
            form.folder_permissions.data,
        )

        flash('{} {}'.format(_l('Invite sent to'), invited_user.email_address),
              'default_with_tick')
        return redirect(url_for('.manage_users', service_id=service_id))

    return render_template(
        'views/invite-user.html',
        form=form,
        service_has_email_auth=service_has_email_auth,
        mobile_number=True,
    )
예제 #13
0
def _add_invited_user_to_service(invited_user):
    invitation = InvitedUser(invited_user)
    user = User.from_id(session['user_id'])
    service_id = invited_user['service']
    user.add_to_service(service_id, invitation.permissions,
                        invitation.folder_permissions)
    return service_id
예제 #14
0
 def create_invite(self, invite_from_id, service_id, email_address,
                   permissions, auth_type, folder_permissions):
     data = {
         'service':
         str(service_id),
         'email_address':
         email_address,
         'from_user':
         invite_from_id,
         'permissions':
         ','.join(
             sorted(
                 translate_permissions_from_admin_roles_to_db(
                     permissions))),
         'auth_type':
         auth_type,
         'invite_link_host':
         self.admin_url,
         'folder_permissions':
         folder_permissions,
     }
     data = _attach_current_user(data)
     resp = self.post(url='/service/{}/invite'.format(service_id),
                      data=data)
     return InvitedUser(**resp['data'])
예제 #15
0
def invite_user(service_id, user_id=None):

    if current_service.has_permission('broadcast'):
        form_class = BroadcastInviteUserForm
    else:
        form_class = InviteUserForm

    form = form_class(
        invalid_email_address=current_user.email_address,
        all_template_folders=current_service.all_template_folders,
        folder_permissions=[
            f['id'] for f in current_service.all_template_folders
        ])

    if user_id:
        user_to_invite = User.from_id(user_id)
        if user_to_invite.belongs_to_service(current_service.id):
            return render_template(
                'views/user-already-team-member.html',
                user_to_invite=user_to_invite,
            )
        if current_service.invite_pending_for(user_to_invite.email_address):
            return render_template(
                'views/user-already-invited.html',
                user_to_invite=user_to_invite,
            )
        if not user_to_invite.default_organisation:
            abort(403)
        if user_to_invite.default_organisation.id != current_service.organisation_id:
            abort(403)
        form.email_address.data = user_to_invite.email_address
    else:
        user_to_invite = None

    service_has_email_auth = current_service.has_permission('email_auth')
    if not service_has_email_auth:
        form.login_authentication.data = 'sms_auth'

    if form.validate_on_submit():
        email_address = form.email_address.data
        invited_user = InvitedUser.create(
            current_user.id,
            service_id,
            email_address,
            form.permissions,
            form.login_authentication.data,
            form.folder_permissions.data,
        )

        flash('Invite sent to {}'.format(invited_user.email_address),
              'default_with_tick')
        return redirect(url_for('.manage_users', service_id=service_id))

    return render_template(
        'views/invite-user.html',
        form=form,
        service_has_email_auth=service_has_email_auth,
        mobile_number=True,
        user_to_invite=user_to_invite,
    )
예제 #16
0
def _add_invited_user_to_service(invited_user):
    invitation = InvitedUser(invited_user)
    user = User.from_id(session["user_id"])
    service_id = invited_user["service"]
    user_api_client.add_user_to_service(service_id, user.id,
                                        invitation.permissions,
                                        invitation.folder_permissions)
    return service_id
예제 #17
0
def _add_invited_user_to_service(invited_user):
    invitation = InvitedUser(**invited_user)
    user = user_api_client.get_user(session['user_id'])
    service_id = invited_user['service']
    user_api_client.add_user_to_service(service_id, user.id,
                                        invitation.permissions,
                                        invitation.folder_permissions)
    return service_id
예제 #18
0
def accept_invite(token):
    invited_user = InvitedUser.from_token(token)

    if not current_user.is_anonymous and current_user.email_address.lower(
    ) != invited_user.email_address.lower():
        message = Markup("""
            You’re signed in as {}.
            This invite is for another email address.
            <a href={} class="govuk-link govuk-link--no-visited-state">Sign out</a>
            and click the link again to accept this invite.
            """.format(current_user.email_address,
                       url_for("main.sign_out", _external=True)))

        flash(message=message)

        abort(403)

    if invited_user.status == 'cancelled':
        service = Service.from_id(invited_user.service)
        return render_template('views/cancelled-invitation.html',
                               from_user=invited_user.from_user.name,
                               service_name=service.name)

    if invited_user.status == 'accepted':
        session.pop('invited_user', None)
        return redirect(
            url_for('main.service_dashboard', service_id=invited_user.service))

    session['invited_user'] = invited_user.serialize()

    existing_user = User.from_email_address_or_none(invited_user.email_address)

    if existing_user:
        invited_user.accept_invite()
        if existing_user in Users(invited_user.service):
            return redirect(
                url_for('main.service_dashboard',
                        service_id=invited_user.service))
        else:
            service = Service.from_id(invited_user.service)
            # if the service you're being added to can modify auth type, then check if this is relevant
            if service.has_permission('email_auth') and (
                    # they have a phone number, we want them to start using it. if they dont have a mobile we just
                    # ignore that option of the invite
                (existing_user.mobile_number
                 and invited_user.auth_type == 'sms_auth') or
                    # we want them to start sending emails. it's always valid, so lets always update
                    invited_user.auth_type == 'email_auth'):
                existing_user.update(auth_type=invited_user.auth_type)
            existing_user.add_to_service(
                service_id=invited_user.service,
                permissions=invited_user.permissions,
                folder_permissions=invited_user.folder_permissions,
            )
            return redirect(
                url_for('main.service_dashboard', service_id=service.id))
    else:
        return redirect(url_for('main.register_from_invite'))
예제 #19
0
def cancel_invited_user(service_id, invited_user_id):
    current_service.cancel_invite(invited_user_id)

    invited_user = InvitedUser.by_id_and_service_id(service_id,
                                                    invited_user_id)

    flash(f'Invitation cancelled for {invited_user.email_address}',
          'default_with_tick')
    return redirect(url_for('main.manage_users', service_id=service_id))
예제 #20
0
def test_register_from_invite(
    client,
    fake_uuid,
    mock_email_is_not_already_in_use,
    mock_register_user,
    mock_send_verify_code,
    mock_accept_invite,
):
    invited_user = InvitedUser(
        {
            'id': fake_uuid,
            'service': fake_uuid,
            'from_user': "",
            'email_address': "*****@*****.**",
            'permissions': ["manage_users"],
            'status': "pending",
            'created_at': datetime.utcnow(),
            'auth_type': 'sms_auth',
            'folder_permissions': [],
            'blocked': True
        }
    )
    with client.session_transaction() as session:
        session['invited_user'] = invited_user.serialize()
    response = client.post(
        url_for('main.register_from_invite'),
        data={
            'name': 'Registered in another Browser',
            'email_address': invited_user.email_address,
            'mobile_number': '+16502532222',
            'service': str(invited_user.id),
            'password': '******',
            'auth_type': 'sms_auth'
        }
    )
    assert response.status_code == 302
    assert response.location == url_for('main.verify', _external=True)
    mock_register_user.assert_called_once_with(
        'Registered in another Browser',
        invited_user.email_address,
        '+16502532222',
        'rZXdoBkuz6U37DDXIaAfpBR1OTJcSZOGICLCz4dMtmopS3KsVauIrtcgqs1eU02',
        'sms_auth',
    )
예제 #21
0
def test_invited_user_from_session_uses_id(client, mocker,
                                           mock_get_invited_user_by_id):
    session_dict = {'invited_user_id': USER_ONE_ID}
    mocker.patch.dict('app.models.user.session',
                      values=session_dict,
                      clear=True)

    assert InvitedUser.from_session().id == USER_ONE_ID

    mock_get_invited_user_by_id.assert_called_once_with(USER_ONE_ID)
예제 #22
0
def test_register_from_invite(
    client,
    fake_uuid,
    mock_email_is_not_already_in_use,
    mock_register_user,
    mock_send_verify_code,
    mock_accept_invite,
):
    invited_user = InvitedUser({
        "id": fake_uuid,
        "service": fake_uuid,
        "from_user": "",
        "email_address": "*****@*****.**",
        "permissions": ["manage_users"],
        "status": "pending",
        "created_at": datetime.utcnow(),
        "auth_type": "sms_auth",
        "folder_permissions": [],
        "blocked": True,
    })
    with client.session_transaction() as session:
        session["invited_user"] = invited_user.serialize()
    response = client.post(
        url_for("main.register_from_invite"),
        data={
            "name": "Registered in another Browser",
            "email_address": invited_user.email_address,
            "mobile_number": "+16502532222",
            "service": str(invited_user.id),
            "password":
            "******",
            "auth_type": "sms_auth",
        },
    )
    assert response.status_code == 302
    assert response.location == url_for("main.verify", _external=True)
    mock_register_user.assert_called_once_with(
        "Registered in another Browser",
        invited_user.email_address,
        "+16502532222",
        "rZXdoBkuz6U37DDXIaAfpBR1OTJcSZOGICLCz4dMtmopS3KsVauIrtcgqs1eU02",
        "sms_auth",
    )
예제 #23
0
def test_register_from_invite_when_user_registers_in_another_browser(
    client,
    api_user_active,
    mock_get_user_by_email,
    mock_accept_invite,
):
    invited_user = InvitedUser({
        "id":
        api_user_active["id"],
        "service":
        api_user_active["id"],
        "from_user":
        "",
        "email_address":
        api_user_active["email_address"],
        "permissions": ["manage_users"],
        "status":
        "pending",
        "created_at":
        datetime.utcnow(),
        "auth_type":
        "sms_auth",
        "folder_permissions": [],
        "blocked":
        False,
    })
    with client.session_transaction() as session:
        session["invited_user"] = invited_user.serialize()
    response = client.post(
        url_for("main.register_from_invite"),
        data={
            "name": "Registered in another Browser",
            "email_address": api_user_active["email_address"],
            "mobile_number": api_user_active["mobile_number"],
            "service": str(api_user_active["id"]),
            "password":
            "******",
            "auth_type": "sms_auth",
        },
    )
    assert response.status_code == 302
    assert response.location == url_for("main.verify", _external=True)
예제 #24
0
def test_register_from_invite(
    client,
    fake_uuid,
    mock_email_is_not_already_in_use,
    mock_register_user,
    mock_send_verify_code,
    mock_accept_invite,
    extra_data,
):
    invited_user = InvitedUser({
        'id': fake_uuid,
        'service': fake_uuid,
        'from_user': "",
        'email_address': "*****@*****.**",
        'permissions': ["manage_users"],
        'status': "pending",
        'created_at': datetime.utcnow(),
        'auth_type': 'sms_auth',
        'folder_permissions': [],
    })
    with client.session_transaction() as session:
        session['invited_user'] = invited_user.serialize()
    response = client.post(
        url_for('main.register_from_invite'),
        data=dict(name='Registered in another Browser',
                  email_address=invited_user.email_address,
                  mobile_number='+4407700900460',
                  service=str(invited_user.id),
                  password='******',
                  auth_type='sms_auth',
                  **extra_data),
    )
    assert response.status_code == 302
    assert response.location == url_for('main.verify', _external=True)
    mock_register_user.assert_called_once_with(
        'Registered in another Browser',
        invited_user.email_address,
        '+4407700900460',
        'somreallyhardthingtoguess',
        'sms_auth',
    )
예제 #25
0
def sign_in():
    if current_user and current_user.is_authenticated:
        return redirect(url_for("main.show_accounts_or_dashboard"))

    form = LoginForm()

    if form.validate_on_submit():

        login_data = {
            "user-agent": request.headers["User-Agent"],
            "location": _geolocate_ip(get_remote_addr(request)),
        }

        user = User.from_email_address_and_password_or_none(form.email_address.data, form.password.data, login_data)

        if user and user.locked:
            flash(
                _("Your account has been locked after {} sign-in attempts. Please email us at [email protected]").format(
                    user.max_failed_login_count
                )
            )
            abort(400)

        if user and user.state == "pending":
            return redirect(url_for("main.resend_email_verification"))

        if user and session.get("invited_user"):
            invited_user = InvitedUser.from_session()
            if user.email_address.lower() != invited_user.email_address.lower():
                flash(_("You cannot accept an invite for another person."))
                session.pop("invited_user", None)
                abort(403)
            else:
                invited_user.accept_invite()
        requires_email_login = user and user.requires_email_login
        if user and user.sign_in():
            if user.sms_auth and not requires_email_login:
                return redirect(url_for(".two_factor_sms_sent", next=request.args.get("next")))
            if user.email_auth or requires_email_login:
                args = {"requires_email_login": True} if requires_email_login else {}
                return redirect(url_for(".two_factor_email_sent", **args))

        # Vague error message for login in case of user not known, inactive or password not verified
        flash(_("The email address or password you entered is incorrect."))

    other_device = current_user.logged_in_elsewhere()
    return render_template(
        "views/signin.html",
        form=form,
        again=bool(request.args.get("next")),
        other_device=other_device,
    )
def test_accepting_invite_removes_invite_from_session(
    client_request,
    mocker,
    sample_invite,
    mock_get_service,
    service_one,
    mock_check_invite_token,
    mock_get_user_by_email,
    mock_get_users_by_service,
    mock_add_user_to_service,
    mock_accept_invite,
    mock_get_service_templates,
    mock_get_template_statistics,
    mock_get_jobs,
    mock_get_service_statistics,
    mock_get_template_folders,
    mock_get_usage,
    mock_get_inbound_sms_summary,
    fake_uuid,
    user,
    landing_page_title,
):
    invite = InvitedUser(**sample_invite)
    user = user(fake_uuid)
    invite.email_address = user.email_address

    mocker.patch('app.invite_api_client.check_token', return_value=invite)
    client_request.login(user)

    page = client_request.get(
        'main.accept_invite',
        token='thisisnotarealtoken',
        _follow_redirects=True,
    )
    assert normalize_spaces(page.select_one('h1').text) == landing_page_title

    with client_request.session_transaction() as session:
        assert 'invited_user' not in session
def test_register_from_invite(
    client,
    fake_uuid,
    mock_email_is_not_already_in_use,
    mock_register_user,
    mock_send_verify_code,
    mock_accept_invite,
):
    invited_user = InvitedUser(fake_uuid, fake_uuid, "",
                               "*****@*****.**",
                               ["manage_users"],
                               "pending",
                               datetime.utcnow(),
                               'sms_auth',
                               [])
    with client.session_transaction() as session:
        session['invited_user'] = invited_user.serialize()
    response = client.post(
        url_for('main.register_from_invite'),
        data={
            'name': 'Registered in another Browser',
            'email_address': invited_user.email_address,
            'mobile_number': '+4407700900460',
            'service': str(invited_user.id),
            'password': '******',
            'auth_type': 'sms_auth'
        }
    )
    assert response.status_code == 302
    assert response.location == url_for('main.verify', _external=True)
    mock_register_user.assert_called_once_with(
        'Registered in another Browser',
        invited_user.email_address,
        '+4407700900460',
        'somreallyhardthingtoguess',
        'sms_auth',
    )
예제 #28
0
def sign_in():
    if current_user and current_user.is_authenticated:
        return redirect(url_for('main.show_accounts_or_dashboard'))

    form = LoginForm()
    password_reset_url = url_for('.forgot_password',
                                 next=request.args.get('next'))
    redirect_url = request.args.get('next')

    if form.validate_on_submit():

        user = User.from_email_address_and_password_or_none(
            form.email_address.data, form.password.data)

        if user and user.state == 'pending':
            return redirect(
                url_for('main.resend_email_verification', next=redirect_url))

        if user and session.get('invited_user'):
            invited_user = InvitedUser.from_session()
            if user.email_address.lower() != invited_user.email_address.lower(
            ):
                flash("You cannot accept an invite for another person.")
                session.pop('invited_user', None)
                abort(403)
            else:
                invited_user.accept_invite()
        if user and user.sign_in():
            if user.sms_auth:
                return redirect(url_for('.two_factor', next=redirect_url))
            if user.email_auth:
                return redirect(
                    url_for('.two_factor_email_sent', next=redirect_url))

        # Vague error message for login in case of user not known, locked, inactive or password not verified
        flash(
            Markup(
                (f"The email address or password you entered is incorrect."
                 f" <a href={password_reset_url}>Forgotten your password?</a>"
                 )))

    other_device = current_user.logged_in_elsewhere()
    return render_template('views/signin.html',
                           form=form,
                           again=bool(redirect_url),
                           other_device=other_device,
                           password_reset_url=password_reset_url)
def test_shows_registration_page_from_invite(
    client_request,
    fake_uuid,
    email_address,
    expected_value,
):
    with client_request.session_transaction() as session:
        session['invited_user'] = InvitedUser(
            fake_uuid, fake_uuid, "",
            email_address,
            ["manage_users"],
            "pending",
            datetime.utcnow(),
            'sms_auth', []
        ).serialize()
    page = client_request.get('main.register_from_invite')
    assert page.select_one('input[name=name]')['value'] == expected_value
예제 #30
0
def sign_in():
    if current_user and current_user.is_authenticated:
        return redirect(url_for('main.show_accounts_or_dashboard'))

    form = LoginForm()

    if form.validate_on_submit():

        login_data = {
            "user-agent": request.headers["User-Agent"],
            "location": _geolocate_ip(request.remote_addr)
        }

        user = User.from_email_address_and_password_or_none(
            form.email_address.data, form.password.data, login_data)

        if user and user.state == 'pending':
            return redirect(url_for('main.resend_email_verification'))

        if user and session.get('invited_user'):
            invited_user = InvitedUser.from_session()
            if user.email_address.lower() != invited_user.email_address.lower(
            ):
                flash("You can't accept an invite for another person.")
                session.pop('invited_user', None)
                abort(403)
            else:
                invited_user.accept_invite()
        if user and user.sign_in():
            if user.sms_auth:
                return redirect(
                    url_for('.two_factor', next=request.args.get('next')))
            if user.email_auth:
                return redirect(url_for('.two_factor_email_sent'))

        # Vague error message for login in case of user not known, locked, inactive or password not verified
        flash(_("The email address or password you entered is incorrect."))

    other_device = current_user.logged_in_elsewhere()
    return render_template('views/signin.html',
                           form=form,
                           again=bool(request.args.get('next')),
                           other_device=other_device)