Пример #1
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
Пример #2
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
Пример #3
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
Пример #4
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")
Пример #5
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),
        ])
Пример #6
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"
Пример #7
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")
Пример #8
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
Пример #9
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")
Пример #10
0
def test_link(request_ctx):
    """Test a user affiliation initialization."""
    with request_ctx("/link") as ctx:
        org = Organisation.create(name="THE ORGANISATION", confirmed=True)
        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"
Пример #11
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
Пример #12
0
def test_load_task_from_csv(models):
    org = Organisation.create(name="TEST0")
    # flake8: noqa
    test = Task.load_from_csv(
        """First name	Last name	email address	Organisation	Campus/Department	City	Course or Job title	Start date	End date	Student/Staff
FNA	LBA	[email protected]	TEST1	Research Funding	Wellington	Programme Manager - ORCID	2016-09		Staff
FNA	LBA	[email protected]	TEST1	Research Funding	Wellington	Programme Manager - Insights and Evaluation	2014		Staff
FNA	LBA	[email protected]	TEST0	External Affairs	Wellington	Senior Evaluation Officer	2011	2014	Staff
FNA	LBA	[email protected]	TEST0	Policy and Evaluation	Wellington	Evaluation Officer	2005	2011	Staff
FNA	LBA	[email protected]	TEST0	Marsden Fund	Wellington	Research Assessor	2001	2004	Staff
FNB	LNB	[email protected]	TEST1	Communications and Outreach	Wellington	Projects and Events Coordinator	2013		Staff
FNB	LNB	[email protected]	TEST0	Science and Education Group	Wellington	School Programmes Manager	2008	2013	Staff
FNB	LNB	TEST_FN TEST_LN <*****@*****.**>	TEST0	Science and Education Group	Wellington	Project Manager	2000	2004	Staff
FNB	LNB	[email protected]	TEST0	Science and Education Group	Wellington	Manager Special Programmes	2004	2008	Staff
""",
        filename="TEST.tsv",
        org=org)
    assert test.record_count == 9
    assert AffiliationRecord.select().count(
    ) == test.record_count + 10  # The 10 value is from already inserted entries.
Пример #13
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
Пример #14
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.create(name="THE ORGANISATION", confirmed=True, orcid_client_id="CLIENT000")
    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.")
Пример #15
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
Пример #16
0
def test_send_email(app):
    """Test emailing."""
    with app.app_context():

        # app.config["SERVER_NAME"] = "ORCIDHUB"

        with patch("emails.message.Message") as msg_cls, patch(
                "flask.current_app.jinja_env"):
            msg = msg_cls.return_value = Mock()
            utils.send_email("template.html", (
                "TEST USER",
                "*****@*****.**",
            ),
                             subject="TEST")

            msg_cls.assert_called_once()
            msg.send.assert_called_once()

            msg.reset_mock()
            dkip_key_path = app.config["DKIP_KEY_PATH"]
            app.config["DKIP_KEY_PATH"] = __file__
            utils.send_email("template", (
                "TEST USER",
                "*****@*****.**",
            ),
                             base="BASE",
                             subject="TEST")
            msg.dkim.assert_called_once()
            msg.send.assert_called_once()

            msg.reset_mock()
            app.config["DKIP_KEY_PATH"] = "NON-EXISTING FILE..."
            utils.send_email("template", (
                "TEST USER",
                "*****@*****.**",
            ),
                             base="BASE",
                             subject="TEST")
            msg.dkim.assert_not_called()
            msg.send.assert_called_once()
            app.config["DKIP_KEY_PATH"] = dkip_key_path

            # User organisation's logo
            msg.reset_mock()
            logo_file = File.create(filename="LOGO.png",
                                    data=b"000000000000000000000",
                                    mimetype="image/png",
                                    token="TOKEN000")
            org = Organisation.create(name="THE ORGANISATION",
                                      tuakiri_name="THE ORGANISATION",
                                      confirmed=True,
                                      orcid_client_id="APP-5ZVH4JRQ0C27RVH5",
                                      orcid_secret="Client Secret",
                                      city="CITY",
                                      logo=logo_file,
                                      country="COUNTRY",
                                      disambiguation_org_id="ID",
                                      disambiguation_org_source="SOURCE")
            utils.send_email("template", (
                "TEST USER",
                "*****@*****.**",
            ),
                             base="BASE {LOGO}",
                             subject="TEST WITH BASE AND LOGO",
                             org=org)
            msg.send.assert_called_once()
            _, kwargs = msg_cls.call_args
            assert kwargs["subject"] == "TEST WITH BASE AND LOGO"
            assert kwargs["mail_from"] == (
                "NZ ORCID HUB",
                "*****@*****.**",
            )
            expected_html = f"BASE http://{app.config['SERVER_NAME'].lower()}/logo/TOKEN000"
            assert kwargs["html"] == expected_html
            assert kwargs["text"] == expected_html + "\n\n"

            # Using organisation template
            msg.reset_mock()
            org.email_template = "TEMPLATE {LOGO}"
            org.email_template_enabled = True
            org.save()
            utils.send_email("template", (
                "TEST USER",
                "*****@*****.**",
            ),
                             sender=(
                                 None,
                                 None,
                             ),
                             subject="TEST WITH ORG BASE AND LOGO",
                             org=org)
            msg.send.assert_called_once()
            _, kwargs = msg_cls.call_args
            assert kwargs["subject"] == "TEST WITH ORG BASE AND LOGO"
            assert kwargs["mail_from"] == (
                "NZ ORCID HUB",
                "*****@*****.**",
            )
            expected_html = f"TEMPLATE http://{app.config['SERVER_NAME'].lower()}/logo/TOKEN000"
            assert kwargs["html"] == expected_html
            assert kwargs["text"] == expected_html + "\n\n"

        # temlates w/o extension and missing template file
        # login_user(super_user)
        from jinja2.exceptions import TemplateNotFound

        with pytest.raises(TemplateNotFound):
            utils.send_email("missing_template.html", (
                "TEST USER",
                "*****@*****.**",
            ),
                             logo="LOGO",
                             subject="TEST")
Пример #17
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
Пример #18
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
Пример #19
0
def test_send_user_invitation(test_db, request_ctx):
    """Test to send user invitation."""
    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",
                              disambiguation_org_id="ID",
                              disambiguation_org_source="SOURCE")

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

    u = User(email="*****@*****.**",
             name="TEST USER",
             username="******",
             roles=Role.RESEARCHER,
             orcid=None,
             confirmed=True,
             organisation=org)
    u.save()
    user_org = UserOrg(user=u, org=org)
    user_org.save()
    task = Task(id=123, org=org)
    task.save()
    email = "*****@*****.**"
    first_name = "TEST"
    last_name = "Test"
    affiliation_types = {"staff"}
    with patch("smtplib.SMTP") as mock_smtp, request_ctx("/") as ctxx:

        instance = mock_smtp.return_value
        error = {
            email:
            (450, "Requested mail action not taken: mailbox unavailable")
        }
        instance.utils.send_user_invitation.return_value = error
        result = instance.utils.send_user_invitation(
            inviter=inviter,
            org=org,
            email=email,
            first_name=first_name,
            last_name=last_name,
            affiliation_types=affiliation_types,
            task_id=task.id)
        rv = ctxx.app.full_dispatch_request()
        assert rv.status_code == 200
        assert instance.utils.send_user_invitation.called  # noqa: E712
        assert (450, 'Requested mail action not taken: mailbox unavailable'
                ) == result[email]

    with patch("orcid_hub.utils.send_email") as send_email:
        result = utils.send_user_invitation(
            inviter=inviter.id,
            org=org.id,
            email=email,
            first_name=first_name,
            last_name=last_name,
            affiliation_types=affiliation_types,
            start_date=[1971, 1, 1],
            end_date=[2018, 5, 29],
            task_id=task.id)
        send_email.assert_called_once()
        assert result == UserInvitation.select().order_by(
            UserInvitation.id.desc()).first().id
Пример #20
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
Пример #21
0
def test_sync_profile(app, mocker):
    """Test sync_profile."""
    mocker.patch(
        "orcid_api_v3.api.DevelopmentMemberAPIV30Api.update_employmentv3",
        return_value=Mock(status=201, headers={'Location': '12344/XYZ/54321'}))
    mocker.patch(
        "orcid_api_v3.api.DevelopmentMemberAPIV30Api.update_educationv3",
        return_value=Mock(status=201, headers={'Location': '12344/XYZ/12345'}))

    def sync_profile_mock(*args, **kwargs):
        utils.sync_profile(*args, **kwargs)
        return Mock(id="test-test-test-test")

    mocker.patch("orcid_hub.utils.sync_profile.queue", sync_profile_mock)

    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="NZ",
        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)

    utils.sync_profile(task_id=999999)

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

    mocker.patch("orcid_hub.orcid_client.MemberAPIV3.get_record",
                 lambda *args: None)
    utils.sync_profile(task_id=t.id, delay=0)

    resp = get_profile()
    mocker.patch("orcid_hub.orcid_client.MemberAPIV3.get_record",
                 lambda *args: resp)
    utils.sync_profile(task_id=t.id, delay=0)

    resp["activities-summary"]["educations"]["affiliation-group"] = []
    mocker.patch("orcid_hub.orcid_client.MemberAPIV3.get_record",
                 lambda *args: resp)
    utils.sync_profile(task_id=t.id, delay=0)

    mocker.patch("orcid_hub.orcid_client.MemberAPIV3.update_employmentv3",
                 side_effect=Exception("FAILED"))
    utils.sync_profile(task_id=t.id, delay=0)

    resp["activities-summary"]["employments"]["affiliation-group"][0][
        "summaries"][0]["employment-summary"]["source"] = None
    resp["activities-summary"]["employments"]["affiliation-group"][0][
        "summaries"][0]["employment-summary"]["source"] = None
    mocker.patch("orcid_hub.orcid_client.MemberAPIV3.get_record",
                 lambda *args: resp)
    utils.sync_profile(task_id=t.id, delay=0)

    org.disambiguated_id = None
    org.save()
    utils.sync_profile(task_id=t.id, delay=0)

    assert Log.select().count() > 0
Пример #22
0
def test_member_api(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.create(name="THE ORGANISATION", confirmed=True, orcid_client_id="CLIENT000")
    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)

    MemberAPI(user=user)
    assert configuration.access_token is None or configuration.access_token == ''

    MemberAPI(user=user, org=org)
    assert configuration.access_token is None or configuration.access_token == ''

    MemberAPI(user=user, org=org, access_token="ACCESS000")
    assert configuration.access_token == 'ACCESS000'

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

    with patch.object(
            api_client.ApiClient, "call_api", side_effect=ApiException(
                reason="FAILURE", status=401)) as call_api:
        with patch.object(OrcidToken, "delete") as delete:
            api.get_record()
            app.logger.error.assert_called_with("ApiException Occured: (401)\nReason: FAILURE\n")
            call_api.assert_called_once()
            delete.assert_called_once()

    with patch.object(
            api_client.ApiClient,
            "call_api",
            side_effect=ApiException(reason="FAILURE 999", status=999)) as call_api:
        api.get_record()
        app.logger.error.assert_called_with("ApiException Occured: (999)\nReason: FAILURE 999\n")

    with patch.object(
            api_client.ApiClient, "call_api", side_effect=ApiException(
                reason="FAILURE", status=401)) as call_api:
        with patch.object(OrcidToken, "get", side_effect=Exception("FAILURE")) as get:
            api.get_record()
            app.logger.exception.assert_called_with(
                "Exception occured while retriving ORCID Token")
            call_api.assert_called_once()
            get.assert_called_once()

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

    # Test API call auditing:
    with patch.object(
            api_client.RESTClientObject.__base__,
            "request",
            return_value=Mock(data=b"""{"mock": "data"}""", status_code=200)) as request_mock:

        api.get_record()

        request_mock.assert_called_once_with(
            _preload_content=False,
            _request_timeout=None,
            body=None,
            headers={
                "Accept": "application/json",
                "User-Agent": "Swagger-Codegen/1.0.0/python",
                "Authorization": "Bearer ACCESS123"
            },
            method="GET",
            post_params=None,
            query_params=None,
            url="https://api.sandbox.orcid.org/v2.0/1001-0001-0001-0001")
        api_call = OrcidApiCall.select().first()
        assert api_call.response == '{"mock": "data"}'
        assert api_call.url == "https://api.sandbox.orcid.org/v2.0/1001-0001-0001-0001"

        with patch.object(OrcidApiCall, "create", side_effect=Exception("FAILURE")) as create:
            api.get_record()
            create.assert_called_once()

    with patch.object(
            api_client.RESTClientObject.__base__,
            "request",
            return_value=Mock(data=None, status_code=200)) as request_mock:
        # api.get_record()
        OrcidApiCall.delete().execute()
        api.view_person("1234-XXXX-XXXX-XXXX")
        api_call = OrcidApiCall.select().first()
        assert api_call.response is None
        assert api_call.url == "https://api.sandbox.orcid.org/v2.0/1234-XXXX-XXXX-XXXX/person"
Пример #23
0
def test_onboard_org(client):
    """Test to organisation onboarding."""
    org = Organisation.create(name="THE ORGANISATION:test_onboard_org",
                              tuakiri_name="THE ORGANISATION:test_onboard_org",
                              confirmed=False,
                              orcid_client_id="CLIENT ID",
                              orcid_secret="Client Secret",
                              city="CITY",
                              country="COUNTRY",
                              disambiguated_id="ID",
                              disambiguation_source="RINGGOLD",
                              is_email_sent=True)
    u = User.create(email="*****@*****.**",
                    name="TEST USER",
                    roles=Role.TECHNICAL,
                    orcid="123",
                    confirmed=True,
                    organisation=org)
    second_user = User.create(email="*****@*****.**",
                              name="TEST USER",
                              roles=Role.ADMIN,
                              orcid="1243",
                              confirmed=True,
                              organisation=org)
    UserOrg.create(user=second_user, org=org, is_admin=True)
    org_info = OrgInfo.create(name="A NEW ORGANISATION",
                              tuakiri_name="A NEW ORGANISATION")
    org.tech_contact = u
    org_info.save()
    org.save()

    client.login_root()
    with patch("orcid_hub.utils.send_email"):
        resp = client.post("/invite/organisation",
                           data=dict(org_name="A NEW ORGANISATION",
                                     org_email="*****@*****.**"),
                           follow_redirects=True)
        assert User.select().where(
            User.email == "*****@*****.**").exists()
        resp = client.post("/invite/organisation",
                           data=dict(org_name="A NEW ORGANISATION",
                                     org_email="*****@*****.**",
                                     tech_contact='y'),
                           follow_redirects=True)
        assert User.select().where(
            User.email == "*****@*****.**").exists()
    org = Organisation.get(name="A NEW ORGANISATION")
    user = User.get(email="*****@*****.**")
    assert user.name is None
    assert org.tech_contact == user
    client.logout()

    resp = client.login(user,
                        **{
                            "Sn": "TECHNICAL",
                            "Givenname": "CONTACT",
                            "Displayname": "Test User",
                            "shib_O": "NEW ORGANISATION"
                        },
                        follow_redirects=True)
    user = User.get(email="*****@*****.**")
    org = user.organisation
    assert user.is_tech_contact_of(org)
    resp = client.get("/confirm/organisation")
    assert resp.status_code == 200
    org = Organisation.get(org.id)
    assert b"<!DOCTYPE html>" in resp.data, "Expected HTML content"
    assert b"Take me to ORCID to obtain my Client ID and Client Secret" in resp.data

    with patch("orcid_hub.authcontroller.requests") as requests:
        requests.post.return_value = Mock(data=b'XXXX', status_code=200)
        resp = client.post("/confirm/organisation",
                           data={
                               "orcid_client_id": "APP-1234567890ABCDEF",
                               "orcid_secret":
                               "12345678-1234-1234-1234-1234567890ab",
                               "country": "NZ",
                               "city": "Auckland",
                               "disambiguated_id": "XYZ123",
                               "disambiguation_source": "RINGGOLD",
                               "name": org.name,
                               "email": user.email,
                           })
    assert resp.status_code == 302
    url = urlparse(resp.location).path
    assert url == "/link"
    resp = client.get(url)
    client.logout()
    org = Organisation.get(org.id)
    assert org.disambiguated_id == "XYZ123"
    assert org.disambiguation_source == "RINGGOLD"
    assert org.orcid_client_id == "APP-1234567890ABCDEF"
    assert org.orcid_secret == "12345678-1234-1234-1234-1234567890ab"

    user = User.get(email="*****@*****.**")
    resp = client.login(user,
                        **{
                            "Sn": "NEW ORGANISATION",
                            "Givenname": "ADMINISTRATOR",
                            "Displayname": "Admin User",
                            "shib_O": "NEW ORGANISATION"
                        },
                        follow_redirects=True)
    assert b"Take me to ORCID to allow A NEW ORGANISATION permission to access my ORCID record" in resp.data
    resp = client.get("/confirm/organisation")
    assert resp.status_code == 302
    assert urlparse(resp.location).path == "/admin/viewmembers/"

    resp = client.get("/admin/viewmembers/")
    assert b"*****@*****.**" in resp.data

    resp = client.get("/admin/viewmembers/export/csv/")
    assert resp.headers["Content-Type"] == "text/csv; charset=utf-8"
    assert b"*****@*****.**" in resp.data
    assert b"*****@*****.**" in resp.data
Пример #24
0
def test_orcid_login_callback_admin_flow(patch, patch2, request_ctx):
    """Test login from orcid callback function for Organisation Technical contact."""
    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="*****@*****.**",
                    roles=Role.TECHNICAL,
                    orcid="123",
                    confirmed=False,
                    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() as resp:
        request.args = {"invitation_token": token, "state": "xyz"}
        session['oauth_state'] = "xyz"
        resp = authcontroller.orcid_login_callback(request)
        assert resp.status_code == 302
        assert resp.location.startswith("/")
    with request_ctx() as respx:
        request.args = {"invitation_token": token, "state": "xyzabc"}
        session['oauth_state'] = "xyz"
        respx = authcontroller.orcid_login_callback(request)
        assert respx.status_code == 302
        assert respx.location.startswith("/")
    with request_ctx() as resp:
        request.args = {
            "invitation_token": token,
            "state": "xyz",
            "error": "access_denied"
        }
        session['oauth_state'] = "xyz"
        resp = authcontroller.orcid_login_callback(request)
        assert resp.status_code == 302
        assert resp.location.startswith("/")
    with request_ctx() as ct:
        token = utils.generate_confirmation_token(email=u.email, org=None)
        request.args = {"invitation_token": token, "state": "xyz"}
        session['oauth_state'] = "xyz"
        ctxx = authcontroller.orcid_login_callback(request)
        assert ctxx.status_code == 302
        assert ctxx.location.startswith("/")
    with request_ctx() as ctxxx:
        request.args = {"invitation_token": token, "state": "xyzabc"}
        session['oauth_state'] = "xyz"
        ctxxx = authcontroller.orcid_login_callback(request)
        assert ctxxx.status_code == 302
        assert ctxxx.location.startswith("/")
    with request_ctx() as cttxx:
        request.args = {
            "invitation_token": token,
            "state": "xyz",
            "error": "access_denied"
        }
        session['oauth_state'] = "xyz"
        cttxx = authcontroller.orcid_login_callback(request)
        assert cttxx.status_code == 302
        assert cttxx.location.startswith("/")
    with request_ctx() as ct:
        token = utils.generate_confirmation_token(email=u.email, org=None)
        request.args = {"invitation_token": token, "state": "xyz"}
        session['oauth_state'] = "xyz"
        ct = authcontroller.orcid_login_callback(request)
        assert ct.status_code == 302
        assert ct.location.startswith("/")
    with request_ctx():
        request.args = {"invitation_token": None, "state": "xyz"}
        session['oauth_state'] = "xyz"
        ct = authcontroller.orcid_login_callback(request)
        assert ct.status_code == 302
        assert ct.location.startswith("/")
    with request_ctx():
        # Test case for catching general exception: invitation token here is integer, so an exception will be thrown.
        request.args = {"invitation_token": 123, "state": "xyz"}
        session['oauth_state'] = "xyz"
        ct = authcontroller.orcid_login_callback(request)
        assert ct.status_code == 302
        assert ct.location.startswith("/")
    with request_ctx():
        # User login via orcid, where organisation is not confirmed.
        u.orcid = "12121"
        u.save()
        request.args = {"invitation_token": None, "state": "xyz"}
        session['oauth_state'] = "xyz"
        resp = authcontroller.orcid_login_callback(request)
        assert resp.status_code == 302
        assert resp.location.startswith("/about")
    with request_ctx():
        # User login via orcid, where organisation is confirmed, so showing viewmembers page.
        org.tech_contact = u
        org.confirmed = True
        org.save()
        request.args = {"invitation_token": None, "state": "xyz"}
        session['oauth_state'] = "xyz"
        resp = authcontroller.orcid_login_callback(request)
        assert resp.status_code == 302
        assert resp.location.startswith("/admin/viewmembers/")
    with request_ctx():
        # User login via orcid, where organisation is not confirmed and user is tech, so showing confirm org page.
        org.confirmed = False
        org.save()
        request.args = {"invitation_token": None, "state": "xyz"}
        session['oauth_state'] = "xyz"
        resp = authcontroller.orcid_login_callback(request)
        assert resp.status_code == 302
        assert resp.location.startswith("/confirm/organisation")
Пример #25
0
def test_orcid_login_callback_admin_flow(mocker, client):
    """Test login from orcid callback function for Organisation Technical contact."""
    mocker.patch("orcid_hub.OAuth2Session.fetch_token",
                 side_effect=fetch_token_mock)
    mocker.patch("orcid_hub.orcid_client.MemberAPIV20Api.view_emails",
                 side_effect=get_record_mock)
    org = Organisation.create(
        name="THE ORGANISATION:test_orcid_login_callback_admin_flow",
        tuakiri_name="THE ORGANISATION:test_orcid_login_callback_admin_flow",
        confirmed=False,
        orcid_client_id="CLIENT ID",
        orcid_secret="Client Secret",
        city="CITY",
        country="COUNTRY",
        disambiguated_id="ID",
        disambiguation_source="RINGGOLD",
        is_email_sent=True)
    u = User.create(email="*****@*****.**",
                    roles=Role.TECHNICAL,
                    orcid="123",
                    confirmed=False,
                    organisation=org)
    UserOrg.create(user=u, org=org, is_admin=True)
    token = utils.new_invitation_token()
    OrgInvitation.create(token=token, univitee=u, email=u.email, org=org)

    resp = client.get(f"/orcid/login/{token}")
    assert resp.status_code == 200
    assert token.encode() in resp.data

    state = session["oauth_state"]

    resp = client.get(f"/auth/?invitation_token={token}&state={state}&login=1")
    assert resp.status_code == 302
    assert urlparse(resp.location).path == "/"

    resp = client.get(
        f"/auth/?invitation_token={token}&state={state}abc&login=1")
    assert resp.status_code == 302
    assert urlparse(resp.location).path == "/"

    resp = client.get(
        f"/auth/?invitation_token={token}&state={state}&error=access_denied&login=1"
    )
    assert resp.status_code == 302
    assert urlparse(resp.location).path == "/"

    resp = client.get(f"/auth/?state=xyz&login=1")
    assert resp.status_code == 302
    assert urlparse(resp.location).path == "/"

    resp = client.get(
        f"/auth/?invitation_token=abc12345&state={state}ABC&login=1")
    assert resp.status_code == 302
    assert urlparse(resp.location).path == "/"

    # User login via orcid, where organisation is not confirmed.
    u.orcid = "123"
    u.save()
    resp = client.get(f"/auth/?state={state}&login=1")
    assert resp.status_code == 302
    assert urlparse(resp.location).path == "/about"

    # User login via orcid, where organisation is confirmed, so showing viewmembers page.
    org.tech_contact = u
    org.confirmed = True
    org.save()
    resp = client.get(f"/auth/?state={state}&login=1")
    assert resp.status_code == 302
    assert urlparse(resp.location).path == "/admin/viewmembers/"

    # User login via orcid, where organisation is not confirmed and user is tech, so showing confirm org page.
    org.confirmed = False
    org.save()
    resp = client.get(f"/auth/?state={state}&login=1")
    assert resp.status_code == 302
    assert urlparse(resp.location).path == "/confirm/organisation"
Пример #26
0
def test_orcid_login_callback_researcher_flow(client, mocker):
    """Test login from orcid callback function for researcher and display profile."""
    fetch_token = mocker.patch("orcid_hub.OAuth2Session.fetch_token",
                               side_effect=fetch_token_mock)
    mocker.patch(
        "orcid_hub.orcid_client.MemberAPI.create_or_update_affiliation",
        side_effect=affiliation_mock)
    org = Organisation.create(
        name="THE ORGANISATION:test_orcid_login_callback_researcher_flow",
        tuakiri_name=
        "THE ORGANISATION:test_orcid_login_callback_researcher_flow",
        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)
    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.new_invitation_token()
    UserInvitation.create(email=u.email,
                          token=token,
                          affiliations=Affiliation.EMP,
                          org=org,
                          invitee=u)

    resp = client.get(f"/orcid/login/{token}")
    assert resp.status_code == 200
    assert token.encode() in resp.data

    state = session['oauth_state']

    resp = client.get(f"/auth/?state={state}&login=1")
    assert resp.status_code == 302
    assert resp.location.endswith("/link")
    fetch_token.assert_called_once()

    resp = client.get(f"/auth/?invitation_token={token}&login=1")
    assert resp.status_code == 302
    assert urlparse(resp.location).path == "/"
    fetch_token.assert_called_once()

    resp = client.get(f"/auth/?invitation_token={token}&login=1",
                      follow_redirects=True)
    assert b"Danger" in resp.data
    assert b"Something went wrong, Please retry giving permissions " in resp.data

    fetch_token.reset_mock()
    resp = client.get(f"/auth/?invitation_token={token}&state={state}",
                      follow_redirects=True)
    assert b"Warning" in resp.data
    assert b"The ORCID Hub was not able to automatically write an affiliation" in resp.data

    OrcidToken.delete().where(OrcidToken.user == u,
                              OrcidToken.org == org).execute()
    fetch_token.reset_mock()
    resp = client.get(f"/auth/?invitation_token={token}&state={state}&login=1")
    assert resp.status_code == 302
    assert resp.location.endswith("/profile")
    fetch_token.assert_called_once()
    assert OrcidToken.select().where(OrcidToken.user == u).count() == 1

    resp = client.get(f"/orcid/login/{token}", follow_redirects=True)
    assert b"You have already given permission" in resp.data
Пример #27
0
def test_onboard_org(request_ctx):
    """Test to organisation onboarding."""
    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)
    second_user = User.create(email="*****@*****.**",
                              name="TEST USER",
                              roles=Role.ADMIN,
                              orcid="1243",
                              confirmed=True,
                              organisation=org)
    org_info = OrgInfo.create(name="THE ORGANISATION",
                              tuakiri_name="THE ORGANISATION")
    org.tech_contact = u
    org_info.save()
    org.save()

    OrgInvitation.get_or_create(email=u.email, org=org, token="sdsddsd")
    UserOrg.create(user=u, org=org, is_admin=True)

    with request_ctx("/confirm/organisation") as ctx:
        login_user(u)
        u.save()
        assert u.is_tech_contact_of(org)
        rv = ctx.app.full_dispatch_request()
        assert rv.status_code == 200
        assert b"<!DOCTYPE html>" in rv.data, "Expected HTML content"
        assert b"Take me to ORCID to obtain my Client ID and Client Secret" in rv.data,\
            "Expected Button on the confirmation page"
    with request_ctx("/confirm/organisation") as ctxx:
        second_user.save()
        login_user(second_user)
        rv = ctxx.app.full_dispatch_request()
        assert rv.status_code == 302
        assert rv.location.startswith("/admin/viewmembers/")
    with request_ctx("/confirm/organisation",
                     method="POST",
                     data={
                         "orcid_client_id": "APP-FDFN3F52J3M4L34S",
                         "orcid_secret":
                         "4916c2d7-085e-487e-94d0-32450a9cfe6c",
                         "country": "NZ",
                         "city": "Auckland",
                         "disambiguated_id": "xyz",
                         "disambiguation_source": "xyz",
                         "name": "THE ORGANISATION"
                     }) as cttxx:
        login_user(u)
        u.save()
        with patch("orcid_hub.authcontroller.requests") as requests:
            requests.post.return_value = Mock(data=b'XXXX', status_code=200)
            rv = cttxx.app.full_dispatch_request()
            assert rv.status_code == 302
            assert rv.location.startswith("/link")