Пример #1
0
def test_profile(client):
    """Test an affilated user profile and ORCID data retrieval and a user profile that doesn't hava an ORCID."""
    org = Organisation.get(name="THE ORGANISATION")
    test_user = User.create(email="*****@*****.**",
                            organisation=org,
                            orcid="ABC123",
                            confirmed=True)
    OrcidToken.create(user=test_user,
                      org=org,
                      scope="/read-limited,/activities/update",
                      access_token="ABC1234")
    resp = client.login(test_user, follow_redirects=True)
    resp = client.get("/profile", follow_redirects=True)

    assert resp.status_code == 200
    assert b"ABC123" in resp.data
    client.logout()

    # Test a user profile that doesn't hava an ORCID.
    user = User.select().where(User.organisation == org,
                               User.orcid.is_null()).first()
    resp = client.login(user, follow_redirects=True)
    resp = client.get("/profile")
    assert resp.status_code == 302
    assert "/link" in resp.location
Пример #2
0
def test_orcid_login_callback_researcher_flow(patch, patch2, request_ctx):
    """Test login from orcid callback function for researcher and display profile."""
    org = Organisation.create(name="THE ORGANISATION",
                              tuakiri_name="THE ORGANISATION",
                              confirmed=True,
                              orcid_client_id="CLIENT ID",
                              orcid_secret="Client Secret",
                              city="CITY",
                              country="COUNTRY",
                              disambiguated_id="ID",
                              disambiguation_source="SOURCE",
                              is_email_sent=True)
    u = User.create(email="*****@*****.**",
                    name="TEST USER",
                    roles=Role.RESEARCHER,
                    orcid="123",
                    confirmed=True,
                    organisation=org)
    UserOrg.create(user=u, org=org, is_admin=False)
    token = utils.generate_confirmation_token(email=u.email, org=org.name)
    UserInvitation.create(email=u.email,
                          token=token,
                          affiliations=Affiliation.EMP)
    OrcidToken.create(user=u,
                      org=org,
                      scope='/read-limited,/activities/update')
    with request_ctx():
        request.args = {"invitation_token": token, "state": "xyz"}
        session['oauth_state'] = "xyz"
        resp = authcontroller.orcid_login_callback(request)
        assert resp.status_code == 302
        # display profile
        assert resp.location.startswith("/profile")
Пример #3
0
def test_field_is_updated(testdb):
    u = User.create(email="*****@*****.**", name="TESTER")
    u.save()
    u.save()
    assert not u.field_is_updated("name")
    u.name = "NEW VALUE"
    assert u.field_is_updated("name")
Пример #4
0
def test_link_orcid_auth_callback(name, request_ctx):
    """Test ORCID callback - the user authorized the organisation access to the ORCID profile."""
    with request_ctx("/auth?state=xyz") as ctx:
        org = Organisation(name="THE ORGANISATION", confirmed=True)
        org.save()

        test_user = User.create(
            name=name,
            email="*****@*****.**",
            organisation=org,
            orcid="ABC123",
            confirmed=True)
        orcidtoken = OrcidToken.create(
            user=test_user,
            org=org,
            scope="/read-limited,/activities/update",
            access_token="ABC1234")
        login_user(test_user, remember=True)
        session['oauth_state'] = "xyz"
        rv = ctx.app.full_dispatch_request()
        assert rv.status_code == 302, "If the user is already affiliated, the user should be redirected ..."
        assert "profile" in rv.location, "redirection to 'profile' showing the ORCID"

        u = User.get(id=test_user.id)
        orcidtoken = OrcidToken.get(user=u)
        assert u.orcid == "ABC-123-456-789"
        assert orcidtoken.access_token == "ABC1234"
        if name:
            assert u.name == name, "The user name should be changed"
        else:
            assert u.name == "NEW TEST", "the user name should be set from record coming from ORCID"
Пример #5
0
def test_orcid_callback(request_ctx):
    """Test orcid researcher deny flow."""
    org = Organisation.create(name="THE ORGANISATION",
                              tuakiri_name="THE ORGANISATION",
                              confirmed=True,
                              orcid_client_id="CLIENT ID",
                              orcid_secret="Client Secret",
                              city="CITY",
                              country="COUNTRY",
                              disambiguated_id="ID",
                              disambiguation_source="SOURCE",
                              is_email_sent=True)

    user = User.create(email="*****@*****.**",
                       name="TEST USER",
                       roles=Role.TECHNICAL,
                       orcid="123",
                       confirmed=True,
                       organisation=org)
    UserOrg.create(user=user, org=org, is_admin=True)

    with request_ctx("/auth") as ctx:
        login_user(user, remember=True)
        request.args = ImmutableMultiDict([('error', 'access_denied'),
                                           ('login', '2')])
        rv = ctx.app.full_dispatch_request()
        assert rv.status_code == 302
        assert rv.location.startswith("/link")
Пример #6
0
def test_orcid_login(request_ctx):
    """Test login from orcid."""
    org = Organisation.create(name="THE ORGANISATION",
                              tuakiri_name="THE ORGANISATION",
                              confirmed=False,
                              orcid_client_id="CLIENT ID",
                              orcid_secret="Client Secret",
                              city="CITY",
                              country="COUNTRY",
                              disambiguated_id="ID",
                              disambiguation_source="SOURCE",
                              is_email_sent=True)
    u = User.create(email="*****@*****.**",
                    name="TEST USER",
                    roles=Role.TECHNICAL,
                    orcid="123",
                    confirmed=True,
                    organisation=org)
    UserOrg.create(user=u, org=org, is_admin=True)
    token = utils.generate_confirmation_token(email=u.email, org=org.name)
    with request_ctx("/orcid/login/" + token.decode("utf-8")) as ctxx:
        rv = ctxx.app.full_dispatch_request()
        assert rv.status_code == 200
        orcid_authorize = OrcidAuthorizeCall.get(method="GET")
        assert "&email=test123%40test.test.net" in orcid_authorize.url
Пример #7
0
def test_link_orcid_auth_callback(name, mocker, client):
    """Test ORCID callback - the user authorized the organisation access to the ORCID profile."""
    mocker.patch("requests_oauthlib.OAuth2Session.fetch_token", lambda self, *args, **kwargs: dict(
        name="NEW TEST",
        access_token="ABC123",
        orcid="ABC-123-456-789",
        scope=["/read-limited"],
        expires_in="1212",
        refresh_token="ABC1235"))

    org = Organisation.get(name="THE ORGANISATION")
    test_user = User.create(
        name=name,
        email="*****@*****.**",
        organisation=org,
        orcid="ABC123",
        confirmed=True)
    UserOrg.create(user=test_user, org=org, affiliations=Affiliation.NONE)
    client.login(test_user)
    User.update(name=name).execute()
    resp = client.get("/link")
    state = session['oauth_state']
    resp = client.get(f"/auth?state={state}")
    assert resp.status_code == 302, "If the user is already affiliated, the user should be redirected ..."
    assert "profile" in resp.location, "redirection to 'profile' showing the ORCID"

    u = User.get(id=test_user.id)
    orcidtoken = OrcidToken.get(user=u)
    assert u.orcid == "ABC-123-456-789"
    assert orcidtoken.access_token == "ABC123"
    if name:
        assert u.name == name, "The user name should be changed"
    else:
        assert u.name == "NEW TEST", "the user name should be set from record coming from ORCID"
Пример #8
0
def test_tuakiri_login_usgin_eppn(client):
    """Test logging attempt via Shibboleth using differt values to identify the user."""
    org = Organisation(tuakiri_name="ORGANISATION 123ABC")
    org.save()
    user = User.create(email="*****@*****.**",
                       eppn="*****@*****.**",
                       roles=Role.RESEARCHER)
    user.save()

    rv = client.get("/Tuakiri/login",
                    headers={
                        "Auedupersonsharedtoken": "ABC123",
                        "Sn": "LAST NAME/SURNAME/FAMILY NAME",
                        'Givenname': "FIRST NAME/GIVEN NAME",
                        "Mail": "*****@*****.**",
                        "O": "ORGANISATION 123ABC",
                        "Displayname": "TEST USER FROM 123",
                        "Unscoped-Affiliation": "staff",
                        "Eppn": "*****@*****.**"
                    })

    assert rv.status_code == 302
    u = User.get(eppn="*****@*****.**")
    assert u.email == "*****@*****.**"
    assert u.name == "TEST USER FROM 123", "Expected to have the user in the DB"
    assert u.first_name == "FIRST NAME/GIVEN NAME"
    assert u.last_name == "LAST NAME/SURNAME/FAMILY NAME"
Пример #9
0
def test_logout(client):
    """Test to logout."""
    org = Organisation.create(name="THE ORGANISATION:test_logout",
                              tuakiri_name="University of Auckland",
                              confirmed=True,
                              is_email_sent=True)
    user = User.create(email="*****@*****.**",
                       name="TEST USER",
                       roles=Role.TECHNICAL,
                       confirmed=True,
                       organisation=org)

    client.login(user)
    resp = client.get("/logout")
    # UoA user:
    assert resp.status_code == 302
    assert "Shibboleth.sso" in resp.location
    assert "uoa-slo" in resp.location

    org.tuakiri_name = org.name
    org.save()
    client.login(user)
    resp = client.get("/logout")
    # non-UoA user:
    assert resp.status_code == 302
    assert "Shibboleth.sso" in resp.location
    assert "uoa-slo" not in resp.location
Пример #10
0
def test_orcid_login(client):
    """Test login from orcid."""
    org = Organisation.get(name="THE ORGANISATION")
    u = User.create(email="*****@*****.**",
                    name="TEST USER",
                    roles=Role.TECHNICAL,
                    orcid="123",
                    confirmed=True,
                    organisation=org)
    user_org = UserOrg.create(user=u, org=org, is_admin=True)

    resp = client.get("/orcid/login/NOT-EXISTTING", follow_redirects=True)
    assert resp.status_code == 200
    assert b"Failed to login via ORCID using token NOT-EXISTTING" in resp.data

    token = "TOKEN-1234567"
    ui = UserInvitation.create(org=org, invitee=u, email=u.email, token=token)
    resp = client.get(f"/orcid/login/{token}")
    assert resp.status_code == 200
    orcid_authorize = OrcidAuthorizeCall.get(method="GET")
    assert "&email=test123_test_orcid_login%40test.test.net" in orcid_authorize.url
    ui.created_at -= timedelta(days=100)
    ui.save()
    resp = client.get(f"/orcid/login/{token}")
    assert resp.status_code == 302
    url = urlparse(resp.location)
    assert url.path == '/'
    # Testing the expired token flow for researcher
    user_org.is_admin = False
    user_org.save()
    resp = client.get(f"/orcid/login/{token}")
    assert resp.status_code == 302
    url = urlparse(resp.location)
    assert url.path == '/'
Пример #11
0
def test_link_orcid_auth_callback_with_affiliation(name, request_ctx):
    """Test ORCID callback - the user authorized the organisation access to the ORCID profile."""
    with patch("orcid_hub.orcid_client.MemberAPI") as m, patch(
            "orcid_hub.orcid_client.SourceClientId"), request_ctx("/auth?state=xyz") as ctx:
        org = Organisation.create(
            name="THE ORGANISATION",
            confirmed=True,
            orcid_client_id="CLIENT ID",
            city="CITY",
            country="COUNTRY",
            disambiguated_id="ID",
            disambiguation_source="SOURCE")

        test_user = User.create(
            name=name,
            email="*****@*****.**",
            organisation=org,
            orcid="ABC123",
            confirmed=True)

        UserOrg.create(user=test_user, org=org, affiliations=Affiliation.EMP | Affiliation.EDU)

        login_user(test_user, remember=True)
        session['oauth_state'] = "xyz"
        api_mock = m.return_value
        ctx.app.full_dispatch_request()
        assert test_user.orcid == "ABC-123-456-789"

        orcid_token = OrcidToken.get(user=test_user, org=org)
        assert orcid_token.access_token == "ABC123"

        api_mock.create_or_update_affiliation.assert_has_calls([
            call(affiliation=Affiliation.EDU, initial=True),
            call(affiliation=Affiliation.EMP, initial=True),
        ])
Пример #12
0
def test_orcid_callback(client, mocker):
    """Test orcid researcher deny flow."""
    org = Organisation.create(
        name="THE ORGANISATION:test_orcid_callback",
        tuakiri_name="THE ORGANISATION:test_orcid_callback",
        confirmed=True,
        orcid_client_id="CLIENT ID",
        orcid_secret="Client Secret",
        city="CITY",
        country="COUNTRY",
        disambiguated_id="ID",
        disambiguation_source="RINGGOLD",
        is_email_sent=True)
    user = User.create(email="*****@*****.**",
                       name="TEST USER",
                       roles=Role.TECHNICAL,
                       orcid="123",
                       confirmed=True,
                       organisation=org)
    UserOrg.create(user=user, org=org, is_admin=True)

    client.login(user)
    resp = client.get("/auth?error=access_denied&login=2")
    assert resp.status_code == 302
    assert "/link" in resp.location
Пример #13
0
def test_link(request_ctx):
    """Test orcid profile linking."""
    org = Organisation.create(name="THE ORGANISATION",
                              tuakiri_name="THE ORGANISATION",
                              confirmed=True,
                              orcid_client_id="CLIENT ID",
                              orcid_secret="Client Secret",
                              city="CITY",
                              country="COUNTRY",
                              disambiguated_id="ID",
                              disambiguation_source="SOURCE",
                              is_email_sent=True)

    user = User.create(email="*****@*****.**",
                       name="TEST USER",
                       roles=Role.TECHNICAL,
                       orcid="123",
                       confirmed=True,
                       organisation=org)
    UserOrg.create(user=user, org=org, is_admin=True)
    with request_ctx("/link") as ctx:
        login_user(user, remember=True)
        request.args = ImmutableMultiDict([('error', 'access_denied')])
        rv = ctx.app.full_dispatch_request()
        assert rv.status_code == 200
        assert b"<!DOCTYPE html>" in rv.data, "Expected HTML content"
Пример #14
0
def test_profile_wo_orcid(request_ctx):
    """Test a user profile that doesn't hava an ORCID."""
    with request_ctx("/profile") as ctx:
        org = Organisation.create(name="THE ORGANISATION:test_profile", confirmed=True)
        test_user = User.create(
            email="*****@*****.**", organisation=org, orcid=None, confirmed=True)
        login_user(test_user, remember=True)

        resp = ctx.app.full_dispatch_request()
        assert resp.status_code == 302
        assert resp.location == url_for("link")
Пример #15
0
def test_test_database(models):
    """Test of the consitency of the test database."""
    assert Organisation.select().count() == 10
    assert User.select().count() == 63
    assert OrcidToken.select().count() == 60
    assert AffiliationRecord.select().count() == 10
    assert FundingRecord.select().count() == 10
    assert FundingContributor.select().count() == 10
    assert FundingInvitee.select().count() == 10
    assert ExternalId.select().count() == 10
    assert WorkRecord.select().count() == 10
    assert WorkContributor.select().count() == 10
    assert WorkExternalId.select().count() == 10
    assert WorkInvitee.select().count() == 10
    assert PeerReviewRecord.select().count() == 10
    assert PeerReviewExternalId.select().count() == 10
    assert PeerReviewInvitee.select().count() == 10
    assert ResearcherUrlRecord.select().count() == 10
    assert OtherNameRecord.select().count() == 10
    assert KeywordRecord.select().count() == 10
    assert Task.select().count() == 30
    assert UserOrgAffiliation.select().count() == 30

    assert User.get(id=43).admin_for.count() == 10
    assert User.get(id=1).admin_for.count() == 0
    assert User.get(id=42).admin_for.count() > 0
    assert User.get(id=2).organisations.count() > 0
    assert Organisation.get(id=1).admins.count() == 1
    assert Organisation.get(id=5).users.count() > 0
    assert Organisation.get(id=5).admins.count() > 0
    assert User.select().where(User.orcid == User.get(
        email="*****@*****.**").orcid).count() == 3
    assert len(User.get(email="*****@*****.**").org_links) == 3

    user = User.get(email="*****@*****.**")
    available_organisations = user.available_organisations
    assert available_organisations.count() == 10

    admin = User.create(email="*****@*****.**", organisation=user.organisation, confirmed=True,
            first_name="TEST", last_name="ADMIN", roles=Role.ADMIN)
    ui = UserInvitation.create(email=user.email, invitee=user, inviter=admin, token="TOKEN-123")
    admin.delete_instance()
    ui = UserInvitation.get(ui.id)
    assert ui.inviter_id is None
    user.delete_instance()
    assert not UserInvitation.select().where(UserInvitation.id == ui.id).exists()

    org = Organisation.select().limit(1).first()
    user = User.select().limit(1).first()
    ot = OrcidToken.create(user=user, org=org, scope="S1,S2,S3")
    assert len(ot.scopes) == 3

    ot.scopes = ["A", "B", "C", "D"]
    assert ot.scope == "A,B,C,D"
Пример #16
0
def test_process_other_id_records(app, mocker):
    """Test create or update researcher other id."""
    mocker.patch("orcid_hub.utils.send_email", send_mail_mock)
    mocker.patch(
        "orcid_api_v3.api.DevelopmentMemberAPIV30Api.create_external_identifierv3",
        create_or_update_fund_mock)
    mocker.patch("orcid_hub.orcid_client.MemberAPIV3.get_record",
                 return_value=get_profile())
    org = app.data["org"]
    u = User.create(email="*****@*****.**",
                    name="TEST USER",
                    roles=Role.RESEARCHER,
                    orcid="12344",
                    confirmed=True,
                    organisation=org)

    UserOrg.create(user=u, org=org)

    t = Task.create(org=org,
                    filename="xyz.json",
                    created_by=u,
                    updated_by=u,
                    task_type=TaskType.OTHER_ID)

    OtherIdRecord.create(task=t,
                         type="grant_number",
                         value="xyz",
                         url="https://xyz.com",
                         relationship="SELF",
                         is_active=True,
                         status="email sent",
                         first_name="Test",
                         last_name="Test",
                         email="*****@*****.**",
                         visibility="PUBLIC",
                         display_index=1)

    UserInvitation.create(invitee=u,
                          inviter=u,
                          org=org,
                          task=t,
                          email="*****@*****.**",
                          token="xyztoken")

    OrcidToken.create(user=u,
                      org=org,
                      scopes="/read-limited,/person/update",
                      access_token="Test_token")
    utils.process_other_id_records()
    record = OtherIdRecord.get(email="*****@*****.**")
    assert 12399 == record.put_code
    assert "12344" == record.orcid
Пример #17
0
def test_link(request_ctx):
    """Test a user affiliation initialization."""
    with request_ctx("/link") as ctx:
        org = Organisation.get(name="THE ORGANISATION")
        test_user = User.create(
            name="TEST USER 123", email="*****@*****.**", organisation=org, confirmed=True)
        login_user(test_user, remember=True)

        rv = ctx.app.full_dispatch_request()
        assert b"<!DOCTYPE html>" in rv.data, "Expected HTML content"
        assert b"TEST USER 123" in rv.data, "Expected to have the user name on the page"
        assert b"*****@*****.**" in rv.data, "Expected to have the user email on the page"
        assert b"URL_123" in rv.data, "Expected to have ORCiD authorization link on the page"
Пример #18
0
def test_send_work_funding_peer_review_invitation(app, mocker):
    """Test to send user invitation."""
    send_email = mocker.patch("orcid_hub.utils.send_email")
    org = app.data["org"]
    inviter = User.create(email="*****@*****.**",
                          name="TEST USER",
                          roles=Role.RESEARCHER,
                          orcid=None,
                          confirmed=True,
                          organisation=org)

    email = "*****@*****.**"
    u = User.create(email=email,
                    name="TEST USER",
                    roles=Role.RESEARCHER,
                    orcid=None,
                    confirmed=True,
                    organisation=org)
    UserOrg.create(user=u, org=org)
    task = Task.create(org=org, task_type=1)
    fr = FundingRecord.create(task=task, title="xyz", type="Award")
    FundingInvitee.create(record=fr,
                          email=email,
                          first_name="Alice",
                          last_name="Bob")

    server_name = app.config.get("SERVER_NAME")
    app.config["SERVER_NAME"] = "abc.orcidhub.org.nz"
    utils.send_user_invitation(inviter=inviter,
                               org=org,
                               email=email,
                               name=u.name,
                               user=u,
                               task_id=task.id)
    app.config["SERVER_NAME"] = server_name
    send_email.assert_called_once()
Пример #19
0
def test_sync_profile(app, mocker):
    """Test sync_profile."""
    mocker.patch("orcid_api.MemberAPIV20Api.update_employment",
                 return_value=Mock(status=201,
                                   headers={'Location': '12344/XYZ/54321'}))
    mocker.patch("orcid_api.MemberAPIV20Api.update_education",
                 return_value=Mock(status=201,
                                   headers={'Location': '12344/XYZ/12345'}))

    org = Organisation.create(
        name="THE ORGANISATION:test_sync_profile",
        tuakiri_name="THE ORGANISATION:test_sync_profile",
        confirmed=True,
        orcid_client_id="APP-5ZVH4JRQ0C27RVH5",
        orcid_secret="Client Secret",
        city="CITY",
        country="COUNTRY",
        disambiguated_id="ID",
        disambiguation_source="SOURCE")
    u = User.create(email="*****@*****.**",
                    name="TEST USER",
                    roles=Role.RESEARCHER,
                    orcid="12344",
                    confirmed=True,
                    organisation=org)
    UserOrg.create(user=u, org=org)
    access_token = "ACCESS-TOKEN"

    t = Task.create(org=org, task_type=TaskType.SYNC)
    api = MemberAPI(org=org)

    mocker.patch("orcid_hub.orcid_client.MemberAPI.get_record",
                 lambda *args: None)
    api.sync_profile(task=t, user=u, access_token=access_token)

    OrcidToken.create(user=u,
                      org=org,
                      scope="/read-limited,/activities/update")
    mocker.patch("orcid_hub.orcid_client.MemberAPI.get_record",
                 lambda *args: None)
    api.sync_profile(task=t, user=u, access_token=access_token)
    assert Log.select().count() > 0

    mocker.patch("orcid_hub.orcid_client.MemberAPI.get_record",
                 return_value=get_profile())
    api.sync_profile(task=t, user=u, access_token=access_token)
    last_log = Log.select().order_by(Log.id.desc()).first()
    assert "Successfully update" in last_log.message
Пример #20
0
def test_track_event(request_ctx):
    """Test to track event."""
    category = "test"
    action = "test"
    label = None
    value = 0

    u = User.create(email="*****@*****.**",
                    name="TEST USER",
                    username="******",
                    roles=Role.RESEARCHER,
                    confirmed=True)

    with request_ctx("/"):
        login_user(u)
        resp = utils.track_event(category, action, label, value)
        assert resp.status_code == 200
Пример #21
0
def test_select_user_org(request_ctx):
    """Test organisation switch of current user."""
    org = Organisation.create(
        name="THE ORGANISATION:test_select_user_org",
        tuakiri_name="THE ORGANISATION:test_select_user_org",
        confirmed=True,
        orcid_client_id="CLIENT ID",
        orcid_secret="Client Secret",
        city="CITY",
        country="COUNTRY",
        disambiguated_id="ID",
        disambiguation_source="RINGGOLD",
        is_email_sent=True)
    org2 = Organisation.create(
        name="THE ORGANISATION2:test_select_user_org",
        tuakiri_name="THE ORGANISATION2:test_select_user_org",
        confirmed=True,
        orcid_client_id="CLIENT ID",
        orcid_secret="Client Secret",
        city="CITY",
        country="COUNTRY",
        disambiguated_id="ID",
        disambiguation_source="RINGGOLD",
        is_email_sent=True)

    user = User.create(
        email="*****@*****.**",
        name="TEST USER",
        roles=Role.TECHNICAL,
        orcid="123",
        confirmed=True,
        organisation=org)
    org.save()
    org2.save()
    user.save()
    UserOrg.create(user=user, org=org, is_admin=True)
    user_org2 = UserOrg.create(user=user, org=org2, is_admin=True)
    with request_ctx(f"/select/user_org/{user_org2.id}") as ctx:
        login_user(user, remember=True)
        resp = ctx.app.full_dispatch_request()
        assert resp.status_code == 302
        assert user.organisation_id != org.id
        # Current users organisation has been changes from 1 to 2
        assert user.organisation_id == org2.id
Пример #22
0
def test_logout(request_ctx):
    """Test to logout."""
    user = User.create(email="*****@*****.**",
                       name="TEST USER",
                       roles=Role.TECHNICAL,
                       confirmed=True,
                       organisation=Organisation.create(
                           name="THE ORGANISATION",
                           tuakiri_name="THE ORGANISATION",
                           confirmed=True,
                           is_email_sent=True))

    with request_ctx("/logout") as ctx:
        # UoA user:
        login_user(user)
        session["shib_O"] = "University of Auckland"
        rv = ctx.app.full_dispatch_request()
        assert rv.status_code == 302
        assert "Shibboleth.sso" in rv.location
        assert "uoa-slo" in rv.location
Пример #23
0
def test_link_orcid_auth_callback_with_affiliation(name, request_ctx):
    """Test ORCID callback - the user authorized the organisation access to the ORCID profile."""
    with patch("orcid_hub.orcid_client.MemberAPI") as m, patch(
            "orcid_hub.orcid_client.SourceClientId"), request_ctx(
                "/auth?state=xyz") as ctx:
        org = Organisation.get(name="THE ORGANISATION")
        test_user = User.create(name=name,
                                email="*****@*****.**",
                                organisation=org,
                                orcid="ABC123",
                                confirmed=True)

        UserOrg.create(user=test_user,
                       org=org,
                       affiliations=Affiliation.EMP | Affiliation.EDU)

        login_user(test_user, remember=True)
        session['oauth_state'] = "xyz"
        api_mock = m.return_value
        ctx.app.full_dispatch_request()
        assert test_user.orcid == "ABC-123-456-789"

        orcid_token = OrcidToken.get(user=test_user, org=org)
        assert orcid_token.access_token == "ABC123"

        api_mock.create_or_update_affiliation.assert_has_calls([
            call(affiliation=Affiliation.EDU, initial=True),
            call(affiliation=Affiliation.EMP, initial=True),
        ])
        # User with no Affiliation, should get flash warning.
        user_org = UserOrg.get(user=test_user, org=org)
        user_org.affiliations = Affiliation.NONE
        user_org.save()
        orcid_token.delete_instance()
        resp = ctx.app.full_dispatch_request()
        assert resp.status_code == 302
        assert b"<!DOCTYPE HTML" in resp.data, "Expected HTML content"
        assert "profile" in resp.location, "redirection to 'profile' showing the ORCID"
Пример #24
0
def test_member_api_v3(app, mocker):
    """Test MemberAPI extension and wrapper of ORCID API."""
    mocker.patch.multiple("orcid_hub.app.logger", error=DEFAULT, exception=DEFAULT, info=DEFAULT)
    org = Organisation.get(name="THE ORGANISATION")
    user = User.create(
        orcid="1001-0001-0001-0001",
        name="TEST USER 123",
        email="*****@*****.**",
        organisation=org,
        confirmed=True)
    UserOrg.create(user=user, org=org, affiliation=Affiliation.EDU)

    api = MemberAPIV3(user=user)
    assert api.api_client.configuration.access_token is None or api.api_client.configuration.access_token == ''

    api = MemberAPIV3(user=user, org=org)
    assert api.api_client.configuration.access_token is None or api.api_client.configuration.access_token == ''

    api = MemberAPIV3(user=user, org=org, access_token="ACCESS000")
    assert api.api_client.configuration.access_token == 'ACCESS000'

    OrcidToken.create(access_token="ACCESS123",
                      user=user,
                      org=org,
                      scopes="/read-limited,/activities/update",
                      expires_in='121')
    api = MemberAPIV3(user=user, org=org)
    assert api.api_client.configuration.access_token == "ACCESS123"

    # Test API call auditing:
    request_mock = mocker.patch.object(
        api.api_client.rest_client.pool_manager, "request",
        MagicMock(return_value=Mock(data=b"""{"mock": "data"}""", status=200)))

    api.get_record()

    request_mock.assert_called_once_with(
        "GET",
        "https://api.sandbox.orcid.org/v3.0/1001-0001-0001-0001",
        fields=None,
        preload_content=False,
        timeout=None,
        headers={
            "Accept": "application/json",
            "Content-Type": "application/json",
            "User-Agent": "Swagger-Codegen/1.0.0/python",
            "Authorization": "Bearer ACCESS123"
        })

    api_call = OrcidApiCall.select().first()
    assert api_call.response == '{"mock": "data"}'
    assert api_call.url == "https://api.sandbox.orcid.org/v3.0/1001-0001-0001-0001"

    create = mocker.patch.object(OrcidApiCall, "create", side_effect=Exception("FAILURE"))
    api.get_record()
    create.assert_called_once()
    app.logger.exception.assert_called_with("Failed to create API call log entry.")

    # Handling of get_record
    call_api = mocker.patch.object(
            api.api_client, "call_api",
            side_effect=v3.rest.ApiException(reason="FAILURE", status=401))
    delete = mocker.patch.object(OrcidToken, "delete")
    api.get_record()
    call_api.assert_called_once()
    delete.assert_called_once()

    call_api = mocker.patch.object(
            api.api_client, "call_api",
            side_effect=v3.rest.ApiException(reason="FAILURE 999", status=999))
    api.get_record()
    app.logger.error.assert_called_with("ApiException Occurred: (999)\nReason: FAILURE 999\n")

    call_api = mocker.patch.object(
            api.api_client, "call_api",
            side_effect=v3.rest.ApiException(reason="FAILURE", status=401))
    api.get_record()
    app.logger.error.assert_called_with("ApiException Occurred: (401)\nReason: FAILURE\n")
    call_api.assert_called_once()

    call_api = mocker.patch.object(
            api.api_client,
            "call_api",
            return_value=(Mock(data=b"""{"mock": "data"}"""), 200, [],))
    api.get_record()
    call_api.assert_called_with(
        f"/v3.0/{user.orcid}",
        "GET",
        _preload_content=False,
        auth_settings=["orcid_auth"],
        header_params={"Accept": "application/json"},
        response_type=None)

    # Failed logging:
    request_mock = mocker.patch(
            "orcid_api_v3.rest.RESTClientObject.request",
            return_value=Mock(data=None, status_code=200))
Пример #25
0
def test_link_orcid_auth_callback_with_affiliation(name, mocker, client):
    """Test ORCID callback - the user authorized the organisation access to the ORCID profile."""
    mocker.patch("requests_oauthlib.OAuth2Session.fetch_token", lambda self, *args, **kwargs: dict(
        name="NEW TEST",
        access_token="ABC123",
        orcid="ABC-123-456-789",
        scope=['/read-limited,/activities/update'],
        expires_in="1212",
        refresh_token="ABC1235"))
    m = mocker.patch("orcid_hub.orcid_client.MemberAPI")
    mocker.patch("orcid_hub.orcid_client.SourceClientId")

    org = Organisation.get(name="THE ORGANISATION")
    test_user = User.create(
        name=name,
        email="*****@*****.**",
        organisation=org,
        orcid="ABC123",
        confirmed=True)

    UserOrg.create(user=test_user, org=org, affiliations=Affiliation.EMP | Affiliation.EDU)

    client.login(test_user)
    resp = client.get("/link")
    state = session['oauth_state']

    resp = client.get(f"/auth?state={state}")
    api_mock = m.return_value
    test_user = User.get(test_user.id)
    assert test_user.orcid == "ABC-123-456-789"

    orcid_token = OrcidToken.get(user=test_user, org=org)
    assert orcid_token.access_token == "ABC123"

    api_mock.create_or_update_affiliation.assert_has_calls([
        call(affiliation=Affiliation.EDU, initial=True),
        call(affiliation=Affiliation.EMP, initial=True),
    ])

    # User with no Affiliation, should get flash warning.
    user_org = UserOrg.get(user=test_user, org=org)
    user_org.affiliations = Affiliation.NONE
    user_org.save()
    orcid_token.delete_instance()

    assert OrcidToken.select().where(OrcidToken.user == test_user, OrcidToken.org == org).count() == 0
    resp = client.get(f"/auth?state={state}")
    assert resp.status_code == 302
    assert b"<!DOCTYPE HTML" in resp.data, "Expected HTML content"
    assert "profile" in resp.location, "redirection to 'profile' showing the ORCID"
    assert OrcidToken.select().where(OrcidToken.user == test_user, OrcidToken.org == org).count() == 1

    get_person = mocker.patch("requests_oauthlib.OAuth2Session.get", return_value=Mock(status_code=200))
    resp = client.get(f"/profile", follow_redirects=True)
    assert b"can create and update research activities" in resp.data
    get_person.assert_called_once()

    get_person = mocker.patch("requests_oauthlib.OAuth2Session.get", return_value=Mock(status_code=401))
    resp = client.get(f"/profile", follow_redirects=True)
    assert b"you'll be taken to ORCID to create or sign into your ORCID record" in resp.data
    get_person.assert_called_once()
Пример #26
0
def test_create_or_update_funding(email_patch, patch, test_db, request_ctx):
    """Test create or update funding."""
    org = Organisation.create(name="THE ORGANISATION",
                              tuakiri_name="THE ORGANISATION",
                              confirmed=True,
                              orcid_client_id="APP-5ZVH4JRQ0C27RVH5",
                              orcid_secret="Client Secret",
                              city="CITY",
                              country="COUNTRY",
                              disambiguation_org_id="ID",
                              disambiguation_org_source="SOURCE")

    u = User.create(email="*****@*****.**",
                    name="TEST USER",
                    username="******",
                    roles=Role.RESEARCHER,
                    orcid="123",
                    confirmed=True,
                    organisation=org)

    UserOrg.create(user=u, org=org)

    t = Task.create(org=org,
                    filename="xyz.json",
                    created_by=u,
                    updated_by=u,
                    task_type=1)

    fr = FundingRecord.create(task=t,
                              title="Test titile",
                              translated_title="Test title",
                              translated_title_language_code="Test",
                              type="GRANT",
                              organization_defined_type="Test org",
                              short_description="Test desc",
                              amount="1000",
                              currency="USD",
                              org_name="Test_orgname",
                              city="Test city",
                              region="Test",
                              country="Test",
                              disambiguated_org_identifier="Test_dis",
                              disambiguation_source="Test_source",
                              is_active=True)

    FundingInvitees.create(funding_record=fr,
                           first_name="Test",
                           email="*****@*****.**",
                           visibility="PUBLIC",
                           orcid="123")

    ExternalId.create(funding_record=fr,
                      type="Test_type",
                      value="Test_value",
                      url="Test",
                      relationship="SELF")

    FundingContributor.create(funding_record=fr,
                              orcid="1213",
                              role="LEAD",
                              name="Contributor",
                              email="*****@*****.**")

    UserInvitation.create(invitee=u,
                          inviter=u,
                          org=org,
                          task=t,
                          email="*****@*****.**",
                          token="xyztoken")

    OrcidToken.create(user=u,
                      org=org,
                      scope="/read-limited,/activities/update",
                      access_token="Test_token")

    utils.process_funding_records()
    funding_invitees = FundingInvitees.get(orcid=12344)
    assert 12399 == funding_invitees.put_code
    assert "12344" == funding_invitees.orcid
Пример #27
0
def test_is_emp_or_edu_record_present(app, mocker):
    """Test 'is_emp_or_edu_record_present' method."""
    mocker.patch.multiple("orcid_hub.app.logger", error=DEFAULT, exception=DEFAULT, info=DEFAULT)
    org = Organisation.get(name="THE ORGANISATION")
    user = User.create(
        orcid="1001-0001-0001-0001",
        name="TEST USER 123",
        email="*****@*****.**",
        organisation=org,
        confirmed=True)
    UserOrg.create(user=user, org=org, affiliation=Affiliation.EDU)

    api = MemberAPI(user=user, org=org)

    test_responses = [
        None,
        """{"mock": "data"}""",
        """{
            "employment-summary": [{"source": {"source-client-id": {"path": "CLIENT000"}}, "put-code": 123}],
            "education-summary": [{"source": {"source-client-id": {"path": "CLIENT000"}}, "put-code": 456}]
        }""",
        """{"employment-summary": [], "education-summary": []}"""
    ]

    for data in test_responses:
        with patch.object(
                api_client.ApiClient,
                "call_api",
                return_value=Mock(data=data)) as call_api:
            api.is_emp_or_edu_record_present(Affiliation.EDU)
            call_api.assert_called_with(
                "/v2.0/{orcid}/educations",
                "GET", {"orcid": "1001-0001-0001-0001"}, {}, {"Accept": "application/json"},
                _preload_content=False,
                _request_timeout=None,
                _return_http_data_only=True,
                auth_settings=["orcid_auth"],
                body=None,
                callback=None,
                collection_formats={},
                files={},
                post_params=[],
                response_type="Educations")
            api.is_emp_or_edu_record_present(Affiliation.EMP)
            call_api.assert_called_with(
                "/v2.0/{orcid}/employments",
                "GET", {"orcid": "1001-0001-0001-0001"}, {}, {"Accept": "application/json"},
                _preload_content=False,
                _request_timeout=None,
                _return_http_data_only=True,
                auth_settings=["orcid_auth"],
                body=None,
                callback=None,
                collection_formats={},
                files={},
                post_params=[],
                response_type="Employments")

    with patch.object(
            api_client.ApiClient, "call_api", side_effect=ApiException(
                reason="FAILURE", status=401)) as call_api:
        api.is_emp_or_edu_record_present(Affiliation.EDU)
        app.logger.error.assert_called_with(
            "For TEST USER 123 ([email protected]) while checking for employment "
            "and education records, Encountered Exception: (401)\nReason: FAILURE\n")

    with patch.object(
            api_client.ApiClient, "call_api", side_effect=Exception("EXCEPTION")) as call_api:
        api.is_emp_or_edu_record_present(Affiliation.EDU)
        app.logger.exception.assert_called_with(
            "Failed to verify presence of employment or education record.")
Пример #28
0
def test_create_or_update_affiliation(patch, test_db, request_ctx):
    """Test create or update affiliation."""
    org = Organisation.create(name="THE ORGANISATION",
                              tuakiri_name="THE ORGANISATION",
                              confirmed=True,
                              orcid_client_id="APP-5ZVH4JRQ0C27RVH5",
                              orcid_secret="Client Secret",
                              city="CITY",
                              country="COUNTRY",
                              disambiguation_org_id="ID",
                              disambiguation_org_source="SOURCE")
    u = User.create(email="*****@*****.**",
                    name="TEST USER",
                    username="******",
                    roles=Role.RESEARCHER,
                    orcid="123",
                    confirmed=True,
                    organisation=org)
    UserOrg.create(user=u, org=org)

    t = Task.create(org=org,
                    filename="xyz.json",
                    created_by=u,
                    updated_by=u,
                    task_type=0)

    AffiliationRecord.create(is_active=True,
                             task=t,
                             external_id="Test",
                             first_name="Test",
                             last_name="Test",
                             email="*****@*****.**",
                             orcid="123112311231",
                             organisation="asdasd",
                             affiliation_type="staff",
                             role="Test",
                             department="Test",
                             city="Test",
                             state="Test",
                             country="Test",
                             disambiguated_id="Test",
                             disambiguation_source="Test")

    UserInvitation.create(invitee=u,
                          inviter=u,
                          org=org,
                          task=t,
                          email="*****@*****.**",
                          token="xyztoken")

    OrcidToken.create(user=u,
                      org=org,
                      scope="/read-limited,/activities/update",
                      access_token="Test_token")

    tasks = (Task.select(
        Task, AffiliationRecord, User,
        UserInvitation.id.alias("invitation_id"), OrcidToken
    ).where(
        AffiliationRecord.processed_at.is_null(), AffiliationRecord.is_active,
        ((User.id.is_null(False)
          & User.orcid.is_null(False) & OrcidToken.id.is_null(False)) |
         ((User.id.is_null() | User.orcid.is_null() | OrcidToken.id.is_null())
          & UserInvitation.id.is_null() &
          (AffiliationRecord.status.is_null()
           | AffiliationRecord.status.contains("sent").__invert__())))).join(
               AffiliationRecord,
               on=(Task.id == AffiliationRecord.task_id)).join(
                   User,
                   JOIN.LEFT_OUTER,
                   on=((User.email == AffiliationRecord.email) |
                       (User.orcid == AffiliationRecord.orcid))).join(
                           Organisation,
                           JOIN.LEFT_OUTER,
                           on=(Organisation.id == Task.org_id)).
             join(UserInvitation,
                  JOIN.LEFT_OUTER,
                  on=((UserInvitation.email == AffiliationRecord.email) &
                      (UserInvitation.task_id == Task.id))).join(
                          OrcidToken,
                          JOIN.LEFT_OUTER,
                          on=((OrcidToken.user_id == User.id) &
                              (OrcidToken.org_id == Organisation.id) &
                              (OrcidToken.scope.contains("/activities/update"))
                              )).limit(20))
    for (task_id, org_id, user), tasks_by_user in groupby(
            tasks, lambda t: (
                t.id,
                t.org_id,
                t.affiliation_record.user,
            )):
        utils.create_or_update_affiliations(user=user,
                                            org_id=org_id,
                                            records=tasks_by_user)
    affiliation_record = AffiliationRecord.get(task=t)
    assert 12399 == affiliation_record.put_code
    assert "12344" == affiliation_record.orcid
    assert "Employment record was updated" in affiliation_record.status
Пример #29
0
def test_create_or_update_peer_review(email_patch, patch, test_db,
                                      request_ctx):
    """Test create or update peer review."""
    org = Organisation.create(name="THE ORGANISATION",
                              tuakiri_name="THE ORGANISATION",
                              confirmed=True,
                              orcid_client_id="APP-5ZVH4JRQ0C27RVH5",
                              orcid_secret="Client Secret",
                              city="CITY",
                              country="COUNTRY",
                              disambiguation_org_id="ID",
                              disambiguation_org_source="SOURCE")

    u = User.create(email="*****@*****.**",
                    name="TEST USER",
                    username="******",
                    roles=Role.RESEARCHER,
                    orcid="12344",
                    confirmed=True,
                    organisation=org)

    UserOrg.create(user=u, org=org)

    t = Task.create(id=12,
                    org=org,
                    filename="xyz.json",
                    created_by=u,
                    updated_by=u,
                    task_type=3)
    pr = PeerReviewRecord.create(task=t,
                                 review_group_id="issn:12131",
                                 reviewer_role="reviewer",
                                 review_url="xyz",
                                 review_type="REVIEW",
                                 subject_external_id_type="doi",
                                 subject_external_id_value="1212",
                                 subject_external_id_url="url/SELF",
                                 subject_external_id_relationship="SELF",
                                 subject_container_name="Journal title",
                                 subject_type="JOURNAL_ARTICLE",
                                 subject_name_title="name",
                                 subject_name_subtitle="subtitle",
                                 subject_name_translated_title_lang_code="en",
                                 subject_name_translated_title="sdsd",
                                 subject_url="url",
                                 convening_org_name="THE ORGANISATION",
                                 convening_org_city="auckland",
                                 convening_org_region="auckland",
                                 convening_org_country="nz",
                                 convening_org_disambiguated_identifier="123",
                                 convening_org_disambiguation_source="1212",
                                 is_active=True)

    PeerReviewInvitee.create(peer_review_record=pr,
                             first_name="Test",
                             email="*****@*****.**",
                             orcid="12344",
                             visibility="PUBLIC")

    PeerReviewExternalId.create(peer_review_record=pr,
                                type="Test_type",
                                value="122334_different",
                                url="Test",
                                relationship="SELF")

    UserInvitation.create(invitee=u,
                          inviter=u,
                          org=org,
                          task=t,
                          email="*****@*****.**",
                          token="xyztoken")

    OrcidToken.create(user=u,
                      org=org,
                      scope="/read-limited,/activities/update",
                      access_token="Test_token")

    utils.process_peer_review_records()
    peer_review_invitees = PeerReviewInvitee.get(orcid=12344)
    assert 12399 == peer_review_invitees.put_code
    assert "12344" == peer_review_invitees.orcid
Пример #30
0
def test_create_or_update_work(email_patch, patch, test_db, request_ctx):
    """Test create or update work."""
    org = Organisation.create(name="THE ORGANISATION",
                              tuakiri_name="THE ORGANISATION",
                              confirmed=True,
                              orcid_client_id="APP-5ZVH4JRQ0C27RVH5",
                              orcid_secret="Client Secret",
                              city="CITY",
                              country="COUNTRY",
                              disambiguation_org_id="ID",
                              disambiguation_org_source="SOURCE")

    u = User.create(email="*****@*****.**",
                    name="TEST USER",
                    username="******",
                    roles=Role.RESEARCHER,
                    orcid="12344",
                    confirmed=True,
                    organisation=org)

    UserOrg.create(user=u, org=org)

    t = Task.create(org=org,
                    filename="xyz.json",
                    created_by=u,
                    updated_by=u,
                    task_type=2)

    wr = WorkRecord.create(task=t,
                           title="Test titile",
                           sub_title="Test titile",
                           translated_title="Test title",
                           translated_title_language_code="Test",
                           journal_title="Test titile",
                           short_description="Test desc",
                           citation_type="Test",
                           citation_value="Test",
                           type="BOOK_CHAPTER",
                           url="Test org",
                           language_code="en",
                           country="Test",
                           org_name="Test_orgname",
                           city="Test city",
                           region="Test",
                           is_active=True)

    WorkInvitees.create(work_record=wr,
                        first_name="Test",
                        email="*****@*****.**",
                        orcid="12344",
                        visibility="PUBLIC")

    WorkExternalId.create(work_record=wr,
                          type="Test_type",
                          value="Test_value",
                          url="Test",
                          relationship="SELF")

    WorkContributor.create(work_record=wr,
                           contributor_sequence="1",
                           orcid="1213",
                           role="LEAD",
                           name="xyz",
                           email="*****@*****.**")

    UserInvitation.create(invitee=u,
                          inviter=u,
                          org=org,
                          task=t,
                          email="*****@*****.**",
                          token="xyztoken")

    OrcidToken.create(user=u,
                      org=org,
                      scope="/read-limited,/activities/update",
                      access_token="Test_token")

    utils.process_work_records()
    work_invitees = WorkInvitees.get(orcid=12344)
    assert 12399 == work_invitees.put_code
    assert "12344" == work_invitees.orcid