Skip to content

2610 orcid tokens#5110

Open
everreau wants to merge 13 commits intoopenlibhums:masterfrom
everreau:2610-orcid-tokens
Open

2610 orcid tokens#5110
everreau wants to merge 13 commits intoopenlibhums:masterfrom
everreau:2610-orcid-tokens

Conversation

@everreau
Copy link
Contributor

Addresses: #2610

When orcid is enabled:

  • Save orcid auth token and expiration when orcid is authenticated
  • Allow users to add orcid via authentication
  • When orcid is removed by admin or user revoke token
  • Notify users when token is not valid in profile and edit user views
  • Don't allow users to manually edit orcids.
  • Allow co-authors to request orcids

@everreau
Copy link
Contributor Author

supersedes: #4399

@everreau everreau requested a review from alainna January 27, 2026 19:11
@alainna
Copy link
Contributor

alainna commented Jan 28, 2026

So great, @everreau! I've suggested some changes in line with ORCID's brand guidelines

This is only for journals at the moment, is that correct? Could the co-author use the ORCID login option to connect their iD to their account rather than connecting the iD in their profile? What happens if the co-author is a frozen author without an account, or if the account isn't active?

@everreau
Copy link
Contributor Author

everreau commented Feb 2, 2026

@alainna. All of the login features also work for preprints. I don't see any reference at all to orcids in the preprint author interface. I think we (cdl) would send whatever orcid was in the author's account to crossref even though it's not visible and it appears in the preprint front end. The profile and the account are the same as far as I know. The interface on main is a bit different than what we're currently running. Maybe we should setup a time so you can take a look at what I have. I hadn't really thought about what would happen if a user connects their orcid after the frozen authors were already made. I'll take a look at that.

@ajrbyers
Copy link
Member

ajrbyers commented Feb 4, 2026

@alainna. All of the login features also work for preprints. I don't see any reference at all to orcids in the preprint author interface. I think we (cdl) would send whatever orcid was in the author's account to crossref even though it's not visible and it appears in the preprint front end. The profile and the account are the same as far as I know. The interface on main is a bit different than what we're currently running. Maybe we should setup a time so you can take a look at what I have. I hadn't really thought about what would happen if a user connects their orcid after the frozen authors were already made. I'll take a look at that.

On the FrozenAuthor object orcid is a property that will either return FrozenAuthor.frozen_orcid atrribute and if there is none check if the linked account has an orcid attribute and return that instead.

@ajrbyers
Copy link
Member

ajrbyers commented Feb 4, 2026

@joemull can you do the first technical review on this and then pass it to me please?

@joemull
Copy link
Member

joemull commented Feb 5, 2026

Just an update: I should be able to get to this later next week 16 or 17 Feb.

@alainna
Copy link
Contributor

alainna commented Feb 10, 2026

Some suggestions for this dev: eScholarship#46

Copy link
Member

@joemull joemull left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is hugely appreciated--thank you for putting it in.

I'm having trouble testing it out (an issue with OLH's ORCID sandbox that will take a few days to resolve), but I've gone ahead and given you some comments from reading the code. Hope they're clear but please do ping me if anything does not make sense.

response = self.client.get(reverse("core_edit_profile"))
self.assertContains(response, "ORCID iD could not be validated.")
self.assertContains(response, "Connect your ORCID")
self.assertContains(response, "https://sandbox.orcid.org/0000-0000-0000-0000")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this test (or any of the ones below) rely on a network connection? We'll need to put mocks into any test that relies on a network connection.

response, '<input type="text" name="orcid" maxlength="40" id="id_orcid">'
)

def test_profile_orcid_enabled_no_orcid(self):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe add an override_settings decorator on this and other tests that expect ENABLE_ORCID=True, in case someone has it off and runs tests.

orcid = models.CharField(
max_length=40, null=True, blank=True, verbose_name=_("ORCiD")
)
orcid_token = models.CharField(max_length=40, null=True, blank=True)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Charfields should not have null=True

expiry = models.DateTimeField(
default=generate_expiry_date, verbose_name=_("Expires on")
)
access_token = models.CharField(max_length=40, null=True, blank=True)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as the other one--charfields should not have null=True

messages.SUCCESS,
_("Your ORCID has been connected to your account."),
)
return redirect(logic.reverse_with_next("core_edit_profile", next_url))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Haven't been able to test this yet but I'm actually having trouble working out what's happening just by reading it, especially the case where they're not authenticated and they get sent to a different login screen. Can you add a comment above with context, like the other if / else branches have?

<tr>
<th>{% trans 'Name' %}</th>
<th>{% trans 'Email' %}</th>
<th>{% trans 'ORCID' %}</th>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"ORCID iD"?

"type": "rich-text"
},
"value": {
"default": "<p>Dear {{ user.full_name }}<br/><br/>Your co-author has requested your ORCID iD. You can add it by through your profile {{ user_profile_url }}.<br/></p>"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Typo: "by through"

"editor",
"journal-manager"
]
},
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It looks like this separate template isn't needed, since the email text is the same and the link is the same. Only the subject differs. Is there another reason for it?

def is_token_valid(orcid_id, token):
api_client = OrcidAPI(
settings.ORCID_CLIENT_ID, settings.ORCID_CLIENT_SECRET, sandbox=True
)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The sandbox parameter needs to be able to change in production. Maybe it should be based on whether sandbox.orcid.org is present in the URL in settings.py?

logger.info("Retrieving ORCID profile for %s", orcid)
api_client = OrcidAPI(settings.ORCID_CLIENT_ID, settings.ORCID_CLIENT_SECRET)
api_client = OrcidAPI(
settings.ORCID_CLIENT_ID, settings.ORCID_CLIENT_SECRET, sandbox=True
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same comment about changing sandbox in production.

@joemull joemull assigned everreau and unassigned joemull Feb 16, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants