diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/roles/config/DefaultRoles.java b/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/roles/config/DefaultRoles.java new file mode 100644 index 00000000000..f70e2107c6f --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/roles/config/DefaultRoles.java @@ -0,0 +1,49 @@ +/* Copyright (c) 2020, 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 org.wso2.carbon.device.mgt.common.roles.config; + +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlElementWrapper; +import javax.xml.bind.annotation.XmlRootElement; +import java.util.List; + +@XmlRootElement(name = "DefaultRoles") +public class DefaultRoles { + + private boolean enabled; + private List roles; + + @XmlElement(name = "Enabled", required = true) + public boolean isEnabled() { + return enabled; + } + + public void setEnabled(boolean enabled) { + this.enabled = enabled; + } + + @XmlElementWrapper(name = "Roles", required = true) + @XmlElement(name = "Role", required = true) + public List getRoles() { + return roles; + } + + public void setRoles(List roles) { + this.roles = roles; + } +} diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/roles/config/Role.java b/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/roles/config/Role.java new file mode 100644 index 00000000000..f633b9b2d3c --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/roles/config/Role.java @@ -0,0 +1,49 @@ +/* Copyright (c) 2020, 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 org.wso2.carbon.device.mgt.common.roles.config; + +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlElementWrapper; +import javax.xml.bind.annotation.XmlRootElement; +import java.util.List; + +@XmlRootElement(name = "Role") +public class Role { + + private String name; + private List permissions; + + @XmlElement(name = "Name", required = true) + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + @XmlElementWrapper(name = "Permissions", required = true) + @XmlElement(name = "Permission", required = true) + public List getPermissions() { + return permissions; + } + + public void setPermissions(List permissions) { + this.permissions = permissions; + } +} diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/config/DeviceManagementConfig.java b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/config/DeviceManagementConfig.java index 456de2f2d47..cf589679881 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/config/DeviceManagementConfig.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/config/DeviceManagementConfig.java @@ -18,6 +18,7 @@ package org.wso2.carbon.device.mgt.core.config; import org.wso2.carbon.device.mgt.common.enrollment.notification.EnrollmentNotificationConfiguration; +import org.wso2.carbon.device.mgt.common.roles.config.DefaultRoles; import org.wso2.carbon.device.mgt.core.config.analytics.OperationAnalyticsConfiguration; import org.wso2.carbon.device.mgt.core.config.archival.ArchivalConfiguration; import org.wso2.carbon.device.mgt.core.config.cache.CertificateCacheConfiguration; @@ -60,7 +61,7 @@ public final class DeviceManagementConfig { private RemoteSessionConfiguration remoteSessionConfiguration; private ArchivalConfiguration archivalConfiguration; private EnrollmentNotificationConfiguration enrollmentNotificationConfiguration; - + private DefaultRoles defaultRoles; @XmlElement(name = "ManagementRepository", required = true) public DeviceManagementConfigRepository getDeviceManagementConfigRepository() { @@ -215,5 +216,10 @@ public final class DeviceManagementConfig { EnrollmentNotificationConfiguration enrollmentNotificationConfiguration) { this.enrollmentNotificationConfiguration = enrollmentNotificationConfiguration; } + + @XmlElement(name = "DefaultRoles", required = true) + public DefaultRoles getDefaultRoles() { return defaultRoles; } + + public void setDefaultRoles(DefaultRoles defaultRoles) { this.defaultRoles = defaultRoles; } } diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/internal/DeviceManagementServiceComponent.java b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/internal/DeviceManagementServiceComponent.java index edc388f2029..daf740fa609 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/internal/DeviceManagementServiceComponent.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/internal/DeviceManagementServiceComponent.java @@ -72,9 +72,11 @@ import org.wso2.carbon.device.mgt.core.task.DeviceTaskManagerService; import org.wso2.carbon.device.mgt.core.config.ui.UIConfigurationManager; import org.wso2.carbon.device.mgt.core.util.DeviceManagementSchemaInitializer; import org.wso2.carbon.device.mgt.core.util.DeviceManagerUtil; +import org.wso2.carbon.device.mgt.core.util.DeviceMgtTenantMgtListener; import org.wso2.carbon.email.sender.core.service.EmailSenderService; import org.wso2.carbon.ndatasource.core.DataSourceService; import org.wso2.carbon.registry.core.service.RegistryService; +import org.wso2.carbon.stratos.common.listeners.TenantMgtListener; import org.wso2.carbon.user.core.service.RealmService; import org.wso2.carbon.utils.Axis2ConfigurationContextObserver; import org.wso2.carbon.utils.ConfigurationContextService; @@ -245,6 +247,9 @@ public class DeviceManagementServiceComponent { componentContext.getBundleContext().registerService(PrivacyComplianceProvider.class.getName(), privacyComplianceProvider, null); + componentContext.getBundleContext() + .registerService(TenantMgtListener.class.getName(), new DeviceMgtTenantMgtListener(), null); + if (log.isDebugEnabled()) { log.debug("Device management core bundle has been successfully initialized"); } diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/util/DeviceMgtTenantMgtListener.java b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/util/DeviceMgtTenantMgtListener.java new file mode 100644 index 00000000000..5e0e0cff931 --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/util/DeviceMgtTenantMgtListener.java @@ -0,0 +1,148 @@ +/* Copyright (c) 2020, 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 org.wso2.carbon.device.mgt.core.util; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.wso2.carbon.context.PrivilegedCarbonContext; +import org.wso2.carbon.device.mgt.common.permission.mgt.PermissionManagementException; +import org.wso2.carbon.device.mgt.common.roles.config.Role; +import org.wso2.carbon.device.mgt.core.config.DeviceConfigurationManager; +import org.wso2.carbon.device.mgt.core.config.DeviceManagementConfig; +import org.wso2.carbon.device.mgt.core.internal.DeviceManagementDataHolder; +import org.wso2.carbon.device.mgt.core.permission.mgt.PermissionUtils; +import org.wso2.carbon.registry.core.exceptions.RegistryException; +import org.wso2.carbon.stratos.common.beans.TenantInfoBean; +import org.wso2.carbon.stratos.common.listeners.TenantMgtListener; +import org.wso2.carbon.user.api.Permission; +import org.wso2.carbon.user.api.UserStoreException; +import org.wso2.carbon.user.api.UserStoreManager; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class DeviceMgtTenantMgtListener implements TenantMgtListener { + private static final Log log = LogFactory.getLog(DeviceMgtTenantMgtListener.class); + private static final int EXEC_ORDER = 10; + private static final String PERMISSION_ACTION = "ui.execute"; + + @Override + public void onTenantCreate(TenantInfoBean tenantInfoBean) { + DeviceManagementConfig config = DeviceConfigurationManager.getInstance().getDeviceManagementConfig(); + if (config.getDefaultRoles().isEnabled()) { + Map> roleMap = getValidRoleMap(config); + try { + PrivilegedCarbonContext.startTenantFlow(); + PrivilegedCarbonContext.getThreadLocalCarbonContext() + .setTenantDomain(tenantInfoBean.getTenantDomain(), true); + UserStoreManager userStoreManager = DeviceManagementDataHolder.getInstance().getRealmService() + .getTenantUserRealm(tenantInfoBean.getTenantId()).getUserStoreManager(); + + roleMap.forEach((key, value) -> { + try { + userStoreManager.addRole(key, null, value.toArray(new Permission[0])); + } catch (UserStoreException e) { + log.error("Error occurred while adding default roles into user store.", e); + } + }); + } catch (UserStoreException e) { + log.error("Error occurred while getting user store manager.", e); + } finally { + PrivilegedCarbonContext.endTenantFlow(); + } + } + } + + @Override + public void onTenantUpdate(TenantInfoBean tenantInfoBean) { + // doing nothing + } + + @Override + public void onTenantDelete(int i) { + // doing nothing + } + + @Override + public void onTenantRename(int i, String s, String s1) { + // doing nothing + } + + @Override + public void onTenantInitialActivation(int i) { + // doing nothing + } + + @Override + public void onTenantActivation(int i) { + // doing nothing + } + + @Override + public void onTenantDeactivation(int i) { + // doing nothing + } + + @Override + public void onSubscriptionPlanChange(int i, String s, String s1) { + // doing nothing + } + + @Override + public int getListenerOrder() { + return EXEC_ORDER; + } + + @Override + public void onPreDelete(int i) { + // doing nothing + } + + /** + * Use the default roles defined in the cdm-config and evaluate the defined permissions. If permissions does not + * exist then exclude them and return role map which contains defined roles in the cdm-config and existing + * permission list as a roleMap + * @param config cdm-config + * @return {@link Map} key is role name and value is list of permissions which needs to be assigned to the role + * defined in the key. + */ + private Map> getValidRoleMap(DeviceManagementConfig config) { + Map> roleMap = new HashMap<>(); + try { + for (Role role : config.getDefaultRoles().getRoles()) { + List permissionList = new ArrayList<>(); + for (String permissionPath : role.getPermissions()) { + if (PermissionUtils.checkResourceExists(permissionPath)) { + Permission permission = new Permission(permissionPath, PERMISSION_ACTION); + + permissionList.add(permission); + } else { + log.warn("Permission " + permissionPath + " does not exist. Hence it will not add to role " + + role.getName()); + } + } + roleMap.put(role.getName(), permissionList); + } + } catch (PermissionManagementException | RegistryException e) { + log.error("Error occurred while checking permission existence.", e); + } + return roleMap; + } +} diff --git a/features/device-mgt/org.wso2.carbon.device.mgt.basics.feature/src/main/resources/conf/cdm-config.xml b/features/device-mgt/org.wso2.carbon.device.mgt.basics.feature/src/main/resources/conf/cdm-config.xml index 925c5da5b40..bef658a6157 100644 --- a/features/device-mgt/org.wso2.carbon.device.mgt.basics.feature/src/main/resources/conf/cdm-config.xml +++ b/features/device-mgt/org.wso2.carbon.device.mgt.basics.feature/src/main/resources/conf/cdm-config.xml @@ -159,5 +159,16 @@ org.wso2.carbon.device.mgt.common.enrollment.notification.EnrollmentNotifier http://localhost:8280 + + false + + + test_role + + /permission/admin/Login + + + +