WIP: Move user-service API implementation as a service #271

Draft
osh.silva wants to merge 5 commits from osh.silva/device-mgt-core:user-service-10389 into master

@ -19,6 +19,7 @@ package io.entgra.device.mgt.core.device.mgt.api.jaxrs.beans;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.google.gson.Gson;
import io.entgra.device.mgt.core.device.mgt.common.BasePaginatedResult;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import io.entgra.device.mgt.core.device.mgt.common.operation.mgt.Activity;

@ -19,13 +19,14 @@
package io.entgra.device.mgt.core.device.mgt.api.jaxrs.beans;
import com.fasterxml.jackson.annotation.JsonProperty;
import io.entgra.device.mgt.core.device.mgt.common.BasePaginatedResult;
import io.swagger.annotations.ApiModelProperty;
import io.entgra.device.mgt.core.device.mgt.common.app.mgt.Application;
import java.util.ArrayList;
import java.util.List;
public class ApplicationList extends BasePaginatedResult{
public class ApplicationList extends BasePaginatedResult {
private List<Application> applicationList = new ArrayList<>();

@ -19,13 +19,14 @@
package io.entgra.device.mgt.core.device.mgt.api.jaxrs.beans;
import com.fasterxml.jackson.annotation.JsonProperty;
import io.entgra.device.mgt.core.device.mgt.common.BasePaginatedResult;
import io.swagger.annotations.ApiModelProperty;
import io.entgra.device.mgt.core.device.mgt.common.policy.mgt.monitor.ComplianceData;
import java.util.ArrayList;
import java.util.List;
public class ComplianceDeviceList extends BasePaginatedResult{
public class ComplianceDeviceList extends BasePaginatedResult {
private List<ComplianceData> complianceData = new ArrayList<>();
@ApiModelProperty(value = "List of devices returned")

@ -20,6 +20,7 @@ package io.entgra.device.mgt.core.device.mgt.api.jaxrs.beans;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.google.gson.Gson;
import io.entgra.device.mgt.core.device.mgt.common.BasePaginatedResult;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import io.entgra.device.mgt.core.device.mgt.common.operation.mgt.DeviceActivity;

@ -18,6 +18,7 @@
package io.entgra.device.mgt.core.device.mgt.api.jaxrs.beans;
import com.fasterxml.jackson.annotation.JsonProperty;
import io.entgra.device.mgt.core.device.mgt.common.BasePaginatedResult;
import io.swagger.annotations.ApiModelProperty;
import java.util.ArrayList;

@ -18,6 +18,7 @@
package io.entgra.device.mgt.core.device.mgt.api.jaxrs.beans;
import com.fasterxml.jackson.annotation.JsonProperty;
import io.entgra.device.mgt.core.device.mgt.common.BasePaginatedResult;
import io.swagger.annotations.ApiModelProperty;
import io.entgra.device.mgt.core.device.mgt.common.Device;

@ -20,7 +20,7 @@ package io.entgra.device.mgt.core.device.mgt.api.jaxrs.beans;
import com.fasterxml.jackson.annotation.JsonProperty;
import io.swagger.annotations.ApiModelProperty;
import io.entgra.device.mgt.core.device.mgt.common.DeviceIdentifier;
import io.entgra.device.mgt.core.device.mgt.api.jaxrs.beans.BasePaginatedResult;
import io.entgra.device.mgt.core.device.mgt.common.BasePaginatedResult;
import java.util.ArrayList;
import java.util.List;

@ -19,6 +19,7 @@
package io.entgra.device.mgt.core.device.mgt.api.jaxrs.beans;
import com.fasterxml.jackson.annotation.JsonProperty;
import io.entgra.device.mgt.core.device.mgt.common.BasePaginatedResult;
import io.swagger.annotations.ApiModelProperty;
import java.util.ArrayList;

@ -18,6 +18,7 @@
package io.entgra.device.mgt.core.device.mgt.api.jaxrs.beans;
import com.fasterxml.jackson.annotation.JsonProperty;
import io.entgra.device.mgt.core.device.mgt.common.BasePaginatedResult;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import io.entgra.device.mgt.core.device.mgt.common.metadata.mgt.Metadata;

@ -18,6 +18,7 @@
package io.entgra.device.mgt.core.device.mgt.api.jaxrs.beans;
import com.fasterxml.jackson.annotation.JsonProperty;
import io.entgra.device.mgt.core.device.mgt.common.BasePaginatedResult;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import io.entgra.device.mgt.core.device.mgt.common.notification.mgt.Notification;

@ -18,6 +18,7 @@
package io.entgra.device.mgt.core.device.mgt.api.jaxrs.beans;
import com.fasterxml.jackson.annotation.JsonProperty;
import io.entgra.device.mgt.core.device.mgt.common.BasePaginatedResult;
import io.swagger.annotations.ApiModelProperty;
import io.entgra.device.mgt.core.device.mgt.common.operation.mgt.Operation;

@ -18,6 +18,7 @@
package io.entgra.device.mgt.core.device.mgt.api.jaxrs.beans;
import com.fasterxml.jackson.annotation.JsonProperty;
import io.entgra.device.mgt.core.device.mgt.common.BasePaginatedResult;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import io.entgra.device.mgt.core.device.mgt.common.policy.mgt.Policy;

@ -18,6 +18,7 @@
package io.entgra.device.mgt.core.device.mgt.api.jaxrs.beans;
import com.fasterxml.jackson.annotation.JsonProperty;
import io.entgra.device.mgt.core.device.mgt.common.BasePaginatedResult;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;

@ -18,6 +18,8 @@
package io.entgra.device.mgt.core.device.mgt.api.jaxrs.beans;
import com.fasterxml.jackson.annotation.JsonProperty;
import io.entgra.device.mgt.core.device.mgt.common.BasePaginatedResult;
import io.entgra.device.mgt.core.device.mgt.common.UserInfo;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;

@ -18,6 +18,7 @@
package io.entgra.device.mgt.core.device.mgt.api.jaxrs.beans;
import com.fasterxml.jackson.annotation.JsonProperty;
import io.entgra.device.mgt.core.device.mgt.common.BasePaginatedResult;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;

@ -19,8 +19,6 @@ package io.entgra.device.mgt.core.device.mgt.api.jaxrs.beans.analytics;
import com.fasterxml.jackson.annotation.JsonProperty;
import io.swagger.annotations.ApiModelProperty;
import io.entgra.device.mgt.core.device.mgt.common.Device;
import io.entgra.device.mgt.core.device.mgt.api.jaxrs.beans.BasePaginatedResult;
import java.util.ArrayList;
import java.util.List;

@ -19,12 +19,11 @@ package io.entgra.device.mgt.core.device.mgt.api.jaxrs.beans.analytics;
import com.fasterxml.jackson.annotation.JsonProperty;
import io.swagger.annotations.ApiModelProperty;
import io.entgra.device.mgt.core.device.mgt.common.Device;
import java.util.ArrayList;
import java.util.List;
import org.wso2.carbon.analytics.datasource.commons.Record;
import io.entgra.device.mgt.core.device.mgt.api.jaxrs.beans.BasePaginatedResult;
import io.entgra.device.mgt.core.device.mgt.common.BasePaginatedResult;
/**
* This hold stats data record

@ -2793,7 +2793,15 @@ public interface DeviceManagementService {
message = "Error occurred while getting the version data.",
response = ErrorResponse.class)
})
Response getDeviceFilters();
Response getDeviceFilters(
@ApiParam(
name = "isGroups",
value = "Check if group data is needed", required = false)
@QueryParam("isGroups") boolean isGroups,
@ApiParam(
name = "isConfig",
value = "Check if config data is needed", required = false)
@QueryParam("isConfig") boolean isConfig);
@GET
@Produces(MediaType.APPLICATION_JSON)

@ -34,15 +34,15 @@ import io.entgra.device.mgt.core.apimgt.annotations.Scopes;
import io.entgra.device.mgt.core.apimgt.annotations.Scope;
import io.entgra.device.mgt.core.device.mgt.common.invitation.mgt.DeviceEnrollmentInvitation;
import io.entgra.device.mgt.core.device.mgt.api.jaxrs.beans.ActivityList;
import io.entgra.device.mgt.core.device.mgt.api.jaxrs.beans.BasicUserInfo;
import io.entgra.device.mgt.core.device.mgt.api.jaxrs.beans.BasicUserInfoList;
import io.entgra.device.mgt.core.device.mgt.common.BasicUserInfo;
import io.entgra.device.mgt.core.device.mgt.common.BasicUserInfoList;
import io.entgra.device.mgt.core.device.mgt.api.jaxrs.beans.Credential;
import io.entgra.device.mgt.core.device.mgt.api.jaxrs.beans.EnrollmentInvitation;
import io.entgra.device.mgt.core.device.mgt.common.EnrollmentInvitation;
import io.entgra.device.mgt.core.device.mgt.api.jaxrs.beans.ErrorResponse;
import io.entgra.device.mgt.core.device.mgt.api.jaxrs.beans.OldPasswordResetWrapper;
import io.entgra.device.mgt.core.device.mgt.api.jaxrs.beans.PermissionList;
import io.entgra.device.mgt.core.device.mgt.api.jaxrs.beans.RoleList;
import io.entgra.device.mgt.core.device.mgt.api.jaxrs.beans.UserInfo;
import io.entgra.device.mgt.core.device.mgt.common.UserInfo;
import io.entgra.device.mgt.core.device.mgt.api.jaxrs.beans.UserStoreList;
import io.entgra.device.mgt.core.device.mgt.api.jaxrs.util.Constants;
@ -54,7 +54,6 @@ import javax.ws.rs.HeaderParam;
import javax.ws.rs.POST;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.MediaType;

@ -26,6 +26,10 @@ import io.entgra.device.mgt.core.application.mgt.common.exception.SubscriptionMa
import io.entgra.device.mgt.core.application.mgt.common.services.ApplicationManager;
import io.entgra.device.mgt.core.application.mgt.common.services.SubscriptionManager;
import io.entgra.device.mgt.core.application.mgt.core.util.HelperUtil;
import io.entgra.device.mgt.core.device.mgt.common.configuration.mgt.ConfigurationEntry;
import io.entgra.device.mgt.core.device.mgt.common.configuration.mgt.ConfigurationManagementException;
import io.entgra.device.mgt.core.device.mgt.common.configuration.mgt.PlatformConfiguration;
import io.entgra.device.mgt.core.device.mgt.common.group.mgt.GroupFilter;
import io.entgra.device.mgt.core.device.mgt.api.jaxrs.service.impl.util.DisenrollRequest;
import org.apache.commons.httpclient.HttpStatus;
import org.apache.commons.lang.StringUtils;
@ -102,14 +106,15 @@ import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Properties;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ExecutionException;
import java.util.Arrays;
import java.util.HashMap;
@Path("/devices")
public class DeviceManagementServiceImpl implements DeviceManagementService {
public static final String DATE_FORMAT_NOW = "yyyy-MM-dd HH:mm:ss";
private static final String DEFAULT_ADMIN_ROLE = "admin";
private static final Log log = LogFactory.getLog(DeviceManagementServiceImpl.class);
@GET
@ -1672,8 +1677,39 @@ public class DeviceManagementServiceImpl implements DeviceManagementService {
@GET
@Path("/filters")
@Override
public Response getDeviceFilters() {
public Response getDeviceFilters( @QueryParam("isGroups") boolean isGroups, @QueryParam("isConfig") boolean isConfig) {
try {
String currentUser = PrivilegedCarbonContext.getThreadLocalCarbonContext().getUsername();
List<String> permissions = DeviceMgtAPIUtils
.getUserManagementService().getPermissions(currentUser);
List<GroupFilter> groupFilters = new ArrayList<>();
List<ConfigurationEntry> configList = new ArrayList<>();
if (isGroups) {
List<String> roles = DeviceMgtAPIUtils
.getUserManagementService().getRoles(currentUser);
boolean isAdmin = DEFAULT_ADMIN_ROLE.equals(currentUser);
boolean hasAdminRole = Arrays.asList(roles).contains(DEFAULT_ADMIN_ROLE);
if (permissions.contains("/permission/admin/device-mgt/admin/groups/view")) {
if (StringUtils.isBlank(currentUser) || isAdmin || hasAdminRole) {
groupFilters = DeviceMgtAPIUtils.getGroupManagementProviderService().getGroupFilterValues(null, null);
} else {
groupFilters = DeviceMgtAPIUtils.getGroupManagementProviderService().getGroupFilterValues(currentUser, null);
}
} else {
if (hasAdminRole) {
groupFilters = DeviceMgtAPIUtils.getGroupManagementProviderService().getGroupFilterValues(null, null);
} else {
groupFilters = DeviceMgtAPIUtils.getGroupManagementProviderService().getGroupFilterValues(currentUser, null);
}
}
}
if (isConfig) {
if (permissions.contains("/permission/admin/device-mgt/platform-configurations/view")) {
PlatformConfiguration config = DeviceMgtAPIUtils.getPlatformConfigurationManagementService().
getConfiguration(MDMAppConstants.RegistryConstants.GENERAL_CONFIG_RESOURCE_PATH);
configList = config.getConfiguration();
}
}
List<String> deviceTypeNames = new ArrayList<>();
List<String> ownershipNames = new ArrayList<>();
List<String> statusNames = new ArrayList<>();
@ -1693,11 +1729,25 @@ public class DeviceManagementServiceImpl implements DeviceManagementService {
deviceFilters.setDeviceTypes(deviceTypeNames);
deviceFilters.setOwnerships(ownershipNames);
deviceFilters.setStatuses(statusNames);
deviceFilters.setConfigs(configList);
deviceFilters.setGroups(groupFilters);
return Response.status(Response.Status.OK).entity(deviceFilters).build();
} catch (DeviceManagementException e) {
String msg = "Error occurred white retrieving device types to be used in device filters.";
log.error(msg, e);
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build();
} catch (UserManagementException e) {
String msg = "Error occurred while retrieving permission details to be used in device filters.";
log.error(msg, e);
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build();
} catch (GroupManagementException e) {
String msg = "Error occurred while retrieving group data for device filters values.";
log.error(msg, e);
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build();
} catch (ConfigurationManagementException e) {
String msg = "Error occurred while retrieving config data for device filter values.";
log.error(msg, e);
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build();
}
}

@ -19,7 +19,9 @@ package io.entgra.device.mgt.core.device.mgt.api.jaxrs.service.impl;
import com.google.gson.JsonArray;
import com.google.gson.JsonObject;
import io.entgra.device.mgt.core.device.mgt.common.Device;
import io.entgra.device.mgt.core.device.mgt.common.BasicUserInfoMetadata;
import io.entgra.device.mgt.core.device.mgt.common.exceptions.UserManagementException;
import io.entgra.device.mgt.core.device.mgt.core.service.UserManagementProviderService;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
@ -28,7 +30,6 @@ import org.eclipse.wst.common.uriresolver.internal.util.URIEncoder;
import org.wso2.carbon.context.CarbonContext;
import org.wso2.carbon.context.PrivilegedCarbonContext;
import io.entgra.device.mgt.core.device.mgt.common.exceptions.DeviceManagementException;
import io.entgra.device.mgt.core.device.mgt.common.EnrolmentInfo;
import io.entgra.device.mgt.core.device.mgt.common.configuration.mgt.ConfigurationManagementException;
import io.entgra.device.mgt.core.device.mgt.common.exceptions.OTPManagementException;
import io.entgra.device.mgt.core.device.mgt.common.invitation.mgt.DeviceEnrollmentInvitation;
@ -39,16 +40,16 @@ import io.entgra.device.mgt.core.device.mgt.core.DeviceManagementConstants;
import io.entgra.device.mgt.core.device.mgt.core.service.DeviceManagementProviderService;
import io.entgra.device.mgt.core.device.mgt.core.service.EmailMetaInfo;
import io.entgra.device.mgt.core.device.mgt.api.jaxrs.beans.ActivityList;
import io.entgra.device.mgt.core.device.mgt.api.jaxrs.beans.BasicUserInfo;
import io.entgra.device.mgt.core.device.mgt.api.jaxrs.beans.BasicUserInfoList;
import io.entgra.device.mgt.core.device.mgt.api.jaxrs.beans.BasicUserInfoWrapper;
import io.entgra.device.mgt.core.device.mgt.common.BasicUserInfo;
import io.entgra.device.mgt.core.device.mgt.common.BasicUserInfoList;
import io.entgra.device.mgt.core.device.mgt.common.BasicUserInfoWrapper;
import io.entgra.device.mgt.core.device.mgt.api.jaxrs.beans.Credential;
import io.entgra.device.mgt.core.device.mgt.api.jaxrs.beans.EnrollmentInvitation;
import io.entgra.device.mgt.core.device.mgt.common.EnrollmentInvitation;
import io.entgra.device.mgt.core.device.mgt.api.jaxrs.beans.ErrorResponse;
import io.entgra.device.mgt.core.device.mgt.api.jaxrs.beans.OldPasswordResetWrapper;
import io.entgra.device.mgt.core.device.mgt.api.jaxrs.beans.PermissionList;
import io.entgra.device.mgt.core.device.mgt.api.jaxrs.beans.RoleList;
import io.entgra.device.mgt.core.device.mgt.api.jaxrs.beans.UserInfo;
import io.entgra.device.mgt.core.device.mgt.common.UserInfo;
import io.entgra.device.mgt.core.device.mgt.api.jaxrs.beans.UserStoreList;
import io.entgra.device.mgt.core.device.mgt.api.jaxrs.exception.BadRequestException;
import io.entgra.device.mgt.core.device.mgt.api.jaxrs.service.api.UserManagementService;
@ -70,8 +71,6 @@ import org.wso2.carbon.user.api.UserStoreException;
import org.wso2.carbon.user.api.UserStoreManager;
import org.wso2.carbon.user.core.UserCoreConstants;
import org.wso2.carbon.user.core.service.RealmService;
import org.wso2.carbon.user.mgt.UserRealmProxy;
import org.wso2.carbon.user.mgt.common.UIPermissionNode;
import org.wso2.carbon.user.mgt.common.UserAdminException;
import org.wso2.carbon.utils.CarbonUtils;
import org.wso2.carbon.utils.multitenancy.MultitenantConstants;
@ -83,7 +82,6 @@ import javax.ws.rs.HeaderParam;
import javax.ws.rs.POST;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.MediaType;
@ -92,10 +90,8 @@ import java.io.File;
import java.io.UnsupportedEncodingException;
import java.net.URI;
import java.net.URISyntaxException;
import java.security.SecureRandom;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.Instant;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
@ -129,6 +125,7 @@ public class UserManagementServiceImpl implements UserManagementService {
@Override
public Response addUser(UserInfo userInfo) {
try {
UserManagementProviderService ums = DeviceMgtAPIUtils.getUserManagementService();
UserStoreManager userStoreManager = DeviceMgtAPIUtils.getUserStoreManager();
if (userStoreManager.isExistingUser(userInfo.getUsername())) {
// if user already exists
@ -140,51 +137,8 @@ public class UserManagementServiceImpl implements UserManagementService {
String msg = "User by username: " + userInfo.getUsername() + " already exists. Try with another username." ;
return Response.status(Response.Status.CONFLICT).entity(msg).build();
}
String initialUserPassword;
if (userInfo.getPassword() != null) {
initialUserPassword = userInfo.getPassword();
} else {
initialUserPassword = this.generateInitialUserPassword();
}
Map<String, String> defaultUserClaims =
this.buildDefaultUserClaims(userInfo.getFirstname(), userInfo.getLastname(),
userInfo.getEmailAddress(), true);
userStoreManager.addUser(userInfo.getUsername(), initialUserPassword,
userInfo.getRoles(), defaultUserClaims, null);
// Outputting debug message upon successful addition of user
if (log.isDebugEnabled()) {
log.debug("User '" + userInfo.getUsername() + "' has successfully been added.");
}
BasicUserInfo createdUserInfo = this.getBasicUserInfo(userInfo.getUsername());
// Outputting debug message upon successful retrieval of user
if (log.isDebugEnabled()) {
log.debug("User by username: " + userInfo.getUsername() + " was found.");
}
DeviceManagementProviderService dms = DeviceMgtAPIUtils.getDeviceManagementService();
String[] bits = userInfo.getUsername().split("/");
String username = bits[bits.length - 1];
String recipient = userInfo.getEmailAddress();
Properties props = new Properties();
props.setProperty("first-name", userInfo.getFirstname());
props.setProperty("last-name", userInfo.getLastname());
props.setProperty("username", username);
props.setProperty("password", initialUserPassword);
EmailMetaInfo metaInfo = new EmailMetaInfo(recipient, props);
BasicUserInfoWrapper userInfoWrapper = new BasicUserInfoWrapper();
String message;
try {
dms.sendRegistrationEmail(metaInfo);
message = "An invitation mail will be sent to this user to initiate device enrollment.";
} catch (ConfigurationManagementException e) {
message = "Mail Server is not configured. Email invitation will not be sent.";
}
userInfoWrapper.setBasicUserInfo(createdUserInfo);
userInfoWrapper.setMessage(message);
userInfoWrapper = ums.addUser(userInfo);
return Response.created(new URI(API_BASE_PATH + "/" + URIEncoder.encode(userInfo.getUsername(),
"UTF-8"))).entity(userInfoWrapper).build();
} catch (UserStoreException e) {
@ -205,8 +159,8 @@ public class UserManagementServiceImpl implements UserManagementService {
log.error(msg, e);
return Response.serverError().entity(
new ErrorResponse.ErrorResponseBuilder().setMessage(msg).build()).build();
} catch (DeviceManagementException e) {
String msg = "Error occurred while sending registration email to the user " + userInfo.getUsername();
} catch (UserManagementException e) {
String msg = "Error occurred while trying to add the user '" + userInfo.getUsername() + "'";
log.error(msg, e);
return Response.serverError().entity(
new ErrorResponse.ErrorResponseBuilder().setMessage(msg).build()).build();
@ -221,6 +175,7 @@ public class UserManagementServiceImpl implements UserManagementService {
username = domain + '/' + username;
}
try {
UserManagementProviderService ums = DeviceMgtAPIUtils.getUserManagementService();
UserStoreManager userStoreManager = DeviceMgtAPIUtils.getUserStoreManager();
if (!userStoreManager.isExistingUser(username)) {
if (log.isDebugEnabled()) {
@ -229,14 +184,19 @@ public class UserManagementServiceImpl implements UserManagementService {
String msg = "User by username: " + username + " does not exist.";
return Response.status(Response.Status.NOT_FOUND).entity(msg).build();
}
BasicUserInfo user = this.getBasicUserInfo(username);
BasicUserInfo user = ums.getUser(username);
return Response.status(Response.Status.OK).entity(user).build();
} catch (UserStoreException e) {
String msg = "Error occurred while retrieving information of the user '" + username + "'";
log.error(msg, e);
return Response.serverError().entity(
new ErrorResponse.ErrorResponseBuilder().setMessage(msg).build()).build();
} catch (UserManagementException e) {
String message = "Error occurred while trying to get the user '" + username + "'";
log.error(message, e);
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
.entity(new ErrorResponse.ErrorResponseBuilder().setMessage(message).build())
.build();
}
}
@ -247,6 +207,7 @@ public class UserManagementServiceImpl implements UserManagementService {
username = domain + '/' + username;
}
try {
UserManagementProviderService ums = DeviceMgtAPIUtils.getUserManagementService();
UserStoreManager userStoreManager = DeviceMgtAPIUtils.getUserStoreManager();
if (!userStoreManager.isExistingUser(username)) {
if (log.isDebugEnabled()) {
@ -256,67 +217,21 @@ public class UserManagementServiceImpl implements UserManagementService {
String msg = "User by username: " + username + " does not exist.";
return Response.status(Response.Status.NOT_FOUND).entity(msg).build();
}
Map<String, String> defaultUserClaims =
this.buildDefaultUserClaims(userInfo.getFirstname(), userInfo.getLastname(),
userInfo.getEmailAddress(), false);
if (StringUtils.isNotEmpty(userInfo.getPassword())) {
// Decoding Base64 encoded password
userStoreManager.updateCredentialByAdmin(username,
userInfo.getPassword());
log.debug("User credential of username: " + username + " has been changed");
}
List<String> currentRoles = this.getFilteredRoles(userStoreManager, username);
List<String> newRoles = new ArrayList<>();
if (userInfo.getRoles() != null) {
newRoles = Arrays.asList(userInfo.getRoles());
}
List<String> rolesToAdd = new ArrayList<>(newRoles);
List<String> rolesToDelete = new ArrayList<>();
for (String role : currentRoles) {
if (newRoles.contains(role)) {
rolesToAdd.remove(role);
} else {
rolesToDelete.add(role);
}
}
rolesToDelete.remove(ROLE_EVERYONE);
rolesToAdd.remove(ROLE_EVERYONE);
userStoreManager.updateRoleListOfUser(username,
rolesToDelete.toArray(new String[rolesToDelete.size()]),
rolesToAdd.toArray(new String[rolesToAdd.size()]));
userStoreManager.setUserClaimValues(username, defaultUserClaims, null);
// Outputting debug message upon successful addition of user
if (log.isDebugEnabled()) {
log.debug("User by username: " + username + " was successfully updated.");
}
BasicUserInfo updatedUserInfo = this.getBasicUserInfo(username);
return Response.ok().entity(updatedUserInfo).build();
return Response.ok().entity(ums.updateUser(username, userInfo)).build();
} catch (UserStoreException e) {
String msg = "Error occurred while trying to update user '" + username + "'";
log.error(msg, e);
return Response.serverError().entity(
new ErrorResponse.ErrorResponseBuilder().setMessage(msg).build()).build();
} catch (UserManagementException e) {
String message = "Error occurred while trying to update the user '" + username + "'";
log.error(message, e);
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
.entity(new ErrorResponse.ErrorResponseBuilder().setMessage(message).build())
.build();
}
}
private List<String> getFilteredRoles(UserStoreManager userStoreManager, String username)
throws UserStoreException {
String[] roleListOfUser;
roleListOfUser = userStoreManager.getRoleListOfUser(username);
List<String> filteredRoles = new ArrayList<>();
for (String role : roleListOfUser) {
if (!(role.startsWith("Internal/") || role.startsWith("Authentication/"))) {
filteredRoles.add(role);
}
}
return filteredRoles;
}
@DELETE
@Consumes(MediaType.WILDCARD)
@Override
@ -368,6 +283,7 @@ public class UserManagementServiceImpl implements UserManagementService {
username = domain + '/' + username;
}
try {
UserManagementProviderService ums = DeviceMgtAPIUtils.getUserManagementService();
UserStoreManager userStoreManager = DeviceMgtAPIUtils.getUserStoreManager();
if (!userStoreManager.isExistingUser(username)) {
if (log.isDebugEnabled()) {
@ -378,13 +294,19 @@ public class UserManagementServiceImpl implements UserManagementService {
}
RoleList result = new RoleList();
result.setList(getFilteredRoles(userStoreManager, username));
result.setList(ums.getRoles(username));
return Response.status(Response.Status.OK).entity(result).build();
} catch (UserStoreException e) {
String msg = "Error occurred while trying to retrieve roles of the user '" + username + "'";
log.error(msg, e);
return Response.serverError().entity(
new ErrorResponse.ErrorResponseBuilder().setMessage(msg).build()).build();
} catch (UserManagementException e) {
String message = "Error occurred while trying to retrieve roles of the user '" + username + "'";
log.error(message, e);
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
.entity(new ErrorResponse.ErrorResponseBuilder().setMessage(message).build())
.build();
}
}
@ -409,46 +331,15 @@ public class UserManagementServiceImpl implements UserManagementService {
int appliedLimit = -1;
try {
UserStoreManager userStoreManager = DeviceMgtAPIUtils.getUserStoreManager();
//As the listUsers function accepts limit only to accommodate offset we are passing offset + limit
List<String> users = Arrays.asList(userStoreManager.listUsers(appliedFilter, appliedLimit));
if (domain != null && !domain.isEmpty()) {
users = getUsersFromDomain(domain, users);
}
userList = new ArrayList<>(users.size());
BasicUserInfo user;
for (String username : users) {
if (Constants.APIM_RESERVED_USER.equals(username) || Constants.RESERVED_USER.equals(username)) {
continue;
}
user = getBasicUserInfo(username);
userList.add(user);
}
int toIndex = offset + limit;
int listSize = userList.size();
int lastIndex = listSize - 1;
if (offset <= lastIndex) {
if (toIndex <= listSize) {
offsetList = userList.subList(offset, toIndex);
} else {
offsetList = userList.subList(offset, listSize);
}
} else {
offsetList = new ArrayList<>();
}
BasicUserInfoList result = new BasicUserInfoList();
result.setList(offsetList);
result.setCount(userList.size());
return Response.status(Response.Status.OK).entity(result).build();
} catch (UserStoreException e) {
String msg = "Error occurred while retrieving the list of users.";
log.error(msg, e);
return Response.serverError().entity(
new ErrorResponse.ErrorResponseBuilder().setMessage(msg).build()).build();
UserManagementProviderService ums = DeviceMgtAPIUtils.getUserManagementService();
BasicUserInfoList basicUserInfoList = ums.getUsers(appliedFilter,appliedLimit, domain, limit, offset);
return Response.status(Response.Status.OK).entity(basicUserInfoList).build();
} catch (UserManagementException e) {
String message = "Error occurred while trying to retrieve all users of domain '" + domain + "'";
log.error(message, e);
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
.entity(new ErrorResponse.ErrorResponseBuilder().setMessage(message).build())
.build();
}
}
@ -475,78 +366,17 @@ public class UserManagementServiceImpl implements UserManagementService {
limit = Constants.DEFAULT_PAGE_LIMIT;
}
List<BasicUserInfo> filteredUserList = new ArrayList<>();
List<String> commonUsers = null, tempList;
BasicUserInfo basicUserInfo = new BasicUserInfo();
basicUserInfo.setUsername(username);
basicUserInfo.setFirstname(firstName);
basicUserInfo.setLastname(lastName);
basicUserInfo.setEmailAddress(emailAddress);
try {
if (StringUtils.isNotEmpty(username)) {
commonUsers = getUserList(null, "*" + username + "*");
}
if (commonUsers != null) {
commonUsers.remove(Constants.APIM_RESERVED_USER);
commonUsers.remove(Constants.RESERVED_USER);
}
if (!skipSearch(commonUsers) && StringUtils.isNotEmpty(firstName)) {
tempList = getUserList(Constants.USER_CLAIM_FIRST_NAME, "*" + firstName + "*");
if (commonUsers == null) {
commonUsers = tempList;
} else {
commonUsers.retainAll(tempList);
}
}
if (!skipSearch(commonUsers) && StringUtils.isNotEmpty(lastName)) {
tempList = getUserList(Constants.USER_CLAIM_LAST_NAME, "*" + lastName + "*");
if (commonUsers == null || commonUsers.size() == 0) {
commonUsers = tempList;
} else {
commonUsers.retainAll(tempList);
}
}
if (!skipSearch(commonUsers) && StringUtils.isNotEmpty(emailAddress)) {
tempList = getUserList(Constants.USER_CLAIM_EMAIL_ADDRESS, "*" + emailAddress + "*");
if (commonUsers == null || commonUsers.size() == 0) {
commonUsers = tempList;
} else {
commonUsers.retainAll(tempList);
}
}
BasicUserInfo basicUserInfo;
if (commonUsers != null) {
for (String user : commonUsers) {
basicUserInfo = new BasicUserInfo();
basicUserInfo.setUsername(user);
basicUserInfo.setEmailAddress(getClaimValue(user, Constants.USER_CLAIM_EMAIL_ADDRESS));
basicUserInfo.setFirstname(getClaimValue(user, Constants.USER_CLAIM_FIRST_NAME));
basicUserInfo.setLastname(getClaimValue(user, Constants.USER_CLAIM_LAST_NAME));
filteredUserList.add(basicUserInfo);
}
}
int toIndex = offset + limit;
int listSize = filteredUserList.size();
int lastIndex = listSize - 1;
List<BasicUserInfo> offsetList;
if (offset <= lastIndex) {
if (toIndex <= listSize) {
offsetList = filteredUserList.subList(offset, toIndex);
} else {
offsetList = filteredUserList.subList(offset, listSize);
}
} else {
offsetList = new ArrayList<>();
}
BasicUserInfoList result = new BasicUserInfoList();
result.setList(offsetList);
result.setCount(commonUsers != null ? commonUsers.size() : 0);
UserManagementProviderService ums = DeviceMgtAPIUtils.getUserManagementService();
BasicUserInfoList result = ums.getUsersSearch(basicUserInfo, offset, limit);
return Response.status(Response.Status.OK).entity(result).build();
} catch (UserStoreException e) {
} catch (UserManagementException e) {
String msg = "Error occurred while retrieving the list of users.";
log.error(msg, e);
return Response.serverError().entity(
@ -650,28 +480,10 @@ public class UserManagementServiceImpl implements UserManagementService {
}
List<UserInfo> userList;
try {
UserStoreManager userStoreManager = DeviceMgtAPIUtils.getUserStoreManager();
String[] users;
if (userStoreDomain.equals("all")) {
users = userStoreManager.listUsers(filter + "*", limit);
} else {
users = userStoreManager.listUsers(userStoreDomain + "/" + filter + "*", limit);
}
userList = new ArrayList<>();
UserInfo user;
for (String username : users) {
if (Constants.APIM_RESERVED_USER.equals(username) || Constants.RESERVED_USER.equals(username)) {
continue;
}
user = new UserInfo();
user.setUsername(username);
user.setEmailAddress(getClaimValue(username, Constants.USER_CLAIM_EMAIL_ADDRESS));
user.setFirstname(getClaimValue(username, Constants.USER_CLAIM_FIRST_NAME));
user.setLastname(getClaimValue(username, Constants.USER_CLAIM_LAST_NAME));
userList.add(user);
}
UserManagementProviderService ums = DeviceMgtAPIUtils.getUserManagementService();
userList = ums.getUserNames(filter, userStoreDomain, offset, limit);
return Response.status(Response.Status.OK).entity(userList).build();
} catch (UserStoreException e) {
} catch (UserManagementException e) {
String msg = "Error occurred while retrieving the list of users using the filter : " + filter;
log.error(msg, e);
return Response.serverError().entity(
@ -1043,28 +855,13 @@ public class UserManagementServiceImpl implements UserManagementService {
String username = CarbonContext.getThreadLocalCarbonContext().getUsername();
try {
UserStoreManager userStoreManager = DeviceMgtAPIUtils.getUserStoreManager();
UserManagementProviderService ums = DeviceMgtAPIUtils.getUserManagementService();
if (!userStoreManager.isExistingUser(username)) {
String message = "User by username: " + username + " does not exist for permission retrieval.";
log.error(message);
return Response.status(Response.Status.NOT_FOUND).entity(message).build();
}
// Get a list of roles which the user assigned to
List<String> roles = getFilteredRoles(userStoreManager, username);
List<String> permissions = new ArrayList<>();
UserRealm userRealm = DeviceMgtAPIUtils.getUserRealm();
int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId();
// Get permissions for each role
for (String roleName : roles) {
try {
permissions.addAll(getPermissionsListFromRole(roleName, userRealm, tenantId));
} catch (UserAdminException e) {
String message = "Error occurred while retrieving the permissions of role '" + roleName + "'";
log.error(message, e);
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
.entity(new ErrorResponse.ErrorResponseBuilder().setMessage(message).build())
.build();
}
}
List<String> permissions = ums.getPermissions(username);
PermissionList permissionList = new PermissionList();
permissionList.setList(permissions);
return Response.status(Response.Status.OK).entity(permissionList).build();
@ -1074,26 +871,15 @@ public class UserManagementServiceImpl implements UserManagementService {
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
.entity(new ErrorResponse.ErrorResponseBuilder().setMessage(message).build())
.build();
} catch (UserManagementException e) {
String message = "Error occurred while trying to retrieve permissions of the user '" + username + "'";
log.error(message, e);
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
.entity(new ErrorResponse.ErrorResponseBuilder().setMessage(message).build())
.build();
}
}
private Map<String, String> buildDefaultUserClaims(String firstName, String lastName, String emailAddress,
boolean isFresh) {
Map<String, String> defaultUserClaims = new HashMap<>();
defaultUserClaims.put(Constants.USER_CLAIM_FIRST_NAME, firstName);
defaultUserClaims.put(Constants.USER_CLAIM_LAST_NAME, lastName);
defaultUserClaims.put(Constants.USER_CLAIM_EMAIL_ADDRESS, emailAddress);
if (isFresh) {
defaultUserClaims.put(Constants.USER_CLAIM_CREATED, String.valueOf(Instant.now().getEpochSecond()));
} else {
defaultUserClaims.put(Constants.USER_CLAIM_MODIFIED, String.valueOf(Instant.now().getEpochSecond()));
}
if (log.isDebugEnabled()) {
log.debug("Default claim map is created for new user: " + defaultUserClaims.toString());
}
return defaultUserClaims;
}
/**
* This method is used to build String map for user claims with updated external device details
*
@ -1128,37 +914,6 @@ public class UserManagementServiceImpl implements UserManagementService {
return userClaims;
}
private String generateInitialUserPassword() {
int passwordLength = 6;
//defining the pool of characters to be used for initial password generation
String lowerCaseCharset = "abcdefghijklmnopqrstuvwxyz";
String upperCaseCharset = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
String numericCharset = "0123456789";
SecureRandom randomGenerator = new SecureRandom();
String totalCharset = lowerCaseCharset + upperCaseCharset + numericCharset;
int totalCharsetLength = totalCharset.length();
StringBuilder initialUserPassword = new StringBuilder();
for (int i = 0; i < passwordLength; i++) {
initialUserPassword.append(
totalCharset.charAt(randomGenerator.nextInt(totalCharsetLength)));
}
if (log.isDebugEnabled()) {
log.debug("Initial user password is created for new user: " + initialUserPassword);
}
return initialUserPassword.toString();
}
private BasicUserInfo getBasicUserInfo(String username) throws UserStoreException {
BasicUserInfo userInfo = new BasicUserInfo();
userInfo.setUsername(username);
userInfo.setEmailAddress(getClaimValue(username, Constants.USER_CLAIM_EMAIL_ADDRESS));
userInfo.setFirstname(getClaimValue(username, Constants.USER_CLAIM_FIRST_NAME));
userInfo.setLastname(getClaimValue(username, Constants.USER_CLAIM_LAST_NAME));
userInfo.setCreatedDate(getClaimValue(username, Constants.USER_CLAIM_CREATED));
userInfo.setModifiedDate(getClaimValue(username, Constants.USER_CLAIM_MODIFIED));
return userInfo;
}
private String getClaimValue(String username, String claimUri) throws UserStoreException {
UserStoreManager userStoreManager = DeviceMgtAPIUtils.getUserStoreManager();
return userStoreManager.getUserClaimValue(username, claimUri, null);
@ -1179,74 +934,6 @@ public class UserManagementServiceImpl implements UserManagementService {
return DeviceManagementConstants.EmailAttributes.DEFAULT_ENROLLMENT_TEMPLATE;
}
/**
* Searches users which matches a given filter based on a claim
*
* @param claim the claim value to apply the filter. If <code>null</code> users will be filtered by username.
* @param filter the search query.
* @return <code>List<String></code> of users which matches.
* @throws UserStoreException If unable to search users.
*/
private ArrayList<String> getUserList(String claim, String filter) throws UserStoreException {
String defaultFilter = "*";
org.wso2.carbon.user.core.UserStoreManager userStoreManager =
(org.wso2.carbon.user.core.UserStoreManager) DeviceMgtAPIUtils.getUserStoreManager();
String appliedFilter = filter + defaultFilter;
String[] users;
if (log.isDebugEnabled()) {
log.debug("Searching Users - claim: " + claim + " filter: " + appliedFilter);
}
if (StringUtils.isEmpty(claim)) {
users = userStoreManager.listUsers(appliedFilter, -1);
} else {
users = userStoreManager.getUserList(claim, appliedFilter, null);
}
if (log.isDebugEnabled()) {
log.debug("Returned user count: " + users.length);
}
return new ArrayList<>(Arrays.asList(users));
}
/**
* User search provides an AND search result and if either of the filter returns an empty set of users, there is no
* need to carry on the search further. This method decides whether to carry on the search or not.
*
* @param commonUsers current filtered user list.
* @return <code>true</code> if further search is needed.
*/
private boolean skipSearch(List<String> commonUsers) {
return commonUsers != null && commonUsers.size() == 0;
}
/**
* Returns a list of permissions of a given role
* @param roleName name of the role
* @param tenantId the user's tenetId
* @param userRealm user realm of the tenant
* @return list of permissions
* @throws UserAdminException If unable to get the permissions
*/
private static List<String> getPermissionsListFromRole(String roleName, UserRealm userRealm, int tenantId)
throws UserAdminException {
org.wso2.carbon.user.core.UserRealm userRealmCore;
try {
userRealmCore = (org.wso2.carbon.user.core.UserRealm) userRealm;
} catch (ClassCastException e) {
String message = "Provided UserRealm object is not an instance of org.wso2.carbon.user.core.UserRealm";
log.error(message, e);
throw new UserAdminException(message, e);
}
UserRealmProxy userRealmProxy = new UserRealmProxy(userRealmCore);
List<String> permissionsList = new ArrayList<>();
final UIPermissionNode rolePermissions = userRealmProxy.getRolePermissions(roleName, tenantId);
DeviceMgtAPIUtils.iteratePermissions(rolePermissions, permissionsList);
return permissionsList;
}
/**
* Returns a Response with the list of user stores available for a tenant
@ -1283,23 +970,4 @@ public class UserManagementServiceImpl implements UserManagementService {
userStoreList.setCount(userStores.size());
return Response.status(Response.Status.OK).entity(userStoreList).build();
}
/**
* Iterates through the list of all users and returns a list of users from the specified user store domain
* @param domain user store domain name
* @param users list of all users from UserStoreManager
* @return list of users from specified user store domain
*/
public List<String> getUsersFromDomain(String domain, List<String> users) {
List<String> userList = new ArrayList<>();
for(String username : users) {
String[] domainName = username.split("/");
if(domain.equals(Constants.PRIMARY_USER_STORE) && domainName.length == 1) {
userList.add(username);
} else if (domainName[0].equals(domain) && domainName.length > 1) {
userList.add(username);
}
}
return userList;
}
}

@ -21,6 +21,7 @@ package io.entgra.device.mgt.core.device.mgt.api.jaxrs.util;
import io.entgra.device.mgt.core.apimgt.webapp.publisher.APIPublisherService;
import io.entgra.device.mgt.core.application.mgt.common.services.ApplicationManager;
import io.entgra.device.mgt.core.application.mgt.common.services.SubscriptionManager;
import io.entgra.device.mgt.core.device.mgt.core.service.UserManagementProviderService;
import org.apache.axis2.AxisFault;
import org.apache.axis2.client.Options;
import org.apache.axis2.java.security.SSLProtocolSocketFactory;
@ -282,6 +283,18 @@ public class DeviceMgtAPIUtils {
return deviceManagementProviderService;
}
public static UserManagementProviderService getUserManagementService() {
PrivilegedCarbonContext ctx = PrivilegedCarbonContext.getThreadLocalCarbonContext();
UserManagementProviderService userManagementProviderService =
(UserManagementProviderService) ctx.getOSGiService(UserManagementProviderService.class, null);
if (userManagementProviderService == null) {
String msg = "UserImpl Management provider service has not initialized.";
log.error(msg);
throw new IllegalStateException(msg);
}
return userManagementProviderService;
}
public static DeviceTypeGeneratorService getDeviceTypeGeneratorService() {
PrivilegedCarbonContext ctx = PrivilegedCarbonContext.getThreadLocalCarbonContext();
DeviceTypeGeneratorService deviceTypeGeneratorService =

@ -18,7 +18,9 @@
package io.entgra.device.mgt.core.device.mgt.api.jaxrs.service.impl;
import io.entgra.device.mgt.core.device.mgt.common.Device;
import io.entgra.device.mgt.core.device.mgt.common.*;
import io.entgra.device.mgt.core.device.mgt.common.exceptions.UserManagementException;
import io.entgra.device.mgt.core.device.mgt.core.service.UserManagementProviderService;
import org.mockito.Mockito;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;
@ -40,12 +42,10 @@ import io.entgra.device.mgt.core.device.mgt.common.spi.OTPManagementService;
import io.entgra.device.mgt.core.device.mgt.core.otp.mgt.service.OTPManagementServiceImpl;
import io.entgra.device.mgt.core.device.mgt.core.service.DeviceManagementProviderService;
import io.entgra.device.mgt.core.device.mgt.core.service.DeviceManagementProviderServiceImpl;
import io.entgra.device.mgt.core.device.mgt.api.jaxrs.beans.BasicUserInfo;
import io.entgra.device.mgt.core.device.mgt.api.jaxrs.beans.EnrollmentInvitation;
import io.entgra.device.mgt.core.device.mgt.api.jaxrs.beans.UserInfo;
import io.entgra.device.mgt.core.device.mgt.api.jaxrs.service.api.UserManagementService;
import io.entgra.device.mgt.core.device.mgt.api.jaxrs.util.Constants;
import io.entgra.device.mgt.core.device.mgt.api.jaxrs.util.DeviceMgtAPIUtils;
import org.wso2.carbon.context.PrivilegedCarbonContext;
import org.wso2.carbon.user.api.RealmConfiguration;
import org.wso2.carbon.user.api.UserRealm;
import org.wso2.carbon.user.api.UserStoreException;
@ -70,6 +70,8 @@ public class UserManagementServiceImplTest {
private UserStoreManager userStoreManager;
private UserManagementService userManagementService;
private DeviceManagementProviderService deviceManagementProviderService;
private UserManagementProviderService userManagementProviderService;
private OTPManagementService otpManagementService;
private static final String DEFAULT_DEVICE_USER = "Internal/devicemgt-user";
private UserRealm userRealm;
@ -86,9 +88,10 @@ public class UserManagementServiceImplTest {
}
@BeforeClass
public void setup() throws UserStoreException {
public void init() throws UserStoreException {
initMocks(this);
userManagementService = new UserManagementServiceImpl();
userManagementProviderService = Mockito.mock(UserManagementProviderService.class);
userStoreManager = Mockito.mock(UserStoreManager.class, Mockito.RETURNS_MOCKS);
deviceManagementProviderService = Mockito
.mock(DeviceManagementProviderServiceImpl.class, Mockito.CALLS_REAL_METHODS);
@ -112,6 +115,8 @@ public class UserManagementServiceImplTest {
public void testAddUser() throws UserStoreException, ConfigurationManagementException, DeviceManagementException {
PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getUserStoreManager"))
.toReturn(this.userStoreManager);
PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getUserManagementService"))
.toReturn(userManagementProviderService);
PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getDeviceManagementService"))
.toReturn(this.deviceManagementProviderService);
Mockito.doReturn(true).when(userStoreManager).isExistingUser("admin");
@ -150,11 +155,27 @@ public class UserManagementServiceImplTest {
@Test(description = "This method tests the getUser method of UserManagementService", dependsOnMethods =
"testAddUser")
public void testGetUser() throws UserStoreException {
public void testGetUser() throws UserStoreException, UserManagementException {
PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getUserStoreManager"))
.toReturn(this.userStoreManager);
PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getUserManagementService"))
.toReturn(userManagementProviderService);
BasicUserInfo basicUserInfo = new BasicUserInfo();
Mockito.doReturn(basicUserInfo).when(userManagementProviderService)
.getUser(Mockito.anyString());
Response response = userManagementService.getUser(TEST_USERNAME, null, null);
Assert.assertEquals(response.getStatus(), Response.Status.OK.getStatusCode(), "User retrieval failed");
Mockito.reset(userManagementProviderService);
basicUserInfo.setUsername(TEST_USERNAME);
basicUserInfo.setFirstname(TEST_USERNAME);
basicUserInfo.setLastname(TEST_USERNAME);
basicUserInfo.setEmailAddress("test@gmail.com");
Mockito.doReturn(basicUserInfo).when(userManagementProviderService)
.getUser(Mockito.anyString());
response = userManagementService.getUser("test", null, null);
Assert.assertEquals(response.getStatus(), Response.Status.OK.getStatusCode(),
"GetUser request failed with valid parameters");
Mockito.reset(this.userManagementProviderService);
BasicUserInfo userInfo = (BasicUserInfo) response.getEntity();
Assert.assertEquals(userInfo.getFirstname(), TEST_USERNAME,
"Retrieved user object is different from the original one " + "saved");
@ -168,6 +189,8 @@ public class UserManagementServiceImplTest {
@Test(description = "This method tests the updateUser method of UserManagementService", dependsOnMethods =
{"testGetUser"})
public void testUpdateUser() throws UserStoreException {
PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getUserManagementService"))
.toReturn(this.userManagementProviderService);
PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getUserStoreManager"))
.toReturn(this.userStoreManager);
Response response = userManagementService.updateUser(TEST2_USERNAME, null, null);
@ -184,15 +207,24 @@ public class UserManagementServiceImplTest {
@Test(description = "This method tests the getRolesOfUser method of UserManagementService", dependsOnMethods =
{"testUpdateUser"})
public void testGetRolesOfUser() {
public void testGetRolesOfUser() throws UserManagementException {
PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getUserStoreManager"))
.toReturn(this.userStoreManager);
PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getUserManagementService"))
.toReturn(userManagementProviderService);
List<String> roles= new ArrayList<>();
Mockito.doReturn(roles).when(userManagementProviderService)
.getRoles(Mockito.anyString());
Response response = userManagementService.getRolesOfUser(TEST2_USERNAME, null);
Assert.assertEquals(response.getStatus(), Response.Status.NOT_FOUND.getStatusCode(),
"Roles of a non-existing user was successfully retrieved");
Mockito.reset(userManagementProviderService);
Mockito.doReturn(roles).when(userManagementProviderService)
.getRoles(Mockito.anyString());
response = userManagementService.getRolesOfUser(TEST_USERNAME, null);
Assert.assertEquals(response.getStatus(), Response.Status.OK.getStatusCode(),
"Retrieval of roles of a existing user failed.");
Mockito.reset(this.userManagementProviderService);
}
@Test(description = "This method tests the IsUserExists method of UserManagementService", dependsOnMethods =
@ -228,12 +260,13 @@ public class UserManagementServiceImplTest {
public void testGetUserNames() throws UserStoreException {
PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getUserStoreManager"))
.toReturn(this.userStoreManager);
PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getUserManagementService"))
.toReturn(userManagementProviderService);
Mockito.doReturn(new String[] { TEST_USERNAME }).when(userStoreManager)
.listUsers(Mockito.anyString(), Mockito.anyInt());
Response response = userManagementService.getUserNames(TEST_USERNAME, null, "00", 0, 0);
Assert.assertEquals(response.getStatus(), Response.Status.OK.getStatusCode(),
"Getting user names is failed for a valid request");
}
@Test(description = "This method tests the getUsers method of UserManagementService",
@ -241,6 +274,8 @@ public class UserManagementServiceImplTest {
public void testGetUsers() {
PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getUserStoreManager"))
.toReturn(userStoreManager);
PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getUserManagementService"))
.toReturn(userManagementProviderService);
Response response = userManagementService.getUsers(null, "00", 0, 10, null);
Assert.assertEquals(response.getStatus(), Response.Status.OK.getStatusCode(), "GetUsers request failed");
}
@ -299,6 +334,8 @@ public class UserManagementServiceImplTest {
+ "DeviceManagementProviderService", dependsOnMethods = {"testGetUserCount"})
public void testNegativeScenarios1()
throws ConfigurationManagementException, DeviceManagementException, OTPManagementException {
PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getUserManagementService"))
.toReturn(userManagementProviderService);
PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getUserStoreManager"))
.toReturn(this.userStoreManager);
PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getDeviceManagementService"))
@ -318,41 +355,61 @@ public class UserManagementServiceImplTest {
response = userManagementService.inviteToEnrollDevice(enrollmentInvitation);
Assert.assertEquals(response.getStatus(), Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(),
"Invite existing users to enroll device succeeded under erroneous conditions");
Mockito.reset(this.userManagementProviderService);
}
@Test(description = "This method tests the behaviour of the different methods when there is an issue is "
+ "userStoreManager", dependsOnMethods = {"testNegativeScenarios1"})
public void testNegativeScenarios2() throws UserStoreException {
public void testNegativeScenarios2() throws UserStoreException, UserManagementException {
PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getUserStoreManager"))
.toReturn(this.userStoreManager);
PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getUserManagementService"))
.toReturn(userManagementProviderService);
Mockito.doThrow(new UserStoreException()).when(userStoreManager).isExistingUser(TEST3_USERNAME);
Response response = userManagementService.getUser(TEST3_USERNAME, null, null);
Assert.assertEquals(response.getStatus(), Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(),
"Response returned successful for a user retrieval with problematic inputs");
Mockito.when(this.userManagementProviderService.getUser(Mockito.anyString()))
.thenThrow(new UserManagementException());
response = userManagementService.getUser(TEST3_USERNAME, null, null);
Assert.assertEquals(response.getStatus(), Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(),
"Response returned successful for a user retrieval with problematic inputs");
UserInfo userInfo = new UserInfo();
userInfo.setUsername(TEST3_USERNAME);
Mockito.reset(this.userManagementProviderService);
Mockito.when(this.userManagementProviderService.getUser(Mockito.anyString()))
.thenThrow(new UserManagementException());
response = userManagementService.addUser(userInfo);
Assert.assertEquals(response.getStatus(), Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(),
"Response returned successful for a user addition with problematic inputs");
Mockito.reset(this.userManagementProviderService);
Mockito.when(this.userManagementProviderService.getUser(Mockito.anyString()))
.thenThrow(new UserManagementException());
response = userManagementService.updateUser(TEST3_USERNAME, null, userInfo);
Assert.assertEquals(response.getStatus(), Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(),
"Response returned successful for a user updating request with problematic inputs");
response = userManagementService.removeUser(TEST3_USERNAME, null);
Assert.assertEquals(response.getStatus(), Response.Status.BAD_REQUEST.getStatusCode(),
"Response returned successful for a user removal request with problematic inputs");
Mockito.reset(this.userManagementProviderService);
Mockito.when(this.userManagementProviderService.getUser(Mockito.anyString()))
.thenThrow(new UserManagementException());
response = userManagementService.getRolesOfUser(TEST3_USERNAME, null);
Assert.assertEquals(response.getStatus(), Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(),
"Response returned successful for a user role retrieval request with problematic inputs");
response = userManagementService.isUserExists(TEST3_USERNAME);
Assert.assertEquals(response.getStatus(), Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(),
"Response returned successful for checking existence of user under problematic conditions");
Mockito.reset(this.userManagementProviderService);
}
@Test(description = "This method tests the behaviour of various methods when there is an issue with UserStore "
+ "Manager", dependsOnMethods = {"testNegativeScenarios2"})
public void testNegativeScenarios3() throws UserStoreException {
public void testNegativeScenarios3() throws UserStoreException, UserManagementException {
PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getUserStoreManager"))
.toReturn(this.userStoreManager);
PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getUserManagementService"))
.toReturn(userManagementProviderService);
PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getUserRealm")).toReturn(userRealm);
PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getUserStoreCountRetrieverService"))
.toReturn(null);
@ -366,12 +423,17 @@ public class UserManagementServiceImplTest {
.getUserClaimValue(Mockito.any(), Mockito.any(), Mockito.any());
Mockito.doThrow(new UserStoreException()).when(userStoreManager)
.listUsers(Mockito.anyString(), Mockito.anyInt());
Mockito.when(this.userManagementProviderService.getUsers(Mockito.anyString(), Mockito.anyInt(), Mockito.anyString(), Mockito.anyInt(), Mockito.anyInt()))
.thenThrow(new UserManagementException());
Response response = userManagementService.getUsers(TEST_USERNAME, "00", 0, 10, null);
Assert.assertEquals(response.getStatus(), Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(),
"Response returned successful for a users retrieval request.");
response = userManagementService.getUserCount();
Assert.assertEquals(response.getStatus(), Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(),
"Response returned successful for a user count retrieval request.");
Mockito.reset(this.userManagementProviderService);
Mockito.when(this.userManagementProviderService.getUserNames(Mockito.anyString(), Mockito.anyString(), Mockito.anyInt(), Mockito.anyInt()))
.thenThrow(new UserManagementException());
response = userManagementService.getUserNames(TEST_USERNAME, null, "00", 0, 10);
Assert.assertEquals(response.getStatus(), Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(),
"Response returned successful for a user count retrieval request.");
@ -381,6 +443,7 @@ public class UserManagementServiceImplTest {
response = userManagementService.inviteExistingUsersToEnrollDevice(deviceEnrollmentInvitation);
Assert.assertEquals(response.getStatus(), Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(),
"Invite existing users to enroll device succeeded under erroneous conditions");
Mockito.reset(this.userManagementProviderService);
}
/**

@ -15,7 +15,7 @@
* specific language governing permissions and limitations
* under the License.
*/
package io.entgra.device.mgt.core.device.mgt.api.jaxrs.beans;
package io.entgra.device.mgt.core.device.mgt.common;
import com.fasterxml.jackson.annotation.JsonProperty;
import io.swagger.annotations.ApiModelProperty;
@ -38,4 +38,4 @@ public class BasePaginatedResult {
public void setCount(long count) {
this.count = count;
}
}
}

@ -15,7 +15,7 @@
* specific language governing permissions and limitations
* under the License.
*/
package io.entgra.device.mgt.core.device.mgt.api.jaxrs.beans;
package io.entgra.device.mgt.core.device.mgt.common;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;

@ -15,9 +15,11 @@
* specific language governing permissions and limitations
* under the License.
*/
package io.entgra.device.mgt.core.device.mgt.api.jaxrs.beans;
package io.entgra.device.mgt.core.device.mgt.common;
import com.fasterxml.jackson.annotation.JsonProperty;
import io.entgra.device.mgt.core.device.mgt.common.BasePaginatedResult;
import io.entgra.device.mgt.core.device.mgt.common.BasicUserInfo;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;

@ -0,0 +1,49 @@
/*
* Copyright (c) 2023, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved.
*
* Entgra (Pvt) Ltd. 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 io.entgra.device.mgt.core.device.mgt.common;
import com.fasterxml.jackson.annotation.JsonProperty;
import io.swagger.annotations.ApiModelProperty;
import java.util.ArrayList;
import java.util.List;
public class BasicUserInfoMetadata {
private List<BasicUserInfo> users = new ArrayList<>();
private int totalUserCount;
public int getTotalUserCount() {
return totalUserCount;
}
public void setTotalUserCount(int totalUserCount) {
this.totalUserCount = totalUserCount;
}
public List<BasicUserInfo> getList() {
return users;
}
public void setList(List<BasicUserInfo> users) {
this.users = users;
}
}

@ -16,8 +16,9 @@
* under the License.
*/
package io.entgra.device.mgt.core.device.mgt.api.jaxrs.beans;
package io.entgra.device.mgt.core.device.mgt.common;
import io.entgra.device.mgt.core.device.mgt.common.BasicUserInfo;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;

@ -17,6 +17,10 @@
*/
package io.entgra.device.mgt.core.device.mgt.common;
import io.entgra.device.mgt.core.device.mgt.common.configuration.mgt.ConfigurationEntry;
import io.entgra.device.mgt.core.device.mgt.common.configuration.mgt.PlatformConfiguration;
import io.entgra.device.mgt.core.device.mgt.common.group.mgt.GroupFilter;
import java.io.Serializable;
import java.util.List;
@ -31,6 +35,10 @@ public class DeviceFilters implements Serializable {
private List<String> ownerships;
private List<String> statuses;
private List<ConfigurationEntry> configs;
private List<GroupFilter> groups;
public List<String> getDeviceTypes() {
return deviceTypes;
}
@ -54,4 +62,20 @@ public class DeviceFilters implements Serializable {
public void setStatuses(List<String> statuses) {
this.statuses = statuses;
}
public List<GroupFilter> getGroups() {
return groups;
}
public void setGroups(List<GroupFilter> groups) {
this.groups = groups;
}
public List<ConfigurationEntry> getConfigs() {
return configs;
}
public void setConfigs(List<ConfigurationEntry> configs) {
this.configs = configs;
}
}

@ -16,7 +16,7 @@
* under the License.
*/
package io.entgra.device.mgt.core.device.mgt.api.jaxrs.beans;
package io.entgra.device.mgt.core.device.mgt.common;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;

@ -16,8 +16,9 @@
* under the License.
*/
package io.entgra.device.mgt.core.device.mgt.api.jaxrs.beans;
package io.entgra.device.mgt.core.device.mgt.common;
import io.entgra.device.mgt.core.device.mgt.common.BasicUserInfo;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
@ -50,4 +51,4 @@ public class UserInfo extends BasicUserInfo {
this.roles = roles;
}
}
}

@ -0,0 +1,44 @@
/*
* Copyright (c) 2023, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved.
*
* Entgra (Pvt) Ltd. 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 io.entgra.device.mgt.core.device.mgt.common.exceptions;
public class UserManagementException extends Exception {
private static final long serialVersionUID = -3151279311929070297L;
public UserManagementException(String msg, Exception nestedEx) {
super(msg, nestedEx);
}
public UserManagementException(String message, Throwable cause) {
super(message, cause);
}
public UserManagementException(String msg) {
super(msg);
}
public UserManagementException() {
super();
}
public UserManagementException(Throwable cause) {
super(cause);
}
}

@ -0,0 +1,48 @@
/*
* Copyright (c) 2023, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved.
*
* Entgra (Pvt) Ltd. 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 io.entgra.device.mgt.core.device.mgt.common.group.mgt;
import io.swagger.annotations.ApiModelProperty;
public class GroupFilter {
private static final long serialVersionUID = 1998131711L;
@ApiModelProperty(name = "id", value = "ID of the device group in the device group information database.")
private int id;
@ApiModelProperty(name = "name", value = "The device group name that can be set on the device group by the user.",
required = true)
private String name;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}

@ -148,6 +148,15 @@ public final class DeviceManagementConstants {
public static final String CLAIM_EMAIL_ADDRESS = "http://wso2.org/claims/emailaddress";
public static final String CLAIM_FIRST_NAME = "http://wso2.org/claims/givenname";
public static final String CLAIM_LAST_NAME = "http://wso2.org/claims/lastname";
public static final String CLAIM_CREATED = "http://wso2.org/claims/created";
public static final String CLAIM_MODIFIED = "http://wso2.org/claims/modified";
public static final String CLAIM_DEVICES = "http://wso2.org/claims/devices";
public static final String RESERVED_USER = "reserved_user";
public static final String APIM_RESERVED_USER = "apim_reserved_user";
public static final String PRIMARY_USER_STORE = "PRIMARY";
// Permissions that are given for a normal device user.
public static final Permission[] PERMISSIONS_FOR_DEVICE_USER = {

@ -21,9 +21,9 @@ package io.entgra.device.mgt.core.device.mgt.core.dao;
import io.entgra.device.mgt.core.device.mgt.common.Device;
import io.entgra.device.mgt.core.device.mgt.common.GroupPaginationRequest;
import io.entgra.device.mgt.core.device.mgt.common.PaginationRequest;
import io.entgra.device.mgt.core.device.mgt.common.exceptions.ReportManagementException;
import io.entgra.device.mgt.core.device.mgt.common.group.mgt.DeviceGroup;
import io.entgra.device.mgt.core.device.mgt.common.group.mgt.DeviceGroupRoleWrapper;
import io.entgra.device.mgt.core.device.mgt.common.group.mgt.GroupFilter;
import java.util.List;
import java.util.Map;
@ -221,6 +221,16 @@ public interface GroupDAO {
*/
List<DeviceGroup> getGroups(GroupPaginationRequest paginationRequest, int tenantId) throws GroupManagementDAOException;
/**
* Get paginated list of Device Groups Names in tenant for filtering.
*
* @param paginationRequest to filter results.
* @param tenantId of user's tenant.
* @return List of all Groups in the provided filter.
* @throws GroupManagementDAOException
*/
List<GroupFilter> getGroupFilterDetails(GroupPaginationRequest paginationRequest, int tenantId) throws GroupManagementDAOException;
/**
* Get paginated list of Device Groups in tenant with specified device group ids.
*
@ -255,6 +265,15 @@ public interface GroupDAO {
*/
List<DeviceGroup> getGroups(List<Integer> deviceGroupIds, int tenantId) throws GroupManagementDAOException;
/**
* Get the list of Device Groups in tenant for filtering.
*
* @param tenantId of user's tenant.
* @return List of all Device Groups in the provided filter.
* @throws GroupManagementDAOException
*/
List<GroupFilter> getGroupFilterDetails(List<Integer> deviceGroupIds, int tenantId) throws GroupManagementDAOException;
/**
* Get the list of Device Groups in tenant.
*
@ -469,4 +488,4 @@ public interface GroupDAO {
List<String> groupNames)
throws GroupManagementDAOException;
}
}

@ -19,6 +19,7 @@
package io.entgra.device.mgt.core.device.mgt.core.dao.impl;
import io.entgra.device.mgt.core.device.mgt.common.group.mgt.DeviceGroupRoleWrapper;
import io.entgra.device.mgt.core.device.mgt.common.group.mgt.GroupFilter;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
@ -106,6 +107,48 @@ public abstract class AbstractGroupDAOImpl implements GroupDAO {
}
}
@Override
public List<GroupFilter> getGroupFilterDetails(GroupPaginationRequest request, int tenantId)
throws GroupManagementDAOException {
try {
Connection conn = GroupManagementDAOFactory.getConnection();
String sql = "SELECT ID, GROUP_NAME FROM DM_GROUP "
+ "WHERE TENANT_ID = ?";
if (request != null && StringUtils.isNotBlank(request.getOwner())) {
sql += " AND OWNER LIKE ?";
}
if (request != null && request.getRowCount() != 0) {
sql += " LIMIT ? OFFSET ?";
}
try (PreparedStatement stmt = conn.prepareStatement(sql)) {
int paramIndex = 1;
stmt.setInt(paramIndex++, tenantId);
if (request != null && StringUtils.isNotBlank(request.getOwner())) {
stmt.setString(paramIndex++, request.getOwner() + "%");
}
if (request != null && request.getRowCount() != 0) {
stmt.setInt(paramIndex++, request.getRowCount());
stmt.setInt(paramIndex, request.getStartIndex());
}
List<GroupFilter> groupFilterDetails = new ArrayList<>();
try (ResultSet resultSet = stmt.executeQuery()) {
while (resultSet.next()) {
GroupFilter group = new GroupFilter();
group.setId(resultSet.getInt("ID"));
group.setName(resultSet.getString("GROUP_NAME"));
groupFilterDetails.add(group);
}
}
return groupFilterDetails;
}
} catch (SQLException e) {
String msg = "Error occurred while retrieving groups in tenant: " + tenantId;
log.error(msg);
throw new GroupManagementDAOException(msg, e);
}
}
@Override
public List<DeviceGroup> getGroups(GroupPaginationRequest request, List<Integer> deviceGroupIds,
int tenantId) throws GroupManagementDAOException {
@ -208,6 +251,47 @@ public abstract class AbstractGroupDAOImpl implements GroupDAO {
}
}
@Override
public List<GroupFilter> getGroupFilterDetails(List<Integer> deviceGroupIds, int tenantId) throws GroupManagementDAOException {
int deviceGroupIdsCount = deviceGroupIds.size();
if (deviceGroupIdsCount == 0) {
return new ArrayList<>();
}
try {
Connection conn = GroupManagementDAOFactory.getConnection();
String sql = "SELECT ID, GROUP_NAME FROM DM_GROUP WHERE TENANT_ID = ?";
sql += " AND ID IN (";
for (int i = 0; i < deviceGroupIdsCount; i++) {
sql += (deviceGroupIdsCount - 1 != i) ? "?," : "?";
}
sql += ")";
try (PreparedStatement stmt = conn.prepareStatement(sql)) {
int paramIndex = 1;
stmt.setInt(paramIndex++, tenantId);
for (Integer deviceGroupId : deviceGroupIds) {
stmt.setInt(paramIndex++, deviceGroupId);
}
List<GroupFilter> groupFilters = new ArrayList<>();
try (ResultSet resultSet = stmt.executeQuery()) {
while (resultSet.next()) {
GroupFilter groupFilter = new GroupFilter();
groupFilter.setId(resultSet.getInt("ID"));
groupFilter.setName(resultSet.getString("GROUP_NAME"));
groupFilters.add(groupFilter);
}
}
return groupFilters;
}
} catch (SQLException e) {
String msg = "Error occurred while retrieving groups of groups IDs " + deviceGroupIds
+ " in tenant: " + tenantId;
log.error(msg);
throw new GroupManagementDAOException(msg, e);
}
}
@Override
public List<DeviceGroup> getGroups(GroupPaginationRequest request, List<Integer> deviceGroupIds,

@ -18,6 +18,7 @@
package io.entgra.device.mgt.core.device.mgt.core.internal;
import io.entgra.device.mgt.core.device.mgt.core.service.UserManagementProviderService;
import io.entgra.device.mgt.core.server.bootup.heartbeat.beacon.service.HeartBeatManagementService;
import org.wso2.carbon.context.PrivilegedCarbonContext;
import io.entgra.device.mgt.core.device.mgt.common.DeviceStatusTaskPluginConfig;
@ -93,6 +94,8 @@ public class DeviceManagementDataHolder {
private WhiteLabelManagementService whiteLabelManagementService;
private TraccarManagementService traccarManagementService;
private UserManagementProviderService userManagementProviderService;
private final Map<DeviceType, DeviceStatusTaskPluginConfig> deviceStatusTaskPluginConfigs = Collections.synchronizedMap(
new HashMap<>());
@ -384,6 +387,14 @@ public class DeviceManagementDataHolder {
this.whiteLabelManagementService = whiteLabelManagementService;
}
public UserManagementProviderService getUserManagementProviderService() {
return userManagementProviderService;
}
public void setUserManagementProviderService(UserManagementProviderService userManagementProviderService) {
this.userManagementProviderService = userManagementProviderService;
}
public TraccarManagementService getTraccarManagementService() {
TraccarManagementService traccarManagementService;
PrivilegedCarbonContext ctx = PrivilegedCarbonContext.getThreadLocalCarbonContext();

@ -17,6 +17,7 @@
*/
package io.entgra.device.mgt.core.device.mgt.core.internal;
import io.entgra.device.mgt.core.device.mgt.core.service.*;
import io.entgra.device.mgt.core.server.bootup.heartbeat.beacon.service.HeartBeatManagementService;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
@ -77,10 +78,6 @@ import io.entgra.device.mgt.core.device.mgt.core.push.notification.mgt.task.Push
import io.entgra.device.mgt.core.device.mgt.core.report.mgt.ReportManagementServiceImpl;
import io.entgra.device.mgt.core.device.mgt.core.search.mgt.SearchManagerService;
import io.entgra.device.mgt.core.device.mgt.core.search.mgt.impl.SearchManagerServiceImpl;
import io.entgra.device.mgt.core.device.mgt.core.service.DeviceManagementProviderService;
import io.entgra.device.mgt.core.device.mgt.core.service.DeviceManagementProviderServiceImpl;
import io.entgra.device.mgt.core.device.mgt.core.service.GroupManagementProviderService;
import io.entgra.device.mgt.core.device.mgt.core.service.GroupManagementProviderServiceImpl;
import io.entgra.device.mgt.core.device.mgt.core.task.DeviceTaskManagerService;
import io.entgra.device.mgt.core.device.mgt.core.traccar.api.service.DeviceAPIClientService;
import io.entgra.device.mgt.core.device.mgt.core.traccar.api.service.impl.DeviceAPIClientServiceImpl;
@ -306,6 +303,11 @@ public class DeviceManagementServiceComponent {
DeviceManagementDataHolder.getInstance().setDeviceManagementProvider(deviceManagementProvider);
bundleContext.registerService(DeviceManagementProviderService.class.getName(), deviceManagementProvider, null);
/* Registering User Management Service */
UserManagementProviderService userManagementProviderService = new UserManagementProviderServiceImpl();
DeviceManagementDataHolder.getInstance().setUserManagementProviderService(userManagementProviderService);
bundleContext.registerService(UserManagementProviderService.class.getName(), userManagementProviderService, null);
/* Registering Device API Client Service */
DeviceAPIClientService deviceAPIClientService = new DeviceAPIClientServiceImpl();
DeviceManagementDataHolder.getInstance().setDeviceAPIClientService(deviceAPIClientService);

@ -30,6 +30,7 @@ import io.entgra.device.mgt.core.device.mgt.common.group.mgt.GroupAlreadyExistEx
import io.entgra.device.mgt.core.device.mgt.common.group.mgt.GroupManagementException;
import io.entgra.device.mgt.core.device.mgt.common.group.mgt.GroupNotExistException;
import io.entgra.device.mgt.core.device.mgt.common.group.mgt.RoleDoesNotExistException;
import io.entgra.device.mgt.core.device.mgt.common.group.mgt.GroupFilter;
import org.wso2.carbon.user.api.AuthorizationManager;
import org.wso2.carbon.user.api.UserStoreManager;
@ -189,6 +190,17 @@ public interface GroupManagementProviderService {
PaginationResult getGroupsWithHierarchy(String username, GroupPaginationRequest request,
boolean requireGroupProps) throws GroupManagementException;
/**
* Get device groups of the provided filter.
*
* @param username of the user.
* @param request to filter results
* @return {@link PaginationResult} paginated groups.
* @throws GroupManagementException on error during retrieval of groups for provided filter
*/
List<GroupFilter> getGroupFilterValues(String username, GroupPaginationRequest request) throws GroupManagementException;
/**
* Get all hierarchical device groups count in tenant
*

@ -26,6 +26,7 @@ import io.entgra.device.mgt.core.device.mgt.common.group.mgt.GroupAlreadyExistEx
import io.entgra.device.mgt.core.device.mgt.common.group.mgt.GroupManagementException;
import io.entgra.device.mgt.core.device.mgt.common.group.mgt.GroupNotExistException;
import io.entgra.device.mgt.core.device.mgt.common.group.mgt.RoleDoesNotExistException;
import io.entgra.device.mgt.core.device.mgt.common.group.mgt.GroupFilter;
import io.entgra.device.mgt.core.device.mgt.core.dao.DeviceDAO;
import io.entgra.device.mgt.core.device.mgt.core.dao.DeviceManagementDAOException;
import io.entgra.device.mgt.core.device.mgt.core.dao.DeviceManagementDAOFactory;
@ -615,6 +616,44 @@ public class GroupManagementProviderServiceImpl implements GroupManagementProvid
return groupResult;
}
@Override
public List<GroupFilter> getGroupFilterValues(String username, GroupPaginationRequest request) throws GroupManagementException {
if (request != null) {
DeviceManagerUtil.validateGroupListPageSize(request);
}
if (log.isDebugEnabled()) {
log.debug("Get groups filters " + username);
}
List<GroupFilter> groupFilters;
try {
int tenantId = CarbonContext.getThreadLocalCarbonContext().getTenantId();
if (StringUtils.isBlank(username)) {
GroupManagementDAOFactory.openConnection();
groupFilters = groupDAO.getGroupFilterDetails(request, tenantId);
} else {
List<Integer> allDeviceGroupIdsOfUser = getGroupIds(username);
GroupManagementDAOFactory.openConnection();
groupFilters = groupDAO.getGroupFilterDetails(allDeviceGroupIdsOfUser, tenantId);
}
} catch (SQLException e) {
String msg = "Error occurred while opening a connection to the data source to retrieve all groups of filter.";
log.error(msg, e);
throw new GroupManagementException(msg, e);
} catch (GroupManagementDAOException e) {
String msg = "Error occurred while retrieving all groups of filter";
log.error(msg, e);
throw new GroupManagementException(msg, e);
} finally {
GroupManagementDAOFactory.closeConnection();
}
return groupFilters;
}
private List<DeviceGroup> getGroups(List<Integer> groupIds, int tenantId) throws GroupManagementException {
try {
GroupManagementDAOFactory.openConnection();

@ -0,0 +1,111 @@
/*
* Copyright (c) 2023, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved.
*
* Entgra (Pvt) Ltd. 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 io.entgra.device.mgt.core.device.mgt.core.service;
import io.entgra.device.mgt.core.device.mgt.common.*;
import io.entgra.device.mgt.core.device.mgt.common.exceptions.UserManagementException;
import java.util.List;
/**
* Proxy class for all Device Management related operations that take the corresponding plugin type in
* and resolve the appropriate plugin implementation
*/
public interface UserManagementProviderService {
/**
* Method to retrieve the filtered roles of the user.
*
* @param userInfo new user data
* @return BasicUserInfoWrapper which has the information about the added user.
* @throws UserManagementException If some unusual behaviour is observed while adding the user.
*/
BasicUserInfoWrapper addUser(UserInfo userInfo) throws UserManagementException;
/**
* Method to retrieve the filtered roles of the user.
*
* @param username name of the user
* @return BasicUserInfo object which consists of the user data.
* @throws UserManagementException If some unusual behaviour is observed while getting the user data.
*/
BasicUserInfo getUser(String username) throws UserManagementException;
/**
* Method to retrieve the filtered roles of the user.
*
* @param username name of the user the permissions are retrieved from
* @return List of permissions of the given user.
* @throws UserManagementException If some unusual behaviour is observed while fetching the permissions of user.
*/
List<String> getPermissions(String username) throws UserManagementException;
/**
* Method to retrieve the filtered roles of the user.
*
* @param username name of the user the roles are retrieved from
* @return List of roles of the given user.
* @throws UserManagementException If some unusual behaviour is observed while fetching the roles of user.
*/
List<String> getRoles(String username) throws UserManagementException;
/**
* Method to retrieve the filtered roles of the user.
*
* @param username name of the user the roles are retrieved from
* @return Object with the updated user data.
* @throws UserManagementException If some unusual behaviour is observed while updating user.
*/
BasicUserInfo updateUser(String username, UserInfo userInfo) throws UserManagementException;
/**
* Method to retrieve the list of users.
*
* @param appliedFilter filter to be applied when retrieving the user list
* @param appliedLimit this value is set to 1-1 to get the whole set of users
* @param domain domain of the users
* @param limit the maximum number of the users to be retrieved
* @param offset the starting index of data retrieval
* @throws UserManagementException If some unusual behaviour is observed while fetching the users.
*/
BasicUserInfoList getUsers(String appliedFilter, int appliedLimit, String domain, int limit, int offset) throws UserManagementException;
/**
* Method to retrieve the list of users.
*
* @param basicUserInfo data needed for the user search
* @param limit the maximum number of the users to be retrieved
* @param offset the starting index of data retrieval
* @throws UserManagementException If some unusual behaviour is observed while fetching the users.
*/
BasicUserInfoList getUsersSearch(BasicUserInfo basicUserInfo, int offset, int limit) throws UserManagementException;
/**
* Method to retrieve the list of users based on filter.
*
* @param filter data needed for the user search
* @param userStoreDomain domain of the user
* @param limit the maximum number of the users to be retrieved
* @param offset the starting index of data retrieval
* @throws UserManagementException If some unusual behaviour is observed while fetching the users.
*/
List<UserInfo> getUserNames(String filter, String userStoreDomain, int offset, int limit) throws UserManagementException;
}

@ -0,0 +1,563 @@
/*
* Copyright (c) 2023, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved.
*
* Entgra (Pvt) Ltd. 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 io.entgra.device.mgt.core.device.mgt.core.service;
import com.google.gson.JsonArray;
import io.entgra.device.mgt.core.device.mgt.common.*;
import io.entgra.device.mgt.core.device.mgt.common.configuration.mgt.ConfigurationManagementException;
import io.entgra.device.mgt.core.device.mgt.common.exceptions.DeviceManagementException;
import io.entgra.device.mgt.core.device.mgt.common.exceptions.UserManagementException;
import io.entgra.device.mgt.core.device.mgt.core.DeviceManagementConstants;
import io.entgra.device.mgt.core.device.mgt.core.internal.DeviceManagementDataHolder;
import io.entgra.device.mgt.core.device.mgt.extensions.logger.spi.EntgraLogger;
import io.entgra.device.mgt.core.notification.logger.impl.EntgraDeviceEnrolmentLoggerImpl;
import org.apache.commons.lang.StringUtils;
import org.wso2.carbon.context.CarbonContext;
import org.wso2.carbon.user.api.UserRealm;
import org.wso2.carbon.user.api.UserStoreException;
import org.wso2.carbon.user.api.UserStoreManager;
import org.wso2.carbon.user.mgt.UserRealmProxy;
import org.wso2.carbon.user.mgt.common.UIPermissionNode;
import org.wso2.carbon.user.mgt.common.UserAdminException;
import java.security.SecureRandom;
import java.time.Instant;
import java.util.*;
public class UserManagementProviderServiceImpl implements UserManagementProviderService {
private static final EntgraLogger log = new EntgraDeviceEnrolmentLoggerImpl(UserManagementProviderServiceImpl.class);
private static final String ROLE_EVERYONE = "Internal/everyone";
@Override
public BasicUserInfoWrapper addUser(UserInfo userInfo) throws UserManagementException {
try {
int tenantId = CarbonContext.getThreadLocalCarbonContext().getTenantId();
UserStoreManager userStoreManager = DeviceManagementDataHolder.getInstance().
getRealmService().getTenantUserRealm(tenantId).getUserStoreManager();
String initialUserPassword;
if (userInfo.getPassword() != null) {
initialUserPassword = userInfo.getPassword();
} else {
initialUserPassword = this.generateInitialUserPassword();
}
Map<String, String> defaultUserClaims =
this.buildDefaultUserClaims(userInfo.getFirstname(), userInfo.getLastname(),
userInfo.getEmailAddress(), true);
userStoreManager.addUser(userInfo.getUsername(), initialUserPassword,
userInfo.getRoles(), defaultUserClaims, null);
// Outputting debug message upon successful addition of user
if (log.isDebugEnabled()) {
log.debug("User '" + userInfo.getUsername() + "' has successfully been added.");
}
BasicUserInfo createdUserInfo = this.getBasicUserInfo(userInfo.getUsername());
// Outputting debug message upon successful retrieval of user
if (log.isDebugEnabled()) {
log.debug("User by username: " + userInfo.getUsername() + " was found.");
}
DeviceManagementProviderService managementProviderService = DeviceManagementDataHolder
.getInstance().getDeviceManagementProvider();
String[] bits = userInfo.getUsername().split("/");
String username = bits[bits.length - 1];
String recipient = userInfo.getEmailAddress();
Properties props = new Properties();
props.setProperty("first-name", userInfo.getFirstname());
props.setProperty("last-name", userInfo.getLastname());
props.setProperty("username", username);
props.setProperty("password", initialUserPassword);
EmailMetaInfo metaInfo = new EmailMetaInfo(recipient, props);
BasicUserInfoWrapper userInfoWrapper = new BasicUserInfoWrapper();
String message;
try {
managementProviderService.sendRegistrationEmail(metaInfo);
message = "An invitation mail will be sent to this user to initiate device enrollment.";
} catch (ConfigurationManagementException e) {
message = "Mail Server is not configured. Email invitation will not be sent.";
} catch (DeviceManagementException e) {
throw new RuntimeException(e);
}
userInfoWrapper.setBasicUserInfo(createdUserInfo);
userInfoWrapper.setMessage(message);
return userInfoWrapper;
} catch (UserStoreException e) {
String msg = "Error occurred while trying to add user '" + userInfo.getUsername() + "' to the " +
"underlying user management system";
log.error(msg, e);
throw new UserManagementException(msg, e);
}
}
@Override
public BasicUserInfo getUser(String username) throws UserManagementException {
try {
return this.getBasicUserInfo(username);
} catch (UserStoreException e) {
String message = "Error occurred while getting data of user '" + username + "'";
log.error(message, e);
throw new UserManagementException(message, e);
}
}
@Override
public List<String> getPermissions(String username) throws UserManagementException {
try {
int tenantId = CarbonContext.getThreadLocalCarbonContext().getTenantId();
UserStoreManager userStoreManager = DeviceManagementDataHolder.getInstance().
getRealmService().getTenantUserRealm(tenantId).getUserStoreManager();
List<String> roles = getFilteredRoles(userStoreManager, username);
List<String> permissions = new ArrayList<>();
UserRealm userRealm = DeviceManagementDataHolder.getInstance().
getRealmService().getTenantUserRealm(tenantId);
// Get permissions for each role
for (String roleName : roles) {
try {
permissions.addAll(getPermissionsListFromRole(roleName, userRealm, tenantId));
} catch (UserAdminException e) {
String message = "Error occurred while retrieving the permissions of role '" + roleName + "'";
log.error(message, e);
throw new UserManagementException(message, e);
}
}
return permissions;
} catch (UserStoreException e) {
String message = "Error occurred while trying to retrieve roles of the user '" + username + "'";
log.error(message, e);
throw new UserManagementException(message, e);
}
}
@Override
public List<String> getRoles(String username) throws UserManagementException {
try {
int tenantId = CarbonContext.getThreadLocalCarbonContext().getTenantId();
UserStoreManager userStoreManager = DeviceManagementDataHolder.getInstance().
getRealmService().getTenantUserRealm(tenantId).getUserStoreManager();
List<String> roles = getFilteredRoles(userStoreManager, username);
return roles;
} catch (UserStoreException e) {
String message = "Error occurred while trying to retrieve roles of the user '" + username + "'";
log.error(message, e);
throw new UserManagementException(message, e);
}
}
@Override
public BasicUserInfo updateUser(String username, UserInfo userInfo) throws UserManagementException {
try {
int tenantId = CarbonContext.getThreadLocalCarbonContext().getTenantId();
UserStoreManager userStoreManager = DeviceManagementDataHolder.getInstance().
getRealmService().getTenantUserRealm(tenantId).getUserStoreManager();
Map<String, String> defaultUserClaims =
this.buildDefaultUserClaims(userInfo.getFirstname(), userInfo.getLastname(),
userInfo.getEmailAddress(), false);
if (StringUtils.isNotEmpty(userInfo.getPassword())) {
// Decoding Base64 encoded password
userStoreManager.updateCredentialByAdmin(username,
userInfo.getPassword());
log.debug("User credential of username: " + username + " has been changed");
}
List<String> currentRoles = this.getFilteredRoles(userStoreManager, username);
List<String> newRoles = new ArrayList<>();
if (userInfo.getRoles() != null) {
newRoles = Arrays.asList(userInfo.getRoles());
}
List<String> rolesToAdd = new ArrayList<>(newRoles);
List<String> rolesToDelete = new ArrayList<>();
for (String role : currentRoles) {
if (newRoles.contains(role)) {
rolesToAdd.remove(role);
} else {
rolesToDelete.add(role);
}
}
rolesToDelete.remove(ROLE_EVERYONE);
rolesToAdd.remove(ROLE_EVERYONE);
userStoreManager.updateRoleListOfUser(username,
rolesToDelete.toArray(new String[rolesToDelete.size()]),
rolesToAdd.toArray(new String[rolesToAdd.size()]));
userStoreManager.setUserClaimValues(username, defaultUserClaims, null);
// Outputting debug message upon successful addition of user
if (log.isDebugEnabled()) {
log.debug("User by username: " + username + " was successfully updated.");
}
return this.getBasicUserInfo(username);
} catch (UserStoreException e) {
String message = "Error occurred while trying to retrieve roles of the user '" + username + "'";
log.error(message, e);
throw new UserManagementException(message, e);
}
}
@Override
public BasicUserInfoList getUsers(String appliedFilter, int appliedLimit, String domain, int limit, int offset)
throws UserManagementException {
try {
int tenantId = CarbonContext.getThreadLocalCarbonContext().getTenantId();
UserStoreManager userStoreManager = DeviceManagementDataHolder.getInstance().
getRealmService().getTenantUserRealm(tenantId).getUserStoreManager();
List<BasicUserInfo> userList, offsetList;
//As the listUsers function accepts limit only to accommodate offset we are passing offset + limit
List<String> users = Arrays.asList(userStoreManager.listUsers(appliedFilter, appliedLimit));
if (domain != null && !domain.isEmpty()) {
users = getUsersFromDomain(domain, users);
}
userList = new ArrayList<>(users.size());
BasicUserInfo user;
for (String username : users) {
if (DeviceManagementConstants.User.APIM_RESERVED_USER.equals(username) || DeviceManagementConstants.User.RESERVED_USER.equals(username)) {
continue;
}
user = getBasicUserInfo(username);
userList.add(user);
}
int toIndex = offset + limit;
int listSize = userList.size();
int lastIndex = listSize - 1;
if (offset <= lastIndex) {
if (toIndex <= listSize) {
offsetList = userList.subList(offset, toIndex);
} else {
offsetList = userList.subList(offset, listSize);
}
} else {
offsetList = new ArrayList<>();
}
BasicUserInfoList result = new BasicUserInfoList();
result.setList(offsetList);
result.setCount(userList.size());
return result;
} catch (UserStoreException e) {
String msg = "Error occurred while retrieving the list of users.";
log.error(msg, e);
throw new UserManagementException(msg, e);
}
}
@Override
public BasicUserInfoList getUsersSearch(BasicUserInfo basicUserInfo, int offset, int limit) throws UserManagementException {
List<BasicUserInfo> filteredUserList = new ArrayList<>();
List<String> commonUsers = null, tempList;
try {
if (basicUserInfo.getUsername() != null && StringUtils.isNotEmpty(basicUserInfo.getUsername())) {
commonUsers = getUserList(null, "*" + basicUserInfo.getUsername() + "*");
}
if (commonUsers != null) {
commonUsers.remove(DeviceManagementConstants.User.APIM_RESERVED_USER);
commonUsers.remove(DeviceManagementConstants.User.RESERVED_USER);
}
if (!skipSearch(commonUsers) && basicUserInfo.getFirstname() != null && StringUtils.isNotEmpty(basicUserInfo.getFirstname())) {
tempList = getUserList(DeviceManagementConstants.User.CLAIM_FIRST_NAME, "*" + basicUserInfo.getFirstname() + "*");
if (commonUsers == null) {
commonUsers = tempList;
} else {
commonUsers.retainAll(tempList);
}
}
if (!skipSearch(commonUsers) && basicUserInfo.getLastname() != null && StringUtils.isNotEmpty(basicUserInfo.getLastname())) {
tempList = getUserList(DeviceManagementConstants.User.CLAIM_LAST_NAME, "*" + basicUserInfo.getLastname() + "*");
if (commonUsers == null || commonUsers.size() == 0) {
commonUsers = tempList;
} else {
commonUsers.retainAll(tempList);
}
}
if (!skipSearch(commonUsers) && basicUserInfo.getEmailAddress() != null && StringUtils.isNotEmpty(basicUserInfo.getEmailAddress())) {
tempList = getUserList(DeviceManagementConstants.User.CLAIM_EMAIL_ADDRESS, "*" + basicUserInfo.getEmailAddress() + "*");
if (commonUsers == null || commonUsers.size() == 0) {
commonUsers = tempList;
} else {
commonUsers.retainAll(tempList);
}
}
BasicUserInfo newBasicUserInfo;
if (commonUsers != null) {
for (String user : commonUsers) {
newBasicUserInfo = new BasicUserInfo();
newBasicUserInfo.setUsername(user);
newBasicUserInfo.setEmailAddress(getClaimValue(user, DeviceManagementConstants.User.CLAIM_EMAIL_ADDRESS));
newBasicUserInfo.setFirstname(getClaimValue(user, DeviceManagementConstants.User.CLAIM_FIRST_NAME));
newBasicUserInfo.setLastname(getClaimValue(user, DeviceManagementConstants.User.CLAIM_LAST_NAME));
filteredUserList.add(newBasicUserInfo);
}
}
int toIndex = offset + limit;
int listSize = filteredUserList.size();
int lastIndex = listSize - 1;
List<BasicUserInfo> offsetList;
if (offset <= lastIndex) {
if (toIndex <= listSize) {
offsetList = filteredUserList.subList(offset, toIndex);
} else {
offsetList = filteredUserList.subList(offset, listSize);
}
} else {
offsetList = new ArrayList<>();
}
BasicUserInfoList basicUserInfoList = new BasicUserInfoList();
basicUserInfoList.setList(offsetList);
basicUserInfoList.setCount(commonUsers != null ? commonUsers.size() : 0);
return basicUserInfoList;
} catch (UserStoreException e) {
String msg = "Error occurred while retrieving the list of users.";
log.error(msg, e);
throw new UserManagementException(msg, e);
}
}
@Override
public List<UserInfo> getUserNames(String filter, String userStoreDomain, int offset, int limit) throws UserManagementException {
List<UserInfo> userList;
try {
int tenantId = CarbonContext.getThreadLocalCarbonContext().getTenantId();
UserStoreManager userStoreManager = DeviceManagementDataHolder.getInstance().
getRealmService().getTenantUserRealm(tenantId).getUserStoreManager();
String[] users;
if (userStoreDomain.equals("all")) {
users = userStoreManager.listUsers(filter + "*", limit);
} else {
users = userStoreManager.listUsers(userStoreDomain + "/" + filter + "*", limit);
}
userList = new ArrayList<>();
UserInfo user;
for (String username : users) {
if (DeviceManagementConstants.User.APIM_RESERVED_USER.equals(username) || DeviceManagementConstants.User.RESERVED_USER.equals(username)) {
continue;
}
user = new UserInfo();
user.setUsername(username);
user.setEmailAddress(getClaimValue(username, DeviceManagementConstants.User.CLAIM_EMAIL_ADDRESS));
user.setFirstname(getClaimValue(username, DeviceManagementConstants.User.CLAIM_FIRST_NAME));
user.setLastname(getClaimValue(username, DeviceManagementConstants.User.CLAIM_LAST_NAME));
userList.add(user);
}
return userList;
} catch (UserStoreException e) {
String msg = "Error occurred while retrieving the list of users using the filter : " + filter;
log.error(msg, e);
throw new UserManagementException(msg, e);
}
}
/**
* User search provides an AND search result and if either of the filter returns an empty set of users, there is no
* need to carry on the search further. This method decides whether to carry on the search or not.
*
* @param commonUsers current filtered user list.
* @return <code>true</code> if further search is needed.
*/
private boolean skipSearch(List<String> commonUsers) {
return commonUsers != null && commonUsers.size() == 0;
}
/**
* Searches users which matches a given filter based on a claim
*
* @param claim the claim value to apply the filter. If <code>null</code> users will be filtered by username.
* @param filter the search query.
* @return <code>List<String></code> of users which matches.
* @throws UserStoreException If unable to search users.
*/
private ArrayList<String> getUserList(String claim, String filter) throws UserStoreException {
String defaultFilter = "*";
int tenantId = CarbonContext.getThreadLocalCarbonContext().getTenantId();
org.wso2.carbon.user.core.UserStoreManager userStoreManager = (org.wso2.carbon.user.core.UserStoreManager) DeviceManagementDataHolder.getInstance().
getRealmService().getTenantUserRealm(tenantId).getUserStoreManager();
String appliedFilter = filter + defaultFilter;
String[] users;
if (log.isDebugEnabled()) {
log.debug("Searching Users - claim: " + claim + " filter: " + appliedFilter);
}
if (StringUtils.isEmpty(claim)) {
users = userStoreManager.listUsers(appliedFilter, -1);
} else {
users = userStoreManager.getUserList(claim, appliedFilter, null);
}
if (log.isDebugEnabled()) {
log.debug("Returned user count: " + users.length);
}
return new ArrayList<>(Arrays.asList(users));
}
/**
* Iterates through the list of all users and returns a list of users from the specified user store domain
* @param domain user store domain name
* @param users list of all users from UserStoreManager
* @return list of users from specified user store domain
*/
public List<String> getUsersFromDomain(String domain, List<String> users) {
List<String> userList = new ArrayList<>();
for(String username : users) {
String[] domainName = username.split("/");
if(domain.equals(DeviceManagementConstants.User.PRIMARY_USER_STORE) && domainName.length == 1) {
userList.add(username);
} else if (domainName[0].equals(domain) && domainName.length > 1) {
userList.add(username);
}
}
return userList;
}
private String generateInitialUserPassword() {
int passwordLength = 6;
//defining the pool of characters to be used for initial password generation
String lowerCaseCharset = "abcdefghijklmnopqrstuvwxyz";
String upperCaseCharset = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
String numericCharset = "0123456789";
SecureRandom randomGenerator = new SecureRandom();
String totalCharset = lowerCaseCharset + upperCaseCharset + numericCharset;
int totalCharsetLength = totalCharset.length();
StringBuilder initialUserPassword = new StringBuilder();
for (int i = 0; i < passwordLength; i++) {
initialUserPassword.append(
totalCharset.charAt(randomGenerator.nextInt(totalCharsetLength)));
}
if (log.isDebugEnabled()) {
log.debug("Initial user password is created for new user: " + initialUserPassword);
}
return initialUserPassword.toString();
}
private BasicUserInfo getBasicUserInfo(String username) throws UserStoreException {
BasicUserInfo userInfo = new BasicUserInfo();
userInfo.setUsername(username);
userInfo.setEmailAddress(getClaimValue(username, DeviceManagementConstants.User.CLAIM_EMAIL_ADDRESS));
userInfo.setFirstname(getClaimValue(username, DeviceManagementConstants.User.CLAIM_FIRST_NAME));
userInfo.setLastname(getClaimValue(username, DeviceManagementConstants.User.CLAIM_LAST_NAME));
userInfo.setCreatedDate(getClaimValue(username, DeviceManagementConstants.User.CLAIM_CREATED));
userInfo.setModifiedDate(getClaimValue(username, DeviceManagementConstants.User.CLAIM_MODIFIED));
return userInfo;
}
private String getClaimValue(String username, String claimUri) throws UserStoreException {
int tenantId = CarbonContext.getThreadLocalCarbonContext().getTenantId();
UserStoreManager userStoreManager = DeviceManagementDataHolder.getInstance().
getRealmService().getTenantUserRealm(tenantId).getUserStoreManager();
return userStoreManager.getUserClaimValue(username, claimUri, null);
}
private Map<String, String> buildDefaultUserClaims(String firstName, String lastName, String emailAddress,
boolean isFresh) {
Map<String, String> defaultUserClaims = new HashMap<>();
defaultUserClaims.put(DeviceManagementConstants.User.CLAIM_FIRST_NAME, firstName);
defaultUserClaims.put(DeviceManagementConstants.User.CLAIM_LAST_NAME, lastName);
defaultUserClaims.put(DeviceManagementConstants.User.CLAIM_EMAIL_ADDRESS, emailAddress);
if (isFresh) {
defaultUserClaims.put(DeviceManagementConstants.User.CLAIM_CREATED, String.valueOf(Instant.now().getEpochSecond()));
} else {
defaultUserClaims.put(DeviceManagementConstants.User.CLAIM_MODIFIED, String.valueOf(Instant.now().getEpochSecond()));
}
if (log.isDebugEnabled()) {
log.debug("Default claim map is created for new user: " + defaultUserClaims.toString());
}
return defaultUserClaims;
}
private List<String> getFilteredRoles(UserStoreManager userStoreManager, String username)
throws UserStoreException {
String[] roleListOfUser;
roleListOfUser = userStoreManager.getRoleListOfUser(username);
List<String> filteredRoles = new ArrayList<>();
for (String role : roleListOfUser) {
if (!(role.startsWith("Internal/") || role.startsWith("Authentication/"))) {
filteredRoles.add(role);
}
}
return filteredRoles;
}
/**
* Returns a list of permissions of a given role
* @param roleName name of the role
* @param tenantId the user's tenetId
* @param userRealm user realm of the tenant
* @return list of permissions
* @throws UserAdminException If unable to get the permissions
*/
private static List<String> getPermissionsListFromRole(String roleName, UserRealm userRealm, int tenantId)
throws UserAdminException {
org.wso2.carbon.user.core.UserRealm userRealmCore;
try {
userRealmCore = (org.wso2.carbon.user.core.UserRealm) userRealm;
} catch (ClassCastException e) {
String message = "Provided UserRealm object is not an instance of org.wso2.carbon.user.core.UserRealm";
log.error(message, e);
throw new UserAdminException(message, e);
}
UserRealmProxy userRealmProxy = new UserRealmProxy(userRealmCore);
List<String> permissionsList = new ArrayList<>();
final UIPermissionNode rolePermissions = userRealmProxy.getRolePermissions(roleName, tenantId);
iteratePermissions(rolePermissions, permissionsList);
return permissionsList;
}
/**
* Extract permissions from a UiPermissionNode using recursions
* @param uiPermissionNode an UiPermissionNode Object to extract permissions
* @param list provided list to add permissions
*/
public static void iteratePermissions(UIPermissionNode uiPermissionNode, List<String> list) {
// To prevent NullPointer exceptions
if (uiPermissionNode == null) {
return;
}
for (UIPermissionNode permissionNode : uiPermissionNode.getNodeList()) {
if (permissionNode != null) {
if(permissionNode.isSelected()){
list.add(permissionNode.getResourcePath());
}
if (permissionNode.getNodeList() != null
&& permissionNode.getNodeList().length > 0) {
iteratePermissions(permissionNode, list);
}
}
}
}
}
Loading…
Cancel
Save