From e1cd09b068bea0decdd8bca818c43df688a1d1ad Mon Sep 17 00:00:00 2001 From: Gcolon021 <34667267+Gcolon021@users.noreply.github.com> Date: Tue, 3 Oct 2023 15:20:34 -0400 Subject: [PATCH] Open Access without login (#136) [ALS-4793] By pass Fence for Open Access [ALS-4793] Fix User Roles [ALS-4793] Remove unnecessary logging [ALS-4793] Tmp Solution to potential security hole [ALS-4793] Remove error message [ALS-4793] Modify PSAMA to bypass fence [ALS-4356] Support for open datasets [ALS-4981] Validate the fence code [ALS-4981] Handle Medium Security Findings --- .../avillach/auth/JAXRSConfiguration.java | 13 +- .../auth/data/repository/UserRepository.java | 314 ++++++++++-------- .../dbmi/avillach/auth/rest/AuthService.java | 3 - .../avillach/auth/rest/OpenAuthService.java | 49 +++ .../dbmi/avillach/auth/rest/UserService.java | 6 +- .../service/auth/AuthenticationService.java | 1 - .../auth/FENCEAuthenticationService.java | 8 +- .../auth/OpenAuthenticationService.java | 67 ++++ .../dbmi/avillach/auth/utils/AuthUtils.java | 11 +- 9 files changed, 319 insertions(+), 153 deletions(-) create mode 100644 pic-sure-auth-services/src/main/java/edu/harvard/hms/dbmi/avillach/auth/rest/OpenAuthService.java create mode 100644 pic-sure-auth-services/src/main/java/edu/harvard/hms/dbmi/avillach/auth/service/auth/OpenAuthenticationService.java diff --git a/pic-sure-auth-services/src/main/java/edu/harvard/hms/dbmi/avillach/auth/JAXRSConfiguration.java b/pic-sure-auth-services/src/main/java/edu/harvard/hms/dbmi/avillach/auth/JAXRSConfiguration.java index d0f7a11e3..54756508e 100755 --- a/pic-sure-auth-services/src/main/java/edu/harvard/hms/dbmi/avillach/auth/JAXRSConfiguration.java +++ b/pic-sure-auth-services/src/main/java/edu/harvard/hms/dbmi/avillach/auth/JAXRSConfiguration.java @@ -2,7 +2,6 @@ import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.databind.type.MapType; import edu.harvard.hms.dbmi.avillach.auth.data.entity.Connection; import edu.harvard.hms.dbmi.avillach.auth.data.entity.Privilege; import edu.harvard.hms.dbmi.avillach.auth.data.entity.Role; @@ -11,7 +10,6 @@ import edu.harvard.hms.dbmi.avillach.auth.data.repository.RoleRepository; import edu.harvard.hms.dbmi.avillach.auth.rest.TokenService; import io.swagger.jaxrs.config.BeanConfig; -import org.apache.commons.io.IOUtils; import org.apache.http.client.HttpClient; import org.apache.http.impl.client.HttpClientBuilder; import org.slf4j.Logger; @@ -28,13 +26,10 @@ import javax.ws.rs.ApplicationPath; import javax.ws.rs.core.Application; import javax.ws.rs.core.SecurityContext; -import java.io.InputStream; -import java.net.URL; -import java.nio.charset.StandardCharsets; -import java.nio.file.Files; -import java.nio.file.Paths; -import java.util.*; -import javax.net.ssl.*; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; import static edu.harvard.hms.dbmi.avillach.auth.utils.AuthNaming.AuthRoleNaming.ADMIN; import static edu.harvard.hms.dbmi.avillach.auth.utils.AuthNaming.AuthRoleNaming.SUPER_ADMIN; diff --git a/pic-sure-auth-services/src/main/java/edu/harvard/hms/dbmi/avillach/auth/data/repository/UserRepository.java b/pic-sure-auth-services/src/main/java/edu/harvard/hms/dbmi/avillach/auth/data/repository/UserRepository.java index a627ccd5f..6973e0f2e 100644 --- a/pic-sure-auth-services/src/main/java/edu/harvard/hms/dbmi/avillach/auth/data/repository/UserRepository.java +++ b/pic-sure-auth-services/src/main/java/edu/harvard/hms/dbmi/avillach/auth/data/repository/UserRepository.java @@ -13,152 +13,198 @@ import javax.persistence.NonUniqueResultException; import javax.persistence.criteria.*; import javax.transaction.Transactional; -import java.util.Date; -import java.util.List; -import java.util.Set; -import java.util.UUID; +import java.util.*; import java.util.stream.Collectors; /** *

Provides operations for the User entity to interact with a database.

+ * * @see User */ @Transactional @ApplicationScoped public class UserRepository extends BaseRepository { - private Logger logger = LoggerFactory.getLogger(UserRepository.class); - - protected UserRepository() { - super(User.class); - } - - public User findBySubject(String subject) { - CriteriaQuery query = em.getCriteriaBuilder().createQuery(User.class); - Root queryRoot = query.from(User.class); - query.select(queryRoot); - CriteriaBuilder cb = cb(); - return em.createQuery(query - .where( - eq(cb, queryRoot, "subject", subject))) - .getSingleResult(); - } - - public User findBySubjectAndConnection(String subject, String connectionId){ - CriteriaQuery query = em.getCriteriaBuilder().createQuery(User.class); - Root queryRoot = query.from(User.class); - query.select(queryRoot); - CriteriaBuilder cb = cb(); - try { + private Logger logger = LoggerFactory.getLogger(UserRepository.class); + + protected UserRepository() { + super(User.class); + } + + public User findBySubject(String subject) { + try { + CriteriaQuery query = em.getCriteriaBuilder().createQuery(User.class); + Root queryRoot = query.from(User.class); + query.select(queryRoot); + CriteriaBuilder cb = cb(); + return em.createQuery(query + .where( + eq(cb, queryRoot, "subject", subject))) + .getSingleResult(); + } catch (NoResultException e) { + return null; + } + } + + public User findBySubjectAndConnection(String subject, String connectionId) { + CriteriaQuery query = em.getCriteriaBuilder().createQuery(User.class); + Root queryRoot = query.from(User.class); + query.select(queryRoot); + CriteriaBuilder cb = cb(); + try { return em.createQuery(query - .where( - cb.and( - cb.equal(queryRoot.join("connection") - .get("id"), connectionId), - eq(cb, queryRoot, "subject", subject)))) + .where( + cb.and( + cb.equal(queryRoot.join("connection") + .get("id"), connectionId), + eq(cb, queryRoot, "subject", subject)))) .getSingleResult(); - } catch (NoResultException e){ - return null; + } catch (NoResultException e) { + return null; + } + } + + public List listUnmatchedByConnectionId(Connection connection) { + CriteriaQuery query = em.getCriteriaBuilder().createQuery(User.class); + Root queryRoot = query.from(User.class); + query.select(queryRoot); + CriteriaBuilder cb = cb(); + return em.createQuery(query + .where( + cb.and( + eq(cb, queryRoot, "connection", connection), + eq(cb, queryRoot, "matched", false)))) + .getResultList(); + } + + /** + * @return + */ + public User findOrCreate(User inputUser) { + User user = null; + String subject = inputUser.getSubject(); + try { + user = findBySubject(subject); + logger.info("findOrCreate(), trying to find user: {subject: " + subject + + "}, and found a user with uuid: " + user.getUuid() + + ", subject: " + user.getSubject()); + } catch (NoResultException e) { + logger.debug("findOrCreate() subject " + subject + + " could not be found by `entityManager`, going to create a new user."); + user = createUser(inputUser); + } catch (NonUniqueResultException e) { + logger.error("findOrCreate() " + e.getClass().getSimpleName() + ": " + e.getMessage()); + } + return user; + } + + private User createUser(User inputUser) { + String subject = inputUser.getSubject(); + logger.debug("createUser() creating user, subject: " + subject + " ......"); + em().persist(inputUser); + + User result = getById(inputUser.getUuid()); + if (result != null) + logger.info("createUser() created user, uuid: " + result.getUuid() + + ", subject: " + subject + + ", role: " + result.getRoleString() + + ", privilege: " + result.getPrivilegeString()); + + return result; + } + + public User changeRole(User user, Set roles) { + logger.info("Starting changing the role of user: " + user.getUuid() + + ", with subject: " + user.getSubject() + ", to " + roles.stream().map(role -> role.getName()).collect(Collectors.joining(","))); + user.setRoles(roles); + em().merge(user); + User updatedUser = getById(user.getUuid()); + logger.info("User: " + updatedUser.getUuid() + ", with subject: " + + updatedUser.getSubject() + ", now has a new role: " + updatedUser.getRoleString()); + return updatedUser; + } + + @Override + public void persist(User user) { + findOrCreate(user); + } + + public User findByEmail(String email) { + CriteriaQuery query = em.getCriteriaBuilder().createQuery(User.class); + Root queryRoot = query.from(User.class); + query.select(queryRoot); + CriteriaBuilder cb = cb(); + return em.createQuery(query + .where( + eq(cb, queryRoot, "email", email))) + .getSingleResult(); + } + + public boolean checkAgainstTOSDate(String userId) { + CriteriaQuery query = cb().createQuery(User.class); + Root queryRoot = query.from(User.class); + query.select(queryRoot); + CriteriaBuilder cb = cb(); + + Subquery subquery = query.subquery(Date.class); + Root tosRoot = subquery.from(TermsOfService.class); + subquery.select(cb.greatest(tosRoot.get("dateUpdated"))); + + return !em.createQuery(query + .where( + cb.and( + eq(cb, queryRoot, "subject", userId), + cb.greaterThanOrEqualTo(queryRoot.get("acceptedTOS"), subquery)))) + .getResultList().isEmpty(); + } + + /** + * @param uuid the uuid of the user to find + * @return the user with the given uuid, or null if no user is found + */ + public User findByUUID(UUID uuid) { + CriteriaQuery query = em.getCriteriaBuilder().createQuery(User.class); + Root queryRoot = query.from(User.class); + query.select(queryRoot); + CriteriaBuilder cb = cb(); + try { + return em.createQuery(query + .where( + eq(cb, queryRoot, "uuid", uuid))) + .getSingleResult(); + } catch (NoResultException e) { + logger.error("findByUUID() " + e.getClass().getSimpleName() + ": " + e.getMessage()); } - } - - public List listUnmatchedByConnectionId(Connection connection) { - CriteriaQuery query = em.getCriteriaBuilder().createQuery(User.class); - Root queryRoot = query.from(User.class); - query.select(queryRoot); - CriteriaBuilder cb = cb(); - return em.createQuery(query - .where( - cb.and( - eq(cb, queryRoot, "connection", connection), - eq(cb, queryRoot, "matched", false)))) - .getResultList(); - } - - /** - * - * @return - */ - public User findOrCreate(User inputUser) { - User user = null; - String subject = inputUser.getSubject(); - try{ - user = findBySubject(subject); - logger.info("findOrCreate(), trying to find user: {subject: " + subject+ - "}, and found a user with uuid: " + user.getUuid() - + ", subject: " + user.getSubject()); - } catch (NoResultException e) { - logger.debug("findOrCreate() subject " + subject + - " could not be found by `entityManager`, going to create a new user."); - user = createUser(inputUser); - }catch(NonUniqueResultException e){ - logger.error("findOrCreate() " + e.getClass().getSimpleName() + ": " + e.getMessage()); - } - return user; - } - - private User createUser(User inputUser) { - String subject = inputUser.getSubject(); -// if (subject == null && userId == null){ -// logger.error("createUser() cannot create user when both subject and userId are null"); -// return null; -// } - logger.debug("createUser() creating user, subject: " + subject + " ......"); - em().persist(inputUser); - - User result = getById(inputUser.getUuid()); - if (result != null) - logger.info("createUser() created user, uuid: " + result.getUuid() - + ", subject: " + subject - + ", role: " + result.getRoleString() - + ", privilege: "+ result.getPrivilegeString()); - - return result; - } - - public User changeRole(User user, Set roles){ - logger.info("Starting changing the role of user: " + user.getUuid() - + ", with subject: " + user.getSubject() + ", to " + roles.stream().map(role -> role.getName()).collect(Collectors.joining(","))); - user.setRoles(roles); - em().merge(user); - User updatedUser = getById(user.getUuid()); - logger.info("User: " + updatedUser.getUuid() + ", with subject: " + - updatedUser.getSubject() + ", now has a new role: " + updatedUser.getRoleString()); - return updatedUser; - } - - @Override - public void persist(User user) { - findOrCreate(user); - } - - public User findByEmail(String email) { - CriteriaQuery query = em.getCriteriaBuilder().createQuery(User.class); - Root queryRoot = query.from(User.class); - query.select(queryRoot); - CriteriaBuilder cb = cb(); - return em.createQuery(query - .where( - eq(cb, queryRoot, "email", email))) - .getSingleResult(); - } - - public boolean checkAgainstTOSDate(String userId){ - CriteriaQuery query = cb().createQuery(User.class); - Root queryRoot = query.from(User.class); - query.select(queryRoot); - CriteriaBuilder cb = cb(); - - Subquery subquery = query.subquery(Date.class); - Root tosRoot = subquery.from(TermsOfService.class); - subquery.select(cb.greatest(tosRoot.get("dateUpdated"))); - - return !em.createQuery(query - .where( - cb.and( - eq(cb, queryRoot, "subject", userId), - cb.greaterThanOrEqualTo(queryRoot.get("acceptedTOS"), subquery)))) - .getResultList().isEmpty(); - } + return null; + } + + /** + * Creates a user with a subject of "open_access|{uuid}" + * and an email of "{uuid}@open_access.com" + * + * @return the created user + */ + public User createOpenAccessUser(Role openAccessRole) { + User user = new User(); + em().persist(user); + + user = getById(user.getUuid()); + user.setSubject("open_access|" + user.getUuid().toString()); + if (openAccessRole != null) { + user.setRoles(new HashSet<>(List.of(openAccessRole))); + } else { + logger.error("createOpenAccessUser() openAccessRole is null"); + user.setRoles(new HashSet<>()); + } + user.setEmail(user.getUuid() + "@open_access.com"); + em().merge(user); + + logger.info("createOpenAccessUser() created user, uuid: " + user.getUuid() + + ", subject: " + user.getSubject() + + ", role: " + user.getRoleString() + + ", privilege: " + user.getPrivilegeString() + + ", email: " + user.getEmail()); + return user; + } } diff --git a/pic-sure-auth-services/src/main/java/edu/harvard/hms/dbmi/avillach/auth/rest/AuthService.java b/pic-sure-auth-services/src/main/java/edu/harvard/hms/dbmi/avillach/auth/rest/AuthService.java index 1abf0938e..0c5f0098d 100644 --- a/pic-sure-auth-services/src/main/java/edu/harvard/hms/dbmi/avillach/auth/rest/AuthService.java +++ b/pic-sure-auth-services/src/main/java/edu/harvard/hms/dbmi/avillach/auth/rest/AuthService.java @@ -33,9 +33,6 @@ public class AuthService { private Logger logger = LoggerFactory.getLogger(this.getClass()); - @Inject - AuthorizationService authorizationService; - @Inject AuthenticationService authenticationService; diff --git a/pic-sure-auth-services/src/main/java/edu/harvard/hms/dbmi/avillach/auth/rest/OpenAuthService.java b/pic-sure-auth-services/src/main/java/edu/harvard/hms/dbmi/avillach/auth/rest/OpenAuthService.java new file mode 100644 index 000000000..35b059512 --- /dev/null +++ b/pic-sure-auth-services/src/main/java/edu/harvard/hms/dbmi/avillach/auth/rest/OpenAuthService.java @@ -0,0 +1,49 @@ +package edu.harvard.hms.dbmi.avillach.auth.rest; + +import edu.harvard.hms.dbmi.avillach.auth.JAXRSConfiguration; +import edu.harvard.hms.dbmi.avillach.auth.service.auth.OpenAuthenticationService; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import io.swagger.annotations.ApiParam; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import javax.inject.Inject; +import javax.ws.rs.Consumes; +import javax.ws.rs.POST; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; +import javax.ws.rs.core.Response; +import java.util.Map; + +/** + *

The authentication endpoint for PSAMA.

+ */ +@Api +@Path("/open") +@Consumes("application/json") +@Produces("application/json") +public class OpenAuthService { + + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + @Inject + private OpenAuthenticationService openAuthenticationService; + + @ApiOperation(value = "The authentication endpoint for retrieving a valid user token") + @POST + @Path("/authentication") + public Response authentication(@ApiParam(required = true, value = "A json object that includes all Oauth authentication needs, for example, access_token and redirectURI") Map authRequest) { + logger.debug("authentication() starting..."); + + // idp_provider also has default value of "default" if not set in the config file + // This is a temporary solution to ensure that a user cannot authenticate against fence using the open endpoint + if (!JAXRSConfiguration.idp_provider.equalsIgnoreCase("fence")) { + return openAuthenticationService.authenticate(authRequest); + } + + // Fence authentication is not supported by the open endpoint + return Response.status(Response.Status.FORBIDDEN).build(); + } + +} diff --git a/pic-sure-auth-services/src/main/java/edu/harvard/hms/dbmi/avillach/auth/rest/UserService.java b/pic-sure-auth-services/src/main/java/edu/harvard/hms/dbmi/avillach/auth/rest/UserService.java index 4b6bb1d4b..e6b775af1 100644 --- a/pic-sure-auth-services/src/main/java/edu/harvard/hms/dbmi/avillach/auth/rest/UserService.java +++ b/pic-sure-auth-services/src/main/java/edu/harvard/hms/dbmi/avillach/auth/rest/UserService.java @@ -281,7 +281,8 @@ public Response getCurrentUser( .setPrivileges(user.getPrivilegeNameSet()) .setUuid(user.getUuid().toString()) .setAcceptedTOS(true); //FENCE only returns valid users who have agreed to their terms - + + logger.debug("getCurrentUser() userForDisplay: " + userForDisplay.toString()); // currently, the queryScopes are simple combination of queryScope string together as a set. // We are expecting the queryScope string as plain string. If it is a JSON, we could change the @@ -313,6 +314,8 @@ public Response getCurrentUser( } } + logger.debug("getCurrentUser() returning userForDisplay: " + userForDisplay.toString()); + return PICSUREResponse.success(userForDisplay); } @@ -519,5 +522,4 @@ private void checkAssociation(List users) throws ProtocolException{ } } - } diff --git a/pic-sure-auth-services/src/main/java/edu/harvard/hms/dbmi/avillach/auth/service/auth/AuthenticationService.java b/pic-sure-auth-services/src/main/java/edu/harvard/hms/dbmi/avillach/auth/service/auth/AuthenticationService.java index d17e60d80..c4c551750 100644 --- a/pic-sure-auth-services/src/main/java/edu/harvard/hms/dbmi/avillach/auth/service/auth/AuthenticationService.java +++ b/pic-sure-auth-services/src/main/java/edu/harvard/hms/dbmi/avillach/auth/service/auth/AuthenticationService.java @@ -86,7 +86,6 @@ public Response getToken(Map authRequest){ throw new ApplicationException("cannot get sufficient user information. Please contact admin."); } - //Do we have this user already? User user = userRepository.findBySubjectAndConnection(userId, connectionId); if (user == null){ //Try to match diff --git a/pic-sure-auth-services/src/main/java/edu/harvard/hms/dbmi/avillach/auth/service/auth/FENCEAuthenticationService.java b/pic-sure-auth-services/src/main/java/edu/harvard/hms/dbmi/avillach/auth/service/auth/FENCEAuthenticationService.java index 29e320195..08f40b08d 100644 --- a/pic-sure-auth-services/src/main/java/edu/harvard/hms/dbmi/avillach/auth/service/auth/FENCEAuthenticationService.java +++ b/pic-sure-auth-services/src/main/java/edu/harvard/hms/dbmi/avillach/auth/service/auth/FENCEAuthenticationService.java @@ -157,6 +157,12 @@ public Response getFENCEProfile(String callback_url, Map authReq logger.debug("getFENCEProfile() starting..."); String fence_code = authRequest.get("code"); + // Validate that the fence code is alphanumeric + if (!fence_code.matches("[a-zA-Z0-9]+")) { + logger.error("getFENCEProfile() fence code is not alphanumeric"); + throw new NotAuthorizedException("The fence code is not alphanumeric"); + } + JsonNode fence_user_profile = null; // Get the Gen3/FENCE user profile. It is a JsonNode object try { @@ -334,7 +340,7 @@ private User createUserFromFENCEProfile(JsonNode node) { * @param roleDescription Description of the Role * @return boolean Whether the Role was successfully added to the User or not */ - private boolean upsertRole(User u, String roleName, String roleDescription) { + public boolean upsertRole(User u, String roleName, String roleDescription) { boolean status = false; logger.debug("upsertRole() starting for user subject:"+u.getSubject()); diff --git a/pic-sure-auth-services/src/main/java/edu/harvard/hms/dbmi/avillach/auth/service/auth/OpenAuthenticationService.java b/pic-sure-auth-services/src/main/java/edu/harvard/hms/dbmi/avillach/auth/service/auth/OpenAuthenticationService.java new file mode 100644 index 000000000..ed9e41620 --- /dev/null +++ b/pic-sure-auth-services/src/main/java/edu/harvard/hms/dbmi/avillach/auth/service/auth/OpenAuthenticationService.java @@ -0,0 +1,67 @@ +package edu.harvard.hms.dbmi.avillach.auth.service.auth; + +import edu.harvard.dbmi.avillach.util.response.PICSUREResponse; +import edu.harvard.hms.dbmi.avillach.auth.data.entity.Role; +import edu.harvard.hms.dbmi.avillach.auth.data.entity.User; +import edu.harvard.hms.dbmi.avillach.auth.data.repository.RoleRepository; +import edu.harvard.hms.dbmi.avillach.auth.data.repository.UserRepository; +import edu.harvard.hms.dbmi.avillach.auth.rest.UserService; +import edu.harvard.hms.dbmi.avillach.auth.utils.AuthUtils; +import org.apache.commons.lang3.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import javax.inject.Inject; +import javax.ws.rs.core.Response; +import java.util.HashMap; +import java.util.Map; +import java.util.UUID; + +public class OpenAuthenticationService { + + private final Logger logger = LoggerFactory.getLogger(OpenAuthenticationService.class); + + @Inject + private UserRepository userRepository; + + @Inject + private RoleRepository roleRepository; + + @Inject + AuthUtils authUtil; + + public Response authenticate(Map authRequest) { + String userUUID = authRequest.get("UUID"); + User current_user = null; + + // Try to get the user by UUID + if (StringUtils.isNotBlank(userUUID)) { + try { + UUID uuid = UUID.fromString(userUUID); + current_user = userRepository.findByUUID(uuid); + } catch (IllegalArgumentException e) { + logger.error("Invalid UUID: " + userUUID); + } + } + + // If we can't find the user by UUID, create a new one + if (current_user == null) { + Role openAccessRole = roleRepository.getUniqueResultByColumn("name", FENCEAuthenticationService.fence_open_access_role_name); + current_user = userRepository.createOpenAccessUser(openAccessRole); + + //clear some cache entries if we register a new login + AuthorizationService.clearCache(current_user); + UserService.clearCache(current_user); + } + + HashMap claims = new HashMap<>(); + claims.put("sub", current_user.getSubject()); + claims.put("email", current_user.getUuid() + "@open_access.com"); + claims.put("uuid", current_user.getUuid().toString()); + HashMap responseMap = authUtil.getUserProfileResponse(claims); + + logger.info("LOGIN SUCCESS ___ " + current_user.getEmail() + ":" + current_user.getUuid().toString() + " ___ Authorization will expire at ___ " + responseMap.get("expirationDate") + "___"); + + return PICSUREResponse.success(responseMap); + } +} diff --git a/pic-sure-auth-services/src/main/java/edu/harvard/hms/dbmi/avillach/auth/utils/AuthUtils.java b/pic-sure-auth-services/src/main/java/edu/harvard/hms/dbmi/avillach/auth/utils/AuthUtils.java index 85ddd170e..48bb53213 100644 --- a/pic-sure-auth-services/src/main/java/edu/harvard/hms/dbmi/avillach/auth/utils/AuthUtils.java +++ b/pic-sure-auth-services/src/main/java/edu/harvard/hms/dbmi/avillach/auth/utils/AuthUtils.java @@ -106,15 +106,20 @@ public HashMap getUserProfileResponse(Map claims logger.debug("getUserProfileResponse() acceptedTOS is set"); - boolean acceptedTOS = JAXRSConfiguration.tosEnabled.startsWith("true") ? - tosService.getLatest() == null || tosService.hasUserAcceptedLatest(claims.get("subject").toString()) : true; + boolean acceptedTOS = !JAXRSConfiguration.tosEnabled.startsWith("true") || tosService.getLatest() == null || tosService.hasUserAcceptedLatest(claims.get("subject").toString()); - responseMap.put("acceptedTOS", ""+acceptedTOS); + responseMap.put("acceptedTOS", String.valueOf(acceptedTOS)); logger.debug("getUserProfileResponse() expirationDate is set"); Date expirationDate = new Date(Calendar.getInstance().getTimeInMillis() + JAXRSConfiguration.tokenExpirationTime); responseMap.put("expirationDate", ZonedDateTime.ofInstant(expirationDate.toInstant(), ZoneOffset.UTC).toString()); + // This is required for open access, but optional otherwise + if (claims.get("uuid") != null) { + logger.debug("getUserProfileResponse() uuid field is set"); + responseMap.put("uuid", claims.get("uuid").toString()); + } + logger.debug("getUserProfileResponse() finished"); return responseMap; }