updated device/group access authroization logic

access-fix
Amalka Subasinghe 1 year ago
parent bf4a8a8f63
commit e639413e01

@ -172,6 +172,9 @@ public class GroupManagementAdminServiceImpl implements GroupManagementAdminServ
if (group == null) { if (group == null) {
return Response.status(Response.Status.BAD_REQUEST).build(); return Response.status(Response.Status.BAD_REQUEST).build();
} }
if (StringUtils.isEmpty(group.getOwner())) {
group.setOwner(PrivilegedCarbonContext.getThreadLocalCarbonContext().getUsername());
}
group.setStatus(DeviceGroupConstants.GroupStatus.ACTIVE); group.setStatus(DeviceGroupConstants.GroupStatus.ACTIVE);
try { try {
DeviceMgtAPIUtils.getGroupManagementProviderService().createGroup(group, DEFAULT_ADMIN_ROLE, DEFAULT_ADMIN_PERMISSIONS); DeviceMgtAPIUtils.getGroupManagementProviderService().createGroup(group, DEFAULT_ADMIN_ROLE, DEFAULT_ADMIN_PERMISSIONS);

@ -0,0 +1,15 @@
package io.entgra.device.mgt.core.device.mgt.common.authorization;
public interface GroupAccessAuthorizationService {
public boolean isUserAuthorized(int groupId, String username, String[] groupPermissions)
throws DeviceAccessAuthorizationException;
public boolean isUserAuthorized(int groupId, String username)
throws DeviceAccessAuthorizationException;
public boolean isUserAuthorized(int groupId, String[] groupPermissions)
throws DeviceAccessAuthorizationException;
public boolean isUserAuthorized(int groupId) throws DeviceAccessAuthorizationException;
}

@ -63,10 +63,12 @@ public class DeviceAccessAuthorizationServiceImpl implements DeviceAccessAuthori
return !DeviceManagementDataHolder.getInstance().requireDeviceAuthorization(deviceIdentifier.getType()); return !DeviceManagementDataHolder.getInstance().requireDeviceAuthorization(deviceIdentifier.getType());
} }
//check for admin and ownership permissions //check for admin and ownership permissions
if (isAdmin(username, tenantId) || isDeviceOwner(deviceIdentifier, username)) { if (isDeviceAdminUser(username, tenantId) || isDeviceOwner(deviceIdentifier, username)) {
return true; return true;
} }
//check for group permissions //check for group permissions
if (groupPermissions == null || groupPermissions.length == 0) {
// if group permissions not specified, check whether roles are shared.
try { try {
return isSharedViaGroup(deviceIdentifier, username); return isSharedViaGroup(deviceIdentifier, username);
} catch (GroupManagementException | UserStoreException e) { } catch (GroupManagementException | UserStoreException e) {
@ -74,6 +76,24 @@ public class DeviceAccessAuthorizationServiceImpl implements DeviceAccessAuthori
deviceIdentifier.getId() + " for the user : " + deviceIdentifier.getId() + " for the user : " +
username, e); username, e);
} }
} else {
// if group permissions specified, check whether that permission is available in shared role
try {
boolean isAuthorized = true;
for (String groupPermission : groupPermissions) {
if (!isAuthorizedViaSharedGroup(deviceIdentifier, username, groupPermission)) {
//if at least one failed, authorizations fails and break the loop
isAuthorized = false;
break;
}
}
return isAuthorized;
} catch (DeviceAccessAuthorizationException e) {
throw new DeviceAccessAuthorizationException("Unable to authorize the access to device : " +
deviceIdentifier.getId() + " for the user : " +
username, e);
}
}
} }
private boolean isSharedViaGroup(DeviceIdentifier deviceIdentifier, String username) private boolean isSharedViaGroup(DeviceIdentifier deviceIdentifier, String username)
@ -94,6 +114,30 @@ public class DeviceAccessAuthorizationServiceImpl implements DeviceAccessAuthori
return false; return false;
} }
private boolean isAuthorizedViaSharedGroup(DeviceIdentifier deviceIdentifier, String username, String groupPermission)
throws DeviceAccessAuthorizationException {
try {
List<DeviceGroup> groupsWithDevice = DeviceManagementDataHolder.getInstance()
.getGroupManagementProviderService().getGroups(deviceIdentifier, false);
UserRealm userRealm = DeviceManagementDataHolder.getInstance().getRealmService()
.getTenantUserRealm(getTenantId());
String[] userRoles = userRealm.getUserStoreManager().getRoleListOfUser(username);
for (DeviceGroup deviceGroup : groupsWithDevice) {
List<String> sharingRoles = DeviceManagementDataHolder.getInstance()
.getGroupManagementProviderService().getRoles(deviceGroup.getGroupId());
for (String role : userRoles) {
if (sharingRoles.contains(role) && userRealm.getAuthorizationManager().
isRoleAuthorized(role, groupPermission, CarbonConstants.UI_PERMISSION_ACTION)) {
return true;
}
}
}
return false;
} catch (GroupManagementException | UserStoreException e) {
throw new DeviceAccessAuthorizationException("unable to authorized via shared role, " + groupPermission);
}
}
@Override @Override
public boolean isUserAuthorized(DeviceIdentifier deviceIdentifier, String username) public boolean isUserAuthorized(DeviceIdentifier deviceIdentifier, String username)
throws DeviceAccessAuthorizationException { throws DeviceAccessAuthorizationException {
@ -116,8 +160,8 @@ public class DeviceAccessAuthorizationServiceImpl implements DeviceAccessAuthori
String username = this.getUserName(); String username = this.getUserName();
int tenantId = this.getTenantId(); int tenantId = this.getTenantId();
try { try {
return isAdminUser(username, tenantId); return isDeviceAdminUser(username, tenantId);
} catch (UserStoreException e) { } catch (DeviceAccessAuthorizationException e) {
throw new DeviceAccessAuthorizationException("Unable to check the admin permissions of user : " + throw new DeviceAccessAuthorizationException("Unable to check the admin permissions of user : " +
username + " in tenant : " + tenantId, e); username + " in tenant : " + tenantId, e);
} }
@ -132,7 +176,7 @@ public class DeviceAccessAuthorizationServiceImpl implements DeviceAccessAuthori
return null; return null;
} }
DeviceAuthorizationResult deviceAuthorizationResult = new DeviceAuthorizationResult(); DeviceAuthorizationResult deviceAuthorizationResult = new DeviceAuthorizationResult();
if (isAdmin(username, tenantId)) { if (isDeviceAdminUser(username, tenantId)) {
deviceAuthorizationResult.setAuthorizedDevices(deviceIdentifiers); deviceAuthorizationResult.setAuthorizedDevices(deviceIdentifiers);
return deviceAuthorizationResult; return deviceAuthorizationResult;
} }
@ -149,7 +193,7 @@ public class DeviceAccessAuthorizationServiceImpl implements DeviceAccessAuthori
//check for group permissions //check for group permissions
boolean isAuthorized = true; boolean isAuthorized = true;
for (String groupPermission : groupPermissions) { for (String groupPermission : groupPermissions) {
if (!isAuthorizedViaGroup(username, deviceIdentifier, groupPermission)) { if (!isAuthorizedViaSharedGroup(deviceIdentifier, username, groupPermission)) {
//if at least one failed, authorizations fails and break the loop //if at least one failed, authorizations fails and break the loop
isAuthorized = false; isAuthorized = false;
break; break;
@ -160,7 +204,7 @@ public class DeviceAccessAuthorizationServiceImpl implements DeviceAccessAuthori
} else { } else {
deviceAuthorizationResult.addUnauthorizedDevice(deviceIdentifier); deviceAuthorizationResult.addUnauthorizedDevice(deviceIdentifier);
} }
} catch (GroupManagementException e) { } catch (DeviceAccessAuthorizationException e) {
throw new DeviceAccessAuthorizationException("Unable to authorize the access to device : " + throw new DeviceAccessAuthorizationException("Unable to authorize the access to device : " +
deviceIdentifier.getId() + " for the user : " + deviceIdentifier.getId() + " for the user : " +
username, e); username, e);
@ -188,36 +232,36 @@ public class DeviceAccessAuthorizationServiceImpl implements DeviceAccessAuthori
return isUserAuthorized(deviceIdentifiers, this.getUserName(), groupPermissions); return isUserAuthorized(deviceIdentifiers, this.getUserName(), groupPermissions);
} }
private boolean isAdmin(String username, int tenantId) // private boolean isAdmin(String username, int tenantId)
throws DeviceAccessAuthorizationException { // throws DeviceAccessAuthorizationException {
try { // try {
//Check for admin users. If the user is an admin user we authorize the access to that device. // //Check for admin users. If the user is an admin user we authorize the access to that device.
return (isAdminUser(username, tenantId)); // return (isDeviceAdminUser(username, tenantId));
} catch (UserStoreException e) { // } catch (DeviceAccessAuthorizationException e) {
throw new DeviceAccessAuthorizationException("Unable to authorize the access for the user : " + // throw new DeviceAccessAuthorizationException("Unable to authorize the access for the user : " +
username, e); // username, e);
} // }
} // }
private boolean isAuthorizedViaGroup(String username, DeviceIdentifier deviceIdentifier, String groupPermission) // private boolean isAuthorizedViaGroup(String username, DeviceIdentifier deviceIdentifier, String groupPermission)
throws GroupManagementException { // throws GroupManagementException {
List<DeviceGroup> authorizedGroups = // List<DeviceGroup> authorizedGroups =
DeviceManagementDataHolder.getInstance().getGroupManagementProviderService() // DeviceManagementDataHolder.getInstance().getGroupManagementProviderService()
.getGroups(username, groupPermission, false); // .getGroups(username, groupPermission, false);
List<DeviceGroup> groupsWithDevice = // List<DeviceGroup> groupsWithDevice =
DeviceManagementDataHolder.getInstance().getGroupManagementProviderService() // DeviceManagementDataHolder.getInstance().getGroupManagementProviderService()
.getGroups(deviceIdentifier, false); // .getGroups(deviceIdentifier, false);
for (DeviceGroup group : authorizedGroups) { // for (DeviceGroup group : authorizedGroups) {
Iterator<DeviceGroup> groupsWithDeviceIterator = groupsWithDevice.iterator(); // Iterator<DeviceGroup> groupsWithDeviceIterator = groupsWithDevice.iterator();
while (groupsWithDeviceIterator.hasNext()) { // while (groupsWithDeviceIterator.hasNext()) {
DeviceGroup deviceGroup = groupsWithDeviceIterator.next(); // DeviceGroup deviceGroup = groupsWithDeviceIterator.next();
if (deviceGroup.getGroupId() == group.getGroupId()) { // if (deviceGroup.getGroupId() == group.getGroupId()) {
return true; // return true;
} // }
} // }
} // }
return false; // return false;
} // }
private boolean isDeviceOwner(DeviceIdentifier deviceIdentifier, String username) private boolean isDeviceOwner(DeviceIdentifier deviceIdentifier, String username)
throws DeviceAccessAuthorizationException { throws DeviceAccessAuthorizationException {
@ -232,7 +276,8 @@ public class DeviceAccessAuthorizationServiceImpl implements DeviceAccessAuthori
} }
} }
private boolean isAdminUser(String username, int tenantId) throws UserStoreException { private boolean isDeviceAdminUser(String username, int tenantId) throws DeviceAccessAuthorizationException {
try {
UserRealm userRealm = DeviceManagementDataHolder.getInstance().getRealmService().getTenantUserRealm(tenantId); UserRealm userRealm = DeviceManagementDataHolder.getInstance().getRealmService().getTenantUserRealm(tenantId);
if (userRealm != null && userRealm.getAuthorizationManager() != null) { if (userRealm != null && userRealm.getAuthorizationManager() != null) {
return userRealm.getAuthorizationManager() return userRealm.getAuthorizationManager()
@ -241,6 +286,10 @@ public class DeviceAccessAuthorizationServiceImpl implements DeviceAccessAuthori
CarbonConstants.UI_PERMISSION_ACTION); CarbonConstants.UI_PERMISSION_ACTION);
} }
return false; return false;
} catch (UserStoreException e) {
throw new DeviceAccessAuthorizationException("Unable to authorize the access for the user : " +
username, e);
}
} }
private String getUserName() { private String getUserName() {

@ -0,0 +1,166 @@
package io.entgra.device.mgt.core.device.mgt.core.authorization;
import io.entgra.device.mgt.core.device.mgt.common.DeviceIdentifier;
import io.entgra.device.mgt.core.device.mgt.common.authorization.DeviceAccessAuthorizationException;
import io.entgra.device.mgt.core.device.mgt.common.authorization.GroupAccessAuthorizationService;
import io.entgra.device.mgt.core.device.mgt.common.exceptions.DeviceManagementException;
import io.entgra.device.mgt.core.device.mgt.common.group.mgt.DeviceGroup;
import io.entgra.device.mgt.core.device.mgt.common.group.mgt.GroupManagementException;
import io.entgra.device.mgt.core.device.mgt.common.permission.mgt.Permission;
import io.entgra.device.mgt.core.device.mgt.common.permission.mgt.PermissionManagementException;
import io.entgra.device.mgt.core.device.mgt.core.internal.DeviceManagementDataHolder;
import io.entgra.device.mgt.core.device.mgt.core.permission.mgt.PermissionUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.wso2.carbon.CarbonConstants;
import org.wso2.carbon.context.CarbonContext;
import org.wso2.carbon.user.api.UserRealm;
import org.wso2.carbon.user.api.UserStoreException;
import java.util.List;
public class GroupAccessAuthorizationServiceImpl implements GroupAccessAuthorizationService {
private final static String GROUP_ADMIN_PERMISSION = "/device-mgt/devices/any-group/permitted-actions-under-owning-group";
private final static String GROUP_ADMIN = "Group Management Administrator";
private static Log log = LogFactory.getLog(DeviceAccessAuthorizationServiceImpl.class);
public GroupAccessAuthorizationServiceImpl() {
try {
this.addAdminPermissionToRegistry();
} catch (PermissionManagementException e) {
log.error("Unable to add the group-admin permission to the registry.", e);
}
}
@Override
public boolean isUserAuthorized(int groupId, String username, String[] groupPermissions)
throws DeviceAccessAuthorizationException {
int tenantId = this.getTenantId();
if (username == null || username.isEmpty()) {
username = this.getUserName();
}
//check for admin and ownership permissions
if (isGroupAdminUser(username, tenantId) || isGroupOwner(groupId, username)) {
return true;
}
// if group owner
if (isGroupOwner(groupId, username)) {
//check for group permissions
if (groupPermissions == null || groupPermissions.length == 0) {
return false;
} else {
// if group permissions specified, check whether that permission is available in any user role of the group owner
try {
UserRealm userRealm = DeviceManagementDataHolder.getInstance().getRealmService()
.getTenantUserRealm(getTenantId());
String[] userRoles = userRealm.getUserStoreManager().getRoleListOfUser(username);
boolean isAuthorized = true;
for (String groupPermission : groupPermissions) {
for (String role : userRoles) {
if (!userRealm.getAuthorizationManager().
isRoleAuthorized(role, groupPermission, CarbonConstants.UI_PERMISSION_ACTION)) {
isAuthorized = false;
break;
}
}
}
return isAuthorized;
} catch (UserStoreException e) {
throw new DeviceAccessAuthorizationException("Unable to authorize the access to group : " +
groupId + " for the user : " +
username, e);
}
}
}
return false;
}
@Override
public boolean isUserAuthorized(int groupId, String username)
throws DeviceAccessAuthorizationException {
return isUserAuthorized(groupId, username, null);
}
@Override
public boolean isUserAuthorized(int groupId, String[] groupPermissions)
throws DeviceAccessAuthorizationException {
return isUserAuthorized(groupId, this.getUserName(), groupPermissions);
}
@Override
public boolean isUserAuthorized(int groupId) throws DeviceAccessAuthorizationException {
return isUserAuthorized(groupId, this.getUserName(), null);
}
public boolean isGroupAdminUser() throws DeviceAccessAuthorizationException {
String username = this.getUserName();
int tenantId = this.getTenantId();
try {
return isGroupAdminUser(username, tenantId);
} catch (DeviceAccessAuthorizationException e) {
throw new DeviceAccessAuthorizationException("Unable to check the admin permissions of user : " +
username + " in tenant : " + tenantId, e);
}
}
private boolean isGroupOwner(int groupId, String username)
throws DeviceAccessAuthorizationException {
//Check for group ownership. If the user is the owner of the group we allow the access.
try {
DeviceGroup group = DeviceManagementDataHolder.getInstance().
getGroupManagementProviderService().getGroup(groupId, false);
return username.equals(group.getOwner());
} catch (GroupManagementException e) {
throw new DeviceAccessAuthorizationException("Unable to authorize the access to group : " +
groupId + " for the user : " +
username, e);
}
}
private boolean isGroupAdminUser(String username, int tenantId) throws DeviceAccessAuthorizationException {
try {
UserRealm userRealm = DeviceManagementDataHolder.getInstance().getRealmService().getTenantUserRealm(tenantId);
if (userRealm != null && userRealm.getAuthorizationManager() != null) {
return userRealm.getAuthorizationManager()
.isUserAuthorized(removeTenantDomain(username),
PermissionUtils.getAbsolutePermissionPath(GROUP_ADMIN_PERMISSION),
CarbonConstants.UI_PERMISSION_ACTION);
}
return false;
} catch (UserStoreException e) {
throw new DeviceAccessAuthorizationException("Unable to authorize the access for the user : " +
username, e);
}
}
private String getUserName() {
String username = CarbonContext.getThreadLocalCarbonContext().getUsername();
if (username != null && !username.isEmpty()) {
return removeTenantDomain(username);
}
return null;
}
private String removeTenantDomain(String username) {
String tenantDomain = CarbonContext.getThreadLocalCarbonContext().getTenantDomain();
if (username.endsWith(tenantDomain)) {
return username.substring(0, username.lastIndexOf("@"));
}
return username;
}
private int getTenantId() {
return CarbonContext.getThreadLocalCarbonContext().getTenantId();
}
private boolean addAdminPermissionToRegistry() throws PermissionManagementException {
Permission permission = new Permission();
permission.setName(GROUP_ADMIN);
permission.setPath(PermissionUtils.getAbsolutePermissionPath(GROUP_ADMIN_PERMISSION));
return PermissionUtils.putPermission(permission);
}
}

@ -20,6 +20,7 @@ package io.entgra.device.mgt.core.device.mgt.core.internal;
import io.entgra.device.mgt.core.apimgt.extension.rest.api.APIApplicationServices; import io.entgra.device.mgt.core.apimgt.extension.rest.api.APIApplicationServices;
import io.entgra.device.mgt.core.apimgt.extension.rest.api.PublisherRESTAPIServices; import io.entgra.device.mgt.core.apimgt.extension.rest.api.PublisherRESTAPIServices;
import io.entgra.device.mgt.core.device.mgt.common.authorization.GroupAccessAuthorizationService;
import io.entgra.device.mgt.core.device.mgt.common.metadata.mgt.DeviceStatusManagementService; import io.entgra.device.mgt.core.device.mgt.common.metadata.mgt.DeviceStatusManagementService;
import io.entgra.device.mgt.core.server.bootup.heartbeat.beacon.service.HeartBeatManagementService; import io.entgra.device.mgt.core.server.bootup.heartbeat.beacon.service.HeartBeatManagementService;
import org.wso2.carbon.context.PrivilegedCarbonContext; import org.wso2.carbon.context.PrivilegedCarbonContext;
@ -78,6 +79,7 @@ public class DeviceManagementDataHolder {
private ConfigurationContextService configurationContextService; private ConfigurationContextService configurationContextService;
private final HashMap<String, Boolean> requireDeviceAuthorization = new HashMap<>(); private final HashMap<String, Boolean> requireDeviceAuthorization = new HashMap<>();
private DeviceAccessAuthorizationService deviceAccessAuthorizationService; private DeviceAccessAuthorizationService deviceAccessAuthorizationService;
private GroupAccessAuthorizationService groupAccessAuthorizationService;
private GroupManagementProviderService groupManagementProviderService; private GroupManagementProviderService groupManagementProviderService;
private TaskService taskService; private TaskService taskService;
private EmailSenderService emailSenderService; private EmailSenderService emailSenderService;
@ -447,4 +449,12 @@ public class DeviceManagementDataHolder {
public void setPublisherRESTAPIServices(PublisherRESTAPIServices publisherRESTAPIServices) { public void setPublisherRESTAPIServices(PublisherRESTAPIServices publisherRESTAPIServices) {
this.publisherRESTAPIServices = publisherRESTAPIServices; this.publisherRESTAPIServices = publisherRESTAPIServices;
} }
public GroupAccessAuthorizationService getGroupAccessAuthorizationService() {
return groupAccessAuthorizationService;
}
public void setGroupAccessAuthorizationService(GroupAccessAuthorizationService groupAccessAuthorizationService) {
this.groupAccessAuthorizationService = groupAccessAuthorizationService;
}
} }

@ -17,7 +17,9 @@
*/ */
package io.entgra.device.mgt.core.device.mgt.core.internal; package io.entgra.device.mgt.core.device.mgt.core.internal;
import io.entgra.device.mgt.core.device.mgt.common.authorization.GroupAccessAuthorizationService;
import io.entgra.device.mgt.core.device.mgt.common.metadata.mgt.DeviceStatusManagementService; import io.entgra.device.mgt.core.device.mgt.common.metadata.mgt.DeviceStatusManagementService;
import io.entgra.device.mgt.core.device.mgt.core.authorization.GroupAccessAuthorizationServiceImpl;
import io.entgra.device.mgt.core.device.mgt.core.metadata.mgt.DeviceStatusManagementServiceImpl; import io.entgra.device.mgt.core.device.mgt.core.metadata.mgt.DeviceStatusManagementServiceImpl;
import io.entgra.device.mgt.core.server.bootup.heartbeat.beacon.service.HeartBeatManagementService; import io.entgra.device.mgt.core.server.bootup.heartbeat.beacon.service.HeartBeatManagementService;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
@ -353,6 +355,12 @@ public class DeviceManagementServiceComponent {
bundleContext.registerService(DeviceAccessAuthorizationService.class.getName(), bundleContext.registerService(DeviceAccessAuthorizationService.class.getName(),
deviceAccessAuthorizationService, null); deviceAccessAuthorizationService, null);
/* Registering GroupAccessAuthorization Service */
GroupAccessAuthorizationService groupAccessAuthorizationService = new GroupAccessAuthorizationServiceImpl();
DeviceManagementDataHolder.getInstance().setGroupAccessAuthorizationService(groupAccessAuthorizationService);
bundleContext.registerService(GroupAccessAuthorizationService.class.getName(),
groupAccessAuthorizationService, null);
/* Registering Geo Service */ /* Registering Geo Service */
GeoLocationProviderService geoService = new GeoLocationProviderServiceImpl(); GeoLocationProviderService geoService = new GeoLocationProviderServiceImpl();
DeviceManagementDataHolder.getInstance().setGeoLocationProviderService(geoService); DeviceManagementDataHolder.getInstance().setGeoLocationProviderService(geoService);

Loading…
Cancel
Save