diff --git a/jans-config-api/server/src/main/java/io/jans/configapi/rest/resource/auth/UserResource.java b/jans-config-api/server/src/main/java/io/jans/configapi/rest/resource/auth/UserResource.java index 52ded14a481..8c58be96fa9 100644 --- a/jans-config-api/server/src/main/java/io/jans/configapi/rest/resource/auth/UserResource.java +++ b/jans-config-api/server/src/main/java/io/jans/configapi/rest/resource/auth/UserResource.java @@ -80,30 +80,37 @@ public Response getUserByInum(@PathParam(ApiConstants.INUM) @NotNull String inum logger.debug("user:{}", user); // excludedAttributes - user = userSrv.excludedAttributes(user, ApiConstants.USER_EXCLUDED_ATTRIBUTES); + user = excludeUserAttributes(user); return Response.ok(user).build(); } @POST @ProtectedApi(scopes = { ApiAccessConstants.USER_WRITE_ACCESS }) - public Response createUser(@Valid User user) { + public Response createUser(@Valid User user) throws IllegalAccessException, InvocationTargetException { if (logger.isDebugEnabled()) { logger.debug("User details to be added - user:{}", escapeLog(user)); } user = userSrv.addUser(user, true); logger.debug("User created {}", user); + + // excludedAttributes + user = excludeUserAttributes(user); + return Response.status(Response.Status.CREATED).entity(user).build(); } @PUT @ProtectedApi(scopes = { ApiAccessConstants.USER_WRITE_ACCESS }) - public Response updateUser(@Valid User user) { + public Response updateUser(@Valid User user) throws IllegalAccessException, InvocationTargetException { if (logger.isDebugEnabled()) { logger.debug("User details to be updated - user:{}", escapeLog(user)); } user = userSrv.updateUser((user)); logger.debug("Updated user:{}", user); + + // excludedAttributes + user = excludeUserAttributes(user); return Response.ok(user).build(); } @@ -112,7 +119,7 @@ public Response updateUser(@Valid User user) { @ProtectedApi(scopes = { ApiAccessConstants.USER_WRITE_ACCESS }) @Path(ApiConstants.INUM_PATH) public Response patchUser(@PathParam(ApiConstants.INUM) @NotNull String inum, - @NotNull UserPatchRequest userPatchRequest) throws JsonPatchException, IOException { + @NotNull UserPatchRequest userPatchRequest) throws IllegalAccessException, InvocationTargetException, JsonPatchException, IOException { if (logger.isDebugEnabled()) { logger.debug("User:{} to be patched with :{} ", escapeLog(inum), escapeLog(userPatchRequest)); } @@ -123,6 +130,9 @@ public Response patchUser(@PathParam(ApiConstants.INUM) @NotNull String inum, // patch user existingUser = userSrv.patchUser(inum, userPatchRequest); logger.debug("Patched user:{}", existingUser); + + // excludedAttributes + existingUser = excludeUserAttributes(existingUser); return Response.ok(existingUser).build(); } @@ -160,9 +170,13 @@ private List doSearch(SearchRequest searchReq) throws IllegalAccessExcepti } // excludedAttributes - users = userSrv.excludedAttributes(users, searchReq.getExcludedAttributesStr()); + users = userSrv.excludeAttributes(users, searchReq.getExcludedAttributesStr()); return users; } + + private User excludeUserAttributes(User user) throws IllegalAccessException, InvocationTargetException { + return userSrv.excludeAttributes(user, ApiConstants.USER_EXCLUDED_ATTRIBUTES); + } } diff --git a/jans-config-api/server/src/main/java/io/jans/configapi/service/auth/UserService.java b/jans-config-api/server/src/main/java/io/jans/configapi/service/auth/UserService.java index a5ceeaef255..8505692cdc9 100644 --- a/jans-config-api/server/src/main/java/io/jans/configapi/service/auth/UserService.java +++ b/jans-config-api/server/src/main/java/io/jans/configapi/service/auth/UserService.java @@ -23,15 +23,18 @@ import static io.jans.as.model.util.Util.escapeLog; +import java.lang.reflect.Field; import java.io.IOException; import java.lang.reflect.InvocationTargetException; import java.util.Arrays; +import java.util.HashMap; import java.util.List; import javax.enterprise.context.ApplicationScoped; import javax.inject.Inject; import javax.inject.Named; import org.apache.commons.beanutils.BeanUtils; +import org.apache.commons.beanutils.BeanUtilsBean; import org.apache.commons.lang.StringUtils; import org.slf4j.Logger; @@ -127,7 +130,7 @@ public User getUserBasedOnInum(String inum) { try { result = getUserByInum(inum); } catch (Exception ex) { - logger.error("Failed to load user entry", ex); + logger.debug("Failed to load user entry", ex); } return result; } @@ -165,18 +168,18 @@ else if (attribute.getValue() == null || attribute.getValues() == null) { return user; } - public List excludedAttributes(List users, String commaSeparatedString) + public List excludeAttributes(List users, String commaSeparatedString) throws IllegalAccessException, InvocationTargetException { logger.debug("Attributes:{} to be excluded from users:{} ", commaSeparatedString, users); for (User user : users) { - excludedAttributes(user, commaSeparatedString); + excludeAttributes(user, commaSeparatedString); } logger.debug("Users:{} after excluding attribute:{} ", users, commaSeparatedString); return users; } - public User excludedAttributes(User user, String commaSeparatedString) + public User excludeAttributes(User user, String commaSeparatedString) throws IllegalAccessException, InvocationTargetException { logger.debug("Attributes:{} to be excluded from user:{} ", commaSeparatedString, user); if (user == null || StringUtils.isEmpty(commaSeparatedString)) { @@ -185,19 +188,33 @@ public User excludedAttributes(User user, String commaSeparatedString) List excludedAttributes = Arrays.asList(commaSeparatedString.split(",")); logger.debug("Attributes List:{} to be excluded ", excludedAttributes); + List allFields = authUtil.getAllFields(user.getClass()); + logger.debug("All user fields :{} ",allFields); + + + HashMap map = new HashMap<>(); for (String attribute : excludedAttributes) { - logger.debug("User class conatins attribute:{} ? :{} ", attribute, - authUtil.doesObjectContainField(user, attribute)); - if (authUtil.doesObjectContainField(user, attribute)) { - BeanUtils.setProperty(user, attribute, null); - - } else { + logger.debug("User class allFields:{} conatins attribute:{} ? :{} ", allFields, attribute, + authUtil.containsField(allFields, attribute)); + if (authUtil.containsField(allFields, attribute)) { + logger.debug("User class contains attribute:{} ! ",attribute); + map.put(attribute, null); + } + else { logger.debug("Removing custom attribute:{} from user:{} ", attribute, user); user.removeAttribute(attribute); } } + + logger.debug("Attributes map:{} to be excluded ", map); + if(!map.isEmpty()) { + logger.debug("Removing simple attributes:{} from user object ", map); + BeanUtilsBean.getInstance().getConvertUtils().register(false, false, 0); + BeanUtils.populate(user, map); + } return user; } + } diff --git a/jans-config-api/server/src/main/java/io/jans/configapi/util/AuthUtil.java b/jans-config-api/server/src/main/java/io/jans/configapi/util/AuthUtil.java index 52e84009351..b0d6d59bce4 100644 --- a/jans-config-api/server/src/main/java/io/jans/configapi/util/AuthUtil.java +++ b/jans-config-api/server/src/main/java/io/jans/configapi/util/AuthUtil.java @@ -17,6 +17,7 @@ import io.jans.util.security.StringEncrypter.EncryptionException; import java.lang.reflect.Method; +import java.lang.reflect.Field; import java.util.ArrayList; import java.util.HashSet; import java.util.Arrays; @@ -32,7 +33,6 @@ import javax.ws.rs.core.Response; import org.apache.commons.collections4.CollectionUtils; -import org.apache.commons.lang.StringUtils; import org.slf4j.Logger; @ApplicationScoped @@ -354,13 +354,29 @@ public boolean isEqualCollection(List list1, List list2) { return CollectionUtils.isEqualCollection(list1, list2); } - public boolean doesObjectContainField(Object object, String fieldName) { - log.debug("Check if object:{} contain fieldName:{} ", object, fieldName); - if(object == null || StringUtils.isEmpty(fieldName)) { - return false; - } - return Arrays.stream(object.getClass().getFields()) - .anyMatch(f -> f.getName().equals(fieldName)); - } + public boolean containsField(List allFields, String attribute) { + log.debug("allFields:{}, attribute:{}, allFields.contains(attribute):{} ", allFields , attribute, allFields.stream().anyMatch(f -> f.getName().equals(attribute))); + + return allFields.stream().anyMatch(f -> f.getName().equals(attribute)); + } + + public List getAllFields(Class type) { + List allFields = new ArrayList<>(); + allFields = getAllFields(allFields, type); + log.debug("All Fields of User class:{} ", allFields); + + return allFields; + } + + public List getAllFields(List fields, Class type) { + log.debug("fields:{} of type:{} ", fields, type); + fields.addAll(Arrays.asList(type.getDeclaredFields())); + + if (type.getSuperclass() != null) { + getAllFields(fields, type.getSuperclass()); + } + log.debug("Final fields:{} of type:{} ", fields, type); + return fields; + } }