Skip to content

Commit

Permalink
Merged in CST-10704 (pull request DSpace#1163)
Browse files Browse the repository at this point in the history
CST-10704

Approved-by: Giuseppe Digilio
  • Loading branch information
vins01-4science authored and atarix83 committed Oct 10, 2023
2 parents 20d7dc5 + ac0dad3 commit 3ecb092
Show file tree
Hide file tree
Showing 43 changed files with 3,328 additions and 193 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,10 @@
import org.dspace.core.Context;
import org.dspace.eperson.EPerson;
import org.dspace.eperson.Group;
import org.dspace.eperson.RegistrationData;
import org.dspace.eperson.RegistrationTypeEnum;
import org.dspace.eperson.service.EPersonService;
import org.dspace.eperson.service.RegistrationDataService;
import org.dspace.orcid.OrcidToken;
import org.dspace.orcid.client.OrcidClient;
import org.dspace.orcid.client.OrcidConfiguration;
Expand All @@ -47,11 +50,15 @@
* ORCID authentication for DSpace.
*
* @author Luca Giamminonni (luca.giamminonni at 4science.it)
*
*/
public class OrcidAuthenticationBean implements AuthenticationMethod {


public static final String ORCID_DEFAULT_FIRSTNAME = "Unnamed";
public static final String ORCID_DEFAULT_LASTNAME = ORCID_DEFAULT_FIRSTNAME;
public static final String ORCID_AUTH_ATTRIBUTE = "orcid-authentication";
public static final String ORCID_REGISTRATION_TOKEN = "orcid-registration-token";
public static final String ORCID_DEFAULT_REGISTRATION_URL = "/external-login/{0}";

private final static Logger LOGGER = LoggerFactory.getLogger(OrcidAuthenticationBean.class);

Expand All @@ -78,6 +85,9 @@ public class OrcidAuthenticationBean implements AuthenticationMethod {
@Autowired
private OrcidTokenService orcidTokenService;

@Autowired
private RegistrationDataService registrationDataService;

@Override
public int authenticate(Context context, String username, String password, String realm, HttpServletRequest request)
throws SQLException {
Expand Down Expand Up @@ -184,7 +194,7 @@ private int authenticateWithOrcid(Context context, String code, HttpServletReque
return ePerson.canLogIn() ? logInEPerson(context, token, ePerson) : BAD_ARGS;
}

return canSelfRegister() ? registerNewEPerson(context, person, token) : NO_SUCH_USER;
return canSelfRegister() ? createRegistrationData(context, request, person, token) : NO_SUCH_USER;

}

Expand Down Expand Up @@ -212,48 +222,59 @@ private ResearcherProfile findProfile(Context context, EPerson ePerson) throws S
}
}

private int registerNewEPerson(Context context, Person person, OrcidTokenResponseDTO token) throws SQLException {
private int createRegistrationData(
Context context, HttpServletRequest request, Person person, OrcidTokenResponseDTO token
) throws SQLException {

try {
context.turnOffAuthorisationSystem();

String email = getEmail(person)
.orElseThrow(() -> new IllegalStateException("The email is configured private on orcid"));

String orcid = token.getOrcid();

EPerson eperson = ePersonService.create(context);
RegistrationData registrationData =
this.registrationDataService.create(context, token.getOrcid(), RegistrationTypeEnum.ORCID);

eperson.setNetid(orcid);
registrationData.setEmail(getEmail(person).orElse(null));
setOrcidMetadataOnRegistration(context, registrationData, person, token);

eperson.setEmail(email);
registrationDataService.update(context, registrationData);

Optional<String> firstName = getFirstName(person);
if (firstName.isPresent()) {
eperson.setFirstName(context, firstName.get());
}

Optional<String> lastName = getLastName(person);
if (lastName.isPresent()) {
eperson.setLastName(context, lastName.get());
}
eperson.setCanLogIn(true);
eperson.setSelfRegistered(true);

setOrcidMetadataOnEPerson(context, eperson, token);

ePersonService.update(context, eperson);
context.setCurrentUser(eperson);
request.setAttribute(ORCID_REGISTRATION_TOKEN, registrationData.getToken());
context.commit();
context.dispatchEvents();

return SUCCESS;

} catch (Exception ex) {
LOGGER.error("An error occurs registering a new EPerson from ORCID", ex);
context.rollback();
return NO_SUCH_USER;
} finally {
context.restoreAuthSystemState();
return NO_SUCH_USER;
}
}

private void setOrcidMetadataOnRegistration(
Context context, RegistrationData registration, Person person, OrcidTokenResponseDTO token
) throws SQLException, AuthorizeException {
String orcid = token.getOrcid();

setRegistrationMetadata(context, registration, "eperson.firstname", getFirstName(person));
setRegistrationMetadata(context, registration, "eperson.lastname", getLastName(person));
registrationDataService.setRegistrationMetadataValue(context, registration, "eperson", "orcid", null, orcid);

for (String scope : token.getScopeAsArray()) {
registrationDataService.addMetadata(context, registration, "eperson", "orcid", "scope", scope);
}
}

private void setRegistrationMetadata(
Context context, RegistrationData registration, String metadataString, String value) {
String[] split = metadataString.split("\\.");
String qualifier = split.length > 2 ? split[2] : null;
try {
registrationDataService.setRegistrationMetadataValue(
context, registration, split[0], split[1], qualifier, value
);
} catch (SQLException | AuthorizeException ex) {
LOGGER.error("An error occurs setting metadata", ex);
throw new RuntimeException(ex);
}
}

Expand Down Expand Up @@ -296,16 +317,20 @@ private Optional<String> getEmail(Person person) {
return Optional.ofNullable(emails.get(0).getEmail());
}

private Optional<String> getFirstName(Person person) {
private String getFirstName(Person person) {
return Optional.ofNullable(person.getName())
.map(name -> name.getGivenNames())
.map(givenNames -> givenNames.getContent());
.map(name -> name.getGivenNames())
.map(givenNames -> givenNames.getContent())
.filter(StringUtils::isNotBlank)
.orElse(ORCID_DEFAULT_FIRSTNAME);
}

private Optional<String> getLastName(Person person) {
private String getLastName(Person person) {
return Optional.ofNullable(person.getName())
.map(name -> name.getFamilyName())
.map(givenNames -> givenNames.getContent());
.map(name -> name.getFamilyName())
.map(givenNames -> givenNames.getContent())
.filter(StringUtils::isNotBlank)
.orElse(ORCID_DEFAULT_LASTNAME);
}

private boolean canSelfRegister() {
Expand Down
Loading

0 comments on commit 3ecb092

Please sign in to comment.