Merge branch 'master' of https://github.com/wso2/carbon-device-mgt into transport

revert-70aa11f8
ayyoob 9 years ago
commit cd6a5aad6f

@ -42,12 +42,12 @@ import javax.ws.rs.core.Response;
public class ApiApplicationRegistrationServiceImpl implements ApiApplicationRegistrationService {
private static final Log log = LogFactory.getLog(ApiApplicationRegistrationServiceImpl.class);
@Path("register/tenants/{tenantDomain}")
@Path("register/tenants")
@POST
public Response register(@PathParam("tenantDomain") String tenantDomain,
public Response register(@QueryParam("tenantDomain") String tenantDomain,
@QueryParam("applicationName") String applicationName) {
String authenticatedTenantDomain = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantDomain();
if (authenticatedTenantDomain.equals(MultitenantConstants.SUPER_TENANT_DOMAIN_NAME)) {
if (!authenticatedTenantDomain.equals(MultitenantConstants.SUPER_TENANT_DOMAIN_NAME)) {
return Response.status(Response.Status.NOT_ACCEPTABLE).build();
}
try {

@ -21,7 +21,7 @@ import java.util.List;
/**
* this filter check for permission for the request
*/
public class ApiPermissionFilter implements Filter{
public class ApiPermissionFilter implements Filter {
private static final Log log = LogFactory.getLog(ApiPermissionFilter.class);
private static final String UI_EXECUTE = "ui.execute";
private static final String PERMISSION_CONFIG_PATH = File.separator + "META-INF" + File.separator
@ -53,16 +53,9 @@ public class ApiPermissionFilter implements Filter{
if (servletRequest instanceof HttpServletRequest) {
String uri = ((HttpServletRequest)servletRequest).getRequestURI();
boolean status = false;
if (uri.contains("register/tenants")) {
String urlPermission = getPermission("/register/tenants/*");
if (urlPermission != null) {
status = isUserAuthorized(PERMISSION_PREFIX + urlPermission, UI_EXECUTE);
}
} else {
String urlPermission = getPermission(uri);
if (urlPermission != null) {
status = isUserAuthorized(PERMISSION_PREFIX + urlPermission, UI_EXECUTE);
}
String urlPermission = getPermission(uri);
if (urlPermission != null) {
status = isUserAuthorized(PERMISSION_PREFIX + urlPermission, UI_EXECUTE);
}
if (status) {
filterChain.doFilter(servletRequest, servletResponse);

@ -31,7 +31,7 @@
<Permission>
<name>Register tenant specific application</name>
<path>/device-mgt/admin</path>
<url>/register/tenants/*</url>
<url>/register/tenants</url>
<method>POST</method>
<scope>super_admin_user</scope>
</Permission>

@ -63,6 +63,10 @@
<groupId>com.googlecode.json-simple.wso2</groupId>
<artifactId>json-simple</artifactId>
</dependency>
<dependency>
<groupId>org.wso2.carbon.registry</groupId>
<artifactId>org.wso2.carbon.registry.indexing</artifactId>
</dependency>
</dependencies>
<build>
@ -103,7 +107,9 @@
org.wso2.carbon.utils.multitenancy,
org.json.simple,
org.wso2.carbon.context,
org.wso2.carbon.base
org.wso2.carbon.base,
org.wso2.carbon.registry.core.*;resolution:=optional,
org.wso2.carbon.registry.indexing.*; version="${carbon.registry.imp.pkg.version.range}"
</Import-Package>
<Export-Package>
!org.wso2.carbon.apimgt.application.extension.internal,

@ -35,6 +35,7 @@ import org.wso2.carbon.apimgt.application.extension.exception.APIManagerExceptio
import org.wso2.carbon.apimgt.application.extension.util.APIManagerUtil;
import org.wso2.carbon.apimgt.impl.APIConstants;
import org.wso2.carbon.apimgt.impl.APIManagerFactory;
import org.wso2.carbon.registry.core.exceptions.RegistryException;
import org.wso2.carbon.utils.multitenancy.MultitenantConstants;
import org.wso2.carbon.utils.multitenancy.MultitenantUtils;
@ -57,6 +58,7 @@ public class APIManagementProviderServiceImpl implements APIManagementProviderSe
String username, boolean isAllowedAllDomains)
throws APIManagerException {
try {
APIManagerUtil.loadTenantRegistry();
APIConsumer apiConsumer = APIManagerFactory.getInstance().getAPIConsumer(username);
String groupId = getLoggedInUserGroupId(username, APIManagerUtil.getTenantDomain());
int applicationId = createApplicationAndSubscribeToAllAPIs(apiApplicationName, username);
@ -121,6 +123,7 @@ public class APIManagementProviderServiceImpl implements APIManagementProviderSe
boolean isAllowedAllDomains, String keyType)
throws APIManagerException {
try {
APIManagerUtil.loadTenantRegistry();
APIConsumer apiConsumer = APIManagerFactory.getInstance().getAPIConsumer(username);
if (apiConsumer != null) {
String groupId = getLoggedInUserGroupId(username, APIManagerUtil.getTenantDomain());
@ -177,6 +180,7 @@ public class APIManagementProviderServiceImpl implements APIManagementProviderSe
@Override
public void removeAPIApplication(String applicationName, String username) throws APIManagerException {
try {
APIManagerUtil.loadTenantRegistry();
APIConsumer apiConsumer = APIManagerFactory.getInstance().getAPIConsumer(username);
if (apiConsumer != null) {
String groupId = getLoggedInUserGroupId(username, APIManagerUtil.getTenantDomain());
@ -203,6 +207,7 @@ public class APIManagementProviderServiceImpl implements APIManagementProviderSe
boolean isAllowedAllDomains)
throws APIManagerException {
try {
APIManagerUtil.loadTenantRegistry();
APIConsumer apiConsumer = APIManagerFactory.getInstance().getAPIConsumer(username);
String groupId = getLoggedInUserGroupId(username, APIManagerUtil.getTenantDomain());
int applicationId = createApplicationAndSubscribeToAPIs(apiApplicationName, tags, username);
@ -405,6 +410,9 @@ public class APIManagementProviderServiceImpl implements APIManagementProviderSe
int applicationId = createApplication(apiConsumer, apiApplicationName, username, groupId);
String tenantDomain = MultitenantUtils.getTenantDomain(username);
Set<API> userVisibleAPIs = apiConsumer.getAllPublishedAPIs(tenantDomain);
if (!tenantDomain.equals(MultitenantConstants.SUPER_TENANT_DOMAIN_NAME)) {
userVisibleAPIs.addAll(apiConsumer.getAllPublishedAPIs(MultitenantConstants.SUPER_TENANT_DOMAIN_NAME));
}
Subscriber subscriber = apiConsumer.getSubscriber(username);
Set<SubscribedAPI> subscribedAPIs = apiConsumer.getSubscribedAPIs(subscriber);
for (API visibleApi : userVisibleAPIs) {
@ -441,4 +449,5 @@ public class APIManagementProviderServiceImpl implements APIManagementProviderSe
throw new APIManagerException("Unable to get groupIds of user " + username, e);
}
}
}

@ -18,6 +18,8 @@
package org.wso2.carbon.apimgt.application.extension.internal;
import org.wso2.carbon.apimgt.application.extension.APIManagementProviderService;
import org.wso2.carbon.registry.core.service.TenantRegistryLoader;
import org.wso2.carbon.registry.indexing.service.TenantIndexingLoader;
import org.wso2.carbon.user.core.service.RealmService;
import org.wso2.carbon.user.core.tenant.TenantManager;
@ -26,6 +28,8 @@ public class APIApplicationManagerExtensionDataHolder {
private APIManagementProviderService apiManagementProviderService;
private RealmService realmService;
private TenantManager tenantManager;
private TenantRegistryLoader tenantRegistryLoader;
private TenantIndexingLoader indexLoader;
private APIApplicationManagerExtensionDataHolder() {
}
@ -66,4 +70,20 @@ public class APIApplicationManagerExtensionDataHolder {
public TenantManager getTenantManager() {
return tenantManager;
}
public void setTenantRegistryLoader(TenantRegistryLoader tenantRegistryLoader){
this.tenantRegistryLoader = tenantRegistryLoader;
}
public TenantRegistryLoader getTenantRegistryLoader(){
return tenantRegistryLoader;
}
public void setIndexLoaderService(TenantIndexingLoader indexLoader) {
this.indexLoader = indexLoader;
}
public TenantIndexingLoader getIndexLoaderService(){
return indexLoader;
}
}

@ -23,10 +23,24 @@ import org.osgi.framework.BundleContext;
import org.osgi.service.component.ComponentContext;;
import org.wso2.carbon.apimgt.application.extension.APIManagementProviderService;
import org.wso2.carbon.apimgt.application.extension.APIManagementProviderServiceImpl;
import org.wso2.carbon.registry.core.service.TenantRegistryLoader;
import org.wso2.carbon.registry.indexing.service.TenantIndexingLoader;
import org.wso2.carbon.user.core.service.RealmService;
/**
* @scr.component name="org.wso2.carbon.apimgt.application.extension.internal.APIApplicationManagerExtensionServiceComponent"
* @scr.reference name="tenant.registryloader"
* interface="org.wso2.carbon.registry.core.service.TenantRegistryLoader"
* cardinality="1..1"
* policy="dynamic"
* bind="setTenantRegistryLoader"
* unbind="unsetTenantRegistryLoader"
* @scr.reference name="tenant.indexloader"
* interface="org.wso2.carbon.registry.indexing.service.TenantIndexingLoader"
* cardinality="1..1"
* policy="dynamic"
* bind="setIndexLoader"
* unbind="unsetIndexLoader"
* @scr.reference name="realm.service"
* immediate="true"
* interface="org.wso2.carbon.user.core.service.RealmService"
@ -53,6 +67,25 @@ public class APIApplicationManagerExtensionServiceComponent {
//do nothing
}
protected void setTenantRegistryLoader(TenantRegistryLoader tenantRegistryLoader) {
APIApplicationManagerExtensionDataHolder.getInstance().setTenantRegistryLoader(tenantRegistryLoader);
}
protected void unsetTenantRegistryLoader(TenantRegistryLoader tenantRegistryLoader) {
APIApplicationManagerExtensionDataHolder.getInstance().setTenantRegistryLoader(null);
}
protected void setIndexLoader(TenantIndexingLoader indexLoader) {
if (indexLoader != null && log.isDebugEnabled()) {
log.debug("IndexLoader service initialized");
}
APIApplicationManagerExtensionDataHolder.getInstance().setIndexLoaderService(indexLoader);
}
protected void unsetIndexLoader(TenantIndexingLoader indexLoader) {
APIApplicationManagerExtensionDataHolder.getInstance().setIndexLoaderService(null);
}
/**
* Sets Realm Service.
*

@ -23,6 +23,8 @@ import org.wso2.carbon.apimgt.application.extension.exception.APIManagerExceptio
import org.wso2.carbon.apimgt.application.extension.internal.APIApplicationManagerExtensionDataHolder;
import org.wso2.carbon.base.MultitenantConstants;
import org.wso2.carbon.context.PrivilegedCarbonContext;
import org.wso2.carbon.registry.core.exceptions.RegistryException;
import org.wso2.carbon.registry.core.service.TenantRegistryLoader;
import org.wso2.carbon.user.api.TenantManager;
import org.wso2.carbon.user.api.UserStoreException;
@ -52,4 +54,18 @@ public final class APIManagerUtil {
public static String getTenantDomain() {
return PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantDomain();
}
public static void loadTenantRegistry() throws APIManagerException {
String tenantDomain = getTenantDomain();
try {
int tenantId = getTenantId(tenantDomain);
TenantRegistryLoader tenantRegistryLoader =
APIApplicationManagerExtensionDataHolder.getInstance().getTenantRegistryLoader();
APIApplicationManagerExtensionDataHolder.getInstance().getIndexLoaderService().loadTenantIndex(tenantId);
tenantRegistryLoader.loadTenantRegistry(tenantId);
} catch (RegistryException e) {
throw new APIManagerException("Error occured while loading registry for tenant '" + tenantDomain + "'");
}
}
}

@ -289,8 +289,7 @@ public class APIPublisherUtil {
apiConfig.setTransports(transports);
String sharingValueParam = servletContext.getInitParameter(PARAM_SHARED_WITH_ALL_TENANTS);
boolean isSharedWithAllTenants = (sharingValueParam == null || (!sharingValueParam.isEmpty())
&& Boolean.parseBoolean(sharingValueParam));
boolean isSharedWithAllTenants = Boolean.parseBoolean(sharingValueParam);
apiConfig.setSharedWithAllTenants(isSharedWithAllTenants);
Set<URITemplate> uriTemplates = new LinkedHashSet<>();

@ -31,7 +31,7 @@
<modelVersion>4.0.0</modelVersion>
<artifactId>org.wso2.carbon.certificate.mgt.api</artifactId>
<packaging>war</packaging>
<name>WSO2 Carbon - Mobile Device Management API</name>
<name>WSO2 Carbon - Certificate Management API</name>
<description>WSO2 Carbon - Certificate Management API</description>
<url>http://wso2.org</url>

@ -13,7 +13,7 @@ public interface CertificateMgtService {
* @return X509Certificate type sign certificate.
*/
@POST
@Path("csr-sign")
@Path("signcsr")
@Produces({MediaType.TEXT_PLAIN, MediaType.TEXT_PLAIN})
@Consumes({MediaType.TEXT_PLAIN, MediaType.TEXT_PLAIN})
Response getSignedCertFromCSR(String binarySecurityToken);

@ -8,10 +8,7 @@ import org.wso2.carbon.certificate.mgt.core.impl.CertificateGenerator;
import org.wso2.carbon.certificate.mgt.jaxrs.api.CertificateMgtService;
import org.wso2.carbon.certificate.mgt.jaxrs.exception.Message;
import javax.ws.rs.Consumes;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.*;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import java.security.cert.CertificateEncodingException;

@ -0,0 +1,209 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
~ Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
~
~ WSO2 Inc. licenses this file to you under the Apache License,
~ Version 2.0 (the "License"); you may not use this file except
~ in compliance with the License.
~ You may obtain a copy of the License at
~
~ http://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing,
~ software distributed under the License is distributed on an
~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
~ KIND, either express or implied. See the License for the
~ specific language governing permissions and limitations
~ under the License.
-->
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<parent>
<artifactId>certificate-mgt</artifactId>
<groupId>org.wso2.carbon.devicemgt</groupId>
<version>1.1.1-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>org.wso2.carbon.certificate.mgt.cert.admin.api</artifactId>
<packaging>war</packaging>
<name>WSO2 Carbon - Admin Certificate Management API</name>
<description>WSO2 Carbon - Admin Certificate Management API</description>
<url>http://wso2.org</url>
<build>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.7</source>
<target>1.7</target>
</configuration>
</plugin>
<plugin>
<artifactId>maven-war-plugin</artifactId>
<configuration>
<packagingExcludes>WEB-INF/lib/*cxf*.jar</packagingExcludes>
<warName>admin-certificate</warName>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-scr-plugin</artifactId>
</plugin>
</plugins>
</build>
<profiles>
<profile>
<id>deploy</id>
<build>
<defaultGoal>compile</defaultGoal>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-antrun-plugin</artifactId>
<version>1.7</version>
<executions>
<execution>
<phase>compile</phase>
<goals>
<goal>run</goal>
</goals>
<configuration>
<tasks>
<copy todir="${basedir}/../../../repository/deployment/server/webapps"
overwrite="true">
<fileset dir="${basedir}/target">
<include name="admin-certificate.war"/>
</fileset>
</copy>
</tasks>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
<profile>
<id>client</id>
<build>
<defaultGoal>test</defaultGoal>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>1.2.1</version>
<executions>
<execution>
<phase>test</phase>
<goals>
<goal>java</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
</profiles>
<dependencies>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-frontend-jaxws</artifactId>
</dependency>
<dependency>
<groupId>commons-codec.wso2</groupId>
<artifactId>commons-codec</artifactId>
<exclusions>
<exclusion>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-frontend-jaxrs</artifactId>
</dependency>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-transports-http</artifactId>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>javax.ws.rs</groupId>
<artifactId>jsr311-api</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.wso2.carbon</groupId>
<artifactId>org.wso2.carbon.logging</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.wso2.carbon.devicemgt</groupId>
<artifactId>org.wso2.carbon.device.mgt.common</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.wso2.carbon.devicemgt</groupId>
<artifactId>org.wso2.carbon.device.mgt.core</artifactId>
<scope>provided</scope>
<exclusions>
<exclusion>
<groupId>org.apache.axis2.wso2</groupId>
<artifactId>axis2-client</artifactId>
</exclusion>
<exclusion>
<groupId>org.apache.neethi.wso2</groupId>
<artifactId>neethi</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.wso2.carbon.devicemgt</groupId>
<artifactId>org.wso2.carbon.certificate.mgt.core</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>io.swagger</groupId>
<artifactId>swagger-annotations</artifactId>
</dependency>
<dependency>
<groupId>io.swagger</groupId>
<artifactId>swagger-core</artifactId>
<exclusions>
<exclusion>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>io.swagger</groupId>
<artifactId>swagger-jaxrs</artifactId>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.wso2.carbon.devicemgt</groupId>
<artifactId>org.wso2.carbon.apimgt.annotations</artifactId>
<scope>provided</scope>
</dependency>
</dependencies>
</project>

@ -0,0 +1,123 @@
package org.wso2.carbon.certificate.mgt.cert.jaxrs.api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import io.swagger.annotations.ApiResponse;
import io.swagger.annotations.ApiResponses;
import org.wso2.carbon.apimgt.annotations.api.Permission;
import org.wso2.carbon.certificate.mgt.cert.jaxrs.api.beans.EnrollmentCertificate;
import org.wso2.carbon.certificate.mgt.cert.jaxrs.api.common.MDMAPIException;
import org.wso2.carbon.certificate.mgt.core.dto.CertificateResponse;
import org.wso2.carbon.device.mgt.common.PaginationResult;
import javax.ws.rs.*;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
public interface Certificate {
/**
* Save a list of certificates and relevant information in the database.
*
* @param enrollmentCertificates List of all the certificates which includes the tenant id, certificate as
* a pem and a serial number.
* @return Status of the data persist operation.
*/
@POST
@ApiOperation(
consumes = MediaType.APPLICATION_JSON + ", " + MediaType.APPLICATION_XML,
produces = MediaType.APPLICATION_JSON + ", " + MediaType.APPLICATION_XML,
httpMethod = "POST",
value = "Adding an SSL Certificate",
notes = "Add a new SSL certificate to the client end database")
@ApiResponses(value = {
@ApiResponse(code = 200, message = "Added successfully"),
@ApiResponse(code = 500, message = "Error occurred while saving the certificate")
})
@Permission(scope = "certificate-modify", permissions = {"/permission/admin/device-mgt/certificate/save"})
Response saveCertificate(@HeaderParam("Accept") String acceptHeader,
@ApiParam(name = "enrollmentCertificates", value = "certificate with serial, "
+ "pem and tenant id", required = true) EnrollmentCertificate[]
enrollmentCertificates);
/**
* Get a certificate when the serial number is given.
*
* @param serialNumber serial of the certificate needed.
* @return certificate response.
*/
@GET
@Path("{serialNumber}")
@ApiOperation(
consumes = MediaType.APPLICATION_JSON + ", " + MediaType.APPLICATION_XML,
produces = MediaType.APPLICATION_JSON + ", " + MediaType.APPLICATION_XML,
httpMethod = "GET",
value = "Getting Details of an SSL Certificate",
notes = "Get the client side SSL certificate details",
response = CertificateResponse.class)
@ApiResponses(value = {
@ApiResponse(code = 200, message = "OK", response = CertificateResponse.class),
@ApiResponse(code = 400, message = "Notification status updated successfully"),
@ApiResponse(code = 500, message = "Error occurred while converting PEM file to X509Certificate")
})
@Permission(scope = "certificate-view", permissions = {"/permission/admin/device-mgt/certificate/view"})
Response getCertificate(@HeaderParam("Accept") String acceptHeader,
@ApiParam(name = "serialNumber", value = "Provide the serial number of the "
+ "certificate that you wish to get the details of", required = true)
@PathParam("serialNumber") String serialNumber);
/**
* Get all certificates in a paginated manner.
*
* @param startIndex index of the first record to be fetched
* @param length number of records to be fetched starting from the start index.
* @return paginated result of certificate.
* @throws MDMAPIException
*/
@GET
@Path("paginate")
@ApiOperation(
consumes = MediaType.APPLICATION_JSON + ", " + MediaType.APPLICATION_XML,
produces = MediaType.APPLICATION_JSON + ", " + MediaType.APPLICATION_XML,
httpMethod = "GET",
value = "Getting the Certificate Details in a Paginated Manner",
notes = "You will have many certificates used for mutual SSL. In a situation where you wish to "
+ "view all the certificate details, it is not feasible to show all the details on one "
+ "page therefore the details are paginated",
response = PaginationResult.class)
@ApiResponses(value = {
@ApiResponse(code = 200, message = "OK", response = PaginationResult.class),
@ApiResponse(code = 400, message = "Invalid start index"),
@ApiResponse(code = 400, message = "Invalid length value"),
@ApiResponse(code = 500, message = "Error occurred while fetching all certificates")
})
@Permission(scope = "certificate-view", permissions = {"/permission/admin/device-mgt/certificate/view"})
Response getAllCertificates(@HeaderParam("Accept") String acceptHeader,
@ApiParam(name = "start",
value = "Provide the starting pagination index as the value", required = true)
@QueryParam("start") int startIndex,
@ApiParam(name = "length", value = "Provide how many certificate details you"
+ " require from the starting pagination index as the value",
required = true) @QueryParam("length") int length) throws MDMAPIException;
@DELETE
@Path("{serialNumber}")
@ApiOperation(
consumes = MediaType.APPLICATION_JSON + ", " + MediaType.APPLICATION_XML,
produces = MediaType.APPLICATION_JSON + ", " + MediaType.APPLICATION_XML,
httpMethod = "DELETE",
value = "Deleting an SSL Certificate",
notes = "Delete an SSL certificate that's on the client end",
response = boolean.class)
@ApiResponses(value = {
@ApiResponse(code = 200, message = "OK"),
@ApiResponse(code = 400, message = "Invalid start index"),
@ApiResponse(code = 500, message = "Error when deleting the certificate"
) })
@Permission(scope = "certificate-modify", permissions = {"/permission/admin/device-mgt/certificate/remove"})
Response removeCertificate(@HeaderParam("Accept") String acceptHeader,
@ApiParam(name = "serialNumber", value = "Provide the serial number of the "
+ "certificate that you wish to delete", required = true)
@PathParam("serialNumber") String serialNumber) throws MDMAPIException;
}

@ -0,0 +1,34 @@
package org.wso2.carbon.certificate.mgt.cert.jaxrs.api.beans;
/**
* Created by hasunie on 5/26/16.
*/
public class EnrollmentCertificate {
String serial;
String pem;
int tenantId;
public int getTenantId() {
return tenantId;
}
public void setTenantId(int tenantId) {
this.tenantId = tenantId;
}
public String getSerial() {
return serial;
}
public void setSerial(String serial) {
this.serial = serial;
}
public String getPem() {
return pem;
}
public void setPem(String pem) {
this.pem = pem;
}
}

@ -0,0 +1,33 @@
/*
* Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
*
* WSO2 Inc. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.wso2.carbon.certificate.mgt.cert.jaxrs.api.common;
import javax.ws.rs.Produces;
import javax.ws.rs.core.Response;
import javax.ws.rs.ext.ExceptionMapper;
@Produces({ "application/json", "application/xml" })
public class ErrorHandler implements ExceptionMapper<MDMAPIException> {
public Response toResponse(MDMAPIException exception) {
ErrorMessage errorMessage = new ErrorMessage();
errorMessage.setErrorMessage(exception.getErrorMessage());
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(errorMessage).build();
}
}

@ -0,0 +1,42 @@
/*
* Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
*
* WSO2 Inc. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.wso2.carbon.certificate.mgt.cert.jaxrs.api.common;
public class ErrorMessage {
private String errorMessage;
private String errorCode;
public String getErrorMessage() {
return errorMessage;
}
public void setErrorMessage(String errorMessage) {
this.errorMessage = errorMessage;
}
public String getErrorCode() {
return errorCode;
}
public void setErrorCode(String errorCode) {
this.errorCode = errorCode;
}
}

@ -0,0 +1,95 @@
/*
* Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
*
* WSO2 Inc. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.wso2.carbon.certificate.mgt.cert.jaxrs.api.common;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import javax.ws.rs.Consumes;
import javax.ws.rs.Produces;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.MultivaluedMap;
import javax.ws.rs.ext.MessageBodyReader;
import javax.ws.rs.ext.MessageBodyWriter;
import javax.ws.rs.ext.Provider;
import java.io.*;
import java.lang.annotation.Annotation;
import java.lang.reflect.Type;
import static javax.ws.rs.core.MediaType.APPLICATION_JSON;
@Provider
@Produces(APPLICATION_JSON)
@Consumes(APPLICATION_JSON)
public class GsonMessageBodyHandler implements MessageBodyWriter<Object>, MessageBodyReader<Object> {
private Gson gson;
private static final String UTF_8 = "UTF-8";
public boolean isReadable(Class<?> aClass, Type type, Annotation[] annotations, MediaType mediaType) {
return true;
}
private Gson getGson() {
if (gson == null) {
final GsonBuilder gsonBuilder = new GsonBuilder();
gson = gsonBuilder.create();
}
return gson;
}
public Object readFrom(Class<Object> objectClass, Type type, Annotation[] annotations, MediaType mediaType,
MultivaluedMap<String, String> stringStringMultivaluedMap, InputStream entityStream)
throws IOException, WebApplicationException {
InputStreamReader reader = new InputStreamReader(entityStream, "UTF-8");
try {
return getGson().fromJson(reader, type);
} finally {
reader.close();
}
}
public boolean isWriteable(Class<?> aClass, Type type, Annotation[] annotations, MediaType mediaType) {
return true;
}
public long getSize(Object o, Class<?> aClass, Type type, Annotation[] annotations, MediaType mediaType) {
return -1;
}
public void writeTo(Object object, Class<?> aClass, Type type, Annotation[] annotations, MediaType mediaType,
MultivaluedMap<String, Object> stringObjectMultivaluedMap, OutputStream entityStream)
throws IOException, WebApplicationException {
OutputStreamWriter writer = new OutputStreamWriter(entityStream, UTF_8);
try {
Type jsonType = null;
if (type.equals(type)) {
jsonType = type;
}
getGson().toJson(object, jsonType, writer);
} finally {
writer.close();
}
}
}

@ -0,0 +1,59 @@
/*
* Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
*
* WSO2 Inc. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.wso2.carbon.certificate.mgt.cert.jaxrs.api.common;
/**
* Custom exception class for handling CDM API related exceptions.
*/
public class MDMAPIException extends Exception {
private static final long serialVersionUID = 7950151650447893900L;
private String errorMessage;
public String getErrorMessage() {
return errorMessage;
}
public void setErrorMessage(String errorMessage) {
this.errorMessage = errorMessage;
}
public MDMAPIException(String msg, Exception e) {
super(msg, e);
setErrorMessage(msg);
}
public MDMAPIException(String msg, Throwable cause) {
super(msg, cause);
setErrorMessage(msg);
}
public MDMAPIException(String msg) {
super(msg);
setErrorMessage(msg);
}
public MDMAPIException() {
super();
}
public MDMAPIException(Throwable cause) {
super(cause);
}
}

@ -0,0 +1,31 @@
/*
* Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
*
* WSO2 Inc. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.wso2.carbon.certificate.mgt.cert.jaxrs.api.exception;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
public class BadRequestException extends WebApplicationException {
public BadRequestException(Message message, MediaType mediaType) {
super(Response.status(Response.Status.BAD_REQUEST).entity(message).type(mediaType).build());
}
}

@ -0,0 +1,41 @@
/*
* Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
*
* WSO2 Inc. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.wso2.carbon.certificate.mgt.cert.jaxrs.api.exception;
public class Message {
private String errorMessage;
private String discription;
public String getErrorMessage() {
return errorMessage;
}
public void setErrorMessage(String errorMessage) {
this.errorMessage = errorMessage;
}
public String getDiscription() {
return discription;
}
public void setDiscription(String discription) {
this.discription = discription;
}
}

@ -0,0 +1,181 @@
package org.wso2.carbon.certificate.mgt.cert.jaxrs.api.impl;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.wso2.carbon.certificate.mgt.cert.jaxrs.api.Certificate;
import org.wso2.carbon.certificate.mgt.cert.jaxrs.api.beans.EnrollmentCertificate;
import org.wso2.carbon.certificate.mgt.cert.jaxrs.api.common.MDMAPIException;
import org.wso2.carbon.certificate.mgt.cert.jaxrs.api.exception.Message;
import org.wso2.carbon.certificate.mgt.cert.jaxrs.api.util.DeviceMgtAPIUtils;
import org.wso2.carbon.certificate.mgt.core.dao.CertificateManagementDAOException;
import org.wso2.carbon.certificate.mgt.core.dto.CertificateResponse;
import org.wso2.carbon.certificate.mgt.core.exception.KeystoreException;
import org.wso2.carbon.certificate.mgt.core.service.CertificateManagementService;
import org.wso2.carbon.context.PrivilegedCarbonContext;
import org.wso2.carbon.device.mgt.common.PaginationRequest;
import org.wso2.carbon.device.mgt.common.PaginationResult;
import javax.ws.rs.*;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import java.util.ArrayList;
import java.util.List;
public class CertificateImpl implements Certificate {
private static Log log = LogFactory.getLog(CertificateImpl.class);
/**
* Save a list of certificates and relevant information in the database.
*
* @param enrollmentCertificates List of all the certificates which includes the tenant id, certificate as
* a pem and a serial number.
* @return Status of the data persist operation.
*/
@POST
public Response saveCertificate(@HeaderParam("Accept") String acceptHeader,
EnrollmentCertificate[] enrollmentCertificates) {
MediaType responseMediaType = DeviceMgtAPIUtils.getResponseMediaType(acceptHeader);
CertificateManagementService certificateService;
List<org.wso2.carbon.certificate.mgt.core.bean.Certificate> certificates = new ArrayList<>();
org.wso2.carbon.certificate.mgt.core.bean.Certificate certificate;
certificateService = DeviceMgtAPIUtils.getCertificateManagementService();
try {
for (EnrollmentCertificate enrollmentCertificate : enrollmentCertificates) {
certificate = new org.wso2.carbon.certificate.mgt.core.bean.Certificate();
certificate.setTenantId(PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId());
certificate.setSerial(enrollmentCertificate.getSerial());
certificate.setCertificate(certificateService.pemToX509Certificate(enrollmentCertificate.getPem()));
certificates.add(certificate);
}
certificateService.saveCertificate(certificates);
return Response.status(Response.Status.CREATED).entity("Added successfully.").
type(responseMediaType).build();
} catch (KeystoreException e) {
String msg = "Error occurred while converting PEM file to X509Certificate.";
log.error(msg, e);
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).type(responseMediaType).build();
}
}
/**
* Get a certificate when the serial number is given.
*
* @param serialNumber serial of the certificate needed.
* @return certificate response.
*/
@GET
@Path("{serialNumber}")
public Response getCertificate(@HeaderParam("Accept") String acceptHeader,
@PathParam("serialNumber") String serialNumber) {
MediaType responseMediaType = DeviceMgtAPIUtils.getResponseMediaType(acceptHeader);
Message message = new Message();
if (serialNumber == null || serialNumber.isEmpty()) {
message.setErrorMessage("Invalid serial number");
message.setDiscription("Serial number is missing or invalid.");
return Response.status(Response.Status.BAD_REQUEST).entity(message).type(responseMediaType).build();
}
CertificateManagementService certificateService = DeviceMgtAPIUtils.getCertificateManagementService();
List<CertificateResponse> certificateResponse;
try {
certificateResponse = certificateService.searchCertificates(serialNumber);
return Response.status(Response.Status.OK).entity(certificateResponse).type(responseMediaType).build();
} catch (CertificateManagementDAOException e) {
String msg = "Error occurred while converting PEM file to X509Certificate";
log.error(msg, e);
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).type(responseMediaType).build();
}
}
/**
* Get all certificates in a paginated manner.
*
* @param startIndex index of the first record to be fetched
* @param length number of records to be fetched starting from the start index.
* @return paginated result of certificate.
* @throws MDMAPIException
*/
@GET
@Path("paginate")
public Response getAllCertificates(@HeaderParam("Accept") String acceptHeader,
@QueryParam("start") int startIndex,
@QueryParam("length") int length)
throws MDMAPIException {
MediaType responseMediaType = DeviceMgtAPIUtils.getResponseMediaType(acceptHeader);
Message message = new Message();
if (startIndex < 0) {
message.setErrorMessage("Invalid start index.");
message.setDiscription("Start index cannot be less that 0.");
return Response.status(Response.Status.BAD_REQUEST).entity(message).type(responseMediaType).build();
} else if (length <= 0) {
message.setErrorMessage("Invalid length value.");
message.setDiscription("Length should be a positive integer.");
return Response.status(Response.Status.BAD_REQUEST).entity(message).type(responseMediaType).build();
}
CertificateManagementService certificateService = DeviceMgtAPIUtils.getCertificateManagementService();
PaginationRequest paginationRequest = new PaginationRequest(startIndex, length);
try {
PaginationResult certificates = certificateService.getAllCertificates(paginationRequest);
return Response.status(Response.Status.OK).entity(certificates).type(responseMediaType).build();
} catch (CertificateManagementDAOException e) {
String msg = "Error occurred while fetching all certificates.";
log.error(msg, e);
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).type(responseMediaType).build();
}
}
/**
* Get all certificates
*
* @return certificate details in an array.
* @throws MDMAPIException
*/
@GET
public Response getAllCertificates(@HeaderParam("Accept") String acceptHeader)
throws MDMAPIException {
MediaType responseMediaType = DeviceMgtAPIUtils.getResponseMediaType(acceptHeader);
CertificateManagementService certificateService = DeviceMgtAPIUtils.getCertificateManagementService();
try {
List<CertificateResponse> certificates = certificateService.getCertificates();
return Response.status(Response.Status.OK).entity(certificates).type(responseMediaType).build();
} catch (CertificateManagementDAOException e) {
String msg = "Error occurred while fetching all certificates.";
log.error(msg, e);
throw new MDMAPIException(msg, e);
}
}
@DELETE
@Path("{serialNumber}")
public Response removeCertificate(@HeaderParam("Accept") String acceptHeader,
@PathParam("serialNumber") String serialNumber) throws MDMAPIException {
MediaType responseMediaType = DeviceMgtAPIUtils.getResponseMediaType(acceptHeader);
Message message = new Message();
if (serialNumber == null || serialNumber.isEmpty()) {
message.setErrorMessage("Invalid serial number");
message.setDiscription("Serial number is missing or invalid.");
return Response.status(Response.Status.BAD_REQUEST).entity(message).type(responseMediaType).build();
}
CertificateManagementService certificateService = DeviceMgtAPIUtils.getCertificateManagementService();
boolean deleted;
try {
deleted = certificateService.removeCertificate(serialNumber);
if(deleted){
return Response.status(Response.Status.OK).entity(deleted).type(responseMediaType).build();
} else {
return Response.status(Response.Status.GONE).entity(deleted).type(responseMediaType).build();
}
} catch (CertificateManagementDAOException e) {
String msg = "Error occurred while converting PEM file to X509Certificate";
log.error(msg, e);
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).type(responseMediaType).build();
}
}
}

@ -0,0 +1,75 @@
/*
* Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
*
* WSO2 Inc. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.wso2.carbon.certificate.mgt.cert.jaxrs.api.util;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.wso2.carbon.certificate.mgt.core.service.CertificateManagementService;
import org.wso2.carbon.context.PrivilegedCarbonContext;
import org.wso2.carbon.device.mgt.core.search.mgt.SearchManagerService;
import javax.ws.rs.core.MediaType;
/**
* DMAPIUtils class provides utility function used by CDM REST-API classes.
*/
public class DeviceMgtAPIUtils {
public static final MediaType DEFAULT_CONTENT_TYPE = MediaType.APPLICATION_JSON_TYPE;
private static Log log = LogFactory.getLog(DeviceMgtAPIUtils.class);
public static CertificateManagementService getCertificateManagementService() {
PrivilegedCarbonContext ctx = PrivilegedCarbonContext.getThreadLocalCarbonContext();
CertificateManagementService certificateManagementService = (CertificateManagementService)
ctx.getOSGiService(CertificateManagementService.class, null);
if (certificateManagementService == null) {
String msg = "CertificateImpl Management service not initialized.";
log.error(msg);
throw new IllegalStateException(msg);
}
return certificateManagementService;
}
public static MediaType getResponseMediaType(String acceptHeader) {
MediaType responseMediaType;
if (acceptHeader == null || MediaType.WILDCARD.equals(acceptHeader)) {
responseMediaType = DEFAULT_CONTENT_TYPE;
} else {
responseMediaType = MediaType.valueOf(acceptHeader);
}
return responseMediaType;
}
public static SearchManagerService getSearchManagerService() {
PrivilegedCarbonContext ctx = PrivilegedCarbonContext.getThreadLocalCarbonContext();
SearchManagerService searchManagerService =
(SearchManagerService) ctx.getOSGiService(SearchManagerService.class, null);
if (searchManagerService == null) {
String msg = "DeviceImpl search manager service has not initialized.";
log.error(msg);
throw new IllegalStateException(msg);
}
return searchManagerService;
}
}

@ -0,0 +1,107 @@
/*
* Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
*
* WSO2 Inc. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.wso2.carbon.certificate.mgt.cert.jaxrs.api.util;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
@XmlRootElement
public class ResponsePayload {
private int statusCode;
private String messageFromServer;
private Object responseContent;
@XmlElement
public int getStatusCode() {
return statusCode;
}
public void setStatusCode(int statusCode) {
this.statusCode = statusCode;
}
@XmlElement
public String getMessageFromServer() {
return messageFromServer;
}
public void setMessageFromServer(String messageFromServer) {
this.messageFromServer = messageFromServer;
}
@XmlElement
public Object getResponseContent() {
return responseContent;
}
public void setResponseContent(Object responseContent) {
this.responseContent = responseContent;
}
private ResponsePayloadBuilder getBuilder() {
return new ResponsePayloadBuilder();
}
public static ResponsePayloadBuilder statusCode(int statusCode) {
ResponsePayload message = new ResponsePayload();
return message.getBuilder().statusCode(statusCode);
}
public static ResponsePayloadBuilder messageFromServer(String messageFromServer) {
ResponsePayload message = new ResponsePayload();
return message.getBuilder().messageFromServer(messageFromServer);
}
public static ResponsePayloadBuilder responseContent(String responseContent) {
ResponsePayload message = new ResponsePayload();
return message.getBuilder().responseContent(responseContent);
}
public class ResponsePayloadBuilder {
private int statusCode;
private String messageFromServer;
private Object responseContent;
public ResponsePayloadBuilder statusCode(int statusCode) {
this.statusCode = statusCode;
return this;
}
public ResponsePayloadBuilder messageFromServer(String messageFromServer) {
this.messageFromServer = messageFromServer;
return this;
}
public ResponsePayloadBuilder responseContent(String responseContent) {
this.responseContent = responseContent;
return this;
}
public ResponsePayload build() {
ResponsePayload payload = new ResponsePayload();
payload.setStatusCode(statusCode);
payload.setMessageFromServer(messageFromServer);
payload.setResponseContent(responseContent);
return payload;
}
}
}

@ -0,0 +1,67 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
~ Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
~
~ WSO2 Inc. licenses this file to you under the Apache License,
~ Version 2.0 (the "License"); you may not use this file except
~ in compliance with the License.
~ You may obtain a copy of the License at
~
~ http://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing,
~ software distributed under the License is distributed on an
~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
~ KIND, either express or implied. See the License for the
~ specific language governing permissions and limitations
~ under the License.
-->
<!-- This file contains the list of permissions that are associated with URL end points
of the web app. Each permission should contain the name, permission path ,API path
(URL) , HTTP method and OAUTH2 authorization scope (not-required).
When defining dynamic paths for APIs, path variables are denoted by '*' notation.
For ex:
Actual API endpoint: devicemgt_admin/1.0.0/devices/{device-id}
URL to be represented here: /devices/*
NOTE: All the endpoints of the web app should be available in this file. Otherwise
it will result 403 error at the runtime.
-->
<PermissionConfiguration>
<APIVersion></APIVersion>
<!-- Device related APIs -->
<Permission>
<name>get certificate in the database</name>
<path>/device-mgt/emm-admin/certificate/GetSignCSR</path>
<url>/certificates/signcsr</url>
<method>POST</method>
<scope>emm_admin</scope>
</Permission>
<!-- Certificate related APIs -->
<Permission>
<name>Save certificate in the database</name>
<path>/device-mgt/admin/certificate/save</path>
<url>/certificates</url>
<method>POST</method>
</Permission>
<Permission>
<name>get certificate in the database</name>
<path>/device-mgt/admin/certificate/Get</path>
<url>/certificates/*</url>
<method>GET</method>
</Permission>
<Permission>
<name>get certificate in the database</name>
<path>/device-mgt/admin/certificate/GetAll</path>
<url>/certificates</url>
<method>GET</method>
</Permission>
<Permission>
<name>get certificate in the database</name>
<path>/device-mgt/admin/certificate/Get</path>
<url>/certificates/*</url>
<method>DELETE</method>
</Permission>
<!-- End of Certificate related APIs -->
</PermissionConfiguration>

@ -0,0 +1,35 @@
<?xml version="1.0" encoding="ISO-8859-1"?>
<!--
~ 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.
-->
<!--
This file defines class loading policy of the whole container. But this behaviour can be overridden by individual webapps by putting this file into the META-INF/ directory.
-->
<Classloading xmlns="http://wso2.org/projects/as/classloading">
<!-- Parent-first or child-first. Default behaviour is child-first.-->
<ParentFirst>false</ParentFirst>
<!--
Default environments that contains provides to all the webapps. This can be overridden by individual webapps by specifing required environments
Tomcat environment is the default and every webapps gets it even if they didn't specify it.
e.g. If a webapps requires CXF, they will get both Tomcat and CXF.
-->
<Environments>CXF,Carbon</Environments>
</Classloading>

@ -0,0 +1,66 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
~ Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
~
~ WSO2 Inc. licenses this file to you under the Apache License,
~ Version 2.0 (the "License"); you may not use this file except
~ in compliance with the License.
~ You may obtain a copy of the License at
~
~ http://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing,
~ software distributed under the License is distributed on an
~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
~ KIND, either express or implied. See the License for the
~ specific language governing permissions and limitations
~ under the License.
-->
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:jaxrs="http://cxf.apache.org/jaxrs"
xmlns="http://www.springframework.org/schema/beans"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://cxf.apache.org/jaxrs http://cxf.apache.org/schemas/jaxrs.xsd">
<jaxrs:server id="services" address="/">
<jaxrs:serviceBeans>
<ref bean="swaggerResource"/>
</jaxrs:serviceBeans>
<jaxrs:providers>
<ref bean="jsonProvider"/>
<ref bean="errorHandler"/>
<ref bean="swaggerWriter"/>
</jaxrs:providers>
</jaxrs:server>
<jaxrs:server id="certificateService" address="/certificates">
<jaxrs:serviceBeans>
<ref bean="certificateServiceBean"/>
</jaxrs:serviceBeans>
<jaxrs:providers>
<ref bean="jsonProvider"/>
<ref bean="errorHandler"/>
</jaxrs:providers>
</jaxrs:server>
<bean id="swaggerWriter" class="io.swagger.jaxrs.listing.SwaggerSerializers"/>
<bean id="swaggerResource" class="io.swagger.jaxrs.listing.ApiListingResource"/>
<bean id="swaggerConfig" class="io.swagger.jaxrs.config.BeanConfig">
<property name="resourcePackage" value="org.wso2.carbon.certificate.mgt.cert.jaxrs.api"/>
<property name="version" value="1.0.0"/>
<property name="host" value="localhost:9443"/>
<property name="basePath" value="/"/>
<property name="title" value="Device Management Admin Service API Definitions"/>
<property name="contact" value="dev@wso2.org"/>
<property name="license" value="Apache 2.0"/>
<property name="licenseUrl" value="http://www.apache.org/licenses/LICENSE-2.0.html"/>
<property name="scan" value="true"/>
</bean>
<bean id="certificateServiceBean" class="org.wso2.carbon.certificate.mgt.cert.jaxrs.api.impl.CertificateImpl"/>
<bean id="jsonProvider" class="org.wso2.carbon.certificate.mgt.cert.jaxrs.api.common.GsonMessageBodyHandler"/>
<bean id="errorHandler" class="org.wso2.carbon.certificate.mgt.cert.jaxrs.api.common.ErrorHandler"/>
</beans>

@ -0,0 +1,66 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
~ Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
~
~ WSO2 Inc. licenses this file to you under the Apache License,
~ Version 2.0 (the "License"); you may not use this file except
~ in compliance with the License.
~ You may obtain a copy of the License at
~
~ http://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing,
~ software distributed under the License is distributed on an
~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
~ KIND, either express or implied. See the License for the
~ specific language governing permissions and limitations
~ under the License.
-->
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" version="2.5">
<display-name>Certificate-Webapp</display-name>
<servlet>
<description>JAX-WS/JAX-RS Certificate Management Endpoint</description>
<display-name>JAX-WS/JAX-RS Servlet</display-name>
<servlet-name>CXFServlet</servlet-name>
<servlet-class>
org.apache.cxf.transport.servlet.CXFServlet
</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>CXFServlet</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
<session-config>
<session-timeout>60</session-timeout>
</session-config>
<context-param>
<param-name>isAdminService</param-name>
<param-value>false</param-value>
</context-param>
<context-param>
<param-name>doAuthentication</param-name>
<param-value>true</param-value>
</context-param>
<!--publish to apim-->
<context-param>
<param-name>managed-api-enabled</param-name>
<param-value>true</param-value>
</context-param>
<context-param>
<param-name>managed-api-owner</param-name>
<param-value>admin</param-value>
</context-param>
<security-constraint>
<web-resource-collection>
<web-resource-name>CertificateMgt-Admin</web-resource-name>
<url-pattern>/*</url-pattern>
</web-resource-collection>
<user-data-constraint>
<transport-guarantee>CONFIDENTIAL</transport-guarantee>
</user-data-constraint>
</security-constraint>
</web-app>

@ -55,7 +55,11 @@ public class GenericCertificateDAOImpl implements CertificateDAO {
try {
conn = this.getConnection();
stmt = conn.prepareStatement(
"INSERT INTO DM_DEVICE_CERTIFICATE (SERIAL_NUMBER, CERTIFICATE, TENANT_ID) VALUES (?,?,?)");
"INSERT INTO DM_DEVICE_CERTIFICATE (SERIAL_NUMBER, CERTIFICATE, TENANT_ID, USERNAME)"
+ " VALUES (?,?,?,?)");
PrivilegedCarbonContext threadLocalCarbonContext = PrivilegedCarbonContext.
getThreadLocalCarbonContext();
String username = threadLocalCarbonContext.getUsername();
for (Certificate certificate : certificates) {
String serialNumber = certificate.getSerial();
if (serialNumber == null || serialNumber.isEmpty()) {
@ -67,6 +71,7 @@ public class GenericCertificateDAOImpl implements CertificateDAO {
stmt.setString(1, serialNumber);
stmt.setObject(2, byteArrayInputStream);
stmt.setInt(3, certificate.getTenantId());
stmt.setString(4, username);
stmt.addBatch();
}
stmt.executeBatch();
@ -89,8 +94,8 @@ public class GenericCertificateDAOImpl implements CertificateDAO {
try {
conn = this.getConnection();
String query =
"SELECT CERTIFICATE, SERIAL_NUMBER, TENANT_ID FROM DM_DEVICE_CERTIFICATE WHERE SERIAL_NUMBER = ?" +
" AND TENANT_ID = ? ";
"SELECT CERTIFICATE, SERIAL_NUMBER, TENANT_ID, USERNAME FROM"
+ " DM_DEVICE_CERTIFICATE WHERE SERIAL_NUMBER = ? AND TENANT_ID = ? ";
stmt = conn.prepareStatement(query);
stmt.setString(1, serialNumber);
stmt.setInt(2, tenantId);
@ -102,6 +107,7 @@ public class GenericCertificateDAOImpl implements CertificateDAO {
certificateResponse.setCertificate(certificateBytes);
certificateResponse.setSerialNumber(resultSet.getString("SERIAL_NUMBER"));
certificateResponse.setTenantId(resultSet.getInt("TENANT_ID"));
certificateResponse.setUsername(resultSet.getString("USERNAME"));
CertificateGenerator.extractCertificateDetails(certificateBytes, certificateResponse);
break;
}
@ -128,8 +134,8 @@ public class GenericCertificateDAOImpl implements CertificateDAO {
try {
conn = this.getConnection();
String query =
"SELECT CERTIFICATE, SERIAL_NUMBER, TENANT_ID FROM DM_DEVICE_CERTIFICATE WHERE SERIAL_NUMBER LIKE ?" +
" AND TENANT_ID = ? ";
"SELECT CERTIFICATE, SERIAL_NUMBER, TENANT_ID, USERNAME FROM DM_DEVICE_CERTIFICATE "
+ "WHERE SERIAL_NUMBER LIKE ? AND TENANT_ID = ? ";
stmt = conn.prepareStatement(query);
stmt.setString(1, "%" + serialNumber + "%");
stmt.setInt(2, tenantId);
@ -140,6 +146,7 @@ public class GenericCertificateDAOImpl implements CertificateDAO {
byte [] certificateBytes = resultSet.getBytes("CERTIFICATE");
certificateResponse.setSerialNumber(resultSet.getString("SERIAL_NUMBER"));
certificateResponse.setTenantId(resultSet.getInt("TENANT_ID"));
certificateResponse.setUsername(resultSet.getString("USERNAME"));
CertificateGenerator.extractCertificateDetails(certificateBytes, certificateResponse);
certificates.add(certificateResponse);
}
@ -164,8 +171,8 @@ public class GenericCertificateDAOImpl implements CertificateDAO {
int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId();
try {
Connection conn = this.getConnection();
String sql = "SELECT CERTIFICATE, SERIAL_NUMBER, TENANT_ID FROM DM_DEVICE_CERTIFICATE WHERE TENANT_ID = ? " +
"ORDER BY ID DESC LIMIT ?,?";
String sql = "SELECT CERTIFICATE, SERIAL_NUMBER, TENANT_ID, USERNAME FROM "
+ "DM_DEVICE_CERTIFICATE WHERE TENANT_ID = ? ORDER BY ID DESC LIMIT ?,?";
stmt = conn.prepareStatement(sql);
stmt.setInt(1, tenantId);
stmt.setInt(2, request.getStartIndex());
@ -178,6 +185,7 @@ public class GenericCertificateDAOImpl implements CertificateDAO {
byte [] certificateBytes = resultSet.getBytes("CERTIFICATE");
certificateResponse.setSerialNumber(resultSet.getString("SERIAL_NUMBER"));
certificateResponse.setTenantId(resultSet.getInt("TENANT_ID"));
certificateResponse.setUsername(resultSet.getString("USERNAME"));
CertificateGenerator.extractCertificateDetails(certificateBytes, certificateResponse);
certificates.add(certificateResponse);
resultCount++;
@ -204,8 +212,8 @@ public class GenericCertificateDAOImpl implements CertificateDAO {
int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId();
try {
Connection conn = this.getConnection();
String sql = "SELECT CERTIFICATE, SERIAL_NUMBER, TENANT_ID FROM DM_DEVICE_CERTIFICATE WHERE TENANT_ID = ? " +
"ORDER BY ID DESC";
String sql = "SELECT CERTIFICATE, SERIAL_NUMBER, TENANT_ID, USERNAME"
+ " FROM DM_DEVICE_CERTIFICATE WHERE TENANT_ID = ? ORDER BY ID DESC";
stmt = conn.prepareStatement(sql);
stmt.setInt(1, tenantId);
resultSet = stmt.executeQuery();
@ -215,6 +223,7 @@ public class GenericCertificateDAOImpl implements CertificateDAO {
byte [] certificateBytes = resultSet.getBytes("CERTIFICATE");
certificateResponse.setSerialNumber(resultSet.getString("SERIAL_NUMBER"));
certificateResponse.setTenantId(resultSet.getInt("TENANT_ID"));
certificateResponse.setUsername(resultSet.getString("USERNAME"));
CertificateGenerator.extractCertificateDetails(certificateBytes, certificateResponse);
certificates.add(certificateResponse);
}

@ -56,6 +56,17 @@ public class CertificateResponse {
@ApiModelProperty(name = "certificateVersion", value = "The version of the certificate", required = true)
int certificateVersion;
@ApiModelProperty(name ="username", value="username of the logged user", required = true)
String username;
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public long getNotAfter() {
return notAfter;
}

@ -37,6 +37,7 @@
<modules>
<module>org.wso2.carbon.certificate.mgt.core</module>
<module>org.wso2.carbon.certificate.mgt.api</module>
<module>org.wso2.carbon.certificate.mgt.cert.admin.api</module>
</modules>
<build>

@ -22,8 +22,8 @@ public final class GadgetDataServiceDAOConstants {
public static class DatabaseView {
public static final String DEVICES_VIEW_1 = "DEVICES_WITH_POLICY_COMPLIANCE_STATUS";
public static final String DEVICES_VIEW_2 = "DEVICES_WITH_NON_COMPLIANT_FEATURES";
public static final String DEVICES_VIEW_1 = "POLICY_COMPLIANCE_INFO";
public static final String DEVICES_VIEW_2 = "FEATURE_NON_COMPLIANCE_INFO";
private DatabaseView() {
throw new AssertionError();

@ -20,7 +20,7 @@ package org.wso2.carbon.device.mgt.jaxrs.api;
import io.swagger.annotations.*;
import org.wso2.carbon.apimgt.annotations.api.*;
import org.wso2.carbon.device.mgt.common.configuration.mgt.TenantConfiguration;
import org.wso2.carbon.device.mgt.common.configuration.mgt.PlatformConfiguration;
import javax.ws.rs.*;
import javax.ws.rs.core.MediaType;
@ -55,7 +55,7 @@ public interface Configuration {
@Permission(scope = "configuration-modify", permissions = {"/permission/admin/device-mgt/admin/platform-configs/modify"})
Response saveTenantConfiguration(@ApiParam(name = "configuration", value = "The required properties to "
+ "update the platform configurations the as the <JSON_PAYLOAD> value",
required = true) TenantConfiguration configuration);
required = true) PlatformConfiguration configuration);
@GET
@ApiOperation(
@ -64,7 +64,7 @@ public interface Configuration {
httpMethod = "GET",
value = "Getting General Platform Configurations",
notes = "Get the general platform level configuration details using this REST API",
response = TenantConfiguration.class)
response = PlatformConfiguration.class)
@ApiResponses(value = {
@ApiResponse(code = 200, message = "OK"),
@ApiResponse(code = 500, message = "Error occurred while retrieving the tenant configuration")
@ -86,6 +86,6 @@ public interface Configuration {
@Permission(scope = "configuration-modify", permissions = {"/permission/admin/device-mgt/admin/platform-configs/modify"})
Response updateConfiguration(@ApiParam(name = "configuration", value = "The required properties to update"
+ " the platform configurations the as the <JSON_PAYLOAD> value",
required = true) TenantConfiguration configuration);
required = true) PlatformConfiguration configuration);
}

@ -117,7 +117,7 @@ public interface Device {
*/
@GET
@Path("user/{user}/count")
@Permission(scope = "device-count-own", permissions = {
@Permission(scope = "device-view-own", permissions = {
"/permission/admin/device-mgt/user/devices/list",
"/permission/admin/device-mgt/admin/devices/list"})
Response getDeviceCountOfUser(@PathParam("user") String user);

@ -21,6 +21,7 @@ package org.wso2.carbon.device.mgt.jaxrs.api;
import io.swagger.annotations.*;
import org.wso2.carbon.apimgt.annotations.api.*;
import org.wso2.carbon.device.mgt.common.DeviceIdentifier;
import org.wso2.carbon.device.mgt.common.app.mgt.Application;
import org.wso2.carbon.device.mgt.common.device.details.DeviceInfo;
import org.wso2.carbon.device.mgt.common.device.details.DeviceLocation;
@ -105,4 +106,47 @@ public interface DeviceInformation {
@ApiParam(name = "id", value = "Provide the device identifier",
required = true) @PathParam("id") String id);
@GET
@Path("location/list")
@ApiOperation(
produces = MediaType.APPLICATION_JSON,
httpMethod = "GET",
value = "Get the locations of devices",
notes = "This will return the locations of devices including latitude and longitude as well the "
+ "physical address for the supplied device identifiers",
response = DeviceLocation.class,
responseContainer = "List")
@ApiResponses(value = {
@ApiResponse(code = 200, message = ""),
@ApiResponse(code = 400, message = ""),
@ApiResponse(code = 400, message = ""),
@ApiResponse(code = 500, message = "Internal Server Error")
})
@Permission(scope = "device-info", permissions = {"/permission/admin/device-mgt/admin/devices/list"})
Response getDeviceLocations(@ApiParam(name = "deviceIdentifiers", value = "List of device identifiers",
required = true) List<DeviceIdentifier> deviceIdentifiers);
@GET
@Path("application/{type}/{id}")
@ApiOperation(
produces = MediaType.APPLICATION_JSON,
httpMethod = "GET",
value = "Get the device applications",
notes = "This will return the device applications including their memory usages.",
response = Application.class,
responseContainer = "List")
@ApiResponses(value = {
@ApiResponse(code = 200, message = ""),
@ApiResponse(code = 400, message = ""),
@ApiResponse(code = 400, message = ""),
@ApiResponse(code = 500, message = "Internal Server Error")
})
@Permission(scope = "device-info", permissions = {"/permission/admin/device-mgt/admin/devices/list"})
Response getDeviceApplications(@ApiParam(name = "type", value = "Provide the device type, such as ios, "
+ "android or windows", required = true) @PathParam("type") String type,
@ApiParam(name = "id", value = "Provide the device identifier",
required = true) @PathParam("id") String id);
}

@ -112,7 +112,7 @@ public interface DeviceNotification {
value = "Sending a Device Notification",
notes = "Notify users on device operation failures and other information using this REST API")
@ApiResponses(value = {
@ApiResponse(code = 201, message = "NNotification has added successfully"),
@ApiResponse(code = 201, message = "Notification has been added successfully"),
@ApiResponse(code = 500, message = "Error occurred while updating notification status")
})
@Permission(scope = "device-notification-modify",

@ -28,7 +28,7 @@ import javax.ws.rs.core.Response;
/**
* Features
*/
@API(name = "Device Search", version = "1.0.0", context = "/devicemgt_admin/features", tags = {"devicemgt_admin"})
@API(name = "Feature", version = "1.0.0", context = "/devicemgt_admin/features", tags = {"devicemgt_admin"})
// Below Api is for swagger annotations
@Api(value = "Feature", description = "Feature management related operations can be found here.")
@ -58,7 +58,7 @@ public interface Feature {
@ApiResponses(value = { @ApiResponse(code = 200, message = "List of Features"),
@ApiResponse(code = 500, message = "Error occurred while retrieving the list of features" +
".") })
@Permission(scope = "device-search", permissions = {"/permission/admin/device-mgt/admin/devices/view",
@Permission(scope = "feature-view", permissions = {"/permission/admin/device-mgt/admin/devices/view",
"/permission/admin/device-mgt/user/devices/view"})
Response getFeatures(@ApiParam(name = "type", value = "Provide the device type, such as ios, android or windows",
required = true) @PathParam("type") String type);

@ -21,6 +21,7 @@ package org.wso2.carbon.device.mgt.jaxrs.api;
import io.swagger.annotations.*;
import org.wso2.carbon.apimgt.annotations.api.*;
import org.wso2.carbon.device.mgt.common.app.mgt.Application;
import org.wso2.carbon.device.mgt.common.operation.mgt.Activity;
import org.wso2.carbon.device.mgt.jaxrs.api.common.MDMAPIException;
import org.wso2.carbon.device.mgt.jaxrs.api.context.DeviceOperationContext;
import org.wso2.carbon.device.mgt.jaxrs.beans.ApplicationWrapper;
@ -182,7 +183,8 @@ public interface Operation {
produces = MediaType.APPLICATION_JSON + ", " + MediaType.APPLICATION_XML,
httpMethod = "GET",
value = "Retrieving the operation details.",
notes = "This will return the operation details including the responses from the devices")
notes = "This will return the operation details including the responses from the devices",
response = Activity.class)
@ApiResponses(value = {@ApiResponse(code = 200, message = "Activity details provided successfully.."),
@ApiResponse(code = 500, message = "Error occurred while fetching the activity for the supplied id.")})
@Permission(scope = "operation-view", permissions = {"/permission/admin/device-mgt/admin/devices/view"})
@ -190,4 +192,24 @@ public interface Operation {
required = true) @PathParam("id") String id)
throws MDMAPIException;
@GET
@Path("activity/after/{timestamp}")
@ApiOperation(
consumes = MediaType.APPLICATION_JSON + ", " + MediaType.APPLICATION_XML,
produces = MediaType.APPLICATION_JSON + ", " + MediaType.APPLICATION_XML,
httpMethod = "GET",
value = "Retrieving the operation details updated after given timestamp. Timestamp should be given as unix " +
"value in seconds.",
notes = "This will return the operation details including the responses from the devices update after given" +
"time.",
response = Activity.class,
responseContainer = "List")
@ApiResponses(value = {@ApiResponse(code = 200, message = "Activity details provided successfully.."),
@ApiResponse(code = 500, message = "Error occurred while fetching the activity for the supplied id.")})
@Permission(scope = "operation-view", permissions = {"/permission/admin/device-mgt/admin/devices/view"})
Response getActivityUpdatedAfter(@ApiParam(name = "timestamp", value = "Provide the timestamp as unix in seconds.",
required = true) @PathParam("timestamp") String timestamp)
throws MDMAPIException;
}

@ -146,7 +146,7 @@ public interface Role {
notes = "You are able to add a new role to WSO2 EMM using the REST API.")
@ApiResponses(value = { @ApiResponse(code = 200, message = "Added the role."),
@ApiResponse(code = 500, message = "Error occurred while adding the user role.") })
@Permission(scope = "roles-modify", permissions = {"/permission/admin/device-mgt/admin/roles/add"})
@Permission(scope = "roles-add", permissions = {"/permission/admin/device-mgt/admin/roles/add"})
Response addRole(@ApiParam(name = "roleWrapper", value = "Role and permission details.",
required = true) RoleWrapper roleWrapper);
@ -180,7 +180,7 @@ public interface Role {
@ApiResponses(value = { @ApiResponse(code = 200, message = "Deleted the role."),
@ApiResponse(code = 500, message = "Error occurred while deleting the user role details" +
".") })
@Permission(scope = "roles-modify", permissions = {"/permission/admin/device-mgt/admin/roles/remove"})
@Permission(scope = "roles-remove", permissions = {"/permission/admin/device-mgt/admin/roles/remove"})
Response deleteRole(@ApiParam(name = "rolename", value = "Provide the name of the role you wish to delete.",
required = true) @QueryParam("rolename") String roleName);
@ -217,7 +217,7 @@ public interface Role {
notes = "Get the number of roles in WSO2 EMM.")
@ApiResponses(value = { @ApiResponse(code = 200, message = "Retrieved the role count."),
@ApiResponse(code = 500, message = "Error occurred while retrieving the role count.") })
@Permission(scope = "roles-modify", permissions = {"/permission/admin/device-mgt/admin/roles/list"})
@Permission(scope = "roles-view", permissions = {"/permission/admin/device-mgt/admin/roles/list"})
Response getRoleCount();
}

@ -52,7 +52,7 @@ public interface User {
@ApiResponse(code = 201, message = "Created"),
@ApiResponse(code = 500, message = "Exception in trying to add user by username: 'username'")
})
@Permission(scope = "user-modify", permissions = {"/permission/admin/device-mgt/admin/user/add"})
@Permission(scope = "user-add", permissions = {"/permission/admin/device-mgt/admin/user/add"})
Response addUser(@ApiParam(name = "userWrapper", value = "Includes the required properties to add a user"
+ " as the <JSON_PAYLOAD> value", required = true) UserWrapper userWrapper);
@ -113,7 +113,7 @@ public interface User {
@ApiResponse(code = 400, message = "User by username: 'username' does not exist for removal"),
@ApiResponse(code = 500, message = "Exception in trying to remove user by username: 'username'")
})
@Permission(scope = "user-modify", permissions = {"/permission/admin/device-mgt/admin/user/remove"})
@Permission(scope = "user-remove", permissions = {"/permission/admin/device-mgt/admin/user/remove"})
Response removeUser(@ApiParam(name = "username", value = "Provide the name of the user you wish to delete"
+ " as the value for {username}", required = true)
@QueryParam("username") String username);
@ -220,7 +220,7 @@ public interface User {
@ApiResponse(code = 200, message = "Email invitation was successfully sent to user"),
@ApiResponse(code = 500, message = "Error occurred while retrieving the list of users")
})
@Permission(scope = "user-modify", permissions = {"/permission/admin/device-mgt/admin/users/invite"})
@Permission(scope = "user-invite", permissions = {"/permission/admin/device-mgt/admin/users/invite"})
Response inviteExistingUsersToEnrollDevice(@ApiParam(name = "usernames", value = "List of the users to be"
+ " invited as the <JSON_PAYLOAD>", required = true)
List<String> usernames);
@ -291,7 +291,7 @@ public interface User {
+ " Character Encoding is not supported"),
@ApiResponse(code = 500, message = "Internal Server Error")
})
@Permission(scope = "user-modify", permissions = {"/permission/admin/login"})
@Permission(scope = "user-password-modify", permissions = {"/permission/admin/login"})
Response resetPassword(@ApiParam(name = "credentials", value = "Include the required properties to change"
+ " the user password as <JSON_PAYLOAD> value", required = true)
UserCredentialWrapper credentials);
@ -317,7 +317,7 @@ public interface User {
+ " Character Encoding is not supported"),
@ApiResponse(code = 500, message = "Internal Server Error")
})
@Permission(scope = "user-modify", permissions = {"/permission/admin/device-mgt/admin/users/password-reset"})
@Permission(scope = "user-password-reset", permissions = {"/permission/admin/device-mgt/admin/users/password-reset"})
Response resetPasswordByAdmin(@ApiParam(name = "credentials", value = "Include the required properties "
+ "to change a user password as <JSON_PAYLOAD> value",
required = true) UserCredentialWrapper credentials);

@ -23,7 +23,7 @@ import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.wso2.carbon.device.mgt.common.configuration.mgt.ConfigurationEntry;
import org.wso2.carbon.device.mgt.common.configuration.mgt.ConfigurationManagementException;
import org.wso2.carbon.device.mgt.common.configuration.mgt.TenantConfiguration;
import org.wso2.carbon.device.mgt.common.configuration.mgt.PlatformConfiguration;
import org.wso2.carbon.device.mgt.jaxrs.api.Configuration;
import org.wso2.carbon.device.mgt.jaxrs.api.util.DeviceMgtAPIUtils;
import org.wso2.carbon.device.mgt.jaxrs.api.util.MDMAppConstants;
@ -51,7 +51,7 @@ public class ConfigurationImpl implements Configuration{
private static Log log = LogFactory.getLog(ConfigurationImpl.class);
@POST
public Response saveTenantConfiguration(TenantConfiguration configuration) {
public Response saveTenantConfiguration(PlatformConfiguration configuration) {
ResponsePayload responseMsg = new ResponsePayload();
try {
DeviceMgtAPIUtils.getTenantConfigurationManagementService().saveConfiguration(configuration,
@ -72,7 +72,7 @@ public class ConfigurationImpl implements Configuration{
public Response getConfiguration() {
String msg;
try {
TenantConfiguration tenantConfiguration = DeviceMgtAPIUtils.getTenantConfigurationManagementService().
PlatformConfiguration tenantConfiguration = DeviceMgtAPIUtils.getTenantConfigurationManagementService().
getConfiguration(MDMAppConstants.RegistryConstants.GENERAL_CONFIG_RESOURCE_PATH);
ConfigurationEntry configurationEntry = new ConfigurationEntry();
configurationEntry.setContentType("text");
@ -93,7 +93,7 @@ public class ConfigurationImpl implements Configuration{
}
@PUT
public Response updateConfiguration(TenantConfiguration configuration) {
public Response updateConfiguration(PlatformConfiguration configuration) {
ResponsePayload responseMsg = new ResponsePayload();
try {
DeviceMgtAPIUtils.getTenantConfigurationManagementService().saveConfiguration(configuration,

@ -19,11 +19,15 @@
package org.wso2.carbon.device.mgt.jaxrs.api.impl;
import io.swagger.annotations.ApiParam;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.wso2.carbon.device.mgt.common.DeviceIdentifier;
import org.wso2.carbon.device.mgt.common.app.mgt.Application;
import org.wso2.carbon.device.mgt.common.app.mgt.ApplicationManagementException;
import org.wso2.carbon.device.mgt.common.device.details.DeviceInfo;
import org.wso2.carbon.device.mgt.common.device.details.DeviceLocation;
import org.wso2.carbon.device.mgt.core.app.mgt.ApplicationManagementProviderService;
import org.wso2.carbon.device.mgt.core.device.details.mgt.DeviceDetailsMgtException;
import org.wso2.carbon.device.mgt.core.device.details.mgt.DeviceInformationManager;
import org.wso2.carbon.device.mgt.jaxrs.api.DeviceInformation;
@ -96,5 +100,41 @@ public class DeviceInformationImpl implements DeviceInformation {
}
return Response.status(Response.Status.OK).entity(deviceLocation).build();
}
@Override
@Path("location/list")
public Response getDeviceLocations(@ApiParam(name = "deviceIdentifiers", value = "List of device identifiers",
required = true) List<DeviceIdentifier> deviceIdentifiers) {
DeviceInformationManager informationManager;
List<DeviceLocation> deviceLocations;
try {
informationManager = DeviceMgtAPIUtils.getDeviceInformationManagerService();
deviceLocations = informationManager.getDeviceLocations(deviceIdentifiers);
} catch (DeviceDetailsMgtException e) {
String msg = "Error occurred while getting the device location.";
log.error(msg, e);
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build();
}
return Response.status(Response.Status.OK).entity(deviceLocations).build();
}
@Override
@Path("application/{type}/{id}")
public Response getDeviceApplications(@PathParam("type") String type, @PathParam("id") String id) {
List<Application> applications;
ApplicationManagementProviderService applicationManagementProviderService;
DeviceIdentifier deviceIdentifier = new DeviceIdentifier();
try {
deviceIdentifier.setType(type);
deviceIdentifier.setId(id);
applicationManagementProviderService = DeviceMgtAPIUtils.getAppManagementService();
applications = applicationManagementProviderService.getApplicationListForDevice(deviceIdentifier);
} catch (ApplicationManagementException e) {
String msg = "Error occurred while fetching the apps of the device.";
log.error(msg, e);
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build();
}
return Response.status(Response.Status.OK).entity(applications).build();
}
}

@ -97,7 +97,7 @@ public class DeviceNotificationImpl implements DeviceNotification{
ResponsePayload responseMsg = new ResponsePayload();
try {
DeviceMgtAPIUtils.getNotificationManagementService().addNotification(notification);
responseMsg.setMessageFromServer("Notification has added successfully.");
responseMsg.setMessageFromServer("Notification has been added successfully.");
responseMsg.setStatusCode(HttpStatus.SC_CREATED);
return Response.status(Response.Status.CREATED).entity(responseMsg).build();
} catch (NotificationManagementException e) {

@ -25,7 +25,7 @@ import org.wso2.carbon.device.mgt.common.DeviceIdentifier;
import org.wso2.carbon.device.mgt.common.PaginationResult;
import org.wso2.carbon.device.mgt.common.group.mgt.DeviceGroup;
import org.wso2.carbon.device.mgt.common.group.mgt.DeviceGroupConstants;
import org.wso2.carbon.device.mgt.common.group.mgt.GroupAlreadyEixistException;
import org.wso2.carbon.device.mgt.common.group.mgt.GroupAlreadyExistException;
import org.wso2.carbon.device.mgt.common.group.mgt.GroupManagementException;
import org.wso2.carbon.device.mgt.common.group.mgt.GroupUser;
import org.wso2.carbon.device.mgt.core.service.GroupManagementProviderService;
@ -50,6 +50,9 @@ import java.util.List;
@SuppressWarnings("NonJaxWsWebServices")
public class GroupImpl implements Group {
private static final String GROUP_CANNOT_NULL_MSG = "Group cannot be null.";
private static final String GROUP_NAME_INVALID_MSG = "Provided group name is invalid. Should be in minimum 3 " +
"characters long and should not include any whitespaces.";
private static Log log = LogFactory.getLog(GroupImpl.class);
@Override
@ -58,7 +61,9 @@ public class GroupImpl implements Group {
public Response createGroup(DeviceGroup group) {
String owner = PrivilegedCarbonContext.getThreadLocalCarbonContext().getUsername();
if (group == null) {
return Response.status(Response.Status.BAD_REQUEST).build();
return Response.status(Response.Status.BAD_REQUEST).entity(GROUP_CANNOT_NULL_MSG).build();
} else if (group.getName() == null || !group.getName().matches("^[\\S]{3,30}$")) {
return Response.status(Response.Status.BAD_REQUEST).entity(GROUP_NAME_INVALID_MSG).build();
}
group.setOwner(owner);
group.setDateOfCreation(new Date().getTime());
@ -78,7 +83,7 @@ public class GroupImpl implements Group {
groupManagementService.addGroupSharingRole(owner, group.getName(), owner, DeviceGroupConstants.Roles.DEFAULT_VIEW_EVENTS,
DeviceGroupConstants.Permissions.DEFAULT_VIEW_EVENTS_PERMISSIONS);
return Response.status(Response.Status.CREATED).build();
} catch (GroupAlreadyEixistException e) {
} catch (GroupAlreadyExistException e) {
return Response.status(Response.Status.CONFLICT).entity(e.getMessage()).build();
} catch (GroupManagementException e) {
log.error(e.getErrorMessage(), e);
@ -92,9 +97,12 @@ public class GroupImpl implements Group {
@Consumes("application/json")
@Produces("application/json")
public Response updateGroup(@PathParam("groupName") String groupName, @PathParam("owner") String owner,
DeviceGroup deviceGroup) {
DeviceGroup group) {
if (group.getName() == null || !group.getName().matches("^[\\S]{3,30}$")) {
return Response.status(Response.Status.BAD_REQUEST).entity(GROUP_NAME_INVALID_MSG).build();
}
try {
DeviceMgtAPIUtils.getGroupManagementProviderService().updateGroup(deviceGroup, groupName, owner);
DeviceMgtAPIUtils.getGroupManagementProviderService().updateGroup(group, groupName, owner);
return Response.status(Response.Status.OK).build();
} catch (GroupManagementException e) {
log.error(e.getErrorMessage(), e);

@ -240,17 +240,36 @@ public class OperationImpl implements org.wso2.carbon.device.mgt.jaxrs.api.Opera
@Path("activity/{id}")
public Response getActivity( @PathParam("id") String id)
throws MDMAPIException {
Activity operation;
Activity activity;
DeviceManagementProviderService dmService;
try {
dmService = DeviceMgtAPIUtils.getDeviceManagementService();
operation = dmService.getOperationByActivityId(id);
activity = dmService.getOperationByActivityId(id);
} catch (OperationManagementException e) {
String msg = "Error occurred while fetching the activity for the supplied id.";
log.error(msg, e);
throw new MDMAPIException(msg, e);
}
return Response.status(Response.Status.OK).entity(operation).build();
return Response.status(Response.Status.OK).entity(activity).build();
}
@Override
@GET
@Path("activity/after/{timestamp}")
public Response getActivityUpdatedAfter(@PathParam("timestamp") String timestamp)
throws MDMAPIException {
List<Activity> activities;
DeviceManagementProviderService dmService;
try {
dmService = DeviceMgtAPIUtils.getDeviceManagementService();
activities = dmService.getActivitiesUpdatedAfter(Long.parseLong(timestamp));
} catch (OperationManagementException e) {
String msg = "Error occurred while fetching the activities updated after given time stamp.";
log.error(msg, e);
throw new MDMAPIException(msg, e);
}
return Response.status(Response.Status.OK).entity(activities).build();
}
}

@ -24,12 +24,12 @@ import org.wso2.carbon.certificate.mgt.core.service.CertificateManagementService
import org.wso2.carbon.context.CarbonContext;
import org.wso2.carbon.context.PrivilegedCarbonContext;
import org.wso2.carbon.device.mgt.analytics.dashboard.GadgetDataService;
import org.wso2.carbon.device.mgt.common.configuration.mgt.PlatformConfiguration;
import org.wso2.carbon.device.mgt.common.configuration.mgt.PlatformConfigurationManagementService;
import org.wso2.carbon.device.mgt.jaxrs.api.common.MDMAPIException;
import org.wso2.carbon.device.mgt.common.DeviceIdentifier;
import org.wso2.carbon.device.mgt.common.PaginationResult;
import org.wso2.carbon.device.mgt.common.configuration.mgt.ConfigurationEntry;
import org.wso2.carbon.device.mgt.common.configuration.mgt.TenantConfiguration;
import org.wso2.carbon.device.mgt.common.configuration.mgt.TenantConfigurationManagementService;
import org.wso2.carbon.device.mgt.common.notification.mgt.NotificationManagementService;
import org.wso2.carbon.device.mgt.core.app.mgt.ApplicationManagementProviderService;
import org.wso2.carbon.device.mgt.core.device.details.mgt.DeviceInformationManager;
@ -57,7 +57,7 @@ public class DeviceMgtAPIUtils {
private static final String NOTIFIER_FREQUENCY = "notifierFrequency";
private static Log log = LogFactory.getLog(DeviceMgtAPIUtils.class);
public static int getNotifierFrequency(TenantConfiguration tenantConfiguration) {
public static int getNotifierFrequency(PlatformConfiguration tenantConfiguration) {
List<ConfigurationEntry> configEntryList = tenantConfiguration.getConfiguration();
if (configEntryList != null && !configEntryList.isEmpty()) {
for(ConfigurationEntry entry : configEntryList) {
@ -234,10 +234,10 @@ public class DeviceMgtAPIUtils {
return policyManagementService;
}
public static TenantConfigurationManagementService getTenantConfigurationManagementService() {
public static PlatformConfigurationManagementService getTenantConfigurationManagementService() {
PrivilegedCarbonContext ctx = PrivilegedCarbonContext.getThreadLocalCarbonContext();
TenantConfigurationManagementService tenantConfigurationManagementService =
(TenantConfigurationManagementService) ctx.getOSGiService(TenantConfigurationManagementService.class, null);
PlatformConfigurationManagementService tenantConfigurationManagementService =
(PlatformConfigurationManagementService) ctx.getOSGiService(PlatformConfigurationManagementService.class, null);
if (tenantConfigurationManagementService == null) {
String msg = "Tenant configuration Management service not initialized.";
log.error(msg);

@ -79,6 +79,10 @@
<param-name>managed-api-owner</param-name>
<param-value>admin</param-value>
</context-param>
<context-param>
<param-name>isSharedWithAllTenants</param-name>
<param-value>true</param-value>
</context-param>
<!-- Below configuration is used to redirect http requests to https -->
<security-constraint>

@ -17,7 +17,7 @@
*/
package org.wso2.carbon.device.mgt.common;
import org.wso2.carbon.device.mgt.common.configuration.mgt.TenantConfiguration;
import org.wso2.carbon.device.mgt.common.configuration.mgt.PlatformConfiguration;
import org.wso2.carbon.device.mgt.common.license.mgt.License;
import org.wso2.carbon.device.mgt.common.license.mgt.LicenseManagementException;
@ -40,14 +40,14 @@ public interface DeviceManager {
*
* @return Returns the status of the operation
*/
boolean saveConfiguration(TenantConfiguration configuration) throws DeviceManagementException;
boolean saveConfiguration(PlatformConfiguration configuration) throws DeviceManagementException;
/**
* Method to get platform specific Configuration.
*
* @return Returns the platform specific tenant configurations
*/
TenantConfiguration getConfiguration() throws DeviceManagementException;
PlatformConfiguration getConfiguration() throws DeviceManagementException;
/**
* Method to enrolling a particular device of type mobile, IoT, etc within CDM.

@ -31,12 +31,12 @@ import java.util.List;
/**
* Represents the tenant configuration for a device platform.
*/
@XmlRootElement(name = "tenantConfiguration")
@XmlRootElement(name = "PlatformConfiguration")
@XmlAccessorType(XmlAccessType.NONE)
@ApiModel(value = "TenantConfiguration",
@ApiModel(value = "PlatformConfiguration",
description = "This class carries all information related to a Tenant configuration")
public class TenantConfiguration implements Serializable {
public class PlatformConfiguration implements Serializable {
@XmlElement(name = "type")
@ApiModelProperty(name = "type", value = "type of device", required = true)

@ -21,7 +21,7 @@ package org.wso2.carbon.device.mgt.common.configuration.mgt;
* This represents the tenant configuration management functionality which should be implemented by
* the device type plugins.
*/
public interface TenantConfigurationManagementService {
public interface PlatformConfigurationManagementService {
/**
* Method to add a operation to a device or a set of devices.
@ -31,7 +31,7 @@ public interface TenantConfigurationManagementService {
* @throws org.wso2.carbon.device.mgt.common.configuration.mgt.ConfigurationManagementException If some unusual behaviour is observed while adding the
* configuration.
*/
boolean saveConfiguration(TenantConfiguration tenantConfiguration, String resourcePath) throws
boolean saveConfiguration(PlatformConfiguration tenantConfiguration, String resourcePath) throws
ConfigurationManagementException;
/**
@ -41,6 +41,6 @@ public interface TenantConfigurationManagementService {
* @throws org.wso2.carbon.device.mgt.common.configuration.mgt.ConfigurationManagementException If some unusual behaviour is observed while fetching the
* operation list.
*/
TenantConfiguration getConfiguration(String resourcePath) throws ConfigurationManagementException;
PlatformConfiguration getConfiguration(String resourcePath) throws ConfigurationManagementException;
}

@ -23,6 +23,9 @@ import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import org.wso2.carbon.device.mgt.common.Device;
import org.wso2.carbon.device.mgt.common.DeviceIdentifier;
import org.wso2.carbon.device.mgt.common.app.mgt.Application;
import java.util.List;
@ApiModel(value = "DeviceWrapper", description = "This contains device details including, " +
"location and device meta information.")
@ -38,6 +41,8 @@ public class DeviceWrapper {
@ApiModelProperty(name = "deviceLocation", value = "Device's current location", required = true)
private DeviceLocation deviceLocation;
private List<Application> applications;
public Device getDevice() {
return device;
}
@ -69,5 +74,13 @@ public class DeviceWrapper {
public void setDeviceLocation(DeviceLocation deviceLocation) {
this.deviceLocation = deviceLocation;
}
public List<Application> getApplications() {
return applications;
}
public void setApplications(List<Application> applications) {
this.applications = applications;
}
}

@ -21,31 +21,31 @@ package org.wso2.carbon.device.mgt.common.group.mgt;
/**
* This class represents a custom exception specified for group management
*/
public class GroupAlreadyEixistException extends Exception {
public class GroupAlreadyExistException extends Exception {
private static final long serialVersionUID = -312678379574816874L;
private String errorMessage;
public GroupAlreadyEixistException(String msg, Exception nestedEx) {
public GroupAlreadyExistException(String msg, Exception nestedEx) {
super(msg, nestedEx);
setErrorMessage(msg);
}
public GroupAlreadyEixistException(String message, Throwable cause) {
public GroupAlreadyExistException(String message, Throwable cause) {
super(message, cause);
setErrorMessage(message);
}
public GroupAlreadyEixistException(String msg) {
public GroupAlreadyExistException(String msg) {
super(msg);
setErrorMessage(msg);
}
public GroupAlreadyEixistException() {
public GroupAlreadyExistException() {
super();
}
public GroupAlreadyEixistException(Throwable cause) {
public GroupAlreadyExistException(Throwable cause) {
super(cause);
}

@ -87,4 +87,8 @@ public interface OperationManager {
Activity getOperationByActivityId(String activity) throws OperationManagementException;
List<Operation> getOperationUpdatedAfter(long timestamp) throws OperationManagementException;
List<Activity> getActivitiesUpdatedAfter(long timestamp) throws OperationManagementException;
}

@ -20,8 +20,8 @@ package org.wso2.carbon.device.mgt.core.config.tenant;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.wso2.carbon.device.mgt.common.configuration.mgt.ConfigurationManagementException;
import org.wso2.carbon.device.mgt.common.configuration.mgt.TenantConfiguration;
import org.wso2.carbon.device.mgt.common.configuration.mgt.TenantConfigurationManagementService;
import org.wso2.carbon.device.mgt.common.configuration.mgt.PlatformConfiguration;
import org.wso2.carbon.device.mgt.common.configuration.mgt.PlatformConfigurationManagementService;
import org.wso2.carbon.device.mgt.core.config.ConfigurationManagerConstants;
import org.wso2.carbon.device.mgt.core.config.util.ConfigurationManagerUtil;
import org.wso2.carbon.registry.api.Resource;
@ -36,17 +36,17 @@ import java.io.StringWriter;
import java.nio.charset.Charset;
/**
* This class implements all the functionality exposed as part of the TenantConfigurationManagementService.
* This class implements all the functionality exposed as part of the PlatformConfigurationManagementService.
* Main usage of this module is saving/retrieving tenant configurations to the registry.
*
*/
public class TenantConfigurationManagementServiceImpl
implements TenantConfigurationManagementService {
implements PlatformConfigurationManagementService {
private static final Log log = LogFactory.getLog(TenantConfigurationManagementServiceImpl.class);
@Override
public boolean saveConfiguration(TenantConfiguration tenantConfiguration, String resourcePath)
public boolean saveConfiguration(PlatformConfiguration tenantConfiguration, String resourcePath)
throws ConfigurationManagementException {
boolean status;
try {
@ -54,7 +54,7 @@ public class TenantConfigurationManagementServiceImpl
log.debug("Persisting tenant configurations in Registry");
}
StringWriter writer = new StringWriter();
JAXBContext context = JAXBContext.newInstance(TenantConfiguration.class);
JAXBContext context = JAXBContext.newInstance(PlatformConfiguration.class);
Marshaller marshaller = context.createMarshaller();
marshaller.marshal(tenantConfiguration, writer);
@ -74,19 +74,19 @@ public class TenantConfigurationManagementServiceImpl
}
@Override
public TenantConfiguration getConfiguration(String resourcePath)
public PlatformConfiguration getConfiguration(String resourcePath)
throws ConfigurationManagementException {
Resource resource;
try {
resource = ConfigurationManagerUtil.getRegistryResource(resourcePath);
if(resource != null){
JAXBContext context = JAXBContext.newInstance(TenantConfiguration.class);
JAXBContext context = JAXBContext.newInstance(PlatformConfiguration.class);
Unmarshaller unmarshaller = context.createUnmarshaller();
return (TenantConfiguration) unmarshaller.unmarshal(
return (PlatformConfiguration) unmarshaller.unmarshal(
new StringReader(new String((byte[]) resource.getContent(), Charset
.forName(ConfigurationManagerConstants.CharSets.CHARSET_UTF8))));
}
return new TenantConfiguration();
return new PlatformConfiguration();
} catch (JAXBException e) {
throw new ConfigurationManagementException(
"Error occurred while parsing the Tenant configuration : " + e.getMessage(), e);

@ -72,6 +72,14 @@ public interface DeviceInformationManager {
*/
DeviceLocation getDeviceLocation(DeviceIdentifier deviceIdentifier) throws DeviceDetailsMgtException;
/**
* This method will return the device location with latitude, longitude, address etc.. of supplied devices.
* @param deviceIdentifiers - List of Device identifier and device type.
* @return Device Location list.
* @throws DeviceDetailsMgtException
*/
List<DeviceLocation> getDeviceLocations(List<DeviceIdentifier> deviceIdentifiers) throws DeviceDetailsMgtException;
// /**
// * This method will manage the storing of device application list.
// * @param deviceApplication - Device application list.

@ -121,7 +121,7 @@ public class DeviceInformationManagerImpl implements DeviceInformationManager {
}
}
DeviceManagementDAOFactory.openConnection();
for(Integer id : deviceIds) {
for (Integer id : deviceIds) {
DeviceInfo deviceInfo = deviceDetailsDAO.getDeviceInformation(id);
deviceInfo.setDeviceDetailsMap(deviceDetailsDAO.getDeviceProperties(id));
deviceInfos.add(deviceInfo);
@ -183,5 +183,26 @@ public class DeviceInformationManagerImpl implements DeviceInformationManager {
}
}
@Override
public List<DeviceLocation> getDeviceLocations(List<DeviceIdentifier> deviceIdentifiers) throws DeviceDetailsMgtException {
try {
List<Device> devices = DeviceManagementDataHolder.getInstance().
getDeviceManagementProvider().getAllDevices(deviceIdentifiers.get(0).getType());
List<DeviceLocation> deviceLocations = new ArrayList<>();
DeviceManagementDAOFactory.openConnection();
for (Device device : devices) {
deviceLocations.add(deviceDetailsDAO.getDeviceLocation(device.getId()));
}
return deviceLocations;
} catch (DeviceManagementException e) {
throw new DeviceDetailsMgtException("Exception occurred while retrieving the devices.", e);
} catch (SQLException e) {
throw new DeviceDetailsMgtException("SQL error occurred while retrieving device from database.", e);
} catch (DeviceDetailsMgtDAOException e) {
throw new DeviceDetailsMgtException("Exception occurred while retrieving device locations.", e);
}
}
}

@ -25,13 +25,11 @@ import org.wso2.carbon.apimgt.impl.APIManagerConfigurationService;
import org.wso2.carbon.device.mgt.common.DeviceManagementException;
import org.wso2.carbon.device.mgt.common.app.mgt.ApplicationManagementException;
import org.wso2.carbon.device.mgt.common.authorization.DeviceAccessAuthorizationService;
import org.wso2.carbon.device.mgt.common.configuration.mgt.TenantConfigurationManagementService;
import org.wso2.carbon.device.mgt.common.configuration.mgt.PlatformConfigurationManagementService;
import org.wso2.carbon.device.mgt.common.notification.mgt.NotificationManagementService;
import org.wso2.carbon.device.mgt.common.operation.mgt.OperationManagementException;
import org.wso2.carbon.device.mgt.common.operation.mgt.OperationManager;
import org.wso2.carbon.device.mgt.common.permission.mgt.PermissionManagerService;
import org.wso2.carbon.device.mgt.common.push.notification.PushNotificationConfig;
import org.wso2.carbon.device.mgt.common.push.notification.PushNotificationProvider;
import org.wso2.carbon.device.mgt.common.spi.DeviceManagementService;
import org.wso2.carbon.device.mgt.core.DeviceManagementConstants;
import org.wso2.carbon.device.mgt.core.DeviceManagementPluginRepository;
@ -51,7 +49,6 @@ import org.wso2.carbon.device.mgt.core.notification.mgt.dao.NotificationManageme
import org.wso2.carbon.device.mgt.core.operation.mgt.OperationManagerImpl;
import org.wso2.carbon.device.mgt.core.operation.mgt.dao.OperationManagementDAOFactory;
import org.wso2.carbon.device.mgt.core.permission.mgt.PermissionManagerServiceImpl;
import org.wso2.carbon.device.mgt.core.push.notification.mgt.PushNotificationConfigRepository;
import org.wso2.carbon.device.mgt.core.push.notification.mgt.PushNotificationProviderRepository;
import org.wso2.carbon.device.mgt.core.service.DeviceManagementProviderService;
import org.wso2.carbon.device.mgt.core.service.DeviceManagementProviderServiceImpl;
@ -221,9 +218,9 @@ public class DeviceManagementServiceComponent {
bundleContext.registerService(GroupManagementProviderService.class.getName(), groupManagementProvider, null);
/* Registering Tenant Configuration Management Service */
TenantConfigurationManagementService
PlatformConfigurationManagementService
tenantConfiguration = new TenantConfigurationManagementServiceImpl();
bundleContext.registerService(TenantConfigurationManagementService.class.getName(), tenantConfiguration, null);
bundleContext.registerService(PlatformConfigurationManagementService.class.getName(), tenantConfiguration, null);
/* Registering Notification Service */
NotificationManagementService notificationManagementService

@ -768,7 +768,7 @@ public class OperationManagerImpl implements OperationManager {
act.setActivityId(activity);
return act;
} catch (SQLException e) {
throw new OperationManagementException("Error occurred while opening a connection to the data source", e);
throw new OperationManagementException("Error occurred while opening a connection to the data source.", e);
} catch (OperationManagementDAOException e) {
throw new OperationManagementException("Error occurred while retrieving the operation with activity Id '" +
activity, e);
@ -777,6 +777,26 @@ public class OperationManagerImpl implements OperationManager {
}
}
@Override
public List<Operation> getOperationUpdatedAfter(long timestamp) throws OperationManagementException {
return null;
}
@Override
public List<Activity> getActivitiesUpdatedAfter(long timestamp) throws OperationManagementException {
try {
OperationManagementDAOFactory.openConnection();
return operationDAO.getActivitiesUpdatedAfter(timestamp);
} catch (SQLException e) {
throw new OperationManagementException("Error occurred while opening a connection to the data source.", e);
} catch (OperationManagementDAOException e) {
throw new OperationManagementException("Error occurred while getting the activity list changed after a " +
"given time.", e);
} finally {
OperationManagementDAOFactory.closeConnection();
}
}
private OperationDAO lookupOperationDAO(Operation operation) {
if (operation instanceof CommandOperation) {

@ -69,4 +69,8 @@ public interface OperationDAO {
int getEnrolmentIdFromMappingId(int enrollmentOpMappingId) throws OperationManagementDAOException;
List<Operation> getOperationsUpdatedAfter(long timestamp) throws OperationManagementDAOException;
List<Activity> getActivitiesUpdatedAfter(long timestamp) throws OperationManagementDAOException;
}

@ -326,19 +326,125 @@ public class GenericOperationDAOImpl implements OperationDAO {
return activity;
}
@Override
public List<Activity> getActivitiesUpdatedAfter(long timestamp) throws OperationManagementDAOException {
PreparedStatement stmt = null;
ResultSet rs = null;
List<Activity> activities = new ArrayList<>();
try {
Connection conn = OperationManagementDAOFactory.getConnection();
String sql = "SELECT eom.ENROLMENT_ID, eom.OPERATION_ID, eom.ID AS EOM_MAPPING_ID, dor.ID AS OP_RES_ID,\n" +
"de.DEVICE_ID, d.DEVICE_IDENTIFICATION, \n" +
"d.DEVICE_TYPE_ID, dt.NAME AS DEVICE_TYPE_NAME, eom.STATUS, eom.CREATED_TIMESTAMP, \n" +
"eom.UPDATED_TIMESTAMP, op.OPERATION_CODE, op.TYPE AS OPERATION_TYPE, dor.OPERATION_RESPONSE, \n" +
"dor.RECEIVED_TIMESTAMP FROM DM_ENROLMENT_OP_MAPPING AS eom \n" +
"INNER JOIN DM_OPERATION AS op ON op.ID=eom.OPERATION_ID\n" +
"INNER JOIN DM_ENROLMENT AS de ON de.ID=eom.ENROLMENT_ID\n" +
"INNER JOIN DM_DEVICE AS d ON d.ID=de.DEVICE_ID \n" +
"INNER JOIN DM_DEVICE_TYPE AS dt ON dt.ID=d.DEVICE_TYPE_ID\n" +
"LEFT JOIN DM_DEVICE_OPERATION_RESPONSE AS dor ON dor.ENROLMENT_ID=de.id \n" +
"AND dor.OPERATION_ID=eom.OPERATION_ID\n" +
"WHERE eom.UPDATED_TIMESTAMP > ? AND de.TENANT_ID = ?";
stmt = conn.prepareStatement(sql);
stmt.setLong(1, timestamp);
stmt.setInt(2, PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId());
rs = stmt.executeQuery();
int operationId = 0;
int enrolmentId = 0;
Activity activity = null;
ActivityStatus activityStatus = null;
while (rs.next()) {
if(operationId != rs.getInt("OPERATION_ID")) {
activity = new Activity();
activities.add(activity);
List<ActivityStatus> statusList = new ArrayList<>();
activityStatus = new ActivityStatus();
operationId = rs.getInt("OPERATION_ID");
enrolmentId = rs.getInt("ENROLMENT_ID");
activity.setType(Activity.Type.valueOf(rs.getString("OPERATION_TYPE")));
activity.setCreatedTimeStamp(new java.util.Date(rs.getLong(("CREATED_TIMESTAMP"))).toString());
activity.setCode(rs.getString("OPERATION_CODE"));
DeviceIdentifier deviceIdentifier = new DeviceIdentifier();
deviceIdentifier.setId(rs.getString("DEVICE_IDENTIFICATION"));
deviceIdentifier.setType(rs.getString("DEVICE_TYPE_NAME"));
activityStatus.setDeviceIdentifier(deviceIdentifier);
activityStatus.setStatus(ActivityStatus.Status.valueOf(rs.getString("STATUS")));
List<OperationResponse> operationResponses = new ArrayList<>();
if (rs.getInt("UPDATED_TIMESTAMP") != 0) {
operationResponses.add(this.getOperationResponse(rs));
}
activityStatus.setResponses(operationResponses);
statusList.add(activityStatus);
activity.setActivityStatus(statusList);
activity.setActivityId(this.getActivityId(rs.getInt("OPERATION_ID")));
}
if(operationId == rs.getInt("OPERATION_ID") && enrolmentId != rs.getInt("ENROLMENT_ID")) {
activityStatus = new ActivityStatus();
activity.setType(Activity.Type.valueOf(rs.getString("OPERATION_TYPE")));
activity.setCreatedTimeStamp(new java.util.Date(rs.getLong(("CREATED_TIMESTAMP"))).toString());
activity.setCode(rs.getString("OPERATION_CODE"));
DeviceIdentifier deviceIdentifier = new DeviceIdentifier();
deviceIdentifier.setId(rs.getString("DEVICE_IDENTIFICATION"));
deviceIdentifier.setType(rs.getString("DEVICE_TYPE_NAME"));
activityStatus.setDeviceIdentifier(deviceIdentifier);
activityStatus.setStatus(ActivityStatus.Status.valueOf(rs.getString("STATUS")));
List<OperationResponse> operationResponses = new ArrayList<>();
if (rs.getTimestamp("RECEIVED_TIMESTAMP") !=(null)) {
operationResponses.add(this.getOperationResponse(rs));
}
activityStatus.setResponses(operationResponses);
activity.getActivityStatus().add(activityStatus);
enrolmentId = rs.getInt("ENROLMENT_ID");
} else {
if (rs.getTimestamp("RECEIVED_TIMESTAMP") !=(null)) {
activityStatus.getResponses().add(this.getOperationResponse(rs));
}
}
}
} catch (SQLException e) {
throw new OperationManagementDAOException("Error occurred while getting the operation details from " +
"the database.", e);
} catch (ClassNotFoundException e) {
throw new OperationManagementDAOException("Error occurred while converting the operation response to string.", e);
} catch (IOException e) {
throw new OperationManagementDAOException("IO exception occurred while converting the operations responses.", e);
} finally {
OperationManagementDAOUtil.cleanupResources(stmt, rs);
}
return activities;
}
private OperationResponse getOperationResponse(ResultSet rs) throws
ClassNotFoundException, IOException, SQLException {
OperationResponse response = new OperationResponse();
response.setRecievedTimeStamp(rs.getTimestamp("RECEIVED_TIMESTAMP").toString());
if(rs.getTimestamp("RECEIVED_TIMESTAMP") !=(null)) {
response.setRecievedTimeStamp(rs.getTimestamp("RECEIVED_TIMESTAMP").toString());
}
ByteArrayInputStream bais = null;
ObjectInputStream ois = null;
byte[] contentBytes;
try {
contentBytes = (byte[]) rs.getBytes("OPERATION_RESPONSE");
bais = new ByteArrayInputStream(contentBytes);
ois = new ObjectInputStream(bais);
response.setResponse(ois.readObject().toString());
if(rs.getBytes("OPERATION_RESPONSE") != null) {
contentBytes = (byte[]) rs.getBytes("OPERATION_RESPONSE");
bais = new ByteArrayInputStream(contentBytes);
ois = new ObjectInputStream(bais);
response.setResponse(ois.readObject().toString());
}
} finally {
if (bais != null) {
try {
@ -382,6 +488,42 @@ public class GenericOperationDAOImpl implements OperationDAO {
return -1;
}
@Override
public List<Operation> getOperationsUpdatedAfter(long timestamp) throws OperationManagementDAOException {
PreparedStatement stmt = null;
ResultSet rs = null;
List<Operation> operations = new ArrayList<>();
try {
Connection conn = OperationManagementDAOFactory.getConnection();
String sql = "SELECT o.ID, o.TYPE, o.CREATED_TIMESTAMP, o.RECEIVED_TIMESTAMP, OPERATION_CODE " +
"FROM DM_OPERATION AS o \n" +
"INNER JOIN DM_ENROLMENT_OP_MAPPING AS eom ON eom.OPERATION_ID=o.ID WHERE eom.UPDATED_TIMESTAMP = ?";
stmt = conn.prepareStatement(sql);
stmt.setLong(1, timestamp);
rs = stmt.executeQuery();
if (rs.next()) {
Operation operation = new Operation();
operation.setId(rs.getInt("ID"));
operation.setType(Operation.Type.valueOf(rs.getString("TYPE")));
operation.setCreatedTimeStamp(rs.getTimestamp("CREATED_TIMESTAMP").toString());
operation.setCode(rs.getString("OPERATION_CODE"));
operations.add(operation);
}
} catch (SQLException e) {
throw new OperationManagementDAOException("Error occurred while retrieving the operations updated " +
"after a given time" , e);
} finally {
OperationManagementDAOUtil.cleanupResources(stmt, rs);
}
return operations;
}
@Override
public void deleteOperation(int id) throws OperationManagementDAOException {
PreparedStatement stmt = null;
@ -839,8 +981,13 @@ public class GenericOperationDAOImpl implements OperationDAO {
return Operation.Type.valueOf(type);
}
private void setActivityId(Operation operation, int enrolmentId) {
operation.setActivityId(DeviceManagementConstants.OperationAttributes.ACTIVITY + enrolmentId);
private void setActivityId(Operation operation, int operationId) {
operation.setActivityId(DeviceManagementConstants.OperationAttributes.ACTIVITY + operationId);
}
private String getActivityId( int operationId) {
return DeviceManagementConstants.OperationAttributes.ACTIVITY + operationId;
}

@ -118,4 +118,14 @@ public class PushNotificationBasedOperationManager implements OperationManager {
return this.operationManager.getOperationByActivityId(activity);
}
@Override
public List<Operation> getOperationUpdatedAfter(long timestamp) throws OperationManagementException {
return this.operationManager.getOperationUpdatedAfter(timestamp);
}
@Override
public List<Activity> getActivitiesUpdatedAfter(long timestamp) throws OperationManagementException {
return this.operationManager.getActivitiesUpdatedAfter(timestamp);
}
}

@ -19,8 +19,13 @@
package org.wso2.carbon.device.mgt.core.search.mgt.impl;
import org.wso2.carbon.context.CarbonContext;
import org.wso2.carbon.device.mgt.common.Device;
import org.wso2.carbon.device.mgt.common.app.mgt.ApplicationManagementException;
import org.wso2.carbon.device.mgt.common.device.details.DeviceWrapper;
import org.wso2.carbon.device.mgt.common.search.SearchContext;
import org.wso2.carbon.device.mgt.core.dao.ApplicationDAO;
import org.wso2.carbon.device.mgt.core.dao.DeviceManagementDAOException;
import org.wso2.carbon.device.mgt.core.dao.DeviceManagementDAOFactory;
import org.wso2.carbon.device.mgt.core.search.mgt.*;
import org.wso2.carbon.device.mgt.core.search.mgt.dao.SearchDAO;
@ -35,9 +40,11 @@ import java.util.Map;
public class ProcessorImpl implements Processor {
private SearchDAO searchDAO;
private ApplicationDAO applicationDAO;
public ProcessorImpl() {
searchDAO = DeviceManagementDAOFactory.getSearchDAO();
applicationDAO = DeviceManagementDAOFactory.getApplicationDAO();
}
@Override
@ -91,7 +98,9 @@ public class ProcessorImpl implements Processor {
deviceWrappers.put(Constants.PROP_OR, this.processORSearch(allORDevices));
deviceWrappers.put(Constants.LOCATION, locationDevices);
return aggregator.aggregate(deviceWrappers);
List<DeviceWrapper> finalDeviceWrappers = aggregator.aggregate(deviceWrappers);
this.setApplicationListOfDevices(finalDeviceWrappers);
return finalDeviceWrappers;
}
@Override
@ -186,5 +195,21 @@ public class ProcessorImpl implements Processor {
return maps;
}
private void setApplicationListOfDevices(List<DeviceWrapper> deviceWrappers) throws SearchMgtException {
try {
DeviceManagementDAOFactory.openConnection();
for (DeviceWrapper wrapper : deviceWrappers) {
wrapper.setApplications(applicationDAO.getInstalledApplications(wrapper.getDevice().getId()));
}
} catch (DeviceManagementDAOException e) {
throw new SearchMgtException("Error occurred while fetching the Application List of devices ", e);
} catch (SQLException e) {
throw new SearchMgtException("Error occurred while opening a connection to the data source", e);
} finally {
DeviceManagementDAOFactory.closeConnection();
}
}
}

@ -24,12 +24,11 @@ import org.wso2.carbon.device.mgt.common.EnrolmentInfo;
import org.wso2.carbon.device.mgt.common.FeatureManager;
import org.wso2.carbon.device.mgt.common.PaginationRequest;
import org.wso2.carbon.device.mgt.common.PaginationResult;
import org.wso2.carbon.device.mgt.common.configuration.mgt.TenantConfiguration;
import org.wso2.carbon.device.mgt.common.configuration.mgt.PlatformConfiguration;
import org.wso2.carbon.device.mgt.common.license.mgt.License;
import org.wso2.carbon.device.mgt.common.operation.mgt.Activity;
import org.wso2.carbon.device.mgt.common.operation.mgt.Operation;
import org.wso2.carbon.device.mgt.common.operation.mgt.OperationManagementException;
import org.wso2.carbon.device.mgt.common.operation.mgt.OperationManager;
import org.wso2.carbon.device.mgt.core.dto.DeviceType;
import java.util.List;
@ -78,7 +77,7 @@ public interface DeviceManagementProviderService {
* @throws DeviceManagementException If some unusual behaviour is observed while fetching the
* configuration.
*/
TenantConfiguration getConfiguration(String deviceType) throws DeviceManagementException;
PlatformConfiguration getConfiguration(String deviceType) throws DeviceManagementException;
/**
* Method to get the list of devices owned by an user with paging information.
@ -187,9 +186,9 @@ public interface DeviceManagementProviderService {
boolean enrollDevice(Device device) throws DeviceManagementException;
TenantConfiguration getConfiguration() throws DeviceManagementException;
PlatformConfiguration getConfiguration() throws DeviceManagementException;
boolean saveConfiguration(TenantConfiguration configuration) throws DeviceManagementException;
boolean saveConfiguration(PlatformConfiguration configuration) throws DeviceManagementException;
boolean disenrollDevice(DeviceIdentifier deviceId) throws DeviceManagementException;
@ -245,4 +244,6 @@ public interface DeviceManagementProviderService {
Activity getOperationByActivityId(String activity) throws OperationManagementException;
List<Activity> getActivitiesUpdatedAfter(long timestamp) throws OperationManagementException;
}

@ -30,7 +30,7 @@ import org.wso2.carbon.device.mgt.common.FeatureManager;
import org.wso2.carbon.device.mgt.common.PaginationRequest;
import org.wso2.carbon.device.mgt.common.PaginationResult;
import org.wso2.carbon.device.mgt.common.TransactionManagementException;
import org.wso2.carbon.device.mgt.common.configuration.mgt.TenantConfiguration;
import org.wso2.carbon.device.mgt.common.configuration.mgt.PlatformConfiguration;
import org.wso2.carbon.device.mgt.common.license.mgt.License;
import org.wso2.carbon.device.mgt.common.license.mgt.LicenseManagementException;
import org.wso2.carbon.device.mgt.common.operation.mgt.Activity;
@ -93,7 +93,7 @@ public class DeviceManagementProviderServiceImpl implements DeviceManagementProv
}
@Override
public boolean saveConfiguration(TenantConfiguration configuration) throws DeviceManagementException {
public boolean saveConfiguration(PlatformConfiguration configuration) throws DeviceManagementException {
DeviceManager dms =
pluginRepository.getDeviceManagementService(configuration.getType(),
this.getTenantId()).getDeviceManager();
@ -101,12 +101,12 @@ public class DeviceManagementProviderServiceImpl implements DeviceManagementProv
}
@Override
public TenantConfiguration getConfiguration() throws DeviceManagementException {
public PlatformConfiguration getConfiguration() throws DeviceManagementException {
return null;
}
@Override
public TenantConfiguration getConfiguration(String deviceType) throws DeviceManagementException {
public PlatformConfiguration getConfiguration(String deviceType) throws DeviceManagementException {
DeviceManager dms =
pluginRepository.getDeviceManagementService(deviceType, this.getTenantId()).getDeviceManager();
if (dms == null) {
@ -879,6 +879,11 @@ public class DeviceManagementProviderServiceImpl implements DeviceManagementProv
return DeviceManagementDataHolder.getInstance().getOperationManager().getOperationByActivityId(activity);
}
@Override
public List<Activity> getActivitiesUpdatedAfter(long timestamp) throws OperationManagementException {
return DeviceManagementDataHolder.getInstance().getOperationManager().getActivitiesUpdatedAfter(timestamp);
}
@Override
public List<Device> getDevicesOfUser(String username) throws DeviceManagementException {
List<Device> devices = new ArrayList<>();

@ -22,7 +22,7 @@ import org.wso2.carbon.device.mgt.common.Device;
import org.wso2.carbon.device.mgt.common.DeviceIdentifier;
import org.wso2.carbon.device.mgt.common.PaginationResult;
import org.wso2.carbon.device.mgt.common.group.mgt.DeviceGroup;
import org.wso2.carbon.device.mgt.common.group.mgt.GroupAlreadyEixistException;
import org.wso2.carbon.device.mgt.common.group.mgt.GroupAlreadyExistException;
import org.wso2.carbon.device.mgt.common.group.mgt.GroupManagementException;
import org.wso2.carbon.device.mgt.common.group.mgt.GroupUser;
import org.wso2.carbon.user.core.multiplecredentials.UserDoesNotExistException;
@ -43,7 +43,7 @@ public interface GroupManagementProviderService {
* @throws GroupManagementException
*/
void createGroup(DeviceGroup deviceGroup, String defaultRole,
String[] defaultPermissions) throws GroupManagementException, GroupAlreadyEixistException;
String[] defaultPermissions) throws GroupManagementException, GroupAlreadyExistException;
/**
* Update existing device group.

@ -29,7 +29,7 @@ import org.wso2.carbon.device.mgt.common.DeviceManagementException;
import org.wso2.carbon.device.mgt.common.PaginationResult;
import org.wso2.carbon.device.mgt.common.TransactionManagementException;
import org.wso2.carbon.device.mgt.common.group.mgt.DeviceGroup;
import org.wso2.carbon.device.mgt.common.group.mgt.GroupAlreadyEixistException;
import org.wso2.carbon.device.mgt.common.group.mgt.GroupAlreadyExistException;
import org.wso2.carbon.device.mgt.common.group.mgt.GroupManagementException;
import org.wso2.carbon.device.mgt.common.group.mgt.GroupUser;
import org.wso2.carbon.device.mgt.core.group.mgt.DeviceGroupBuilder;
@ -69,7 +69,7 @@ public class GroupManagementProviderServiceImpl implements GroupManagementProvid
*/
@Override
public void createGroup(DeviceGroup deviceGroup, String defaultRole, String[] defaultPermissions)
throws GroupManagementException, GroupAlreadyEixistException {
throws GroupManagementException, GroupAlreadyExistException {
if (deviceGroup == null) {
throw new GroupManagementException("DeviceGroup cannot be null.", new NullPointerException());
}
@ -83,7 +83,7 @@ public class GroupManagementProviderServiceImpl implements GroupManagementProvid
groupId = this.groupDAO.addGroup(groupBroker, tenantId);
GroupManagementDAOFactory.commitTransaction();
} else {
throw new GroupAlreadyEixistException("Group exist with name " + deviceGroup.getName());
throw new GroupAlreadyExistException("Group exist with name " + deviceGroup.getName());
}
} catch (GroupManagementDAOException e) {
GroupManagementDAOFactory.rollbackTransaction();

@ -16,7 +16,7 @@
package org.wso2.carbon.device.mgt.core;
import org.wso2.carbon.device.mgt.common.*;
import org.wso2.carbon.device.mgt.common.configuration.mgt.TenantConfiguration;
import org.wso2.carbon.device.mgt.common.configuration.mgt.PlatformConfiguration;
import org.wso2.carbon.device.mgt.common.license.mgt.License;
import org.wso2.carbon.device.mgt.common.license.mgt.LicenseManagementException;
@ -34,12 +34,12 @@ public class TestDeviceManager implements DeviceManager {
}
@Override
public boolean saveConfiguration(TenantConfiguration configuration)
public boolean saveConfiguration(PlatformConfiguration configuration)
throws DeviceManagementException {
return false;
}
@Override public TenantConfiguration getConfiguration() throws DeviceManagementException {
@Override public PlatformConfiguration getConfiguration() throws DeviceManagementException {
return null;
}

@ -26,7 +26,14 @@
}
},
"sso": {
"enabled": false
"enabled": false,
"issuer" : "devicemgt",
"appName" : "devicemgt",
"identityProviderUrl" : "https://localhost:9443/samlsso",
"acs": "https://localhost:9443/devicemgt/uuf/sso/acs",
"identityAlias": "wso2carbon",
"responseSigningEnabled" : "true",
"useTenantKey": false
}
},
"errorPages": {

@ -2,7 +2,7 @@
"appContext" : "/devicemgt/",
"webAgentContext" : "/devicemgt-web-agent/",
"apiContext" : "api",
"httpsURL" : "%https.ip%",
"httpsURL" : "https://localhost:8243",
"httpURL" : "%http.ip%",
"wssURL" : "%https.ip%",
"wsURL" : "%http.ip%",
@ -11,9 +11,9 @@
"iOSAPIRoot" : "%https.ip%/ios/",
"dynamicClientRegistrationEndPoint" : "%https.ip%/dynamic-client-web/register/",
"adminService":"%https.ip%",
"idPServer":"%https.ip%",
"idPServer":"https://localhost:8243",
"callBackUrl":"%https.ip%/devicemgt_admin",
"adminUser":"admin",
"adminUser":"admin@carbon.super",
"adminRole":"admin",
"usernameLength":30,
"ssoConfiguration" : {
@ -37,6 +37,11 @@
"emailJSRegEx" : "/^\w+([\.-]?\w+)*@\w+([\.-]?\w+)*(\.\w{2,3})+$/",
"emailRegExViolationErrorMsg" : "Provided email is invalid."
},
"groupValidationConfig": {
"groupNameJSRegEx": "^[\\S]{3,30}$",
"groupNameRegExViolationErrorMsg": "Provided group name is invalid.",
"groupNameHelpMsg": "Should be in minimum 3 characters long and should not include any whitespaces."
},
"roleValidationConfig" : {
"rolenameJSRegEx" : "^[\\S]{3,30}$",
"rolenameRegExViolationErrorMsg" : "Provided role name is invalid.",
@ -50,5 +55,12 @@
"copyrightOwner" : "WSO2 Inc.",
"copyrightOwnersSite" : "http://www.wso2.org",
"copyrightSuffix" : " All Rights Reserved."
}
},
"scopes" : ["license-add", "license-view", "device-view", "device-info", "device-list", "device-view-own",
"device-modify", "device-search", "operation-install", "operation-view", "operation-modify", "operation-uninstall",
"group-add", "group-share", "group-modify", "group-view", "group-remove", "certificate-modify", "certificate-view",
"configuration-view", "configuration-modify", "policy-view", "policy-modify", "device-notification-view",
"device-notification-modify", "feature-view", "arduino_device", "arduino_user", " android_sense_user",
"virtual_firealarm_user", "raspberrypi_user", "roles-view", "roles-modify", "roles-remove", "roles-add",
"user-password-reset", "user-password-modify", "user-modify", "user-view", "user-invite", "user-remove", "user-add"]
}

@ -20,7 +20,8 @@ var apiWrapperUtil = function () {
var module = {};
var tokenUtil = require("/app/modules/util.js").util;
var constants = require("/app/modules/constants.js");
var constants = require("/app/modules/constants.js");
var devicemgtProps = require('/app/conf/devicemgt-props.js').config();
var log = new Log("/app/modules/api-wrapper-util.js");
module.refreshToken = function () {
var tokenPair = session.get(constants.ACCESS_TOKEN_PAIR_IDENTIFIER);
@ -31,11 +32,19 @@ var apiWrapperUtil = function () {
module.setupAccessTokenPair = function (type, properties) {
var tokenPair;
var clientData = tokenUtil.getDyanmicCredentials(properties);
var jwtToken = tokenUtil.getTokenWithJWTGrantType(clientData);
clientData = tokenUtil.getTenantBasedAppCredentials(properties.username, jwtToken);
var encodedClientKeys = tokenUtil.encode(clientData.clientId + ":" + clientData.clientSecret);
session.put(constants.ENCODED_CLIENT_KEYS_IDENTIFIER, encodedClientKeys);
if (type == constants.GRANT_TYPE_PASSWORD) {
var scopes = devicemgtProps.scopes;
var scope = "";
scopes.forEach(function(entry) {
scope += entry + " ";
});
tokenPair =
tokenUtil.getTokenWithPasswordGrantType(properties.username, encodeURIComponent(properties.password), encodedClientKeys);
tokenUtil.getTokenWithPasswordGrantType(properties.username, encodeURIComponent(properties.password),
encodedClientKeys, scope);
} else if (type == constants.GRANT_TYPE_SAML) {
tokenPair = tokenUtil.
getTokenWithSAMLGrantType(properties.samlToken, encodedClientKeys, "PRODUCTION");

@ -65,6 +65,7 @@ var backendServiceInvoker = function () {
}
xmlHttpRequest.setRequestHeader(constants.CONTENT_TYPE_IDENTIFIER, contentType);
xmlHttpRequest.setRequestHeader(constants.ACCEPT_IDENTIFIER, acceptType);
xmlHttpRequest.setRequestHeader(constants.REFERER, String(privateMethods.getClientDomain()));
if (IS_OAUTH_ENABLED) {
var accessToken = privateMethods.getAccessToken();
if (!accessToken) {
@ -150,6 +151,10 @@ var backendServiceInvoker = function () {
header.setName(constants.ACCEPT_IDENTIFIER);
header.setValue(acceptType);
httpMethodObject.addRequestHeader(header);
header = new Header();
header.setName(constants.REFERER);
header.setValue(String(privateMethods.getClientDomain()));
httpMethodObject.addRequestHeader(header);
if (IS_OAUTH_ENABLED) {
var accessToken = privateMethods.getAccessToken();
if (accessToken) {
@ -210,6 +215,12 @@ var backendServiceInvoker = function () {
oAuthAuthenticationData.name = authenticationHeaderName;
oAuthAuthenticationData.value = authenticationHeaderValue;
headers.push(oAuthAuthenticationData);
var referrerData = {};
referrerData.name = constants.REFERER;
referrerData.value = String(privateMethods.getClientDomain());
headers.push(referrerData);
options.HTTPHeaders = headers;
} else {
response.sendRedirect(devicemgtProps["httpsURL"] + "/devicemgt/login");
@ -331,6 +342,16 @@ var backendServiceInvoker = function () {
return privateMethods.initiateHTTPClientRequest(constants.HTTP_DELETE, url, successCallback, errorCallback, contentType, acceptType);
};
/**
* This method fetch the current logged user from the session and returns
* the tenant domain name of the user
* @returns {tenantDomain}
*/
privateMethods.getClientDomain = function () {
var user = session.get(constants.USER_SESSION_KEY);
return user.domain;
}
var publicInvokers = {};
publicInvokers.XMLHttp = publicXMLHTTPInvokers;
publicInvokers.WS = publicWSInvokers;

@ -70,6 +70,7 @@ var HTTP_GET = "GET";
var HTTP_POST = "POST";
var HTTP_PUT = "PUT";
var HTTP_DELETE = "DELETE";
var REFERER = "referer"
var GRANT_TYPE_PASSWORD = "password";
var GRANT_TYPE_SAML = "saml";
@ -78,3 +79,5 @@ var MQTT_QUEUE_CONFIG_NAME = "MQTT";
var HTTP_CONFLICT = 409;
var HTTP_CREATED = 201;
var CACHED_CREDENTIALS = "tenantBasedCredentials";

@ -35,7 +35,7 @@ var onFail;
}
var devicemgtProps = require('/app/conf/devicemgt-props.js').config();
var carbonServer = require("carbon").server;
(new carbonServer.Server({url: devicemgtProps["httpsURL"]}))
(new carbonServer.Server({url: devicemgtProps["adminService"]}))
.login(context.input.username, context.input.password);
};

@ -23,16 +23,15 @@ var util = function () {
var String = Packages.java.lang.String;
var devicemgtProps = require('/app/conf/devicemgt-props.js').config();
var carbon = require('carbon');
var realmService = carbon.server.osgiService('org.wso2.carbon.user.core.service.RealmService');
var adminUserName = realmService.getBootstrapRealmConfiguration().getAdminUserName();
var constants = require("/app/modules/constants.js");
var adminUser = devicemgtProps["adminUser"];
module.getDyanmicCredentials = function (owner) {
var payload = {
"callbackUrl": devicemgtProps.callBackUrl,
"clientName": "devicemgt",
"tokenScope": "admin",
"owner": adminUserName,
"owner": adminUser,
"applicationType": "webapp",
"grantType": "password refresh_token urn:ietf:params:oauth:grant-type:saml2-bearer",
"saasApp" :true
@ -47,6 +46,7 @@ var util = function () {
var data = parse(xhr.responseText);
clientData.clientId = data.client_id;
clientData.clientSecret = data.client_secret;
} else if (xhr.status == 400) {
throw "Invalid client meta data";
} else {
@ -79,7 +79,7 @@ var util = function () {
*/
module.getTokenWithPasswordGrantType = function (username, password, encodedClientKeys, scope) {
var xhr = new XMLHttpRequest();
var tokenEndpoint = devicemgtProps.idPServer + "/oauth2/token";
var tokenEndpoint = devicemgtProps.idPServer + "/token";
xhr.open("POST", tokenEndpoint, false);
xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
xhr.setRequestHeader("Authorization", "Basic " + encodedClientKeys);
@ -137,6 +137,7 @@ var util = function () {
}
return tokenPair;
};
module.refreshToken = function (tokenPair, clientData, scope) {
var xhr = new XMLHttpRequest();
var tokenEndpoint = devicemgtProps.idPServer + "/oauth2/token";
@ -163,5 +164,62 @@ var util = function () {
}
return tokenPair;
};
module.getTokenWithJWTGrantType = function (clientData) {
var jwtService = carbon.server.osgiService('org.wso2.carbon.identity.jwt.client.extension.service.JWTClientManagerService');
var jwtClient = jwtService.getJWTClient();
var jwtToken = jwtClient.getAccessToken(clientData.clientId, clientData.clientSecret, adminUser, null);
return jwtToken;
};
module.getTenantBasedAppCredentials = function (uname, token) {
var tenantDomain = carbonModule.server.tenantDomain({
username: uname
});
var clientData = this.getCachedCredentials(tenantDomain);
if (!clientData) {
var applicationName = "webapp_" + tenantDomain;
var xhr = new XMLHttpRequest();
var endpoint = devicemgtProps["adminService"] + "/api-application-registration/register/tenants?tenantDomain=" +
tenantDomain + "&applicationName=" + applicationName;
xhr.open("POST", endpoint, false);
xhr.setRequestHeader("Content-Type", "application/json");
xhr.setRequestHeader("Authorization", "Bearer " + token.accessToken);
xhr.send();
if (xhr.status == 201) {
var data = parse(xhr.responseText);
clientData = {};
clientData.clientId = data.client_id;
clientData.clientSecret = data.client_secret;
this.setTenantBasedAppCredentials(tenantDomain, clientData);
} else if (xhr.status == 400) {
throw "Invalid client meta data";
} else {
throw "Error in obtaining client id and secret from APIM";
}
}
return clientData;
};
module.setTenantBasedAppCredentials = function (tenantDomain, clientData) {
var cachedMap = application.get(constants.CACHED_CREDENTIALS);
if (!cachedMap) {
cachedMap = new Object();
cachedMap[tenantDomain] = clientData;
application.put(constants.CACHED_CREDENTIALS, cachedMap);
} else {
cachedMap[tenantDomain] = clientData;
}
};
module.getCachedCredentials = function(tenantDomain) {
var cachedMap = application.get(constants.CACHED_CREDENTIALS);
if (cachedMap) {
return cachedMap[tenantDomain];
}
return null;
};
return module;
}();

@ -1,20 +1,3 @@
{{!
Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
WSO2 Inc. licenses this file to you under the Apache License,
Version 2.0 (the "License"); you may not use this file except
in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
}}
{{unit "cdmf.unit.ui.title" pageTitle="Group Management"}}
{{#zone "breadcrumbs"}}
@ -49,11 +32,12 @@
</span>
<hr/>
<form method="GET" class="form-login-box" action="groups">
<div class="form-login-box">
<label class="wr-input-label">Group Name</label>
<div class="wr-input-control">
<input type="text right" id="name" placeholder="Group Name">
<input type="text right" id="name" placeholder="Group Name" data-regex="{{groupNameJSRegEx}}"
data-errormsg="{{groupNameRegExViolationErrorMsg}}">
</div>
<label class="wr-input-label">Description</label>
@ -68,7 +52,7 @@
<button class="wr-btn" onclick="window.location = '{{@app.context}}/groups';return false;">
&nbsp;&nbsp;&nbsp;&nbsp;Cancel&nbsp;&nbsp;&nbsp;&nbsp;</button>
</div>
</form>
</div>
</div>
</div>

@ -0,0 +1,32 @@
/*
* Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
*
* WSO2 Inc. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
/**
* Returns the dynamic state to be populated by add-group page.
*
* @param context Object that gets updated with the dynamic state of this page to be presented
* @returns {*} A context object that returns the dynamic state of this page to be presented
*/
function onRequest(context) {
var devicemgtProps = require('/app/conf/devicemgt-props.js').config();
var page = {};
page["groupNameJSRegEx"] = devicemgtProps.groupValidationConfig.groupNameJSRegEx;
page["groupNameRegExViolationErrorMsg"] = devicemgtProps.groupValidationConfig.groupNameRegExViolationErrorMsg;
page["groupNameHelpMsg"] = devicemgtProps.groupValidationConfig.groupNameHelpMsg;
return page;
}

@ -16,6 +16,18 @@
* under the License.
*/
/**
* Checks if provided input is valid against RegEx input.
*
* @param regExp Regular expression
* @param inputString Input string to check
* @returns {boolean} Returns true if input matches RegEx
*/
function inputIsValid(regExp, inputString) {
regExp = new RegExp(regExp);
return regExp.test(inputString);
}
$(function () {
$("button#add-group-btn").click(function () {
@ -26,6 +38,10 @@ $(function () {
$('.wr-validation-summary strong').text("Group Name is a required field. It cannot be empty.");
$('.wr-validation-summary').removeClass("hidden");
return false;
} else if (!inputIsValid($("input#name").data("regex"), name)) {
$('.wr-validation-summary strong').text($("input#name").data("errormsg"));
$('.wr-validation-summary').removeClass("hidden");
return false;
} else {
var group = {"name": name, "description": description};

@ -226,8 +226,7 @@
<div class="content">
<div class="row">
<div class="col-lg-5 col-md-6 col-centered">
<h3>Exception at backend. Try Later.</h3>
<h3 id="error-msg">Bad Request. Please contact your administrator.</h3>
<div class="buttons">
<a href="#" id="group-400-link" class="btn-operations">
&nbsp;&nbsp;&nbsp;&nbsp;Ok&nbsp;&nbsp;&nbsp;&nbsp;

@ -484,6 +484,9 @@ function displayErrors(jqXHR) {
showPopup();
if (jqXHR.status == 400) {
$(modalPopupContent).html($('#group-400-content').html());
if (jqXHR.responseText) {
$('#error-msg').html(jqXHR.responseText.replace(new RegExp("\"", 'g'), ""));
}
$("a#group-400-link").click(function () {
hidePopup();
});

@ -69,6 +69,8 @@ var constants = {
APP_CONF_AUTH_MODULE_SSO_IDENTITY_PROVIDER_ALIAS: "identityProviderAlias",
APP_CONF_AUTH_MODULE_SSO_IDENTITY_PROVIDER_URL: "identityProviderUrl",
APP_CONF_AUTH_MODULE_SSO_INTERMEDIATE_PAGE: "intermediatePage",
APP_CONF_AUTH_MODULE_SSO_IDENTITY_ALIAS : "identityAlias",
APP_CONF_AUTH_MODULE_SSO_USE_ST_KEY : "useTenantKey",
// Configurations - UUF
UUF_CONF_DISPLAY_NAME: "displayName",
UUF_CONF_LOG_LEVEL: "logLevel",

@ -501,7 +501,6 @@ var module = {};
response.sendError(500, e.message);
return;
}
if (ssoClient.isLogoutResponse(samlResponseObj)) {
// This is a logout response.
module.logout(response);
@ -510,11 +509,15 @@ var module = {};
var ssoConfigs = getSsoConfigurations();
var rsEnabled = ssoConfigs[constants.APP_CONF_AUTH_MODULE_SSO_RESPONSE_SIGNING_ENABLED];
if (utils.parseBoolean(rsEnabled)) {
// Response signing is enabled.
var CarbonUtils = Packages.org.wso2.carbon.utils.CarbonUtils;
var keyStorePassword = CarbonUtils.getServerConfiguration().getFirstProperty("Security.TrustStore.Password");
var keyStoreName = CarbonUtils.getServerConfiguration().getFirstProperty("Security.TrustStore.Location");
var identityAlias = ssoConfigs[constants.APP_CONF_AUTH_MODULE_SSO_IDENTITY_ALIAS];
var keyStoreParams = {
KEY_STORE_NAME: ssoConfigs[constants.APP_CONF_AUTH_MODULE_SSO_KEY_STORE_NAME],
KEY_STORE_PASSWORD: ssoConfigs[constants.APP_CONF_AUTH_MODULE_SSO_KEY_STORE_PASSWORD],
IDP_ALIAS: ssoConfigs[constants.APP_CONF_AUTH_MODULE_SSO_IDENTITY_PROVIDER_ALIAS]
KEY_STORE_NAME: keyStoreName,
KEY_STORE_PASSWORD: keyStorePassword,
IDP_ALIAS: identityAlias,
USE_ST_KEY: !ssoConfigs[constants.APP_CONF_AUTH_MODULE_SSO_USE_ST_KEY]
};
if (!ssoClient.validateSignature(samlResponseObj, keyStoreParams)) {
var msg = "Invalid signature found in the SAML response.";
@ -532,10 +535,13 @@ var module = {};
if (ssoSession.sessionId) {
var ssoSessions = getSsoSessions();
ssoSessions[ssoSession.sessionId] = ssoSession;
var carbonUser = (require("carbon")).server.tenantUser(ssoSession.loggedInUser);
utils.setCurrentUser(carbonUser.username, carbonUser.domain, carbonUser.tenantId);
var scriptArgument = {input: {samlToken: ssoSession.samlToken}, user: module.getCurrentUser()};
handleEvent(OPERATION_LOGIN, EVENT_SUCCESS, scriptArgument);
if (ssoSessions.sessionIndex != null || ssoSessions.sessionIndex != 'undefined') {
module.loadTenant(ssoSessions.loggedInUser);
var carbonUser = (require("carbon")).server.tenantUser(ssoSession.loggedInUser);
utils.setCurrentUser(carbonUser.username, carbonUser.domain, carbonUser.tenantId);
var scriptArgument = {input: {samlToken: ssoSession.samlToken}, user: module.getCurrentUser()};
handleEvent(OPERATION_LOGIN, EVENT_SUCCESS, scriptArgument);
}
} else {
var msg = "Cannot decode SAML login response.";
log.error(msg);
@ -544,6 +550,25 @@ var module = {};
}
};
/**
* Load current user tenant
* @param username logged user name
*/
module.loadTenant = function (username) {
var carbon = require('carbon');
var MultitenantUtils = Packages.org.wso2.carbon.utils.multitenancy.MultitenantUtils;
var MultitenantConstants = Packages.org.wso2.carbon.base.MultitenantConstants;
var TenantAxisUtils = Packages.org.wso2.carbon.core.multitenancy.utils.TenantAxisUtils;
var service;
var ctx;
var domain = MultitenantUtils.getTenantDomain(username);
if (domain != null && !MultitenantConstants.SUPER_TENANT_DOMAIN_NAME.equals(domain)) {
service = carbon.server.osgiService('org.wso2.carbon.utils.ConfigurationContextService');
ctx = service.getServerConfigContext();
TenantAxisUtils.setTenantAccessed(domain, ctx);
}
};
/**
* Basic login.
* @param request {Object} HTTP request

@ -41,128 +41,128 @@ import java.util.concurrent.ConcurrentHashMap;
/**
* This creates JWT Client for each tenant and implements the JWTClientManagerService interface.
*/
public class JWTClientManagerServiceImpl implements JWTClientManagerService{
public class JWTClientManagerServiceImpl implements JWTClientManagerService {
private static Map<String, JWTClient> jwtClientMap;
private static final Log log = LogFactory.getLog(JWTClientManagerServiceImpl.class);
private static final String TENANT_JWT_CONFIG_LOCATION = "/jwt-config/jwt.properties";
private static JWTClient defaultJWTClient;
private static Map<String, JWTClient> jwtClientMap;
private static final Log log = LogFactory.getLog(JWTClientManagerServiceImpl.class);
private static final String TENANT_JWT_CONFIG_LOCATION = "/jwt-config/jwt.properties";
private static JWTClient defaultJWTClient;
public JWTClientManagerServiceImpl() {
jwtClientMap = new ConcurrentHashMap<>();
}
public JWTClientManagerServiceImpl() {
jwtClientMap = new ConcurrentHashMap<>();
}
/**
* this return the jwt based token client to generate token for the tenant.
*/
@Override
public JWTClient getJWTClient() throws JWTClientException {
String tenantDomain = CarbonContext.getThreadLocalCarbonContext().getTenantDomain();
int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(true);
if (tenantId == -1) {
throw new JWTClientException("Invalid tenant domain :" + tenantDomain);
}
//Get jwt client which has been registered for the tenant.
JWTClient jwtClient = getJWTClient(tenantDomain);
if (jwtClient == null) {
//Create a new jwt client for the tenant.
try {
Properties properties = getJWTConfigProperties(tenantId);
if (properties == null) {
if (defaultJWTClient != null) {
return defaultJWTClient;
} else {
throw new JWTClientException("JWT Configuration is not available for tenant " + tenantDomain);
}
}
JWTConfig jwtConfig = new JWTConfig(properties);
jwtClient = new JWTClient(jwtConfig);
addJWTClient(tenantDomain, jwtClient);
} catch (JWTClientAlreadyExistsException e) {
log.warn("Attempting to register a jwt client for the tenant " + tenantDomain +
" when one already exists. Returning existing jwt client");
return getJWTClient(tenantDomain);
} catch (JWTClientConfigurationException e) {
throw new JWTClientException("Failed to parse jwt configuration for tenant " + tenantDomain, e);
}
}
return jwtClient;
}
/**
* this return the jwt based token client to generate token for the tenant.
*/
@Override
public JWTClient getJWTClient() throws JWTClientException {
String tenantDomain = CarbonContext.getThreadLocalCarbonContext().getTenantDomain();
int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(true);
if (tenantId == -1) {
throw new JWTClientException("Invalid tenant domain :" + tenantDomain);
}
//Get jwt client which has been registered for the tenant.
JWTClient jwtClient = getJWTClient(tenantDomain);
if (jwtClient == null) {
//Create a new jwt client for the tenant.
try {
Properties properties = getJWTConfigProperties(tenantId);
if (properties == null) {
if (defaultJWTClient != null) {
return defaultJWTClient;
} else {
throw new JWTClientException("JWT Configuration is not available for tenant " + tenantDomain);
}
}
JWTConfig jwtConfig = new JWTConfig(properties);
jwtClient = new JWTClient(jwtConfig);
addJWTClient(tenantDomain, jwtClient);
} catch (JWTClientAlreadyExistsException e) {
log.warn("Attempting to register a jwt client for the tenant " + tenantDomain +
" when one already exists. Returning existing jwt client");
return getJWTClient(tenantDomain);
} catch (JWTClientConfigurationException e) {
throw new JWTClientException("Failed to parse jwt configuration for tenant " + tenantDomain, e);
}
}
return jwtClient;
}
/**
* This will set the default JWT Client that will be used if there is any available for tenants.
*/
@Override
public void setDefaultJWTClient(Properties properties) throws JWTClientConfigurationException {
if (properties == null) {
throw new JWTClientConfigurationException("Failed to load jwt configuration for super tenant.");
}
String defaultJWTClientMode = properties.getProperty(JWTConstants.DEFAULT_JWT_CLIENT);
boolean isDefaultJwtClient = false;
if (defaultJWTClientMode != null && !defaultJWTClientMode.isEmpty()) {
isDefaultJwtClient = Boolean.parseBoolean(defaultJWTClientMode);
}
if (isDefaultJwtClient) {
try {
JWTConfig jwtConfig = new JWTConfig(properties);
defaultJWTClient = new JWTClient(jwtConfig, true);
addJWTClient(MultitenantConstants.SUPER_TENANT_DOMAIN_NAME, defaultJWTClient);
} catch (JWTClientAlreadyExistsException e) {
log.warn("Attempting to register a jwt client for the super tenant" +
" when one already exists. Returning existing jwt client");
}
}
}
/**
* This will set the default JWT Client that will be used if there is any available for tenants.
*/
@Override
public void setDefaultJWTClient(Properties properties) throws JWTClientConfigurationException {
if (properties == null) {
throw new JWTClientConfigurationException("Failed to load jwt configuration for super tenant.");
}
String defaultJWTClientMode = properties.getProperty(JWTConstants.DEFAULT_JWT_CLIENT);
boolean isDefaultJwtClient = false;
if (defaultJWTClientMode != null && !defaultJWTClientMode.isEmpty()) {
isDefaultJwtClient = Boolean.parseBoolean(defaultJWTClientMode);
}
if (isDefaultJwtClient) {
try {
JWTConfig jwtConfig = new JWTConfig(properties);
defaultJWTClient = new JWTClient(jwtConfig, true);
addJWTClient(MultitenantConstants.SUPER_TENANT_DOMAIN_NAME, defaultJWTClient);
} catch (JWTClientAlreadyExistsException e) {
log.warn("Attempting to register a jwt client for the super tenant" +
" when one already exists. Returning existing jwt client");
}
}
}
/**
* Fetch the jwt client which has been registered under the tenant domain.
*
* @param tenantDomain - The tenant domain under which the jwt client is registered
* @return - Instance of the jwt client which was registered. Null if not registered.
*/
private JWTClient getJWTClient(String tenantDomain) {
if (jwtClientMap.containsKey(tenantDomain)) {
return jwtClientMap.get(tenantDomain);
}
return null;
}
/**
* Fetch the jwt client which has been registered under the tenant domain.
*
* @param tenantDomain - The tenant domain under which the jwt client is registered
* @return - Instance of the jwt client which was registered. Null if not registered.
*/
private JWTClient getJWTClient(String tenantDomain) {
if (jwtClientMap.containsKey(tenantDomain)) {
return jwtClientMap.get(tenantDomain);
}
return null;
}
/**
* Adds a jwt client to the jwt client map.
*
* @param tenantDomain - The tenant domain under which the jwt client will be registered.
* @param jwtClient - Instance of the jwt client
* @throws JWTClientAlreadyExistsException - If a jwt client has already been registered under the tenantdomain
*/
private void addJWTClient(String tenantDomain, JWTClient jwtClient) throws JWTClientAlreadyExistsException {
synchronized (jwtClientMap) {
if (jwtClientMap.containsKey(tenantDomain)) {
throw new JWTClientAlreadyExistsException(
"A jwt client has already been created for the tenant " + tenantDomain);
}
jwtClientMap.put(tenantDomain, jwtClient);
}
}
/**
* Adds a jwt client to the jwt client map.
*
* @param tenantDomain - The tenant domain under which the jwt client will be registered.
* @param jwtClient - Instance of the jwt client
* @throws JWTClientAlreadyExistsException - If a jwt client has already been registered under the tenantdomain
*/
private void addJWTClient(String tenantDomain, JWTClient jwtClient) throws JWTClientAlreadyExistsException {
synchronized (jwtClientMap) {
if (jwtClientMap.containsKey(tenantDomain)) {
throw new JWTClientAlreadyExistsException(
"A jwt client has already been created for the tenant " + tenantDomain);
}
jwtClientMap.put(tenantDomain, jwtClient);
}
}
/**
* Retrieve JWT configs from registry.
*/
private Properties getJWTConfigProperties(int tenantId) throws JWTClientConfigurationException {
try {
Resource config = JWTClientUtil.getConfigRegistryResourceContent(tenantId, TENANT_JWT_CONFIG_LOCATION);
Properties properties = null;
if (config != null) {
properties = new Properties();
properties.load(config.getContentStream());
}
return properties;
} catch (RegistryException e) {
throw new JWTClientConfigurationException("Failed to load the content from registry for tenant " +
tenantId, e);
} catch (IOException e) {
throw new JWTClientConfigurationException(
"Failed to parse the content from the registry for tenant " + tenantId, e);
}
}
/**
* Retrieve JWT configs from registry.
*/
private Properties getJWTConfigProperties(int tenantId) throws JWTClientConfigurationException {
try {
Resource config = JWTClientUtil.getConfigRegistryResourceContent(tenantId, TENANT_JWT_CONFIG_LOCATION);
Properties properties = null;
if (config != null) {
properties = new Properties();
properties.load(config.getContentStream());
}
return properties;
} catch (RegistryException e) {
throw new JWTClientConfigurationException("Failed to load the content from registry for tenant " +
tenantId, e);
} catch (IOException e) {
throw new JWTClientConfigurationException(
"Failed to parse the content from the registry for tenant " + tenantId, e);
}
}
}

@ -24,8 +24,8 @@ import org.w3c.dom.Document;
import org.wso2.carbon.device.mgt.common.Device;
import org.wso2.carbon.device.mgt.common.configuration.mgt.ConfigurationEntry;
import org.wso2.carbon.device.mgt.common.configuration.mgt.ConfigurationManagementException;
import org.wso2.carbon.device.mgt.common.configuration.mgt.TenantConfiguration;
import org.wso2.carbon.device.mgt.common.configuration.mgt.TenantConfigurationManagementService;
import org.wso2.carbon.device.mgt.common.configuration.mgt.PlatformConfiguration;
import org.wso2.carbon.device.mgt.common.configuration.mgt.PlatformConfigurationManagementService;
import org.wso2.carbon.device.mgt.common.group.mgt.DeviceGroup;
import org.wso2.carbon.device.mgt.common.operation.mgt.Operation;
import org.wso2.carbon.device.mgt.core.config.DeviceConfigurationManager;
@ -198,8 +198,8 @@ public class PolicyManagerUtil {
public static int getMonitoringFequency() {
TenantConfigurationManagementService configMgtService = new TenantConfigurationManagementServiceImpl();
TenantConfiguration tenantConfiguration = null;
PlatformConfigurationManagementService configMgtService = new TenantConfigurationManagementServiceImpl();
PlatformConfiguration tenantConfiguration = null;
int monitoringFrequency = 0;
try {
tenantConfiguration = configMgtService.getConfiguration(GENERAL_CONFIG_RESOURCE_PATH);

@ -129,10 +129,9 @@ public class CertificateAuthenticator implements WebappAuthenticator {
isEmpty()) {
authenticationInfo.setTenantId(certificateResponse.getTenantId());
authenticationInfo.setStatus(Status.CONTINUE);
authenticationInfo.setUsername(certificateResponse.getCommonName());
authenticationInfo.setUsername(certificateResponse.getUsername());
try {
authenticationInfo.setTenantDomain(Utils.
getTenantDomain(
authenticationInfo.setTenantDomain(Utils.getTenantDomain(
certificateResponse.getTenantId()));
} catch (AuthenticationException e) {
authenticationInfo.setStatus(Status.FAILURE);

@ -26,6 +26,8 @@ import org.apache.catalina.connector.Request;
import org.apache.catalina.connector.Response;
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.core.util.KeyStoreManager;
import org.wso2.carbon.registry.core.exceptions.RegistryException;
import org.wso2.carbon.registry.core.service.TenantRegistryLoader;
@ -88,12 +90,23 @@ public class JWTAuthenticator implements WebappAuthenticator {
String username = jwsObject.getJWTClaimsSet().getStringClaim(SIGNED_JWT_AUTH_USERNAME);
String tenantDomain = MultitenantUtils.getTenantDomain(username);
int tenantId = Integer.parseInt(jwsObject.getJWTClaimsSet().getStringClaim(SIGNED_JWT_AUTH_TENANT_ID));
PrivilegedCarbonContext.startTenantFlow();
PrivilegedCarbonContext.getThreadLocalCarbonContext().setTenantDomain(tenantDomain);
PrivilegedCarbonContext.getThreadLocalCarbonContext().setTenantId(tenantId);
PublicKey publicKey = publicKeyHolder.get(tenantDomain);
if (publicKey == null) {
loadTenantRegistry(tenantId);
KeyStoreManager keyStoreManager = KeyStoreManager.getInstance(tenantId);
publicKey = keyStoreManager.getDefaultPublicKey();
publicKeyHolder.put(tenantDomain, publicKey);
if (tenantDomain.equals(MultitenantConstants.SUPER_TENANT_DOMAIN_NAME)) {
publicKey = keyStoreManager.getDefaultPublicKey();
} else {
String ksName = tenantDomain.trim().replace('.', '-');
String jksName = ksName + ".jks";
publicKey = keyStoreManager.getKeyStore(jksName).getCertificate(tenantDomain).getPublicKey();
}
if (publicKey != null) {
publicKeyHolder.put(tenantDomain, publicKey);
}
}
//Get the filesystem keystore default primary certificate
@ -124,6 +137,8 @@ public class JWTAuthenticator implements WebappAuthenticator {
log.error("Error occurred while verifying the JWT header.", e);
} catch (Exception e) {
log.error("Error occurred while verifying the JWT header.", e);
} finally {
PrivilegedCarbonContext.endTenantFlow();
}
return authenticationInfo;
}

@ -0,0 +1,123 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
~ Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
~
~ WSO2 Inc. licenses this file to you under the Apache License,
~ Version 2.0 (the "License"); you may not use this file except
~ in compliance with the License.
~ You may obtain a copy of the License at
~
~ http://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing,
~ software distributed under the License is distributed on an
~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
~ KIND, either express or implied. See the License for the
~ specific language governing permissions and limitations
~ under the License.
-->
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<parent>
<groupId>org.wso2.carbon.devicemgt</groupId>
<artifactId>certificate-mgt-feature</artifactId>
<version>1.1.1-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>org.wso2.carbon.certificate.mgt.cert.admin.api.feature</artifactId>
<packaging>pom</packaging>
<name>WSO2 Carbon - Admin Certificate Management API Feature</name>
<url>http://wso2.org</url>
<description>This feature contains the APIs required for Admin Certificate Management.</description>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>copy</id>
<phase>package</phase>
<goals>
<goal>copy</goal>
</goals>
<configuration>
<artifactItems>
<artifactItem>
<groupId>org.wso2.carbon.devicemgt</groupId>
<artifactId>org.wso2.carbon.certificate.mgt.cert.admin.api
</artifactId>
<version>${project.version}</version>
<type>war</type>
<overWrite>true</overWrite>
<outputDirectory>
${project.build.directory}/maven-shared-archive-resources/webapps
</outputDirectory>
<destFileName>admin-certificate.war</destFileName>
</artifactItem>
</artifactItems>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<executions>
<execution>
<id>copy-resources</id>
<phase>generate-resources</phase>
<goals>
<goal>copy-resources</goal>
</goals>
<configuration>
<outputDirectory>src/main/resources</outputDirectory>
<resources>
<resource>
<directory>resources</directory>
<includes>
<include>build.properties</include>
<include>p2.inf</include>
</includes>
</resource>
</resources>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.wso2.maven</groupId>
<artifactId>carbon-p2-plugin</artifactId>
<executions>
<execution>
<id>p2-feature-generation</id>
<phase>package</phase>
<goals>
<goal>p2-feature-gen</goal>
</goals>
<configuration>
<id>org.wso2.carbon.certificate.mgt.cert.admin.api</id>
<propertiesFile>../../../features/etc/feature.properties
</propertiesFile>
<adviceFile>
<properties>
<propertyDef>org.wso2.carbon.p2.category.type:server
</propertyDef>
<propertyDef>org.eclipse.equinox.p2.type.group:false
</propertyDef>
</properties>
</adviceFile>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>

@ -0,0 +1,2 @@
instructions.configure = \
org.eclipse.equinox.p2.touchpoint.natives.copy(source:${installFolder}/../features/org.wso2.carbon.certificate.mgt.cert.admin.api_${feature.version}/webapps/admin-certificate.war,target:${installFolder}/../../deployment/server/webapps/admin-certificate.war,overwrite:true);\

@ -37,6 +37,7 @@
<modules>
<module>org.wso2.carbon.certificate.mgt.server.feature</module>
<module>org.wso2.carbon.certificate.mgt.api.feature</module>
<module>org.wso2.carbon.certificate.mgt.cert.admin.api.feature</module>
</modules>
</project>

@ -22,6 +22,7 @@ CREATE TABLE IF NOT EXISTS DM_DEVICE_CERTIFICATE (
SERIAL_NUMBER VARCHAR(500) DEFAULT NULL,
CERTIFICATE BLOB DEFAULT NULL,
TENANT_ID INTEGER DEFAULT 0,
USERNAME VARCHAR(500) DEFAULT NULL,
PRIMARY KEY (ID)
);
@ -515,7 +516,7 @@ CREATE TABLE IF NOT EXISTS DM_DEVICE_GROUP_POLICY (
-- DASHBOARD RELATED VIEWS --
CREATE VIEW DEVICES_WITH_POLICY_COMPLIANCE_STATUS AS
CREATE VIEW POLICY_COMPLIANCE_INFO AS
SELECT
DEVICE_INFO.DEVICE_ID,
DEVICE_INFO.DEVICE_IDENTIFICATION,
@ -544,7 +545,7 @@ FROM DM_POLICY_COMPLIANCE_STATUS) DEVICE_WITH_POLICY_INFO
ON DEVICE_INFO.DEVICE_ID = DEVICE_WITH_POLICY_INFO.DEVICE_ID
ORDER BY DEVICE_INFO.DEVICE_ID;
CREATE VIEW DEVICES_WITH_NON_COMPLIANT_FEATURES AS
CREATE VIEW FEATURE_NON_COMPLIANCE_INFO AS
SELECT
DM_DEVICE.ID AS DEVICE_ID,
DM_DEVICE.DEVICE_IDENTIFICATION,

@ -22,6 +22,7 @@ CREATE TABLE DM_DEVICE_CERTIFICATE (
SERIAL_NUMBER VARCHAR(500) DEFAULT NULL,
CERTIFICATE VARBINARY(max) DEFAULT NULL,
TENANT_ID INTEGER DEFAULT 0,
USERNAME VARCHAR(500) DEFAULT NULL,
PRIMARY KEY (ID)
);
@ -507,7 +508,7 @@ CREATE INDEX FK_DM_DEVICE_DETAILS_DEVICE_idx ON DM_DEVICE_DETAIL (DEVICE_ID ASC)
-- DASHBOARD RELATED VIEWS --
CREATE VIEW DEVICES_WITH_POLICY_COMPLIANCE_STATUS AS
CREATE VIEW POLICY_COMPLIANCE_INFO AS
SELECT TOP 100 PERCENT
DEVICE_INFO.DEVICE_ID,
DEVICE_INFO.DEVICE_IDENTIFICATION,
@ -539,7 +540,7 @@ ON DEVICE_INFO.DEVICE_ID = DEVICE_WITH_POLICY_INFO.DEVICE_ID
ORDER BY DEVICE_INFO.DEVICE_ID;
GO
CREATE VIEW DEVICES_WITH_NON_COMPLIANT_FEATURES AS
CREATE VIEW FEATURE_NON_COMPLIANCE_INFO AS
SELECT TOP 100 PERCENT
DM_DEVICE.ID AS DEVICE_ID,
DM_DEVICE.DEVICE_IDENTIFICATION,

@ -11,6 +11,7 @@ CREATE TABLE IF NOT EXISTS DM_DEVICE_CERTIFICATE (
SERIAL_NUMBER VARCHAR(500) DEFAULT NULL,
CERTIFICATE BLOB DEFAULT NULL,
TENANT_ID INTEGER DEFAULT 0,
USERNAME VARCHAR(500) DEFAULT NULL,
PRIMARY KEY (ID)
)ENGINE = InnoDB;
@ -545,7 +546,7 @@ POLICY_ID,
STATUS AS IS_COMPLIANT
FROM DM_POLICY_COMPLIANCE_STATUS;
CREATE VIEW DEVICES_WITH_POLICY_COMPLIANCE_STATUS AS
CREATE VIEW POLICY_COMPLIANCE_INFO AS
SELECT
DEVICE_INFO_VIEW.DEVICE_ID,
DEVICE_INFO_VIEW.DEVICE_IDENTIFICATION,
@ -562,7 +563,7 @@ DEVICE_WITH_POLICY_INFO_VIEW
ON DEVICE_INFO_VIEW.DEVICE_ID = DEVICE_WITH_POLICY_INFO_VIEW.DEVICE_ID
ORDER BY DEVICE_INFO_VIEW.DEVICE_ID;
CREATE VIEW DEVICES_WITH_NON_COMPLIANT_FEATURES AS
CREATE VIEW FEATURE_NON_COMPLIANCE_INFO AS
SELECT
DM_DEVICE.ID AS DEVICE_ID,
DM_DEVICE.DEVICE_IDENTIFICATION,

@ -50,6 +50,7 @@ CREATE TABLE DM_DEVICE_CERTIFICATE (
SERIAL_NUMBER VARCHAR2(500) DEFAULT NULL,
CERTIFICATE BLOB DEFAULT NULL,
TENANT_ID NUMBER(10) DEFAULT 0,
USERNAME VARCHAR2(500) DEFAULT NULL,
PRIMARY KEY (ID)
)
/

@ -9,7 +9,8 @@ CREATE TABLE IF NOT EXISTS DM_DEVICE_CERTIFICATE (
ID BIGSERIAL NOT NULL PRIMARY KEY,
SERIAL_NUMBER VARCHAR(500) DEFAULT NULL,
CERTIFICATE BYTEA DEFAULT NULL,
TENANT_ID INTEGER DEFAULT 0
TENANT_ID INTEGER DEFAULT 0,
USERNAME VARCHAR(500) DEFAULT NULL
);
CREATE TABLE IF NOT EXISTS DM_DEVICE (
@ -434,7 +435,7 @@ CREATE TABLE IF NOT EXISTS DM_DEVICE_DETAIL (
-- DASHBOARD RELATED VIEWS --
CREATE VIEW DEVICES_WITH_POLICY_COMPLIANCE_STATUS AS
CREATE VIEW POLICY_COMPLIANCE_INFO AS
SELECT
DEVICE_INFO.DEVICE_ID,
DEVICE_INFO.DEVICE_IDENTIFICATION,
@ -463,7 +464,7 @@ FROM DM_POLICY_COMPLIANCE_STATUS) DEVICE_WITH_POLICY_INFO
ON DEVICE_INFO.DEVICE_ID = DEVICE_WITH_POLICY_INFO.DEVICE_ID
ORDER BY DEVICE_INFO.DEVICE_ID;
CREATE VIEW DEVICES_WITH_NON_COMPLIANT_FEATURES AS
CREATE VIEW FEATURE_NON_COMPLIANCE_INFO AS
SELECT
DM_DEVICE.ID AS DEVICE_ID,
DM_DEVICE.DEVICE_IDENTIFICATION,

@ -52,7 +52,7 @@
<module>features/oauth-extensions</module>
<module>features/email-sender</module>
<module>features/jwt-client</module>
<module>features/device-mgt-extensions</module>
<module>features/device-mgt-extensions</module>
</modules>
<dependencyManagement>
@ -1721,7 +1721,6 @@
</repository>
</repositories>
<properties>
<testng.version>6.1.1</testng.version>
<carbon.kernel.version>4.4.3</carbon.kernel.version>

Loading…
Cancel
Save