From cf1e808cbd4afa8f9e6cdbb6e79caff1ea335ab3 Mon Sep 17 00:00:00 2001 From: ayyoob Date: Tue, 31 May 2016 13:57:38 +0530 Subject: [PATCH 1/5] refactored after testing UserAdminManangmentService --- ...pper.java => OldPasswordResetWrapper.java} | 24 +------ .../mgt/jaxrs/beans/PasswordResetWrapper.java | 41 +++++++++++ .../service/api/UserManagementService.java | 5 +- .../api/admin/UserManagementAdminService.java | 4 +- .../impl/UserManagementServiceImpl.java | 6 +- .../admin/UserManagementAdminServiceImpl.java | 6 +- .../CredentialManagementResponseBuilder.java | 71 ++++++++++++++----- .../mgt/jaxrs/util/DeviceMgtAPIUtils.java | 12 ++++ 8 files changed, 119 insertions(+), 50 deletions(-) rename components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/beans/{UserCredentialWrapper.java => OldPasswordResetWrapper.java} (62%) create mode 100644 components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/beans/PasswordResetWrapper.java diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/beans/UserCredentialWrapper.java b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/beans/OldPasswordResetWrapper.java similarity index 62% rename from components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/beans/UserCredentialWrapper.java rename to components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/beans/OldPasswordResetWrapper.java index e5674b9de71..bef53c06b75 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/beans/UserCredentialWrapper.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/beans/OldPasswordResetWrapper.java @@ -21,34 +21,14 @@ package org.wso2.carbon.device.mgt.jaxrs.beans; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; -@ApiModel(value = "UserCredentialWrapper", description = "User credentials are included in this class.") -public class UserCredentialWrapper { +@ApiModel(value = "OldPasswordResetWrapper", description = "User credentials are included in this class.") +public class OldPasswordResetWrapper extends PasswordResetWrapper{ - @ApiModelProperty(name = "username", value = "Username of the user.", required = true ) - private String username; /* Base64 encoded password */ @ApiModelProperty(name = "oldPassword", value = "Old password of the user.", required = true ) private String oldPassword; - @ApiModelProperty(name = "newPassword", value = "New password of the user.", required = true ) - private String newPassword; - - public String getNewPassword() { - return newPassword; - } - - public void setNewPassword(String newPassword) { - this.newPassword = newPassword; - } - - public String getUsername() { - return username; - } - - public void setUsername(String username) { - this.username = username; - } public String getOldPassword() { return oldPassword; diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/beans/PasswordResetWrapper.java b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/beans/PasswordResetWrapper.java new file mode 100644 index 00000000000..7bd67c20289 --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/beans/PasswordResetWrapper.java @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.wso2.carbon.device.mgt.jaxrs.beans; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; + +@ApiModel(value = "PasswordResetWrapper", description = "User credential is included in this class.") +public class PasswordResetWrapper { + + /* + Base64 encoded password + */ + @ApiModelProperty(name = "newPassword", value = "New password of the user.", required = true ) + private String newPassword; + + public String getNewPassword() { + return newPassword; + } + + public void setNewPassword(String newPassword) { + this.newPassword = newPassword; + } + +} diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/api/UserManagementService.java b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/api/UserManagementService.java index 1631eeaa280..a2c33625754 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/api/UserManagementService.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/api/UserManagementService.java @@ -21,13 +21,12 @@ package org.wso2.carbon.device.mgt.jaxrs.service.api; import io.swagger.annotations.*; import org.wso2.carbon.apimgt.annotations.api.API; import org.wso2.carbon.apimgt.annotations.api.Permission; -import org.wso2.carbon.device.mgt.jaxrs.beans.UserCredentialWrapper; +import org.wso2.carbon.device.mgt.jaxrs.beans.OldPasswordResetWrapper; import org.wso2.carbon.device.mgt.jaxrs.beans.UserWrapper; import javax.ws.rs.*; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; -import java.util.Date; @API(name = "User Management API", version = "1.0.0", context = "/devicemgt_admin/users", tags = {"devicemgt_admin"}) @@ -438,6 +437,6 @@ public interface UserManagementService { @ApiParam( name = "credentials", value = "Credential.", - required = true) UserCredentialWrapper credentials); + required = true) OldPasswordResetWrapper credentials); } diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/api/admin/UserManagementAdminService.java b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/api/admin/UserManagementAdminService.java index 7dd351734b3..baec3eff636 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/api/admin/UserManagementAdminService.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/api/admin/UserManagementAdminService.java @@ -20,7 +20,7 @@ package org.wso2.carbon.device.mgt.jaxrs.service.api.admin; import io.swagger.annotations.*; import org.wso2.carbon.apimgt.annotations.api.Permission; -import org.wso2.carbon.device.mgt.jaxrs.beans.UserCredentialWrapper; +import org.wso2.carbon.device.mgt.jaxrs.beans.PasswordResetWrapper; import javax.ws.rs.*; import javax.ws.rs.core.MediaType; @@ -71,6 +71,6 @@ public interface UserManagementAdminService { @ApiParam( name = "credentials", value = "Credential.", - required = true) UserCredentialWrapper credentials); + required = true) PasswordResetWrapper credentials); } diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/UserManagementServiceImpl.java b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/UserManagementServiceImpl.java index 260b4df2911..1a2bb05f2d8 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/UserManagementServiceImpl.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/UserManagementServiceImpl.java @@ -26,7 +26,7 @@ import org.wso2.carbon.context.CarbonContext; import org.wso2.carbon.device.mgt.common.DeviceManagementException; import org.wso2.carbon.device.mgt.core.service.DeviceManagementProviderService; import org.wso2.carbon.device.mgt.core.service.EmailMetaInfo; -import org.wso2.carbon.device.mgt.jaxrs.beans.UserCredentialWrapper; +import org.wso2.carbon.device.mgt.jaxrs.beans.OldPasswordResetWrapper; import org.wso2.carbon.device.mgt.jaxrs.beans.UserWrapper; import org.wso2.carbon.device.mgt.jaxrs.service.api.UserManagementService; import org.wso2.carbon.device.mgt.jaxrs.util.Constants; @@ -390,8 +390,8 @@ public class UserManagementServiceImpl implements UserManagementService { @PUT @Path("/{username}/credentials") @Override - public Response resetPassword(@PathParam("username") String username, UserCredentialWrapper credentials) { - return CredentialManagementResponseBuilder.buildChangePasswordResponse(credentials); + public Response resetPassword(@PathParam("username") String username, OldPasswordResetWrapper credentials) { + return CredentialManagementResponseBuilder.buildChangePasswordResponse(username, credentials); } } diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/admin/UserManagementAdminServiceImpl.java b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/admin/UserManagementAdminServiceImpl.java index fc30afea174..1613c49b874 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/admin/UserManagementAdminServiceImpl.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/admin/UserManagementAdminServiceImpl.java @@ -18,7 +18,7 @@ */ package org.wso2.carbon.device.mgt.jaxrs.service.impl.admin; -import org.wso2.carbon.device.mgt.jaxrs.beans.UserCredentialWrapper; +import org.wso2.carbon.device.mgt.jaxrs.beans.PasswordResetWrapper; import org.wso2.carbon.device.mgt.jaxrs.service.api.admin.UserManagementAdminService; import org.wso2.carbon.device.mgt.jaxrs.util.CredentialManagementResponseBuilder; @@ -34,8 +34,8 @@ public class UserManagementAdminServiceImpl implements UserManagementAdminServic @POST @Path("/{username}/credentials") @Override - public Response resetPassword(@PathParam("username") String user, UserCredentialWrapper credentials) { - return CredentialManagementResponseBuilder.buildResetPasswordResponse(credentials); + public Response resetPassword(@PathParam("username") String user, PasswordResetWrapper credentials) { + return CredentialManagementResponseBuilder.buildResetPasswordResponse(user, credentials); } } diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/util/CredentialManagementResponseBuilder.java b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/util/CredentialManagementResponseBuilder.java index dfdc187e163..2edbb20ebb7 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/util/CredentialManagementResponseBuilder.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/util/CredentialManagementResponseBuilder.java @@ -18,15 +18,16 @@ package org.wso2.carbon.device.mgt.jaxrs.util; -import org.apache.commons.codec.binary.Base64; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; -import org.wso2.carbon.device.mgt.jaxrs.beans.UserCredentialWrapper; +import org.wso2.carbon.device.mgt.jaxrs.beans.PasswordResetWrapper; +import org.wso2.carbon.device.mgt.jaxrs.beans.OldPasswordResetWrapper; import org.wso2.carbon.user.api.UserStoreException; import org.wso2.carbon.user.api.UserStoreManager; import javax.ws.rs.core.Response; import java.io.UnsupportedEncodingException; +import java.util.regex.Pattern; /** * This class builds Credential modification related Responses @@ -34,26 +35,38 @@ import java.io.UnsupportedEncodingException; public class CredentialManagementResponseBuilder { private static Log log = LogFactory.getLog(CredentialManagementResponseBuilder.class); + private static String PASSWORD_VALIDATION_REGEX_TAG = "PasswordJavaRegEx"; /** * Builds the response to change the password of a user + * @param username - Username of the user. * @param credentials - User credentials * @return Response Object */ - public static Response buildChangePasswordResponse(UserCredentialWrapper credentials) { + public static Response buildChangePasswordResponse(String username, OldPasswordResetWrapper credentials) { try { UserStoreManager userStoreManager = DeviceMgtAPIUtils.getUserStoreManager(); - byte[] decodedNewPassword = Base64.decodeBase64(credentials.getNewPassword()); - byte[] decodedOldPassword = Base64.decodeBase64(credentials.getOldPassword()); - userStoreManager.updateCredential(credentials.getUsername(), new String( - decodedNewPassword, "UTF-8"), new String(decodedOldPassword, "UTF-8")); + if (!userStoreManager.isExistingUser(username)) { + return Response.status(Response.Status.BAD_REQUEST).entity("No user found with the username " + + username).build(); + } + if (credentials == null || credentials.getNewPassword() == null || credentials.getOldPassword() == null) { + return Response.status(Response.Status.BAD_REQUEST).entity("Password cannot be empty.") + .build(); + } + if (!validateCredential(credentials.getNewPassword())) { + return Response.status(Response.Status.BAD_REQUEST).entity("Password does not match with required format.") + .build(); + } + userStoreManager.updateCredential(username, credentials.getNewPassword(), + credentials.getOldPassword()); return Response.status(Response.Status.OK).entity("UserImpl password by username: " + - credentials.getUsername() + " was successfully changed.").build(); + username + " was successfully changed.").build(); } catch (UserStoreException e) { log.error(e.getMessage(), e); return Response.status(Response.Status.BAD_REQUEST).entity("Old password does not match.").build(); } catch (UnsupportedEncodingException e) { - String errorMsg = "Could not change the password of the user: " + credentials.getUsername() + + String errorMsg = "Could not change the password of the user: " + username + ". The Character Encoding is not supported."; log.error(errorMsg, e); return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(errorMsg).build(); @@ -62,27 +75,51 @@ public class CredentialManagementResponseBuilder { /** * Builds the response to reset the password of a user + * @param username - Username of the user. * @param credentials - User credentials * @return Response Object */ - public static Response buildResetPasswordResponse(UserCredentialWrapper credentials) { + public static Response buildResetPasswordResponse(String username, PasswordResetWrapper credentials) { try { UserStoreManager userStoreManager = DeviceMgtAPIUtils.getUserStoreManager(); - byte[] decodedNewPassword = Base64.decodeBase64(credentials.getNewPassword()); - userStoreManager.updateCredentialByAdmin(credentials.getUsername(), new String( - decodedNewPassword, "UTF-8")); - return Response.status(Response.Status.CREATED).entity("UserImpl password by username: " + - credentials.getUsername() + " was successfully changed.").build(); + if (!userStoreManager.isExistingUser(username)) { + return Response.status(Response.Status.BAD_REQUEST).entity("No user found with the username " + + username).build(); + } + if (credentials == null || credentials.getNewPassword() == null) { + return Response.status(Response.Status.BAD_REQUEST).entity("Password cannot be empty.") + .build(); + } + if (!validateCredential(credentials.getNewPassword())) { + return Response.status(Response.Status.BAD_REQUEST).entity("Password does not match with required format.") + .build(); + } + userStoreManager.updateCredentialByAdmin(username, credentials.getNewPassword()); + return Response.status(Response.Status.OK).entity("UserImpl password by username: " + + username + " was successfully changed.").build(); } catch (UserStoreException e) { - String msg = "ErrorResponse occurred while updating the credentials of user '" + credentials.getUsername() + "'"; + String msg = "ErrorResponse occurred while updating the credentials of user '" + username + "'"; log.error(msg, e); return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build(); } catch (UnsupportedEncodingException e) { - String msg = "Could not change the password of the user: " + credentials.getUsername() + + String msg = "Could not change the password of the user: " + username + ". The Character Encoding is not supported."; log.error(msg, e); return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build(); } } + private static boolean validateCredential(String password) + throws UserStoreException, UnsupportedEncodingException { + String passwordValidationRegex = DeviceMgtAPIUtils.getRealmService().getBootstrapRealmConfiguration() + .getUserStoreProperty(PASSWORD_VALIDATION_REGEX_TAG); + if (passwordValidationRegex != null) { + Pattern pattern = Pattern.compile(passwordValidationRegex); + if (pattern.matcher(password).matches()) { + return true; + } + } + return false; + } + } diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/util/DeviceMgtAPIUtils.java b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/util/DeviceMgtAPIUtils.java index 53ec73b8418..f70a157b9f8 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/util/DeviceMgtAPIUtils.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/util/DeviceMgtAPIUtils.java @@ -131,6 +131,18 @@ public class DeviceMgtAPIUtils { return userStoreManager; } + public static RealmService getRealmService() throws UserStoreException { + RealmService realmService; + PrivilegedCarbonContext ctx = PrivilegedCarbonContext.getThreadLocalCarbonContext(); + realmService = (RealmService) ctx.getOSGiService(RealmService.class, null); + if (realmService == null) { + String msg = "Realm service has not initialized."; + log.error(msg); + throw new IllegalStateException(msg); + } + return realmService; + } + /** * Getting the current tenant's user realm */ From d63e5e876b1bf8896336dfa80312c35156275766 Mon Sep 17 00:00:00 2001 From: ayyoob Date: Tue, 31 May 2016 17:09:34 +0530 Subject: [PATCH 2/5] added password validation error msg --- .../util/CredentialManagementResponseBuilder.java | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/util/CredentialManagementResponseBuilder.java b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/util/CredentialManagementResponseBuilder.java index 2edbb20ebb7..d52bdec3d96 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/util/CredentialManagementResponseBuilder.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/util/CredentialManagementResponseBuilder.java @@ -36,6 +36,7 @@ public class CredentialManagementResponseBuilder { private static Log log = LogFactory.getLog(CredentialManagementResponseBuilder.class); private static String PASSWORD_VALIDATION_REGEX_TAG = "PasswordJavaRegEx"; + private static String PASSWORD_VALIDATION_ERROR_MSG_TAG = "PasswordJavaRegExViolationErrorMsg"; /** * Builds the response to change the password of a user @@ -55,8 +56,9 @@ public class CredentialManagementResponseBuilder { .build(); } if (!validateCredential(credentials.getNewPassword())) { - return Response.status(Response.Status.BAD_REQUEST).entity("Password does not match with required format.") - .build(); + String errorMsg = DeviceMgtAPIUtils.getRealmService().getBootstrapRealmConfiguration() + .getUserStoreProperty(PASSWORD_VALIDATION_ERROR_MSG_TAG); + return Response.status(Response.Status.BAD_REQUEST).entity(errorMsg).build(); } userStoreManager.updateCredential(username, credentials.getNewPassword(), credentials.getOldPassword()); @@ -91,8 +93,9 @@ public class CredentialManagementResponseBuilder { .build(); } if (!validateCredential(credentials.getNewPassword())) { - return Response.status(Response.Status.BAD_REQUEST).entity("Password does not match with required format.") - .build(); + String errorMsg = DeviceMgtAPIUtils.getRealmService().getBootstrapRealmConfiguration() + .getUserStoreProperty(PASSWORD_VALIDATION_ERROR_MSG_TAG); + return Response.status(Response.Status.BAD_REQUEST).entity(errorMsg).build(); } userStoreManager.updateCredentialByAdmin(username, credentials.getNewPassword()); return Response.status(Response.Status.OK).entity("UserImpl password by username: " + From bfe215deacea43925b6f131f017fdcba7308a416 Mon Sep 17 00:00:00 2001 From: Ace Date: Tue, 31 May 2016 17:13:11 +0530 Subject: [PATCH 3/5] Adding changes and bug fixes to UserMgtService --- .../device/mgt/jaxrs/beans/UserList.java | 106 ++++++++++++++++++ 1 file changed, 106 insertions(+) create mode 100644 components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/beans/UserList.java diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/beans/UserList.java b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/beans/UserList.java new file mode 100644 index 00000000000..d98733ef89f --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/beans/UserList.java @@ -0,0 +1,106 @@ +/* + * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.wso2.carbon.device.mgt.jaxrs.beans; + +import com.fasterxml.jackson.annotation.JsonProperty; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; + +import java.util.ArrayList; +import java.util.List; + +@ApiModel(value = "List of users", description = "This contains a set of users that matches a given " + + "criteria as a collection") +public class UserList { + + private int count; + private String next; + private String previous; + + private List users = new ArrayList<>(); + + /** + * Number of Devices returned. + */ + @ApiModelProperty(value = "Number of users returned.") + @JsonProperty("count") + public int getCount() { + return count; + } + + public void setCount(int count) { + this.count = count; + } + + + /** + * Link to the next subset of resources qualified. \nEmpty if no more resources are to be returned. + */ + @ApiModelProperty(value = "Link to the next subset of resources qualified. \n " + + "Empty if no more resources are to be returned.") + @JsonProperty("next") + public String getNext() { + return next; + } + + public void setNext(String next) { + this.next = next; + } + + /** + * Link to the previous subset of resources qualified. \nEmpty if current subset is the first subset returned. + */ + @ApiModelProperty(value = "Link to the previous subset of resources qualified. \n" + + "Empty if current subset is the first subset returned.") + @JsonProperty("previous") + public String getPrevious() { + return previous; + } + + public void setPrevious(String previous) { + this.previous = previous; + } + + /** + **/ + @ApiModelProperty(value = "List of devices returned") + @JsonProperty("users") + public List getList() { + return users; + } + + public void setList(List users) { + this.users = users; + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("{\n"); + + sb.append(" count: ").append(count).append(",\n"); + sb.append(" next: ").append(next).append(",\n"); + sb.append(" previous: ").append(previous).append(",\n"); + sb.append(" users: [").append(users).append("\n"); + sb.append("]}\n"); + return sb.toString(); + } + + +} From ddfd678b2a00624db6a2cc03b1b8ae4c1381836f Mon Sep 17 00:00:00 2001 From: Ace Date: Tue, 31 May 2016 17:26:20 +0530 Subject: [PATCH 4/5] Adding user management API bug fixes and improvements --- .../service/api/UserManagementService.java | 7 ++-- .../impl/UserManagementServiceImpl.java | 34 ++++++++++++++----- 2 files changed, 30 insertions(+), 11 deletions(-) diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/api/UserManagementService.java b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/api/UserManagementService.java index a2c33625754..524e3cac01b 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/api/UserManagementService.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/api/UserManagementService.java @@ -22,6 +22,7 @@ import io.swagger.annotations.*; import org.wso2.carbon.apimgt.annotations.api.API; import org.wso2.carbon.apimgt.annotations.api.Permission; import org.wso2.carbon.device.mgt.jaxrs.beans.OldPasswordResetWrapper; +import org.wso2.carbon.device.mgt.jaxrs.beans.UserList; import org.wso2.carbon.device.mgt.jaxrs.beans.UserWrapper; import javax.ws.rs.*; @@ -279,14 +280,14 @@ public interface UserManagementService { value = "Get user list", notes = "If you wish to get the details of all the users registered with EMM, you can do so " + "using the REST API", - response = UserWrapper.class, + response = UserList.class, responseContainer = "List", tags = "User Management") @ApiResponses(value = { @ApiResponse( code = 200, message = "OK. \n Successfully fetched the requested role.", - response = UserWrapper.class, + response = UserList.class, responseContainer = "List", responseHeaders = { @ResponseHeader( @@ -303,7 +304,7 @@ public interface UserManagementService { }), @ApiResponse( code = 304, - message = "Not Modified. \n Empty body because the client has already the latest version of the requested resource."), + message = "Not Modified. \n Empty body because the client already has the latest version of the requested resource."), @ApiResponse( code = 406, message = "Not Acceptable.\n The requested media type is not supported"), diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/UserManagementServiceImpl.java b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/UserManagementServiceImpl.java index 1a2bb05f2d8..9975fbb29be 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/UserManagementServiceImpl.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/UserManagementServiceImpl.java @@ -27,6 +27,7 @@ import org.wso2.carbon.device.mgt.common.DeviceManagementException; import org.wso2.carbon.device.mgt.core.service.DeviceManagementProviderService; import org.wso2.carbon.device.mgt.core.service.EmailMetaInfo; import org.wso2.carbon.device.mgt.jaxrs.beans.OldPasswordResetWrapper; +import org.wso2.carbon.device.mgt.jaxrs.beans.UserList; import org.wso2.carbon.device.mgt.jaxrs.beans.UserWrapper; import org.wso2.carbon.device.mgt.jaxrs.service.api.UserManagementService; import org.wso2.carbon.device.mgt.jaxrs.util.Constants; @@ -142,10 +143,10 @@ public class UserManagementServiceImpl implements UserManagementService { Properties props = new Properties(); props.setProperty("username", usernameBits[1]); props.setProperty("domain-name", tenantDomain); - props.setProperty("first-name", getClaimValue(username, Constants.USER_CLAIM_FIRST_NAME)); + props.setProperty("first-name", getClaimValue(usernameBits[1], Constants.USER_CLAIM_FIRST_NAME)); props.setProperty("password", password); - String recipient = getClaimValue(username, Constants.USER_CLAIM_EMAIL_ADDRESS); + String recipient = getClaimValue(usernameBits[1], Constants.USER_CLAIM_EMAIL_ADDRESS); EmailMetaInfo metaInfo = new EmailMetaInfo(recipient, props); @@ -329,10 +330,15 @@ public class UserManagementServiceImpl implements UserManagementService { if (log.isDebugEnabled()) { log.debug("Getting the list of users with all user-related information"); } - List userList; + List userList, offsetList; + String appliedFilter = ((filter == null) || filter.isEmpty() ? "*" : filter); + int appliedLimit = (limit <= 0) ? -1 : (limit + offset); + try { UserStoreManager userStoreManager = DeviceMgtAPIUtils.getUserStoreManager(); - String[] users = userStoreManager.listUsers("*", -1); + + //As the listUsers function accepts limit only to accommodate offset we are passing offset + limit + String[] users = userStoreManager.listUsers(appliedFilter, appliedLimit); userList = new ArrayList<>(users.length); UserWrapper user; for (String username : users) { @@ -343,12 +349,24 @@ public class UserManagementServiceImpl implements UserManagementService { user.setLastname(getClaimValue(username, Constants.USER_CLAIM_LAST_NAME)); userList.add(user); } - if (userList.size() <= 0) { - return Response.status(Response.Status.NOT_FOUND).entity("No user is available to be retrieved").build(); + + if (offset <= userList.size()) { + offsetList = userList.subList(offset, userList.size()); + } else { + offsetList = new ArrayList<>(); } - return Response.status(Response.Status.OK).entity(userList).build(); + + if (offsetList.size() <= 0) { + return Response.status(Response.Status.NOT_FOUND).entity("No users available for retrieval").build(); + } + + UserList result = new UserList(); + result.setList(offsetList); + result.setCount(offsetList.size()); + + return Response.status(Response.Status.OK).entity(result).build(); } catch (UserStoreException e) { - String msg = "ErrorResponse occurred while retrieving the list of users"; + String msg = "ErrorResponse occurred while retrieving the list of users."; log.error(msg, e); return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build(); } From 3e21c6d50dd8b1ec74b059e131485cfec81c28cf Mon Sep 17 00:00:00 2001 From: prabathabey Date: Tue, 31 May 2016 17:49:26 +0530 Subject: [PATCH 5/5] Improving ceritificate management webapp impl --- .../CertificateManagementAdminService.java | 3 +- ...CertificateManagementAdminServiceImpl.java | 2 +- .../admin/GroupManagementAdminService.java | 130 +++++++++--------- .../GroupManagementAdminServiceImpl.java | 52 +++---- 4 files changed, 94 insertions(+), 93 deletions(-) diff --git a/components/certificate-mgt/org.wso2.carbon.certificate.mgt.cert.admin.api/src/main/java/org/wso2/carbon/certificate/mgt/cert/jaxrs/api/CertificateManagementAdminService.java b/components/certificate-mgt/org.wso2.carbon.certificate.mgt.cert.admin.api/src/main/java/org/wso2/carbon/certificate/mgt/cert/jaxrs/api/CertificateManagementAdminService.java index c7cbc13b523..6988f317122 100644 --- a/components/certificate-mgt/org.wso2.carbon.certificate.mgt.cert.admin.api/src/main/java/org/wso2/carbon/certificate/mgt/cert/jaxrs/api/CertificateManagementAdminService.java +++ b/components/certificate-mgt/org.wso2.carbon.certificate.mgt.cert.admin.api/src/main/java/org/wso2/carbon/certificate/mgt/cert/jaxrs/api/CertificateManagementAdminService.java @@ -227,7 +227,8 @@ public interface CertificateManagementAdminService { produces = MediaType.APPLICATION_JSON, httpMethod = "DELETE", value = "Delete an SSL certificate", - notes = "Delete an SSL certificate that's on the client end") + notes = "Delete an SSL certificate that's on the client end", + tags = "Certificate Management") @ApiResponses(value = { @ApiResponse( code = 200, diff --git a/components/certificate-mgt/org.wso2.carbon.certificate.mgt.cert.admin.api/src/main/java/org/wso2/carbon/certificate/mgt/cert/jaxrs/api/impl/CertificateManagementAdminServiceImpl.java b/components/certificate-mgt/org.wso2.carbon.certificate.mgt.cert.admin.api/src/main/java/org/wso2/carbon/certificate/mgt/cert/jaxrs/api/impl/CertificateManagementAdminServiceImpl.java index ad3b1e81080..ebe9953f8b7 100644 --- a/components/certificate-mgt/org.wso2.carbon.certificate.mgt.cert.admin.api/src/main/java/org/wso2/carbon/certificate/mgt/cert/jaxrs/api/impl/CertificateManagementAdminServiceImpl.java +++ b/components/certificate-mgt/org.wso2.carbon.certificate.mgt.cert.admin.api/src/main/java/org/wso2/carbon/certificate/mgt/cert/jaxrs/api/impl/CertificateManagementAdminServiceImpl.java @@ -22,7 +22,7 @@ import javax.ws.rs.core.Response; import java.util.ArrayList; import java.util.List; -@Path("/certificates") +@Path("/admin/certificates") public class CertificateManagementAdminServiceImpl implements CertificateManagementAdminService { private static Log log = LogFactory.getLog(CertificateManagementAdminServiceImpl.class); diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/api/admin/GroupManagementAdminService.java b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/api/admin/GroupManagementAdminService.java index 1143447c39f..4d5915684b0 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/api/admin/GroupManagementAdminService.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/api/admin/GroupManagementAdminService.java @@ -27,73 +27,73 @@ import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; import java.util.Date; -@Path("/admin/groups") -@Produces(MediaType.APPLICATION_JSON) -@Consumes(MediaType.APPLICATION_JSON) -@Api(value = "Group Management Administrative Service", description = "This an API intended to be used by " + - "'internal' components to log in as an admin user and do a selected number of operations. " + - "Further, this is strictly restricted to admin users only ") +//@Path("/admin/groups") +//@Produces(MediaType.APPLICATION_JSON) +//@Consumes(MediaType.APPLICATION_JSON) +//@Api(value = "Group Management Administrative Service", description = "This an API intended to be used by " + +// "'internal' components to log in as an admin user and do a selected number of operations. " + +// "Further, this is strictly restricted to admin users only ") public interface GroupManagementAdminService { - @GET - @ApiOperation( - produces = MediaType.APPLICATION_JSON, - httpMethod = "GET", - value = "Get groups by the name.", - notes = "Get devices the name of device and tenant.", - response = DeviceGroupWrapper.class, - responseContainer = "List", - tags = "Group Management Administrative Service") - @ApiResponses(value = { - @ApiResponse(code = 200, message = "OK. \n Successfully fetched the list of groups.", - response = DeviceGroupWrapper.class, - responseContainer = "List", - responseHeaders = { - @ResponseHeader( - name = "Content-Type", - description = "The content type of the body"), - @ResponseHeader( - name = "ETag", - description = "Entity Tag of the response resource.\n" + - "Used by caches, or in conditional requests."), - @ResponseHeader( - name = "Last-Modified", - description = "Date and time the resource has been modified the last time.\n" + - "Used by caches, or in conditional requests."), - }), - @ApiResponse( - code = 304, - message = "Not Modified. \n Empty body because the client has already the latest version of the requested resource."), - @ApiResponse( - code = 406, - message = "Not Acceptable.\n The requested media type is not supported"), - @ApiResponse( - code = 500, - message = "Internal Server ErrorResponse. \n Server error occurred while fetching the group list.") - }) - @Permission(scope = "group-view", permissions = {"/permission/admin/device-mgt/user/groups/list"}) - Response getGroupsOfUser( - @ApiParam( - name = "username", - value = "Username of the user.", - required = true) - @QueryParam("username") String username, - @ApiParam( - name = "If-Modified-Since", - value = "Timestamp of the last modified date", - required = false) - @HeaderParam("If-Modified-Since") String timestamp, - @ApiParam( - name = "offset", - value = "Starting point within the complete list of items qualified.", - required = false) - @QueryParam("offset") int offset, - @ApiParam( - name = "limit", - value = "Maximum size of resource array to return.", - required = false) - @QueryParam("limit") int limit); - +// @GET +// @ApiOperation( +// produces = MediaType.APPLICATION_JSON, +// httpMethod = "GET", +// value = "Get groups by the name.", +// notes = "Get devices the name of device and tenant.", +// response = DeviceGroupWrapper.class, +// responseContainer = "List", +// tags = "Group Management Administrative Service") +// @ApiResponses(value = { +// @ApiResponse(code = 200, message = "OK. \n Successfully fetched the list of groups.", +// response = DeviceGroupWrapper.class, +// responseContainer = "List", +// responseHeaders = { +// @ResponseHeader( +// name = "Content-Type", +// description = "The content type of the body"), +// @ResponseHeader( +// name = "ETag", +// description = "Entity Tag of the response resource.\n" + +// "Used by caches, or in conditional requests."), +// @ResponseHeader( +// name = "Last-Modified", +// description = "Date and time the resource has been modified the last time.\n" + +// "Used by caches, or in conditional requests."), +// }), +// @ApiResponse( +// code = 304, +// message = "Not Modified. \n Empty body because the client has already the latest version of the requested resource."), +// @ApiResponse( +// code = 406, +// message = "Not Acceptable.\n The requested media type is not supported"), +// @ApiResponse( +// code = 500, +// message = "Internal Server ErrorResponse. \n Server error occurred while fetching the group list.") +// }) +// @Permission(scope = "group-view", permissions = {"/permission/admin/device-mgt/user/groups/list"}) +// Response getGroupsOfUser( +// @ApiParam( +// name = "username", +// value = "Username of the user.", +// required = true) +// @QueryParam("username") String username, +// @ApiParam( +// name = "If-Modified-Since", +// value = "Timestamp of the last modified date", +// required = false) +// @HeaderParam("If-Modified-Since") String timestamp, +// @ApiParam( +// name = "offset", +// value = "Starting point within the complete list of items qualified.", +// required = false) +// @QueryParam("offset") int offset, +// @ApiParam( +// name = "limit", +// value = "Maximum size of resource array to return.", +// required = false) +// @QueryParam("limit") int limit); +// } diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/admin/GroupManagementAdminServiceImpl.java b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/admin/GroupManagementAdminServiceImpl.java index 7fe91394f43..7573df0f5e2 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/admin/GroupManagementAdminServiceImpl.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/admin/GroupManagementAdminServiceImpl.java @@ -31,32 +31,32 @@ import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; import java.util.Date; -@Path("/admin/groups") -@Produces(MediaType.APPLICATION_JSON) -@Consumes(MediaType.APPLICATION_JSON) +//@Path("/admin/groups") +//@Produces(MediaType.APPLICATION_JSON) +//@Consumes(MediaType.APPLICATION_JSON) public class GroupManagementAdminServiceImpl implements GroupManagementAdminService { - - private static final Log log = LogFactory.getLog(GroupManagementAdminServiceImpl.class); - - @Override - public Response getGroupsOfUser( - @QueryParam("username") String username, - @HeaderParam("If-Modified-Since") String timestamp, - @QueryParam("offset") int offset, - @QueryParam("limit") int limit) { - try { - PaginationResult result = - DeviceMgtAPIUtils.getGroupManagementProviderService().getGroups(username, offset, limit); - if (result != null && result.getRecordsTotal() > 0) { - return Response.status(Response.Status.OK).entity(result).build(); - } else { - return Response.status(Response.Status.NOT_FOUND).build(); - } - } catch (GroupManagementException e) { - String msg = "ErrorResponse occurred while retrieving the groups of user '" + username + "'"; - log.error(msg, e); - return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build(); - } - } +// +// private static final Log log = LogFactory.getLog(GroupManagementAdminServiceImpl.class); +// +// @Override +// public Response getGroupsOfUser( +// @QueryParam("username") String username, +// @HeaderParam("If-Modified-Since") String timestamp, +// @QueryParam("offset") int offset, +// @QueryParam("limit") int limit) { +// try { +// PaginationResult result = +// DeviceMgtAPIUtils.getGroupManagementProviderService().getGroups(username, offset, limit); +// if (result != null && result.getRecordsTotal() > 0) { +// return Response.status(Response.Status.OK).entity(result).build(); +// } else { +// return Response.status(Response.Status.NOT_FOUND).build(); +// } +// } catch (GroupManagementException e) { +// String msg = "ErrorResponse occurred while retrieving the groups of user '" + username + "'"; +// log.error(msg, e); +// return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build(); +// } +// } }