Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

O auth migration #7176

Draft
wants to merge 21 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 11 additions & 1 deletion orcid-core/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -326,8 +326,18 @@
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>4.4.3</version>
<version>3.7.1</version>
</dependency>


<!-- https://mvnrepository.com/artifact/org.json/json -->
<dependency>
<groupId>org.json</groupId>
<artifactId>json</artifactId>
<version>20240303</version>
</dependency>


</dependencies>
<build>
<plugins>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package org.orcid.core.common.util;

import org.apache.commons.lang3.StringUtils;
import org.orcid.core.oauth.OrcidProfileUserDetails;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;

public class AuthenticationUtils {

public static String retrieveEffectiveOrcid() {
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
if (authentication.getDetails() != null) {
if(OrcidProfileUserDetails.class.isAssignableFrom(authentication.getDetails().getClass())) {
return ((OrcidProfileUserDetails) authentication.getDetails()).getOrcid();
} else {
// From the authorization server we will get the effective user from authentication.getName()
String orcid = authentication.getName();
if(StringUtils.isNotBlank(orcid)) {
return orcid;
}
}
}
return null;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

import javax.annotation.Resource;

import org.orcid.core.common.util.AuthenticationUtils;
import org.orcid.core.manager.ClientDetailsManager;
import org.orcid.core.manager.SourceManager;
import org.orcid.core.manager.SourceNameCacheManager;
Expand Down Expand Up @@ -50,7 +51,7 @@ public String retrieveSourceOrcid() {
return authorizationRequest.getClientId();
}
// Normal web user
return retrieveEffectiveOrcid(authentication);
return AuthenticationUtils.retrieveEffectiveOrcid();
}

@Override
Expand All @@ -73,7 +74,7 @@ public SourceEntity retrieveSourceEntity() {

return sourceEntity;
}
String userOrcid = retrieveEffectiveOrcid(authentication);
String userOrcid = AuthenticationUtils.retrieveEffectiveOrcid();
if(userOrcid == null){
// Must be system role
return null;
Expand All @@ -86,25 +87,14 @@ public SourceEntity retrieveSourceEntity() {
return sourceEntity;
}

private String retrieveEffectiveOrcid(Authentication authentication) {
if (authentication.getDetails() != null && OrcidProfileUserDetails.class.isAssignableFrom(authentication.getDetails().getClass())) {
return ((OrcidProfileUserDetails) authentication.getDetails()).getOrcid();
}
return null;
}

private String retrieveEffectiveOrcid() {
return retrieveEffectiveOrcid(SecurityContextHolder.getContext().getAuthentication());
}

@Override
public boolean isInDelegationMode() {
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
String realUserOrcid = getRealUserIfInDelegationMode(authentication);
if (realUserOrcid == null) {
return false;
}
return !retrieveEffectiveOrcid().equals(realUserOrcid);
return !AuthenticationUtils.retrieveEffectiveOrcid().equals(realUserOrcid);
}

@Override
Expand All @@ -124,7 +114,7 @@ public String retrieveRealUserOrcid() {
return realUserIfInDelegationMode;
}
// Normal web user
return retrieveEffectiveOrcid(authentication);
return AuthenticationUtils.retrieveEffectiveOrcid();
}

private String getRealUserIfInDelegationMode(Authentication authentication) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import javax.annotation.Resource;

import org.apache.commons.lang3.StringUtils;
import org.orcid.core.common.util.AuthenticationUtils;
import org.orcid.core.manager.ClientDetailsManager;
import org.orcid.core.manager.SourceNameCacheManager;
import org.orcid.core.manager.v3.SourceManager;
Expand Down Expand Up @@ -68,7 +69,7 @@ public String retrieveActiveSourceId() {
return authorizationRequest.getClientId();
}
// Normal web user
return retrieveEffectiveOrcid(authentication);
return AuthenticationUtils.retrieveEffectiveOrcid();
}

/** This should be used by managers that need active Source information, including OBO.
Expand Down Expand Up @@ -106,7 +107,7 @@ public Source retrieveActiveSource() {
}
return source;
}
String userOrcid = retrieveEffectiveOrcid(authentication);
String userOrcid = AuthenticationUtils.retrieveEffectiveOrcid();
if(userOrcid == null){
// Must be system role
return null;
Expand Down Expand Up @@ -137,7 +138,7 @@ public SourceEntity retrieveActiveSourceEntity() {
sourceEntity.setSourceClient(new ClientDetailsEntity(clientId, clientDetails.getClientName()));
return sourceEntity;
}
String userOrcid = retrieveEffectiveOrcid(authentication);
String userOrcid = AuthenticationUtils.retrieveEffectiveOrcid();
if(userOrcid == null){
// Must be system role
return null;
Expand All @@ -150,25 +151,14 @@ public SourceEntity retrieveActiveSourceEntity() {
return sourceEntity;
}

private String retrieveEffectiveOrcid(Authentication authentication) {
if (authentication.getDetails() != null && OrcidProfileUserDetails.class.isAssignableFrom(authentication.getDetails().getClass())) {
return ((OrcidProfileUserDetails) authentication.getDetails()).getOrcid();
}
return null;
}

private String retrieveEffectiveOrcid() {
return retrieveEffectiveOrcid(SecurityContextHolder.getContext().getAuthentication());
}

@Override
public boolean isInDelegationMode() {
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
String realUserOrcid = getRealUserIfInDelegationMode(authentication);
if (realUserOrcid == null) {
return false;
}
return !retrieveEffectiveOrcid().equals(realUserOrcid);
return !AuthenticationUtils.retrieveEffectiveOrcid().equals(realUserOrcid);
}

@Override
Expand All @@ -188,7 +178,7 @@ public String retrieveRealUserOrcid() {
return realUserIfInDelegationMode;
}
// Normal web user
return retrieveEffectiveOrcid(authentication);
return AuthenticationUtils.retrieveEffectiveOrcid();
}

private String getRealUserIfInDelegationMode(Authentication authentication) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,9 @@ public interface EmailManagerReadOnly extends ManagerReadOnlyBase {

EmailEntity find(String email);

Email findPrimaryEmail(String orcid);
Email findPrimaryEmail(String orcid);

String findPrimaryEmailValueFromCache(String orcid);

EmailFrequencyOptions getEmailFrequencyOptions();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
import org.orcid.utils.OrcidStringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.cache.annotation.Cacheable;

/**
*
Expand Down Expand Up @@ -185,7 +186,17 @@ public Email findPrimaryEmail(String orcid) {
}
return jpaJaxbEmailAdapter.toEmail(emailDao.findPrimaryEmail(orcid));
}


@Override
@Cacheable("primary-email-value")
public String findPrimaryEmailValueFromCache(String orcid) {
if(PojoUtil.isEmpty(orcid)) {
return null;
}
EmailEntity entity = emailDao.findPrimaryEmail(orcid);
return entity.getEmail();
}

@Override
public boolean isUsersOnlyEmail(String orcid, String email) {
List<EmailEntity> emails = emailDao.findByOrcid(orcid, getLastModified(orcid));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,26 +13,19 @@ public class OrcidProfileUserDetails implements UserDetails {

private static final long serialVersionUID = 1L;

private String orcid;
private final String orcid;

private String primaryEmail;

private String password;
private final String password;

private Collection<OrcidWebRole> grantedAuthorities = new HashSet<>();

public OrcidProfileUserDetails() {
}

public OrcidProfileUserDetails(String orcid, String primaryEmail, String password) {
public OrcidProfileUserDetails(String orcid, String password) {
this.orcid = orcid;
this.primaryEmail = primaryEmail;
this.password = password;
}

public OrcidProfileUserDetails(String orcid, String primaryEmail, String password, Collection<OrcidWebRole> grantedAuthorities) {
public OrcidProfileUserDetails(String orcid, String password, Collection<OrcidWebRole> grantedAuthorities) {
this.orcid = orcid;
this.primaryEmail = primaryEmail;
this.password = password;
this.grantedAuthorities = grantedAuthorities;
}
Expand Down Expand Up @@ -122,18 +115,13 @@ public String getOrcid() {
return orcid;
}

public String getPrimaryEmail() {
return primaryEmail;
}

@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((grantedAuthorities == null) ? 0 : grantedAuthorities.hashCode());
result = prime * result + ((orcid == null) ? 0 : orcid.hashCode());
result = prime * result + ((password == null) ? 0 : password.hashCode());
result = prime * result + ((primaryEmail == null) ? 0 : primaryEmail.hashCode());
return result;
}

Expand Down Expand Up @@ -161,11 +149,6 @@ public boolean equals(Object obj) {
return false;
} else if (!password.equals(other.password))
return false;
if (primaryEmail == null) {
if (other.primaryEmail != null)
return false;
} else if (!primaryEmail.equals(other.primaryEmail))
return false;
return true;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,13 +53,13 @@ public class OrcidUserDetailsServiceImpl implements OrcidUserDetailsService {

@Resource
private EmailDao emailDao;

@Resource(name = "emailManagerReadOnlyV3")
protected EmailManagerReadOnly emailManagerReadOnly;


@Resource
private OrcidSecurityManager securityMgr;

@Resource (name = "emailManagerReadOnlyV3")
private EmailManagerReadOnly emailManagerReadOnly;

@Value("${org.orcid.core.baseUri}")
private String baseUrl;

Expand Down Expand Up @@ -107,43 +107,19 @@ public OrcidProfileUserDetails loadUserByProfile(ProfileEntity profile) {
}

private OrcidProfileUserDetails createUserDetails(ProfileEntity profile) {
String primaryEmail = retrievePrimaryEmail(profile);

String primaryEmail = retrievePrimaryEmail(profile.getId());
OrcidProfileUserDetails userDetails = null;

if (profile.getOrcidType() != null) {
OrcidType orcidType = OrcidType.valueOf(profile.getOrcidType());
userDetails = new OrcidProfileUserDetails(profile.getId(), primaryEmail, profile.getEncryptedPassword(), buildAuthorities(orcidType, profile.getGroupType() != null ? MemberType.valueOf(profile.getGroupType()) : null));
userDetails = new OrcidProfileUserDetails(profile.getId(), profile.getEncryptedPassword(), buildAuthorities(orcidType, profile.getGroupType() != null ? MemberType.valueOf(profile.getGroupType()) : null));
} else {
userDetails = new OrcidProfileUserDetails(profile.getId(), primaryEmail, profile.getEncryptedPassword());
userDetails = new OrcidProfileUserDetails(profile.getId(), profile.getEncryptedPassword());
}

return userDetails;
}

private String retrievePrimaryEmail(ProfileEntity profile) {
String orcid = profile.getId();
try {
return emailDao.findPrimaryEmail(orcid).getEmail();
} catch (javax.persistence.NoResultException nre) {
String alternativePrimaryEmail = emailDao.findNewestVerifiedOrNewestEmail(profile.getId());
emailDao.updatePrimary(orcid, alternativePrimaryEmail);

String message = String.format("User with orcid %s have no primary email, so, we are setting the newest verified email, or, the newest email in case non is verified as the primary one", orcid);
LOGGER.error(message);

return alternativePrimaryEmail;
} catch (javax.persistence.NonUniqueResultException nure) {
String alternativePrimaryEmail = emailDao.findNewestPrimaryEmail(profile.getId());
emailDao.updatePrimary(orcid, alternativePrimaryEmail);

String message = String.format("User with orcid %s have more than one primary email, so, we are setting the latest modified primary as the primary one", orcid);
LOGGER.error(message);

return alternativePrimaryEmail;
}
}

private void checkStatuses(ProfileEntity profile) {
if (profile.getPrimaryRecord() != null) {
throw new DeprecatedProfileException("orcid.frontend.security.deprecated_with_primary", profile.getPrimaryRecord().getId(), profile.getId());
Expand Down Expand Up @@ -207,9 +183,25 @@ else if (orcidType.equals(OrcidType.GROUP)) {
}

private List<OrcidWebRole> rolesAsList(OrcidWebRole... roles) {
// Make a mutable list
List<OrcidWebRole> list = new ArrayList<OrcidWebRole>(Arrays.asList(roles));
return list;
return new ArrayList<OrcidWebRole>(Arrays.asList(roles));
}

@Deprecated(forRemoval = true)
private String retrievePrimaryEmail(String orcid) {
try {
return emailDao.findPrimaryEmail(orcid).getEmail();
} catch (javax.persistence.NoResultException nre) {
String alternativePrimaryEmail = emailDao.findNewestVerifiedOrNewestEmail(orcid);
emailDao.updatePrimary(orcid, alternativePrimaryEmail);
String message = String.format("User with orcid %s have no primary email, so, we are setting the newest verified email, or, the newest email in case non is verified as the primary one", orcid);
LOGGER.error(message);
return alternativePrimaryEmail;
} catch (javax.persistence.NonUniqueResultException nure) {
String alternativePrimaryEmail = emailDao.findNewestPrimaryEmail(orcid);
emailDao.updatePrimary(orcid, alternativePrimaryEmail);
String message = String.format("User with orcid %s have more than one primary email, so, we are setting the latest modified primary as the primary one", orcid);
LOGGER.error(message);
return alternativePrimaryEmail;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ static public void clearSecurityContext() {
}

static public void setupSecurityContextForWebUser(String userId, String email) {
OrcidProfileUserDetails details = new OrcidProfileUserDetails(userId, email, "password");
OrcidProfileUserDetails details = new OrcidProfileUserDetails(userId, email);
UsernamePasswordAuthenticationToken auth = new UsernamePasswordAuthenticationToken(userId, "password");
auth.setDetails(details);
SecurityContextImpl securityContext = new SecurityContextImpl();
Expand Down
Loading
Loading