Implemented scope based authorization

revert-70aa11f8
mharindu 9 years ago
parent 59028f9f09
commit 49623a4693

@ -40,6 +40,6 @@ public @interface Permission {
* Represents the associated permissions.
* @return Returns list of permissions.
*/
String[] permissions();
String[] roles();
}

@ -24,7 +24,7 @@ package org.wso2.carbon.apimgt.webapp.publisher.config;
public class PermissionConfiguration {
private String scopeName;
private String[] permissions;
private String[] roles;
public String getScopeName() {
return scopeName;
@ -34,12 +34,12 @@ public class PermissionConfiguration {
this.scopeName = scope;
}
public String[] getPermissions() {
return permissions;
public String[] getRoles() {
return roles;
}
public void setPermissions(String[] permissions) {
this.permissions = permissions;
public void setRoles(String[] roles) {
this.roles = roles;
}
}

@ -19,12 +19,10 @@
package org.wso2.carbon.apimgt.webapp.publisher.lifecycle.util;
import org.apache.catalina.core.StandardContext;
import org.apache.commons.lang.ArrayUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.scannotation.AnnotationDB;
import org.scannotation.WarUrlFinder;
import org.wso2.carbon.apimgt.annotations.api.API;
import org.wso2.carbon.apimgt.annotations.api.Permission;
import org.wso2.carbon.apimgt.api.model.Scope;
@ -36,11 +34,14 @@ import org.wso2.carbon.apimgt.webapp.publisher.config.PermissionManagementExcept
import javax.servlet.ServletContext;
import javax.ws.rs.*;
import java.io.File;
import java.io.IOException;
import java.lang.annotation.Annotation;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URL;
import java.security.AccessController;
import java.security.PrivilegedAction;
@ -58,13 +59,9 @@ public class AnnotationProcessor {
private static final String WILD_CARD = "/*";
private static final String AUTH_TYPE = "Any";
private static final String PROTOCOL_HTTP = "http";
private static final String SERVER_HOST = "carbon.local.ip";
private static final String HTTP_PORT = "httpPort";
private static final String STRING_ARR = "string_arr";
private static final String STRING = "string";
private StandardContext context;
private Method[] pathClazzMethods;
private Class<Path> pathClazz;
Class<API> apiClazz;
@ -73,7 +70,6 @@ public class AnnotationProcessor {
public AnnotationProcessor(final StandardContext context) {
this.context = context;
servletContext = context.getServletContext();
classLoader = servletContext.getClassLoader();
}
@ -90,11 +86,8 @@ public class AnnotationProcessor {
db.addIgnoredPackages(PACKAGE_ORG_CODEHAUS);
db.addIgnoredPackages(PACKAGE_ORG_SPRINGFRAMEWORK);
URL[] libPath = WarUrlFinder.findWebInfLibClasspaths(servletContext);
URL classPath = WarUrlFinder.findWebInfClassesPath(servletContext);
URL[] urls = (URL[]) ArrayUtils.add(libPath, libPath.length, classPath);
db.scanArchives(urls);
URL classPath = findWebInfClassesPath(servletContext);
db.scanArchives(classPath);
//Returns a list of classes with given Annotation
return db.getAnnotationIndex().get(className);
@ -142,7 +135,7 @@ public class AnnotationProcessor {
pathClazzMethods = pathClazz.getMethods();
Annotation rootContectAnno = clazz.getAnnotation(pathClazz);
String subContext = "";
String subContext;
if (rootContectAnno != null) {
subContext = invokeMethod(pathClazzMethods[0], rootContectAnno, STRING);
if (subContext != null && !subContext.isEmpty()) {
@ -151,8 +144,6 @@ public class AnnotationProcessor {
} else {
rootContext = rootContext + "/" + subContext;
}
} else {
subContext = "";
}
if (log.isDebugEnabled()) {
log.debug("API Root Context = " + rootContext);
@ -167,7 +158,7 @@ public class AnnotationProcessor {
}
}
} catch (ClassNotFoundException e) {
log.error("Error when passing the api annotation for device type apis.");
log.error("Error when passing the api annotation for device type apis.", e);
}
return apiResourceConfig;
}
@ -259,7 +250,7 @@ public class AnnotationProcessor {
scope.setKey(permissionConf.getScopeName());
scope.setDescription(permissionConf.getScopeName());
scope.setName(permissionConf.getScopeName());
String roles = StringUtils.join(permissionConf.getPermissions(), ",");
String roles = StringUtils.join(permissionConf.getRoles(), ",");
scope.setRoles(roles);
resource.setScope(scope);
}
@ -369,10 +360,10 @@ public class AnnotationProcessor {
case "scope":
permissionConf.setScopeName(invokeMethod(method, permissionAnnotation, STRING));
break;
case "permissions":
String permissions[] = invokeMethod(method, permissionAnnotation);
this.addPermission(permissions);
permissionConf.setPermissions(permissions);
case "roles":
String roles[] = invokeMethod(method, permissionAnnotation);
this.addPermission(roles);
permissionConf.setRoles(roles);
break;
}
}
@ -387,4 +378,29 @@ public class AnnotationProcessor {
}
}
/**
* Find the URL pointing to "/WEB-INF/classes" This method may not work in conjunction with IteratorFactory
* if your servlet container does not extract the /WEB-INF/classes into a real file-based directory
*
* @param servletContext
* @return null if cannot determin /WEB-INF/classes
*/
public static URL findWebInfClassesPath(ServletContext servletContext)
{
String path = servletContext.getRealPath("/WEB-INF/classes");
if (path == null) return null;
File fp = new File(path);
if (fp.exists() == false) return null;
try
{
URI uri = fp.toURI();
return uri.toURL();
}
catch (MalformedURLException e)
{
throw new RuntimeException(e);
}
}
}

@ -46,7 +46,7 @@ public interface CertificateMgtService {
message = "Internal Server Error. \n Error occurred while retrieving signed certificate.",
response = ErrorResponse.class)
})
@Permission(scope = "sign-csr", permissions = {"/permission/admin/device-mgt/scep/sign-csr"})
@Permission(scope = "sign-csr", roles = {"emm-admin"})
Response getSignedCertFromCSR(
@ApiParam(
name = "If-Modified-Since",

@ -72,7 +72,7 @@ public interface CertificateManagementAdminService {
message = "Internal Server Error. \n Server error occurred while adding certificates.",
response = ErrorResponse.class)
})
@Permission(scope = "certificate-modify", permissions = {"/permission/admin/device-mgt/certificate/save"})
@Permission(scope = "certificate-modify", roles = {"admin"})
Response addCertificate(
@ApiParam(
name = "enrollmentCertificates",
@ -130,7 +130,7 @@ public interface CertificateManagementAdminService {
"Server error occurred while retrieving information requested certificate.",
response = ErrorResponse.class)
})
@Permission(scope = "certificate-view", permissions = {"/permission/admin/device-mgt/certificate/view"})
@Permission(scope = "certificate-view", roles = {"emm-admin"})
Response getCertificate(
@ApiParam(name = "serialNumber",
value = "Provide the serial number of the certificate that you wish to get the details of",
@ -202,7 +202,7 @@ public interface CertificateManagementAdminService {
"Server error occurred while retrieving all certificates enrolled in the system.",
response = ErrorResponse.class)
})
@Permission(scope = "certificate-view", permissions = {"/permission/admin/device-mgt/certificate/view"})
@Permission(scope = "certificate-view", roles = {"emm-admin"})
Response getAllCertificates(
@ApiParam(
name = "offset",
@ -245,7 +245,7 @@ public interface CertificateManagementAdminService {
message = "Internal Server Error. \n " +
"Server error occurred while removing the certificate.",
response = ErrorResponse.class)})
@Permission(scope = "certificate-modify", permissions = {"/permission/admin/device-mgt/certificate/remove"})
@Permission(scope = "certificate-modify", roles = {"emm-admin"})
Response removeCertificate(
@ApiParam(
name = "serialNumber",

@ -46,7 +46,7 @@
<artifactId>maven-war-plugin</artifactId>
<configuration>
<packagingExcludes>WEB-INF/lib/*cxf*.jar</packagingExcludes>
<warName>api#device-mgt#v1.0</warName>
<warName>api-device-mgt-v1.0</warName>
</configuration>
</plugin>
</plugins>
@ -72,7 +72,7 @@
<tasks>
<copy todir="${basedir}/../../../repository/deployment/server/webapps" overwrite="true">
<fileset dir="${basedir}/target">
<include name="api#device-mgt#v1.0.war" />
<include name="api-device-mgt-v1.0.war" />
</fileset>
</copy>
</tasks>

@ -32,7 +32,7 @@ import javax.ws.rs.core.Response;
/**
* Activity related REST-API implementation.
*/
@API(name = "Activities", version = "1.0.0", context = "/devicemgt_admin/activities", tags = {"devicemgt_admin"})
@API(name = "Activity Info Provider", version = "1.0.0", context = "/api-device-mgt-v1.0/activities", tags = {"devicemgt_admin"})
@Path("/activities")
@Api(value = "Activity Info Provider", description = "Activity related information manipulation. For example operation details " +
@ -91,7 +91,7 @@ public interface ActivityInfoProviderService {
message = "Internal Server ErrorResponse. \n Server error occurred while fetching activity data.",
response = ErrorResponse.class)
})
@Permission(scope = "activity-view", permissions = {"/permission/admin/device-mgt/admin/activities/view"})
@Permission(scope = "activity-view", roles = {"emm-user", "emm-admin"})
Response getActivity(
@ApiParam(
name = "id",
@ -147,7 +147,7 @@ public interface ActivityInfoProviderService {
message = "Internal Server ErrorResponse. \n Server error occurred while fetching activity data.",
response = ErrorResponse.class)
})
@Permission(scope = "activity-view", permissions = {"/permission/admin/device-mgt/admin/activities/view"})
@Permission(scope = "activity-view", roles = {"emm-admin"})
Response getActivities(
@ApiParam(
name = "since",

@ -31,7 +31,7 @@ import javax.ws.rs.core.Response;
/**
* General Tenant Configuration REST-API.
*/
@API(name = "Configuration", version = "1.0.0", context = "/devicemgt_admin/configuration", tags = {"devicemgt_admin"})
@API(name = "Configuration Management", version = "1.0.0", context = "/api-device-mgt-v1.0/configuration", tags = {"devicemgt_admin"})
@Path("/configuration")
@Api(value = "Configuration Management", description = "General Tenant Configuration management capabilities are exposed " +
@ -78,8 +78,7 @@ public interface ConfigurationManagementService {
"platform configuration.",
response = ErrorResponse.class)
})
@Permission(scope = "configuration-view",
permissions = {"/permission/admin/device-mgt/admin/platform-configs/view"})
@Permission(scope = "configuration-view", roles = {"emm-admin"})
Response getConfiguration(
@ApiParam(
name = "If-Modified-Since",
@ -126,8 +125,7 @@ public interface ConfigurationManagementService {
"Server error occurred while modifying general platform configuration.",
response = ErrorResponse.class)
})
@Permission(scope = "configuration-modify",
permissions = {"/permission/admin/device-mgt/admin/platform-configs/modify"})
@Permission(scope = "configuration-modify", roles = {"emm-admin"})
Response updateConfiguration(
@ApiParam(
name = "configuration",

@ -37,7 +37,7 @@ import javax.ws.rs.core.Response;
/**
* Device related REST-API. This can be used to manipulated device related details.
*/
@API(name = "Device", version = "1.0.0", context = "/api/device-mgt/admin/devices", tags = {"devicemgt_admin"})
@API(name = "Device Management", version = "1.0.0", context = "/api-device-mgt-v1.0/devices", tags = {"devicemgt_admin"})
@Path("/devices")
@Api(value = "Device Management", description = "This API carries all device management related operations " +
@ -90,10 +90,7 @@ public interface DeviceManagementService {
message = "Internal Server ErrorResponse. \n Server error occurred while fetching the device list.",
response = ErrorResponse.class)
})
@Permission(
scope = "device-list",
permissions = {"/permission/admin/device-mgt/admin/devices/list"}
)
@Permission(scope = "device-list", roles = {"emm-admin"})
Response getDevices(
@ApiParam(
name = "type",
@ -197,13 +194,7 @@ public interface DeviceManagementService {
"Server error occurred while retrieving information requested device.",
response = ErrorResponse.class)
})
@Permission(
scope = "device-view",
permissions = {
"/permission/admin/device-mgt/admin/devices/view",
"/permission/admin/device-mgt/user/devices/view"
}
)
@Permission(scope = "device-view", roles = {"emm-admin"})
Response getDevice(
@ApiParam(
name = "type",
@ -283,12 +274,7 @@ public interface DeviceManagementService {
"Server error occurred while retrieving feature list of the device.",
response = ErrorResponse.class)
})
@Permission(
scope = "device-search",
permissions = {"/permission/admin/device-mgt/admin/devices/view",
"/permission/admin/device-mgt/user/devices/view"
}
)
@Permission(scope = "device-search", roles = {"emm-admin"})
Response getFeaturesOfDevice(
@ApiParam(
name = "type",
@ -362,10 +348,7 @@ public interface DeviceManagementService {
"Server error occurred while enrolling the device.",
response = ErrorResponse.class)
})
@Permission(
scope = "device-search",
permissions = {"/permission/admin/device-mgt/admin/devices/list" }
)
@Permission(scope = "device-search", roles = {"emm-admin" })
Response searchDevices(
@ApiParam(
name = "offset",
@ -445,13 +428,7 @@ public interface DeviceManagementService {
+ "the device.",
response = ErrorResponse.class)
})
@Permission(
scope = "operation-view",
permissions = {
"/permission/admin/device-mgt/admin/devices/view",
"/permission/admin/device-mgt/user/devices/view"
}
)
@Permission(scope = "operation-view", roles = {"emm-admin"})
Response getInstalledApplications(
@ApiParam(
name = "type",
@ -546,13 +523,7 @@ public interface DeviceManagementService {
+ "device.",
response = ErrorResponse.class)
})
@Permission(
scope = "operation-view",
permissions = {
"/permission/admin/device-mgt/admin/devices/view",
"/permission/admin/device-mgt/user/devices/view"
}
)
@Permission(scope = "operation-view", roles = {"emm-admin"})
Response getDeviceOperations(
@ApiParam(
name = "type",
@ -649,6 +620,7 @@ public interface DeviceManagementService {
response = ErrorResponse.class)
}
)
@Permission(scope = "operation-view", roles = {"emm-admin"})
Response getEffectivePolicyOfDevice(
@ApiParam(
name = "type",
@ -689,5 +661,6 @@ public interface DeviceManagementService {
message = "Error occurred while fetching the list of device types.")
}
)
@Permission(scope = "operation-view", roles = {"emm-admin"})
Response getDeviceTypes();
}

@ -34,7 +34,7 @@ import javax.ws.rs.core.Response;
/**
* Notifications related REST-API.
*/
@API(name = "Device Notification Management API", version = "1.0.0", context = "/devicemgt_admin/notifications",
@API(name = "Device Notification Management", version = "1.0.0", context = "/api-device-mgt-v1.0/notifications",
tags = {"devicemgt_admin"})
@Api(value = "Device Notification Management", description = "Device notification related operations can be found here.")
@Path("/notifications")
@ -89,12 +89,7 @@ public interface NotificationManagementService {
message = "Internal Server ErrorResponse. \n Server error occurred while fetching the notification list.",
response = ErrorResponse.class)
})
@Permission(
scope = "device-notification-view",
permissions = {
"/permission/admin/device-mgt/admin/notifications/view",
"/permission/admin/device-mgt/user/notifications/view"
})
@Permission(scope = "device-notification-view", roles = {"emm-admin"})
Response getNotifications(
@ApiParam(
name = "status",

@ -19,6 +19,7 @@
package org.wso2.carbon.device.mgt.jaxrs.service.api;
import io.swagger.annotations.*;
import org.wso2.carbon.apimgt.annotations.api.API;
import org.wso2.carbon.apimgt.annotations.api.Permission;
import org.wso2.carbon.device.mgt.jaxrs.beans.ErrorResponse;
import org.wso2.carbon.device.mgt.jaxrs.beans.PolicyWrapper;
@ -34,6 +35,9 @@ import java.util.List;
* Policy related REST-API. This can be used to manipulated policies and associate them with devices, users, roles,
* groups.
*/
@API(name = "Device Policy Management", version = "1.0.0", context = "/api-device-mgt-v1.0/policies",
tags = {"devicemgt_admin"})
@Api(value = "Device Policy Management", description = "This API carries all the necessary functionalities " +
"around device policy management")
@Path("/policies")
@ -94,9 +98,7 @@ public interface PolicyManagementService {
"Server error occurred while adding a new policy.",
response = ErrorResponse.class)
})
@Permission(
scope = "policy-modify",
permissions = {"/permission/admin/device-mgt/admin/policies/add"})
@Permission(scope = "policy-modify", roles = {"emm-admin"})
Response addPolicy(
@ApiParam(
name = "policy",
@ -149,9 +151,7 @@ public interface PolicyManagementService {
"policies."),
response = ErrorResponse.class)
})
@Permission(
scope = "policy-view",
permissions = {"/permission/admin/device-mgt/admin/policies/list"})
@Permission(scope = "policy-view", roles = {"emm-admin"})
Response getPolicies(
@ApiParam(
name = "If-Modified-Since",
@ -217,9 +217,7 @@ public interface PolicyManagementService {
"policy.",
response = ErrorResponse.class)
})
@Permission(
scope = "policy-view",
permissions = {"/permission/admin/device-mgt/admin/policies/list"})
@Permission(scope = "policy-view", roles = {"emm-admin"})
Response getPolicy(
@ApiParam(
name = "id",
@ -281,9 +279,7 @@ public interface PolicyManagementService {
"Server error occurred while updating the policy.",
response = ErrorResponse.class)
})
@Permission(
scope = "policy-modify",
permissions = {"/permission/admin/device-mgt/admin/policies/update"})
@Permission(scope = "policy-modify", roles = {"emm-admin"})
Response updatePolicy(
@ApiParam(
name = "id",
@ -328,9 +324,7 @@ public interface PolicyManagementService {
"Server error occurred while bulk removing policies.",
response = ErrorResponse.class)
})
@Permission(
scope = "policy-modify",
permissions = {"/permission/admin/device-mgt/admin/policies/remove"})
@Permission(scope = "policy-modify", roles = {"emm-admin"})
Response removePolicies(
@ApiParam(
name = "policyIds",
@ -366,10 +360,7 @@ public interface PolicyManagementService {
message = "ErrorResponse in activating policies.",
response = ErrorResponse.class)
})
@Permission(
scope = "policy-modify", permissions = {
"/permission/admin/device-mgt/admin/policies/update",
"/permission/admin/device-mgt/admin/policies/add"})
@Permission(scope = "policy-modify", roles = {"emm-admin"})
Response activatePolicies(
@ApiParam(
name = "policyIds",
@ -405,11 +396,7 @@ public interface PolicyManagementService {
message = "ErrorResponse in deactivating policies.",
response = ErrorResponse.class)
})
@Permission(
scope = "policy-modify",
permissions = {
"/permission/admin/device-mgt/admin/policies/update",
"/permission/admin/device-mgt/admin/policies/add"})
@Permission(scope = "policy-modify", roles = {"emm-admin"})
Response deactivatePolicies(
@ApiParam(
name = "policyIds",
@ -442,7 +429,7 @@ public interface PolicyManagementService {
message = "ErrorResponse in deactivating policies.",
response = ErrorResponse.class)
})
@Permission(scope = "policy-modify", permissions = {"/permission/admin/device-mgt/admin/policies/update"})
@Permission(scope = "policy-modify", roles = {"emm-admin"})
Response applyChanges();
@ -471,9 +458,7 @@ public interface PolicyManagementService {
message = "Exception in updating policy priorities.",
response = ErrorResponse.class)
})
@Permission(
scope = "",
permissions = {})
@Permission(scope = "policy-modify", roles = {"emm-admin"})
Response updatePolicyPriorities(
@ApiParam(
name = "priorityUpdatedPolicies",

@ -32,7 +32,7 @@ import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import java.util.List;
@API(name = "Role", version = "1.0.0", context = "/devicemgt_admin/roles", tags = {"devicemgt_admin"})
@API(name = "Role Management", version = "1.0.0", context = "/api-device-mgt-v1.0/roles", tags = {"devicemgt_admin"})
@Path("/roles")
@Api(value = "Role Management", description = "Role management related operations can be found here.")
@ -82,11 +82,7 @@ public interface RoleManagementService {
message = "Internal Server ErrorResponse. \n Server error occurred while fetching requested list of roles.",
response = ErrorResponse.class)
})
@Permission(scope = "roles-view", permissions = {
"/permission/admin/device-mgt/admin/roles/list",
"/permission/admin/device-mgt/admin/users/view",
"/permission/admin/device-mgt/admin/policies/add",
"/permission/admin/device-mgt/admin/policies/update"})
@Permission(scope = "roles-view", roles = {"emm-admin"})
Response getRoles(
@ApiParam(
name = "filter",
@ -167,7 +163,7 @@ public interface RoleManagementService {
message = "Internal Server ErrorResponse. \n Server error occurred while fetching the permission list of the requested role.",
response = ErrorResponse.class)
})
@Permission(scope = "roles-view", permissions = {"/permission/admin/device-mgt/admin/roles/list"})
@Permission(scope = "roles-view", roles = {"emm-admin"})
Response getPermissionsOfRole(
@ApiParam(
name = "roleName",
@ -229,7 +225,7 @@ public interface RoleManagementService {
"requested role.",
response = ErrorResponse.class)
})
@Permission(scope = "roles-view", permissions = {"/permission/admin/device-mgt/admin/roles/list"})
@Permission(scope = "roles-view", roles = {"emm-admin"})
Response getRole(
@ApiParam(
name = "roleName",
@ -289,7 +285,7 @@ public interface RoleManagementService {
"Server error occurred while adding a new role.",
response = ErrorResponse.class)
})
@Permission(scope = "roles-modify", permissions = {"/permission/admin/device-mgt/admin/roles/add"})
@Permission(scope = "roles-modify", roles = {"emm-admin"})
Response addRole(
@ApiParam(
name = "role",
@ -341,7 +337,7 @@ public interface RoleManagementService {
"Server error occurred while updating the role.",
response = ErrorResponse.class)
})
@Permission(scope = "roles-modify", permissions = {"/permission/admin/device-mgt/admin/roles/update"})
@Permission(scope = "roles-modify", roles = {"emm-admin"})
Response updateRole(
@ApiParam(
name = "roleName",
@ -378,7 +374,7 @@ public interface RoleManagementService {
"Server error occurred while removing the role.",
response = ErrorResponse.class)
})
@Permission(scope = "roles-modify", permissions = {"/permission/admin/device-mgt/admin/roles/remove"})
@Permission(scope = "roles-modify", roles = {"emm-admin"})
Response deleteRole(
@ApiParam(
name = "roleName",
@ -436,7 +432,7 @@ public interface RoleManagementService {
"Server error occurred while updating the user list of the role.",
response = ErrorResponse.class)
})
@Permission(scope = "roles-modify", permissions = {"/permission/admin/device-mgt/admin/roles/update"})
@Permission(scope = "roles-modify", roles = {"emm-admin"})
Response updateUsersOfRole(
@ApiParam(
name = "roleName",

@ -28,7 +28,7 @@ import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
@API(name = "User Management API", version = "1.0.0", context = "/devicemgt_admin/users", tags = {"devicemgt_admin"})
@API(name = "User Management", version = "1.0.0", context = "/api-device-mgt-v1.0/users", tags = {"devicemgt_admin"})
@Path("/users")
@Api(value = "User Management", description = "User management related operations can be found here.")
@ -87,7 +87,7 @@ public interface UserManagementService {
"Server error occurred while adding a new user.",
response = ErrorResponse.class)
})
@Permission(scope = "user-modify", permissions = {"/permission/admin/device-mgt/admin/user/add"})
@Permission(scope = "user-modify", roles = {"emm-admin"})
Response addUser(
@ApiParam(
name = "user",
@ -138,7 +138,7 @@ public interface UserManagementService {
" fetching the requested user.",
response = ErrorResponse.class)
})
@Permission(scope = "user-view", permissions = {"/permission/admin/device-mgt/admin/user/view"})
@Permission(scope = "user-view", roles = {"emm-admin"})
Response getUser(
@ApiParam(
name = "username",
@ -196,7 +196,7 @@ public interface UserManagementService {
"Server error occurred while updating the user.",
response = ErrorResponse.class)
})
@Permission(scope = "user-modify", permissions = {"/permission/admin/device-mgt/admin/user/update"})
@Permission(scope = "user-modify", roles = {"emm-admin"})
Response updateUser(
@ApiParam(
name = "username",
@ -231,7 +231,7 @@ public interface UserManagementService {
response = ErrorResponse.class
)
})
@Permission(scope = "user-modify", permissions = {"/permission/admin/device-mgt/admin/user/remove"})
@Permission(scope = "user-modify", roles = {"emm-admin"})
Response removeUser(
@ApiParam(name = "username", value = "Username of the user to be deleted.", required = true)
@PathParam("username") String username);
@ -279,7 +279,7 @@ public interface UserManagementService {
" assigned to the user.",
response = ErrorResponse.class)
})
@Permission(scope = "user-view", permissions = {"/permission/admin/device-mgt/admin/user/view"})
@Permission(scope = "user-view", roles = {"emm-admin"})
Response getRolesOfUser(
@ApiParam(name = "username", value = "Username of the user.", required = true)
@PathParam("username") String username);
@ -321,7 +321,7 @@ public interface UserManagementService {
message = "Internal Server ErrorResponse. \n Server error occurred while fetching the user list.",
response = ErrorResponse.class)
})
@Permission(scope = "user-view", permissions = {"/permission/admin/device-mgt/admin/user/list"})
@Permission(scope = "user-view", roles = {"emm-admin"})
Response getUsers(
@ApiParam(
name = "filter",
@ -387,7 +387,7 @@ public interface UserManagementService {
"list that matches the given filter.",
response = ErrorResponse.class)
})
@Permission(scope = "user-view", permissions = {"/permission/admin/device-mgt/admin/user/list"})
@Permission(scope = "user-view", roles = {"emm-admin"})
Response getUserNames(
@ApiParam(
name = "filter",
@ -439,7 +439,7 @@ public interface UserManagementService {
"Server error occurred while updating credentials of the user.",
response = ErrorResponse.class)
})
@Permission(scope = "user-modify", permissions = {"/permission/admin/login"})
@Permission(scope = "user-modify", roles = {"emm-admin"})
Response resetPassword(
@ApiParam(
name = "username",

@ -20,6 +20,7 @@ package org.wso2.carbon.device.mgt.jaxrs.service.api.admin;
import io.swagger.annotations.*;
import org.wso2.carbon.apimgt.annotations.api.API;
import org.wso2.carbon.apimgt.annotations.api.Permission;
import org.wso2.carbon.device.mgt.common.operation.mgt.Activity;
import org.wso2.carbon.device.mgt.jaxrs.beans.ApplicationWrapper;
import org.wso2.carbon.device.mgt.jaxrs.beans.ErrorResponse;
@ -31,7 +32,7 @@ import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
@API(name = "Application", version = "1.0.0", context = "/devicemgt_admin/applications", tags = {"devicemgt_admin"})
@API(name = "Application Management Admin", version = "1.0.0", context = "/api-device-mgt-v1.0/admin/applications", tags = {"devicemgt_admin"})
@Path("/admin/applications")
@Api(value = "Application Management Administrative Service", description = "This an API intended to be used by " +
@ -73,6 +74,7 @@ public interface ApplicationManagementAdminService {
"a given set of devices.",
response = ErrorResponse.class)
})
@Permission(scope = "application-modify", roles = {"emm-admin"})
Response installApplication(
@ApiParam(
name = "applicationWrapper",
@ -111,6 +113,7 @@ public interface ApplicationManagementAdminService {
"a given set of devices.",
response = ErrorResponse.class)
})
@Permission(scope = "application-modify", roles = {"emm-admin"})
Response uninstallApplication(
@ApiParam(
name = "applicationWrapper",

@ -20,6 +20,7 @@ package org.wso2.carbon.device.mgt.jaxrs.service.api.admin;
import io.swagger.annotations.*;
import org.wso2.carbon.apimgt.annotations.api.API;
import org.wso2.carbon.apimgt.annotations.api.Permission;
import org.wso2.carbon.device.mgt.common.Device;
import org.wso2.carbon.device.mgt.jaxrs.beans.ErrorResponse;
@ -27,7 +28,7 @@ import javax.ws.rs.*;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
@API(name = "DeviceManagementAdmin", version = "1.0.0", context = "/devicemgt_admin/applications",
@API(name = "Device Management Admin", version = "1.0.0", context = "/api-device-mgt-v1.0/admin/devices",
tags = {"devicemgt_admin"})
@Path("/admin/devices")
@Api(value = "Device Management Administrative Service", description = "This an API intended to be used by " +
@ -83,6 +84,7 @@ public interface DeviceManagementAdminService {
message = "Internal Server ErrorResponse. \n Server error occurred while fetching the device list.",
response = ErrorResponse.class)
})
@Permission(scope = "device-view", roles = {"emm-admin"})
Response getDevicesByName(
@ApiParam(
name = "name",

@ -19,6 +19,7 @@
package org.wso2.carbon.device.mgt.jaxrs.service.api.admin;
import io.swagger.annotations.*;
import org.wso2.carbon.apimgt.annotations.api.API;
import org.wso2.carbon.apimgt.annotations.api.Permission;
import org.wso2.carbon.device.mgt.jaxrs.beans.ErrorResponse;
import org.wso2.carbon.device.mgt.jaxrs.beans.PasswordResetWrapper;
@ -27,6 +28,8 @@ import javax.ws.rs.*;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
@API(name = "User Management Admin", version = "1.0.0", context = "/api-device-mgt-v1.0/admin/users", tags = {"devicemgt_admin"})
@Path("/admin/users")
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
@ -64,7 +67,7 @@ public interface UserManagementAdminService {
"Server error occurred while updating credentials of the user.",
response = ErrorResponse.class)
})
@Permission(scope = "user-modify", permissions = {"/permission/admin/login"})
@Permission(scope = "user-modify", roles = {"emm-admin"})
Response resetUserPassword(
@ApiParam(
name = "username",

@ -24,47 +24,25 @@ import javax.xml.bind.annotation.XmlRootElement;
/**
* This class represents the information related to permission.
*/
@XmlRootElement (name = "Permission")
public class Permission {
private String name; // permission name
private String path; // permission string
private String url; // url of the resource
private String urlTemplate; // resource template
private String method; // http method
private String scope; //scope of the resource
private String context;
public String getName() {
return name;
public String getContext() {
return context;
}
@XmlElement (name = "name", required = true)
public void setName(String name) {
this.name = name;
public void setContext(String context) {
this.context = context;
}
public String getPath() {
return path;
}
@XmlElement (name = "path", required = true)
public void setPath(String path) {
this.path = path;
}
public String getScope() {
return scope;
}
@XmlElement(name = "scope", required = false)
public void setScope(String scope) {
this.scope = scope;
}
public String getUrl() {
return url;
}
@XmlElement (name = "url", required = true)
public void setUrl(String url) {
this.url = url;
}
@ -73,8 +51,15 @@ public class Permission {
return method;
}
@XmlElement (name = "method", required = true)
public void setMethod(String method) {
this.method = method;
}
public String getUrlTemplate() {
return urlTemplate;
}
public void setUrlTemplate(String urlTemplate) {
this.urlTemplate = urlTemplate;
}
}

@ -29,11 +29,10 @@ public interface PermissionManagerService {
/**
*
* @param permission - Permission to be added
* @return The status of the operation.
* @throws PermissionManagementException If some unusual behaviour is observed while adding the
* permission.
*/
boolean addPermission(Permission permission) throws PermissionManagementException;
void addPermission(Permission permission) throws PermissionManagementException;
/**
*

@ -91,6 +91,10 @@
!org.wso2.carbon.device.mgt.core.internal,
org.wso2.carbon.device.mgt.core.*
</Export-Package>
<Embed-Dependency>
javax.ws.rs-api,
scribe;scope=compile|runtime;inline=false;
</Embed-Dependency>
<DynamicImport-Package>*</DynamicImport-Package>
</instructions>
</configuration>
@ -228,6 +232,7 @@
<groupId>commons-collections.wso2</groupId>
<artifactId>commons-collections</artifactId>
</dependency>
<dependency>
<groupId>org.wso2.carbon.devicemgt</groupId>
<artifactId>org.wso2.carbon.email.sender.core</artifactId>
@ -236,15 +241,12 @@
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.34</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>1.7.1</version>
</dependency>
<dependency>
@ -253,6 +255,26 @@
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.wso2.orbit.org.scannotation</groupId>
<artifactId>scannotation</artifactId>
</dependency>
<dependency>
<groupId>org.wso2.carbon.devicemgt</groupId>
<artifactId>org.wso2.carbon.apimgt.annotations</artifactId>
</dependency>
<dependency>
<groupId>javax.ws.rs</groupId>
<artifactId>javax.ws.rs-api</artifactId>
</dependency>
<dependency>
<groupId>javax.ws.rs</groupId>
<artifactId>jsr311-api</artifactId>
</dependency>
</dependencies>
</project>

@ -248,9 +248,7 @@ public class DeviceAccessAuthorizationServiceImpl implements DeviceAccessAuthori
}
private boolean addAdminPermissionToRegistry() throws PermissionManagementException {
Permission permission = new Permission();
permission.setPath(PermissionUtils.getAbsolutePermissionPath(CDM_ADMIN_PERMISSION));
return PermissionUtils.putPermission(permission);
return PermissionUtils.putPermission(PermissionUtils.getAbsolutePermissionPath(CDM_ADMIN_PERMISSION));
}
private Map<String, String> getOwnershipOfDevices(List<Device> devices) {

@ -0,0 +1,332 @@
/*
* Copyright (c) 2015, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
*
* WSO2 Inc. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.wso2.carbon.device.mgt.core.config.permission;
import org.apache.catalina.core.StandardContext;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.scannotation.AnnotationDB;
import org.wso2.carbon.apimgt.annotations.api.API;
import javax.servlet.ServletContext;
import javax.ws.rs.*;
import java.io.File;
import java.io.IOException;
import java.lang.annotation.Annotation;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URL;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.StringTokenizer;
public class AnnotationProcessor {
private static final Log log = LogFactory.getLog(AnnotationProcessor.class);
private static final String PACKAGE_ORG_APACHE = "org.apache";
private static final String PACKAGE_ORG_CODEHAUS = "org.codehaus";
private static final String PACKAGE_ORG_SPRINGFRAMEWORK = "org.springframework";
private static final String WILD_CARD = "/*";
private static final String URL_SEPARATOR = "/";
private static final String STRING_ARR = "string_arr";
private static final String STRING = "string";
private Method[] pathClazzMethods;
private Class<Path> pathClazz;
Class<API> apiClazz;
private ClassLoader classLoader;
private ServletContext servletContext;
public AnnotationProcessor(final StandardContext context) {
servletContext = context.getServletContext();
classLoader = servletContext.getClassLoader();
}
/**
* Scan the context for classes with annotations
*
* @return
* @throws IOException
*/
public Set<String> scanStandardContext(String className) throws IOException {
AnnotationDB db = new AnnotationDB();
db.addIgnoredPackages(PACKAGE_ORG_APACHE);
db.addIgnoredPackages(PACKAGE_ORG_CODEHAUS);
db.addIgnoredPackages(PACKAGE_ORG_SPRINGFRAMEWORK);
URL classPath = findWebInfClassesPath(servletContext);
db.scanArchives(classPath);
//Returns a list of classes with given Annotation
return db.getAnnotationIndex().get(className);
}
/**
* Method identifies the URL templates and context by reading the annotations of a class
*
* @param entityClasses
* @return
*/
public List<org.wso2.carbon.device.mgt.common.permission.mgt.Permission>
extractPermissions(Set<String> entityClasses) {
List<org.wso2.carbon.device.mgt.common.permission.mgt.Permission> permissions = new ArrayList<>();
if (entityClasses != null && !entityClasses.isEmpty()) {
for (final String className : entityClasses) {
List<org.wso2.carbon.device.mgt.common.permission.mgt.Permission> resourcePermissions =
AccessController.doPrivileged(new PrivilegedAction<List<org.wso2.carbon.device.mgt.common.permission.mgt.Permission>>() {
public List<org.wso2.carbon.device.mgt.common.permission.mgt.Permission> run() {
Class<?> clazz;
List<org.wso2.carbon.device.mgt.common.permission.mgt.Permission> apiPermissions =
new ArrayList<>();
try {
clazz = classLoader.loadClass(className);
apiClazz = (Class<API>)
classLoader.loadClass(org.wso2.carbon.apimgt.annotations.api.API
.class.getName());
Annotation apiAnno = clazz.getAnnotation(apiClazz);
List<org.wso2.carbon.device.mgt.common.permission.mgt.Permission> resourceList;
if (apiAnno != null) {
if (log.isDebugEnabled()) {
log.debug("Application Context root = " + servletContext.getContextPath());
}
try {
String rootContext = servletContext.getContextPath();
pathClazz = (Class<Path>) classLoader.loadClass(Path.class.getName());
pathClazzMethods = pathClazz.getMethods();
Annotation rootContectAnno = clazz.getAnnotation(pathClazz);
String subContext = "";
if (rootContectAnno != null) {
subContext = invokeMethod(pathClazzMethods[0], rootContectAnno, STRING);
if (subContext != null && !subContext.isEmpty()) {
if (subContext.trim().startsWith("/")) {
rootContext = rootContext + subContext;
} else {
rootContext = rootContext + "/" + subContext;
}
}
if (log.isDebugEnabled()) {
log.debug("API Root Context = " + rootContext);
}
}
Method[] annotatedMethods = clazz.getDeclaredMethods();
apiPermissions = getApiResources(rootContext, annotatedMethods);
} catch (Throwable throwable) {
log.error("Error encountered while scanning for annotations", throwable);
}
}
} catch (ClassNotFoundException e) {
log.error("Error when passing the api annotation for device type apis.");
}
return apiPermissions;
}
});
permissions.addAll(resourcePermissions);
}
}
return permissions;
}
/**
* Get Resources for each API
*
* @param resourceRootContext
* @param annotatedMethods
* @return
* @throws Throwable
*/
private List<org.wso2.carbon.device.mgt.common.permission.mgt.Permission>
getApiResources(String resourceRootContext, Method[] annotatedMethods) throws Throwable {
List<org.wso2.carbon.device.mgt.common.permission.mgt.Permission> permissions = new ArrayList<>();
String subCtx;
for (Method method : annotatedMethods) {
Annotation[] annotations = method.getDeclaredAnnotations();
org.wso2.carbon.device.mgt.common.permission.mgt.Permission permission =
new org.wso2.carbon.device.mgt.common.permission.mgt.Permission();
if (isHttpMethodAvailable(annotations)) {
Annotation methodContextAnno = method.getAnnotation(pathClazz);
if (methodContextAnno != null) {
subCtx = invokeMethod(pathClazzMethods[0], methodContextAnno, STRING);
} else {
subCtx = WILD_CARD;
}
permission.setContext(makeContextURLReady(resourceRootContext));
permission.setUrlTemplate(makeContextURLReady(subCtx));
// this check is added to avoid url resolving conflict which happens due
// to adding of '*' notation for dynamic path variables.
if (WILD_CARD.equals(subCtx)) {
subCtx = makeContextURLReady(resourceRootContext);
} else {
subCtx = makeContextURLReady(resourceRootContext) + makeContextURLReady(subCtx);
}
permission.setUrl(replaceDynamicPathVariables(subCtx));
String httpMethod;
for (int i = 0; i < annotations.length; i++) {
httpMethod = getHTTPMethodAnnotation(annotations[i]);
if (httpMethod != null) {
permission.setMethod(httpMethod);
break;
}
}
permissions.add(permission);
}
}
return permissions;
}
/**
* Read Method annotations indicating HTTP Methods
* @param annotation
*/
private String getHTTPMethodAnnotation(Annotation annotation) {
if (annotation.annotationType().getName().equals(GET.class.getName())) {
return HttpMethod.GET;
} else if (annotation.annotationType().getName().equals(POST.class.getName())) {
return HttpMethod.POST;
} else if (annotation.annotationType().getName().equals(OPTIONS.class.getName())) {
return HttpMethod.OPTIONS;
} else if (annotation.annotationType().getName().equals(DELETE.class.getName())) {
return HttpMethod.DELETE;
} else if (annotation.annotationType().getName().equals(PUT.class.getName())) {
return HttpMethod.PUT;
}
return null;
}
private boolean isHttpMethodAvailable(Annotation[] annotations) {
for (Annotation annotation : annotations) {
if (annotation.annotationType().getName().equals(GET.class.getName())) {
return true;
} else if (annotation.annotationType().getName().equals(POST.class.getName())) {
return true;
} else if (annotation.annotationType().getName().equals(OPTIONS.class.getName())) {
return true;
} else if (annotation.annotationType().getName().equals(DELETE.class.getName())) {
return true;
} else if (annotation.annotationType().getName().equals(PUT.class.getName())) {
return true;
}
}
return false;
}
/**
* Append '/' to the context and make it URL ready
*
* @param context
* @return
*/
private String makeContextURLReady(String context) {
if (context != null && ! context.isEmpty()) {
if (context.startsWith("/")) {
return context;
} else {
return "/" + context;
}
}
return "";
}
/**
* When an annotation and method is passed, this method invokes that executes said method against the annotation
*
* @param method
* @param annotation
* @param returnType
* @return
* @throws Throwable
*/
private String invokeMethod(Method method, Annotation annotation, String returnType) throws Throwable {
InvocationHandler methodHandler = Proxy.getInvocationHandler(annotation);
switch (returnType) {
case STRING:
return (String) methodHandler.invoke(annotation, method, null);
case STRING_ARR:
return ((String[]) methodHandler.invoke(annotation, method, null))[0];
default:
return null;
}
}
/**
* Find the URL pointing to "/WEB-INF/classes" This method may not work in conjunction with IteratorFactory
* if your servlet container does not extract the /WEB-INF/classes into a real file-based directory
*
* @param servletContext
* @return null if cannot determin /WEB-INF/classes
*/
public static URL findWebInfClassesPath(ServletContext servletContext)
{
String path = servletContext.getRealPath("/WEB-INF/classes");
if (path == null) return null;
File fp = new File(path);
if (fp.exists() == false) return null;
try
{
URI uri = fp.toURI();
return uri.toURL();
}
catch (MalformedURLException e)
{
throw new RuntimeException(e);
}
}
private String replaceDynamicPathVariables(String path) {
StringBuilder replacedPath = new StringBuilder();
StringTokenizer st = new StringTokenizer(path, URL_SEPARATOR);
String currentToken;
while (st.hasMoreTokens()) {
currentToken = st.nextToken();
if (currentToken.charAt(0) == '{') {
if (currentToken.charAt(currentToken.length() - 1) == '}') {
replacedPath.append(WILD_CARD);
}
} else {
replacedPath.append(URL_SEPARATOR);
replacedPath.append(currentToken);
}
}
return replacedPath.toString();
}
}

@ -25,29 +25,27 @@ import javax.xml.bind.annotation.XmlRootElement;
import java.util.List;
/**
* This class represents the information related to permission configuration.
* This class represents the information related to permissions.
*/
@XmlRootElement (name = "PermissionConfiguration")
public class PermissionConfiguration {
private List<Permission> permissions;
private String apiVersion;
private String scopeName;
private String[] permissions;
public String getApiVersion() {
return apiVersion;
public String getScopeName() {
return scopeName;
}
@XmlElement (name = "APIVersion", required = true)
public void setApiVersion(String apiVersion) {
this.apiVersion = apiVersion;
public void setScopeName(String scope) {
this.scopeName = scope;
}
public List<Permission> getPermissions() {
public String[] getPermissions() {
return permissions;
}
@XmlElement (name = "Permission", required = true)
public void setPermissions(List<Permission> permissions) {
public void setPermissions(String[] permissions) {
this.permissions = permissions;
}
}

@ -26,6 +26,8 @@ import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.wso2.carbon.device.mgt.common.permission.mgt.Permission;
import org.wso2.carbon.device.mgt.common.permission.mgt.PermissionManagementException;
import org.wso2.carbon.device.mgt.common.permission.mgt.PermissionManagerService;
import org.wso2.carbon.device.mgt.core.config.permission.AnnotationProcessor;
import org.wso2.carbon.device.mgt.core.config.permission.PermissionConfiguration;
import org.wso2.carbon.device.mgt.core.permission.mgt.PermissionManagerServiceImpl;
import org.wso2.carbon.device.mgt.core.permission.mgt.PermissionUtils;
@ -35,8 +37,10 @@ import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Unmarshaller;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
import java.util.Set;
/**
* This listener class will initiate the permission addition of permissions defined in
@ -45,7 +49,8 @@ import java.util.List;
@SuppressWarnings("unused")
public class WebAppDeploymentLifecycleListener implements LifecycleListener {
private static final String PERMISSION_CONFIG_PATH = "META-INF" + File.separator + "permissions.xml";
private static final String PARAM_MANAGED_API_ENABLED = "managed-api-enabled";
private static final Log log = LogFactory.getLog(WebAppDeploymentLifecycleListener.class);
@Override
@ -54,34 +59,27 @@ public class WebAppDeploymentLifecycleListener implements LifecycleListener {
StandardContext context = (StandardContext) lifecycleEvent.getLifecycle();
ServletContext servletContext = context.getServletContext();
String contextPath = context.getServletContext().getContextPath();
try {
InputStream permissionStream = servletContext.getResourceAsStream(PERMISSION_CONFIG_PATH);
if (permissionStream != null) {
/* Un-marshaling Device Management configuration */
JAXBContext cdmContext = JAXBContext.newInstance(PermissionConfiguration.class);
Unmarshaller unmarshaller = cdmContext.createUnmarshaller();
PermissionConfiguration permissionConfiguration = (PermissionConfiguration)
unmarshaller.unmarshal(permissionStream);
List<Permission> permissions = permissionConfiguration.getPermissions();
String apiVersion = permissionConfiguration.getApiVersion();
if (permissionConfiguration != null && permissions != null) {
String param = servletContext.getInitParameter(PARAM_MANAGED_API_ENABLED);
boolean isManagedApi = (param != null && !param.isEmpty()) && Boolean.parseBoolean(param);
if (isManagedApi) {
try {
AnnotationProcessor annotationProcessor = new AnnotationProcessor(context);
Set<String> annotatedAPIClasses = annotationProcessor.
scanStandardContext(org.wso2.carbon.apimgt.annotations.api.API.class.getName());
List<Permission> permissions = annotationProcessor.extractPermissions(annotatedAPIClasses);
PermissionManagerService permissionManagerService = PermissionManagerServiceImpl.getInstance();
if (permissions != null) {
for (Permission permission : permissions) {
// update the permission path to absolute permission path
permission.setPath(PermissionUtils.getAbsolutePermissionPath(permission.getPath()));
permission.setUrl(PermissionUtils.getAbsoluteContextPathOfAPI(contextPath, apiVersion,
permission.getUrl()).toLowerCase());
permission.setMethod(permission.getMethod().toUpperCase());
PermissionManagerServiceImpl.getInstance().addPermission(permission);
permissionManagerService.addPermission(permission);
}
}
} catch (PermissionManagementException e) {
log.error("Exception occurred while adding the permissions from webapp : "
+ servletContext.getContextPath(), e);
} catch (IOException e) {
log.error("Cannot find API annotation Class in the webapp '" + contextPath + "' class path", e);
}
} catch (JAXBException e) {
log.error(
"Exception occurred while parsing the permission configuration of webapp : "
+ context.getServletContext().getContextPath(), e);
} catch (PermissionManagementException e) {
log.error("Exception occurred while adding the permissions from webapp : "
+ servletContext.getContextPath(), e);
}
}

@ -22,8 +22,9 @@ import org.wso2.carbon.device.mgt.common.permission.mgt.Permission;
import org.wso2.carbon.device.mgt.common.permission.mgt.PermissionManagementException;
import org.wso2.carbon.device.mgt.common.permission.mgt.PermissionManagerService;
import java.util.List;
import java.util.HashSet;
import java.util.Properties;
import java.util.Set;
/**
* This class will add, update custom permissions defined in permission.xml in webapps and it will
@ -52,10 +53,9 @@ public class PermissionManagerServiceImpl implements PermissionManagerService {
}
@Override
public boolean addPermission(Permission permission) throws PermissionManagementException {
public void addPermission(Permission permission) throws PermissionManagementException {
// adding a permission to the tree
permissionTree.addPermission(permission);
return PermissionUtils.putPermission(permission);
}
@Override

@ -54,9 +54,6 @@ public class PermissionTree {
tempRoot = addPermissionNode(tempRoot, tempChild);
}
tempRoot.addPermission(permission.getMethod(), permission); //setting permission to the vertex
if (log.isDebugEnabled()) {
log.debug("Added permission '" + permission.getName() + "'");
}
}
/**

@ -39,95 +39,93 @@ import java.util.StringTokenizer;
*/
public class PermissionUtils {
public static final String ADMIN_PERMISSION_REGISTRY_PATH = "/permission/admin";
public static final String PERMISSION_PROPERTY_NAME = "name";
public static final String ADMIN_PERMISSION_REGISTRY_PATH = "/permission/admin";
public static final String PERMISSION_PROPERTY_NAME = "name";
public static Registry getGovernanceRegistry() throws PermissionManagementException {
try {
int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId();
return DeviceManagementDataHolder.getInstance().getRegistryService()
.getGovernanceSystemRegistry(
tenantId);
} catch (RegistryException e) {
throw new PermissionManagementException(
"Error in retrieving governance registry instance: " +
e.getMessage(), e);
}
}
public static Registry getGovernanceRegistry() throws PermissionManagementException {
try {
int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId();
return DeviceManagementDataHolder.getInstance().getRegistryService()
.getGovernanceSystemRegistry(
tenantId);
} catch (RegistryException e) {
throw new PermissionManagementException(
"Error in retrieving governance registry instance: " +
e.getMessage(), e);
}
}
public static String getAbsolutePermissionPath(String permissionPath) {
return PermissionUtils.ADMIN_PERMISSION_REGISTRY_PATH + permissionPath;
}
public static String getAbsolutePermissionPath(String permissionPath) {
return PermissionUtils.ADMIN_PERMISSION_REGISTRY_PATH + permissionPath;
}
public static String getAbsoluteContextPathOfAPI(String contextPath, String version, String url) {
if((version != null) && !version.isEmpty()) {
return contextPath + "/" + version + url;
if ((version != null) && !version.isEmpty()) {
return contextPath + "/" + version + url;
}
return contextPath + url;
}
public static Permission getPermission(String path) throws PermissionManagementException {
try {
Resource resource = PermissionUtils.getGovernanceRegistry().get(path);
Permission permission = new Permission();
permission.setName(resource.getProperty(PERMISSION_PROPERTY_NAME));
permission.setPath(resource.getPath());
return permission;
} catch (RegistryException e) {
throw new PermissionManagementException("Error in retrieving registry resource : " +
e.getMessage(), e);
}
}
public static boolean putPermission(Permission permission)
throws PermissionManagementException {
boolean status;
try {
StringTokenizer tokenizer = new StringTokenizer(permission.getPath(), "/");
String lastToken = "", currentToken, tempPath;
while(tokenizer.hasMoreTokens()) {
currentToken = tokenizer.nextToken();
tempPath = lastToken + "/" + currentToken;
if(!checkResourceExists(tempPath)) {
// public static Permission getPermission(String path) throws PermissionManagementException {
// try {
// Resource resource = PermissionUtils.getGovernanceRegistry().get(path);
// Permission permission = new Permission();
// permission.setName(resource.getProperty(PERMISSION_PROPERTY_NAME));
// permission.setPath(resource.getPath());
// return permission;
// } catch (RegistryException e) {
// throw new PermissionManagementException("Error in retrieving registry resource : " +
// e.getMessage(), e);
// }
// }
//
public static boolean putPermission(String permissionPath)
throws PermissionManagementException {
boolean status;
try {
StringTokenizer tokenizer = new StringTokenizer(permissionPath, "/");
String lastToken = "", currentToken, tempPath;
while (tokenizer.hasMoreTokens()) {
currentToken = tokenizer.nextToken();
tempPath = lastToken + "/" + currentToken;
if (!checkResourceExists(tempPath)) {
createRegistryCollection(tempPath, currentToken);
}
lastToken = tempPath;
}
status = true;
} catch (RegistryException e) {
throw new PermissionManagementException(
"Error occurred while persisting permission : " +
permission.getName(), e);
}
return status;
}
}
lastToken = tempPath;
}
status = true;
} catch (RegistryException e) {
throw new PermissionManagementException("Error occurred while persisting permission", e);
}
return status;
}
public static void createRegistryCollection(String path, String resourceName)
throws PermissionManagementException,
RegistryException {
Resource resource = PermissionUtils.getGovernanceRegistry().newCollection();
resource.addProperty(PERMISSION_PROPERTY_NAME, resourceName);
PermissionUtils.getGovernanceRegistry().beginTransaction();
PermissionUtils.getGovernanceRegistry().put(path, resource);
PermissionUtils.getGovernanceRegistry().commitTransaction();
}
public static void createRegistryCollection(String path, String resourceName)
throws PermissionManagementException,
RegistryException {
Resource resource = PermissionUtils.getGovernanceRegistry().newCollection();
resource.addProperty(PERMISSION_PROPERTY_NAME, resourceName);
PermissionUtils.getGovernanceRegistry().beginTransaction();
PermissionUtils.getGovernanceRegistry().put(path, resource);
PermissionUtils.getGovernanceRegistry().commitTransaction();
}
public static boolean checkResourceExists(String path)
throws PermissionManagementException,
org.wso2.carbon.registry.core.exceptions.RegistryException {
return PermissionUtils.getGovernanceRegistry().resourceExists(path);
}
public static boolean checkResourceExists(String path)
throws PermissionManagementException,
org.wso2.carbon.registry.core.exceptions.RegistryException {
return PermissionUtils.getGovernanceRegistry().resourceExists(path);
}
public static Document convertToDocument(File file) throws PermissionManagementException {
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
factory.setNamespaceAware(true);
try {
DocumentBuilder docBuilder = factory.newDocumentBuilder();
return docBuilder.parse(file);
} catch (Exception e) {
throw new PermissionManagementException("Error occurred while parsing file, while converting " +
"to a org.w3c.dom.Document", e);
}
}
public static Document convertToDocument(File file) throws PermissionManagementException {
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
factory.setNamespaceAware(true);
try {
DocumentBuilder docBuilder = factory.newDocumentBuilder();
return docBuilder.parse(file);
} catch (Exception e) {
throw new PermissionManagementException("Error occurred while parsing file, while converting " +
"to a org.w3c.dom.Document", e);
}
}
}

@ -87,11 +87,11 @@ public class PermissionBasedScopeValidator extends OAuth2ScopeValidator {
if (userRealm != null && userRealm.getAuthorizationManager() != null) {
if (userStore != null) {
status = userRealm.getAuthorizationManager()
.isUserAuthorized(userStore + "/" + username, permission.getPath(),
.isUserAuthorized(userStore + "/" + username, permission.getUrl(),
PermissionMethod.UI_EXECUTE);
} else {
status = userRealm.getAuthorizationManager()
.isUserAuthorized(username, permission.getPath(), PermissionMethod.UI_EXECUTE);
.isUserAuthorized(username, permission.getUrl(), PermissionMethod.UI_EXECUTE);
}
}
}

@ -23,6 +23,10 @@ import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.wso2.carbon.base.MultitenantConstants;
import org.wso2.carbon.context.PrivilegedCarbonContext;
import org.wso2.carbon.device.mgt.common.permission.mgt.Permission;
import org.wso2.carbon.device.mgt.common.permission.mgt.PermissionManagementException;
import org.wso2.carbon.device.mgt.common.permission.mgt.PermissionManagerService;
import org.wso2.carbon.device.mgt.core.permission.mgt.PermissionManagerServiceImpl;
import org.wso2.carbon.identity.core.util.IdentityTenantUtil;
import org.wso2.carbon.user.api.TenantManager;
import org.wso2.carbon.user.api.UserStoreException;
@ -30,9 +34,17 @@ import org.wso2.carbon.user.core.service.RealmService;
import org.wso2.carbon.utils.multitenancy.MultitenantUtils;
import org.wso2.carbon.webapp.authenticator.framework.AuthenticationException;
import java.util.Properties;
public class Utils {
private static final Log log = LogFactory.getLog(Utils.class);
private static PermissionManagerService permissionManagerService = PermissionManagerServiceImpl.getInstance();
private static Properties properties;
private static Permission permission;
public static final String URL_PROPERTY = "URL";
public static final String HTTP_METHOD_PROPERTY = "HTTP_METHOD";
public static int getTenantIdOFUser(String username) throws AuthenticationException {
int tenantId = 0;
@ -74,4 +86,15 @@ public class Utils {
}
}
public static String getResourceUri(String url, String httpMethod) throws PermissionManagementException {
properties = new Properties();
properties.put(URL_PROPERTY, url);
properties.put(HTTP_METHOD_PROPERTY, httpMethod);
permission = permissionManagerService.getPermission(properties);
if (permission != null) {
return permission.getContext() + "/1.0.0/1.0.0" + permission.getUrlTemplate() + ":" + permission.getMethod();
}
return null;
}
}

@ -23,6 +23,7 @@ import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.tomcat.util.buf.ByteChunk;
import org.apache.tomcat.util.buf.MessageBytes;
import org.wso2.carbon.device.mgt.common.permission.mgt.PermissionManagementException;
import org.wso2.carbon.webapp.authenticator.framework.AuthenticationException;
import org.wso2.carbon.webapp.authenticator.framework.AuthenticationFrameworkUtil;
import org.wso2.carbon.webapp.authenticator.framework.AuthenticationInfo;
@ -105,7 +106,7 @@ public class OAuthAuthenticator implements WebappAuthenticator {
StringTokenizer tokenizer = new StringTokenizer(requestUri, "/");
String context = tokenizer.nextToken();
if ((context == null) || ("".equals(context))) {
if ((context == null) || (context.isEmpty())) {
authenticationInfo.setStatus(WebappAuthenticator.Status.CONTINUE);
}
String apiVersion = tokenizer.nextToken();
@ -120,7 +121,17 @@ public class OAuthAuthenticator implements WebappAuthenticator {
} else {
String bearerToken = getBearerToken(request);
String resource = requestUri + ":" + requestMethod;
int urlParamIndex = requestUri.indexOf('?');
if(urlParamIndex > 0) {
requestUri = requestUri.substring(0, urlParamIndex);
}
String resource = Utils.getResourceUri(requestUri, requestMethod);
if (resource == null || resource.isEmpty()) {
authenticationInfo.setStatus(Status.FAILURE);
authenticationInfo.setMessage("Requested resource does not exist");
return authenticationInfo;
}
OAuthValidationResponse oAuthValidationResponse =
this.tokenValidator.validateToken(bearerToken, resource);
@ -142,6 +153,8 @@ public class OAuthAuthenticator implements WebappAuthenticator {
log.error("Failed to authenticate the incoming request", e);
} catch (OAuthTokenValidationException e) {
log.error("Failed to authenticate the incoming request due to oauth token validation error.", e);
} catch (PermissionManagementException e) {
log.error("Failed to authenticate the incoming request due to error in permission initialization", e);
}
return authenticationInfo;
}

@ -42,56 +42,7 @@ public class PermissionAuthorizer {
public WebappAuthenticator.Status authorize(Request request, Response response) {
String requestUri = request.getRequestURI();
String requestMethod = request.getMethod();
if (requestUri == null || requestUri.isEmpty() || requestMethod == null || requestMethod.isEmpty()) {
return WebappAuthenticator.Status.CONTINUE;
}
PermissionManagerServiceImpl registryBasedPermissionManager = PermissionManagerServiceImpl.getInstance();
Properties properties = new Properties();
properties.put("",requestUri);
properties.put("",requestMethod);
Permission requestPermission = null;
try {
requestPermission = registryBasedPermissionManager.getPermission(properties);
} catch (PermissionManagementException e) {
log.error(
"Error occurred while fetching the permission for URI : " + Encode.forJava(requestUri) + " ," +
" METHOD : " + requestMethod + ", msg = " + e.getMessage());
}
if (requestPermission == null) {
if (log.isDebugEnabled()) {
log.debug("Permission to request '" + Encode.forJava(requestUri) + "' is not defined in the configuration");
}
return WebappAuthenticator.Status.FAILURE;
}
String permissionString = requestPermission.getPath();
// This is added temporarily until authentication works.
// TODO remove below line.
String username = "admin";
// TODO uncomment this once the authentication works.
//String username = CarbonContext.getThreadLocalCarbonContext().getUsername();
boolean isUserAuthorized;
try {
isUserAuthorized = CarbonContext.getThreadLocalCarbonContext().getUserRealm().
getAuthorizationManager().isUserAuthorized(username, permissionString,
Constants.PermissionMethod.READ);
} catch (UserStoreException e) {
log.error("Error occurred while retrieving user store. " + e.getMessage());
return WebappAuthenticator.Status.FAILURE;
}
if (isUserAuthorized) {
return WebappAuthenticator.Status.SUCCESS;
} else {
return WebappAuthenticator.Status.FAILURE;
}
return WebappAuthenticator.Status.SUCCESS;
}
}

@ -57,7 +57,7 @@
<outputDirectory>
${project.build.directory}/maven-shared-archive-resources/webapps
</outputDirectory>
<destFileName>api#device-mgt#v1.0.war</destFileName>
<destFileName>api-device-mgt-v1.0.war</destFileName>
</artifactItem>
</artifactItems>
</configuration>

@ -1,3 +1,3 @@
instructions.configure = \
org.eclipse.equinox.p2.touchpoint.natives.mkdir(path:${installFolder}/../../deployment/server/webapps/);\
org.eclipse.equinox.p2.touchpoint.natives.copy(source:${installFolder}/../features/org.wso2.carbon.device.mgt.api_${feature.version}/webapps/api#device-mgt#v1.0.war,target:${installFolder}/../../deployment/server/webapps/api#device-mgt#v1.0.war,overwrite:true);\
org.eclipse.equinox.p2.touchpoint.natives.copy(source:${installFolder}/../features/org.wso2.carbon.device.mgt.api_${feature.version}/webapps/api-device-mgt-v1.0.war,target:${installFolder}/../../deployment/server/webapps/api-device-mgt-v1.0.war,overwrite:true);\
Loading…
Cancel
Save