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

revert-70aa11f8
ayyoob 9 years ago
commit 04536a1446

@ -0,0 +1,45 @@
/*
* 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.apimgt.annotations.api;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* This class is the representation of custom developed Permission annotation.
*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Permission {
/**
* Represents the scope name.
* @return Returns scope name.
*/
String scope();
/**
* Represents the associated permissions.
* @return Returns list of permissions.
*/
String[] permissions();
}

@ -18,16 +18,17 @@
*/ */
package org.wso2.carbon.apimgt.webapp.publisher; package org.wso2.carbon.apimgt.webapp.publisher;
import com.google.gson.Gson;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject; import com.google.gson.JsonObject;
import com.google.gson.reflect.TypeToken;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
import org.wso2.carbon.apimgt.api.APIManagementException; import org.wso2.carbon.apimgt.api.APIManagementException;
import org.wso2.carbon.apimgt.api.APIProvider; import org.wso2.carbon.apimgt.api.APIProvider;
import org.wso2.carbon.apimgt.api.FaultGatewaysException; import org.wso2.carbon.apimgt.api.FaultGatewaysException;
import org.wso2.carbon.apimgt.api.model.API; import org.wso2.carbon.apimgt.api.model.*;
import org.wso2.carbon.apimgt.api.model.APIIdentifier;
import org.wso2.carbon.apimgt.api.model.APIStatus;
import org.wso2.carbon.apimgt.api.model.URITemplate;
import org.wso2.carbon.apimgt.impl.APIManagerFactory; import org.wso2.carbon.apimgt.impl.APIManagerFactory;
import org.wso2.carbon.apimgt.webapp.publisher.internal.APIPublisherDataHolder; import org.wso2.carbon.apimgt.webapp.publisher.internal.APIPublisherDataHolder;
import org.wso2.carbon.context.PrivilegedCarbonContext; import org.wso2.carbon.context.PrivilegedCarbonContext;
@ -38,10 +39,7 @@ import org.wso2.carbon.utils.multitenancy.MultitenantUtils;
import javax.xml.stream.XMLStreamException; import javax.xml.stream.XMLStreamException;
import java.io.FileNotFoundException; import java.io.FileNotFoundException;
import java.util.HashMap; import java.util.*;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
/** /**
* This class represents the concrete implementation of the APIPublisherService that corresponds to providing all * This class represents the concrete implementation of the APIPublisherService that corresponds to providing all
@ -50,96 +48,123 @@ import java.util.Map;
public class APIPublisherServiceImpl implements APIPublisherService { public class APIPublisherServiceImpl implements APIPublisherService {
private static final Log log = LogFactory.getLog(APIPublisherServiceImpl.class); private static final Log log = LogFactory.getLog(APIPublisherServiceImpl.class);
private static final String PUBLISH_ACTION = "Publish"; private static final String PUBLISH_ACTION = "Publish";
@Override @Override
public void publishAPI(final API api) throws APIManagementException, FaultGatewaysException { public void publishAPI(final API api) throws APIManagementException, FaultGatewaysException {
String tenantDomain = MultitenantUtils.getTenantDomain(api.getApiOwner()); String tenantDomain = MultitenantUtils.getTenantDomain(api.getApiOwner());
PrivilegedCarbonContext.startTenantFlow(); PrivilegedCarbonContext.startTenantFlow();
PrivilegedCarbonContext.getThreadLocalCarbonContext().setTenantDomain(tenantDomain, true); PrivilegedCarbonContext.getThreadLocalCarbonContext().setTenantDomain(tenantDomain, true);
try { try {
int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(); int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId();
// Below code snippet is added to load API Lifecycle in tenant mode. // Below code snippet is added to load API Lifecycle in tenant mode.
RegistryService registryService = APIPublisherDataHolder.getInstance().getRegistryService(); RegistryService registryService = APIPublisherDataHolder.getInstance().getRegistryService();
CommonUtil.addDefaultLifecyclesIfNotAvailable(registryService.getConfigSystemRegistry(tenantId), CommonUtil.addDefaultLifecyclesIfNotAvailable(registryService.getConfigSystemRegistry(tenantId),
CommonUtil.getRootSystemRegistry(tenantId)); CommonUtil.getRootSystemRegistry(tenantId));
APIProvider provider = APIManagerFactory.getInstance().getAPIProvider(api.getApiOwner()); APIProvider provider = APIManagerFactory.getInstance().getAPIProvider(api.getApiOwner());
MultitenantUtils.getTenantDomain(api.getApiOwner()); MultitenantUtils.getTenantDomain(api.getApiOwner());
if (provider != null) { if (provider != null) {
if (provider.isDuplicateContextTemplate(api.getContext())) { if (provider.isDuplicateContextTemplate(api.getContext())) {
throw new APIManagementException( throw new APIManagementException(
"Error occurred while adding the API. A duplicate API" + "Error occurred while adding the API. A duplicate API" +
" context already exists for " + api.getContext()); " context already exists for " + api.getContext());
} }
if (!provider.isAPIAvailable(api.getId())) { if (!provider.isAPIAvailable(api.getId())) {
provider.addAPI(api); provider.addAPI(api);
provider.changeLifeCycleStatus(api.getId(), PUBLISH_ACTION); provider.changeLifeCycleStatus(api.getId(), PUBLISH_ACTION);
if (log.isDebugEnabled()) { if (log.isDebugEnabled()) {
log.debug("Successfully published API '" + api.getId().getApiName() + log.debug("Successfully published API '" + api.getId().getApiName() +
"' with context '" + api.getContext() + "' and version '" "' with context '" + api.getContext() + "' and version '"
+ api.getId().getVersion() + "'"); + api.getId().getVersion() + "'");
} }
} else { } else {
api.setStatus(APIStatus.PUBLISHED); api.setStatus(provider.getAPI(api.getId()).getStatus());
provider.updateAPI(api); provider.updateAPI(api);
if (log.isDebugEnabled()) { if (log.isDebugEnabled()) {
log.debug("An API already exists with the name '" + api.getId().getApiName() + log.debug("An API already exists with the name '" + api.getId().getApiName() +
"', context '" + api.getContext() + "' and version '" "', context '" + api.getContext() + "' and version '"
+ api.getId().getVersion() + "'. Thus, the API config is updated"); + api.getId().getVersion() + "'. Thus, the API config is updated");
} }
} }
provider.saveSwagger20Definition(api.getId(), createSwaggerDefinition(api)); provider.saveSwagger20Definition(api.getId(), createSwaggerDefinition(api));
} else { } else {
throw new APIManagementException("API provider configured for the given API configuration " + throw new APIManagementException("API provider configured for the given API configuration " +
"is null. Thus, the API is not published"); "is null. Thus, the API is not published");
} }
} catch (FileNotFoundException e) { } catch (FileNotFoundException e) {
throw new APIManagementException("Failed to retrieve life cycle file ", e); throw new APIManagementException("Failed to retrieve life cycle file ", e);
} catch (RegistryException e) { } catch (RegistryException e) {
throw new APIManagementException("Failed to access the registry ", e); throw new APIManagementException("Failed to access the registry ", e);
} catch (XMLStreamException e) { } catch (XMLStreamException e) {
throw new APIManagementException("Failed parsing the lifecycle xml.", e); throw new APIManagementException("Failed parsing the lifecycle xml.", e);
} finally { } finally {
PrivilegedCarbonContext.endTenantFlow(); PrivilegedCarbonContext.endTenantFlow();
} }
} }
private String createSwaggerDefinition(API api) { private String createSwaggerDefinition(API api) {
Map<String, JsonObject> httpVerbsMap = new HashMap<>(); Map<String, JsonObject> httpVerbsMap = new HashMap<>();
List<Scope> scopes = new ArrayList<>();
for (URITemplate uriTemplate : api.getUriTemplates()) {
JsonObject response = new JsonObject(); for (URITemplate uriTemplate : api.getUriTemplates()) {
response.addProperty("200", ""); JsonObject response = new JsonObject();
response.addProperty("200", "");
JsonObject responses = new JsonObject();
responses.add("responses", response); JsonObject responses = new JsonObject();
JsonObject httpVerbs = httpVerbsMap.get(uriTemplate.getUriTemplate()); responses.add("responses", response);
if (httpVerbs == null) { JsonObject httpVerbs = httpVerbsMap.get(uriTemplate.getUriTemplate());
httpVerbs = new JsonObject(); if (httpVerbs == null) {
} httpVerbs = new JsonObject();
httpVerbs.add(uriTemplate.getHTTPVerb().toLowerCase(), responses); }
httpVerbsMap.put(uriTemplate.getUriTemplate(), httpVerbs); JsonObject httpVerb = new JsonObject();
} httpVerb.add("responses", response);
Iterator it = httpVerbsMap.entrySet().iterator(); httpVerb.addProperty("x-auth-type", "Application%20%26%20Application%20User");
JsonObject paths = new JsonObject(); httpVerb.addProperty("x-throttling-tier", "Unlimited");
while (it.hasNext()) { if (uriTemplate.getScope() != null) {
Map.Entry<String, JsonObject> pair = (Map.Entry) it.next(); httpVerb.addProperty("x-scope", uriTemplate.getScope().getName());
paths.add(pair.getKey(), pair.getValue()); scopes.add(uriTemplate.getScope());
it.remove(); }
} httpVerbs.add(uriTemplate.getHTTPVerb().toLowerCase(), httpVerb);
httpVerbsMap.put(uriTemplate.getUriTemplate(), httpVerbs);
JsonObject info = new JsonObject(); }
info.addProperty("title", api.getId().getApiName());
info.addProperty("version", api.getId().getVersion()); Iterator it = httpVerbsMap.entrySet().iterator();
JsonObject paths = new JsonObject();
JsonObject swaggerDefinition = new JsonObject(); while (it.hasNext()) {
swaggerDefinition.add("paths", paths); Map.Entry<String, JsonObject> pair = (Map.Entry) it.next();
swaggerDefinition.addProperty("swagger", "2.0"); paths.add(pair.getKey(), pair.getValue());
swaggerDefinition.add("info", info); it.remove();
}
return swaggerDefinition.toString();
} JsonObject info = new JsonObject();
info.addProperty("title", api.getId().getApiName());
info.addProperty("version", api.getId().getVersion());
JsonObject swaggerDefinition = new JsonObject();
swaggerDefinition.add("paths", paths);
swaggerDefinition.addProperty("swagger", "2.0");
swaggerDefinition.add("info", info);
// adding scopes to swagger definition
if (!api.getScopes().isEmpty()) {
Gson gson = new Gson();
JsonElement element = gson.toJsonTree(api.getScopes(), new TypeToken<Set<Scope>>() {
}.getType());
if (element != null) {
JsonArray apiScopes = element.getAsJsonArray();
JsonObject apim = new JsonObject();
apim.add("x-wso2-scopes", apiScopes);
JsonObject wso2Security = new JsonObject();
wso2Security.add("apim", apim);
swaggerDefinition.add("x-wso2-security", wso2Security);
}
}
if (log.isDebugEnabled()) {
log.debug("API swagger definition: " + swaggerDefinition.toString());
}
return swaggerDefinition.toString();
}
@Override @Override
public void removeAPI(APIIdentifier id) throws APIManagementException { public void removeAPI(APIIdentifier id) throws APIManagementException {
@ -169,4 +194,5 @@ public class APIPublisherServiceImpl implements APIPublisherService {
log.debug("End of publishing the batch of APIs"); log.debug("End of publishing the batch of APIs");
} }
} }
} }

@ -38,38 +38,17 @@ import java.util.*;
public class APIPublisherUtil { public class APIPublisherUtil {
private static final Log log = LogFactory.getLog(APIPublisherUtil.class); private static final Log log = LogFactory.getLog(APIPublisherUtil.class);
private static final String DEFAULT_API_VERSION = "1.0.0"; private static final String DEFAULT_API_VERSION = "1.0.0";
public static final String API_VERSION_PARAM = "{version}"; public static final String API_VERSION_PARAM = "{version}";
public static final String API_PUBLISH_ENVIRONEMENT = "Production and Sandbox"; public static final String API_PUBLISH_ENVIRONMENT = "Production and Sandbox";
private static final String API_CONFIG_DEFAULT_VERSION = "1.0.0"; private static final String API_CONFIG_DEFAULT_VERSION = "1.0.0";
private static final String PARAM_MANAGED_API_NAME = "managed-api-name";
private static final String PARAM_MANAGED_API_VERSION = "managed-api-version";
private static final String PARAM_MANAGED_API_CONTEXT = "managed-api-context";
private static final String PARAM_MANAGED_API_ENDPOINT = "managed-api-endpoint"; private static final String PARAM_MANAGED_API_ENDPOINT = "managed-api-endpoint";
private static final String PARAM_MANAGED_API_OWNER = "managed-api-owner"; private static final String PARAM_MANAGED_API_OWNER = "managed-api-owner";
private static final String PARAM_MANAGED_API_TRANSPORTS = "managed-api-transports"; private static final String PARAM_MANAGED_API_TRANSPORTS = "managed-api-transports";
private static final String PARAM_MANAGED_API_IS_SECURED = "managed-api-isSecured"; private static final String PARAM_MANAGED_API_IS_SECURED = "managed-api-isSecured";
private static final String PARAM_MANAGED_API_APPLICATION = "managed-api-application";
private static final String PARAM_SHARED_WITH_ALL_TENANTS = "isSharedWithAllTenants"; private static final String PARAM_SHARED_WITH_ALL_TENANTS = "isSharedWithAllTenants";
private static final String PARAM_PROVIDER_TENANT_DOMAIN = "providerTenantDomain"; private static final String PARAM_PROVIDER_TENANT_DOMAIN = "providerTenantDomain";
enum HTTPMethod {
GET, POST, DELETE, PUT, OPTIONS
}
private static List<HTTPMethod> httpMethods;
static {
httpMethods = new ArrayList<HTTPMethod>(5);
httpMethods.add(HTTPMethod.GET);
httpMethods.add(HTTPMethod.POST);
httpMethods.add(HTTPMethod.DELETE);
httpMethods.add(HTTPMethod.PUT);
httpMethods.add(HTTPMethod.OPTIONS);
}
public static API getAPI(APIConfig config) throws APIManagementException { public static API getAPI(APIConfig config) throws APIManagementException {
@ -100,13 +79,11 @@ public class APIPublisherUtil {
api.setStatus(APIStatus.CREATED); api.setStatus(APIStatus.CREATED);
api.setTransports(config.getTransports()); api.setTransports(config.getTransports());
api.setContextTemplate(config.getContextTemplate()); api.setContextTemplate(config.getContextTemplate());
api.setUriTemplates(config.getUriTemplates());
Set<String> environments = new HashSet<>(); Set<String> environments = new HashSet<>();
environments.add(API_PUBLISH_ENVIRONEMENT); environments.add(API_PUBLISH_ENVIRONMENT);
api.setEnvironments(environments); api.setEnvironments(environments);
Set<Tier> tiers = new HashSet<>();
Set<Tier> tiers = new HashSet<Tier>();
tiers.add(new Tier(APIConstants.UNLIMITED_TIER)); tiers.add(new Tier(APIConstants.UNLIMITED_TIER));
api.addAvailableTiers(tiers); api.addAvailableTiers(tiers);
@ -132,35 +109,37 @@ public class APIPublisherUtil {
Set<String> tags = new HashSet<>(Arrays.asList(config.getTags())); Set<String> tags = new HashSet<>(Arrays.asList(config.getTags()));
api.addTags(tags); api.addTags(tags);
} }
return api;
}
private static Set<URITemplate> getURITemplates(String endpoint, String authType) { // adding scopes to the api
Set<URITemplate> uriTemplates = new LinkedHashSet<URITemplate>(); Set<URITemplate> uriTemplates = config.getUriTemplates();
if (APIConstants.AUTH_NO_AUTHENTICATION.equals(authType)) { Map<String, Scope> apiScopes = new HashMap<>();
for (HTTPMethod method : httpMethods) {
URITemplate template = new URITemplate(); if (uriTemplates != null) {
template.setAuthType(APIConstants.AUTH_NO_AUTHENTICATION); // this creates distinct scopes list
template.setHTTPVerb(method.toString()); for (URITemplate template : uriTemplates) {
template.setResourceURI(endpoint); Scope scope = template.getScope();
template.setUriTemplate("/*"); if (scope != null) {
uriTemplates.add(template); if (apiScopes.get(scope.getKey()) == null) {
apiScopes.put(scope.getKey(), scope);
}
}
} }
} else { Set<Scope> scopes = new HashSet<>(apiScopes.values());
for (HTTPMethod method : httpMethods) { api.setScopes(scopes);
URITemplate template = new URITemplate();
if (HTTPMethod.OPTIONS.equals(method)) { // this has to be done because of the use of pass by reference
template.setAuthType(APIConstants.AUTH_NO_AUTHENTICATION); // where same object reference of scope should be available for both
} else { // api scope and uri template scope
template.setAuthType(APIConstants.AUTH_APPLICATION_OR_USER_LEVEL_TOKEN); for (Scope scope : scopes) {
for (URITemplate template : uriTemplates) {
if (scope.getKey().equals(template.getScope().getKey())) {
template.setScope(scope);
}
} }
template.setHTTPVerb(method.toString());
template.setResourceURI(endpoint);
template.setUriTemplate("/*");
uriTemplates.add(template);
} }
api.setUriTemplates(uriTemplates);
} }
return uriTemplates; return api;
} }
public static String getServerBaseUrl() { public static String getServerBaseUrl() {
@ -225,12 +204,13 @@ public class APIPublisherUtil {
* Build the API Configuration to be passed to APIM, from a given list of URL templates * Build the API Configuration to be passed to APIM, from a given list of URL templates
* *
* @param servletContext * @param servletContext
* @param apiDef
* @return * @return
*/ */
public static APIConfig buildApiConfig(ServletContext servletContext, APIResourceConfiguration apidef) { public static APIConfig buildApiConfig(ServletContext servletContext, APIResourceConfiguration apiDef) {
APIConfig apiConfig = new APIConfig(); APIConfig apiConfig = new APIConfig();
String name = apidef.getName(); String name = apiDef.getName();
if (name == null || name.isEmpty()) { if (name == null || name.isEmpty()) {
if (log.isDebugEnabled()) { if (log.isDebugEnabled()) {
log.debug("API Name not set in @API Annotation"); log.debug("API Name not set in @API Annotation");
@ -239,7 +219,7 @@ public class APIPublisherUtil {
} }
apiConfig.setName(name); apiConfig.setName(name);
String version = apidef.getVersion(); String version = apiDef.getVersion();
if (version == null || version.isEmpty()) { if (version == null || version.isEmpty()) {
if (log.isDebugEnabled()) { if (log.isDebugEnabled()) {
log.debug("'API Version not set in @API Annotation'"); log.debug("'API Version not set in @API Annotation'");
@ -249,7 +229,7 @@ public class APIPublisherUtil {
apiConfig.setVersion(version); apiConfig.setVersion(version);
String context = apidef.getContext(); String context = apiDef.getContext();
if (context == null || context.isEmpty()) { if (context == null || context.isEmpty()) {
if (log.isDebugEnabled()) { if (log.isDebugEnabled()) {
log.debug("'API Context not set in @API Annotation'"); log.debug("'API Context not set in @API Annotation'");
@ -258,7 +238,7 @@ public class APIPublisherUtil {
} }
apiConfig.setContext(context); apiConfig.setContext(context);
String[] tags = apidef.getTags(); String[] tags = apiDef.getTags();
if (tags == null || tags.length == 0) { if (tags == null || tags.length == 0) {
if (log.isDebugEnabled()) { if (log.isDebugEnabled()) {
log.debug("'API tag not set in @API Annotation'"); log.debug("'API tag not set in @API Annotation'");
@ -323,13 +303,14 @@ public class APIPublisherUtil {
&& Boolean.parseBoolean(sharingValueParam)); && Boolean.parseBoolean(sharingValueParam));
apiConfig.setSharedWithAllTenants(isSharedWithAllTenants); apiConfig.setSharedWithAllTenants(isSharedWithAllTenants);
Set<URITemplate> uriTemplates = new LinkedHashSet<URITemplate>(); Set<URITemplate> uriTemplates = new LinkedHashSet<>();
for (APIResource apiResource : apidef.getResources()) { for (APIResource apiResource : apiDef.getResources()) {
URITemplate template = new URITemplate(); URITemplate template = new URITemplate();
template.setAuthType(apiResource.getAuthType()); template.setAuthType(apiResource.getAuthType());
template.setHTTPVerb(apiResource.getHttpVerb()); template.setHTTPVerb(apiResource.getHttpVerb());
template.setResourceURI(apiResource.getUri()); template.setResourceURI(apiResource.getUri());
template.setUriTemplate(apiResource.getUriTemplate()); template.setUriTemplate(apiResource.getUriTemplate());
template.setScope(apiResource.getScope());
uriTemplates.add(template); uriTemplates.add(template);
} }
apiConfig.setUriTemplates(uriTemplates); apiConfig.setUriTemplates(uriTemplates);

@ -18,70 +18,71 @@
package org.wso2.carbon.apimgt.webapp.publisher.config; package org.wso2.carbon.apimgt.webapp.publisher.config;
import javax.xml.bind.annotation.XmlElement; import org.wso2.carbon.apimgt.api.model.Scope;
import javax.xml.bind.annotation.XmlRootElement;
public class APIResource {
@XmlRootElement(name = "Resource")
public class APIResource{ private String AuthType;
private String HttpVerb;
private String AuthType; private String Uri;
private String HttpVerb; private String UriTemplate;
private String Uri; private String consumes;
private String UriTemplate; private String produces;
private String consumes; private Scope scope;
private String produces;
public String getAuthType() {
public String getAuthType() { return AuthType;
return AuthType; }
}
public void setAuthType(String authType) {
@XmlElement(name = "AuthType", required = true) AuthType = authType;
public void setAuthType(String authType) { }
AuthType = authType;
} public String getHttpVerb() {
return HttpVerb;
public String getHttpVerb() { }
return HttpVerb;
} public void setHttpVerb(String httpVerb) {
HttpVerb = httpVerb;
@XmlElement(name = "HttpVerb", required = true) }
public void setHttpVerb(String httpVerb) {
HttpVerb = httpVerb; public String getUri() {
} return Uri;
}
public String getUri() {
return Uri; public void setUri(String uri) {
} Uri = uri;
}
@XmlElement(name = "Uri", required = true)
public void setUri(String uri) { public String getUriTemplate() {
Uri = uri; return UriTemplate;
} }
public String getUriTemplate() { public void setUriTemplate(String uriTemplate) {
return UriTemplate; UriTemplate = uriTemplate;
} }
@XmlElement(name = "UriTemplate", required = true) public String getConsumes() {
public void setUriTemplate(String uriTemplate) { return consumes;
UriTemplate = uriTemplate; }
}
public void setConsumes(String consumes) {
public String getConsumes() { this.consumes = consumes;
return consumes; }
}
public String getProduces() {
@XmlElement(name = "Consumes", required = true) return produces;
public void setConsumes(String consumes) { }
this.consumes = consumes;
} public void setProduces(String produces) {
this.produces = produces;
public String getProduces() { }
return produces;
} public Scope getScope() {
return scope;
@XmlElement(name = "Produces", required = true) }
public void setProduces(String produces) {
this.produces = produces; public void setScope(Scope scope) {
} this.scope = scope;
}
} }

@ -0,0 +1,45 @@
/*
* 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.apimgt.webapp.publisher.config;
/**
* This class represents the information related to permissions.
*/
public class PermissionConfiguration {
private String scopeName;
private String[] permissions;
public String getScopeName() {
return scopeName;
}
public void setScopeName(String scope) {
this.scopeName = scope;
}
public String[] getPermissions() {
return permissions;
}
public void setPermissions(String[] permissions) {
this.permissions = permissions;
}
}

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

@ -24,8 +24,10 @@ import org.apache.catalina.LifecycleListener;
import org.apache.catalina.core.StandardContext; import org.apache.catalina.core.StandardContext;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
import org.wso2.carbon.apimgt.api.model.*; import org.wso2.carbon.apimgt.api.model.API;
import org.wso2.carbon.apimgt.webapp.publisher.*; import org.wso2.carbon.apimgt.webapp.publisher.APIConfig;
import org.wso2.carbon.apimgt.webapp.publisher.APIPublisherService;
import org.wso2.carbon.apimgt.webapp.publisher.APIPublisherUtil;
import org.wso2.carbon.apimgt.webapp.publisher.config.APIResourceConfiguration; import org.wso2.carbon.apimgt.webapp.publisher.config.APIResourceConfiguration;
import org.wso2.carbon.apimgt.webapp.publisher.internal.APIPublisherDataHolder; import org.wso2.carbon.apimgt.webapp.publisher.internal.APIPublisherDataHolder;
import org.wso2.carbon.apimgt.webapp.publisher.lifecycle.util.AnnotationUtil; import org.wso2.carbon.apimgt.webapp.publisher.lifecycle.util.AnnotationUtil;
@ -39,7 +41,6 @@ import java.util.Set;
public class APIPublisherLifecycleListener implements LifecycleListener { public class APIPublisherLifecycleListener implements LifecycleListener {
private static final Log log = LogFactory.getLog(APIPublisherLifecycleListener.class); private static final Log log = LogFactory.getLog(APIPublisherLifecycleListener.class);
private static final String PARAM_MANAGED_API_ENABLED = "managed-api-enabled"; private static final String PARAM_MANAGED_API_ENABLED = "managed-api-enabled";
@Override @Override
@ -55,6 +56,7 @@ public class APIPublisherLifecycleListener implements LifecycleListener {
AnnotationUtil annotationUtil = new AnnotationUtil(context); AnnotationUtil annotationUtil = new AnnotationUtil(context);
Set<String> annotatedAPIClasses = annotationUtil. Set<String> annotatedAPIClasses = annotationUtil.
scanStandardContext(org.wso2.carbon.apimgt.annotations.api.API.class.getName()); scanStandardContext(org.wso2.carbon.apimgt.annotations.api.API.class.getName());
List<APIResourceConfiguration> apiDefinitions = annotationUtil.extractAPIInfo(servletContext, List<APIResourceConfiguration> apiDefinitions = annotationUtil.extractAPIInfo(servletContext,
annotatedAPIClasses); annotatedAPIClasses);

@ -20,13 +20,18 @@ package org.wso2.carbon.apimgt.webapp.publisher.lifecycle.util;
import org.apache.catalina.core.StandardContext; import org.apache.catalina.core.StandardContext;
import org.apache.commons.lang.ArrayUtils; import org.apache.commons.lang.ArrayUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
import org.scannotation.AnnotationDB; import org.scannotation.AnnotationDB;
import org.scannotation.WarUrlFinder; import org.scannotation.WarUrlFinder;
import org.wso2.carbon.apimgt.annotations.api.API; import org.wso2.carbon.apimgt.annotations.api.API;
import org.wso2.carbon.apimgt.annotations.api.Permission;
import org.wso2.carbon.apimgt.api.model.Scope;
import org.wso2.carbon.apimgt.webapp.publisher.config.APIResource; import org.wso2.carbon.apimgt.webapp.publisher.config.APIResource;
import org.wso2.carbon.apimgt.webapp.publisher.config.APIResourceConfiguration; import org.wso2.carbon.apimgt.webapp.publisher.config.APIResourceConfiguration;
import org.wso2.carbon.apimgt.webapp.publisher.config.PermissionConfiguration;
import org.wso2.carbon.apimgt.webapp.publisher.config.PermissionManagementException;
import javax.servlet.ServletContext; import javax.servlet.ServletContext;
import javax.ws.rs.*; import javax.ws.rs.*;
@ -38,7 +43,9 @@ import java.lang.reflect.Proxy;
import java.net.URL; import java.net.URL;
import java.security.AccessController; import java.security.AccessController;
import java.security.PrivilegedAction; import java.security.PrivilegedAction;
import java.util.*; import java.util.ArrayList;
import java.util.List;
import java.util.Set;
public class AnnotationUtil { public class AnnotationUtil {
@ -118,7 +125,6 @@ public class AnnotationUtil {
.class.getName()); .class.getName());
Annotation apiAnno = clazz.getAnnotation(apiClazz); Annotation apiAnno = clazz.getAnnotation(apiClazz);
List<APIResource> resourceList; List<APIResource> resourceList;
if (apiAnno != null) { if (apiAnno != null) {
@ -224,7 +230,6 @@ public class AnnotationUtil {
Annotation[] annotations = method.getDeclaredAnnotations(); Annotation[] annotations = method.getDeclaredAnnotations();
for (int i = 0; i < annotations.length; i++) { for (int i = 0; i < annotations.length; i++) {
processHTTPMethodAnnotation(resource, annotations[i]); processHTTPMethodAnnotation(resource, annotations[i]);
if (annotations[i].annotationType().getName().equals(Consumes.class.getName())) { if (annotations[i].annotationType().getName().equals(Consumes.class.getName())) {
Class<Consumes> consumesClass = (Class<Consumes>) classLoader.loadClass( Class<Consumes> consumesClass = (Class<Consumes>) classLoader.loadClass(
@ -240,6 +245,18 @@ public class AnnotationUtil {
Annotation producesAnno = method.getAnnotation(producesClass); Annotation producesAnno = method.getAnnotation(producesClass);
resource.setProduces(invokeMethod(producesClassMethods[0], producesAnno, STRING_ARR)); resource.setProduces(invokeMethod(producesClassMethods[0], producesAnno, STRING_ARR));
} }
if (annotations[i].annotationType().getName().equals(Permission.class.getName())) {
PermissionConfiguration permissionConf = this.getPermission(method);
if (permissionConf != null) {
Scope scope = new Scope();
scope.setKey(permissionConf.getScopeName());
scope.setDescription(permissionConf.getScopeName());
scope.setName(permissionConf.getScopeName());
String roles = StringUtils.join(permissionConf.getPermissions(), ",");
scope.setRoles(roles);
resource.setScope(scope);
}
}
} }
resourceList.add(resource); resourceList.add(resource);
} }
@ -314,4 +331,34 @@ public class AnnotationUtil {
InvocationHandler methodHandler = Proxy.getInvocationHandler(annotation); InvocationHandler methodHandler = Proxy.getInvocationHandler(annotation);
return ((String[]) methodHandler.invoke(annotation, method, null)); return ((String[]) methodHandler.invoke(annotation, method, null));
} }
private PermissionConfiguration getPermission(Method currentMethod) throws Throwable {
Class<Permission> permissionClass = (Class<Permission>) classLoader.loadClass(Permission.class.getName());
Annotation permissionAnnotation = currentMethod.getAnnotation(permissionClass);
if (permissionClass != null) {
Method[] permissionClassMethods = permissionClass.getMethods();
PermissionConfiguration permissionConf = new PermissionConfiguration();
for (Method method : permissionClassMethods) {
switch (method.getName()) {
case "scope":
permissionConf.setScopeName(invokeMethod(method, permissionAnnotation, STRING));
break;
case "permissions":
String permissions[] = invokeMethod(method, permissionAnnotation);
this.addPermission(permissions);
permissionConf.setPermissions(permissions);
break;
}
}
return permissionConf;
}
return null;
}
private void addPermission(String[] permissions) throws PermissionManagementException {
for (String permission : permissions) {
PermissionUtils.addPermission(permission);
}
}
} }

@ -0,0 +1,91 @@
/*
* Copyright (c) 2015, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
*
* WSO2 Inc. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* you may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.wso2.carbon.apimgt.webapp.publisher.lifecycle.util;
import org.wso2.carbon.apimgt.webapp.publisher.config.PermissionManagementException;
import org.wso2.carbon.apimgt.webapp.publisher.internal.APIPublisherDataHolder;
import org.wso2.carbon.context.PrivilegedCarbonContext;
import org.wso2.carbon.registry.api.RegistryException;
import org.wso2.carbon.registry.api.Resource;
import org.wso2.carbon.registry.core.Registry;
import java.util.StringTokenizer;
/**
* Utility class which holds necessary utility methods required for persisting permissions in
* registry.
*/
public class PermissionUtils {
public static final String ADMIN_PERMISSION_REGISTRY_PATH = "/permission/admin";
public static final String PERMISSION_PROPERTY_NAME = "name";
public static Registry getGovernanceRegistry() throws PermissionManagementException {
try {
int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId();
return APIPublisherDataHolder.getInstance().getRegistryService()
.getGovernanceSystemRegistry(
tenantId);
} catch (RegistryException e) {
throw new PermissionManagementException(
"Error in retrieving governance registry instance: " +
e.getMessage(), e);
}
}
public static void addPermission(String permission) throws PermissionManagementException {
String resourcePermission = getAbsolutePermissionPath(permission);
try {
StringTokenizer tokenizer = new StringTokenizer(resourcePermission, "/");
String lastToken = "", currentToken, tempPath;
while (tokenizer.hasMoreTokens()) {
currentToken = tokenizer.nextToken();
tempPath = lastToken + "/" + currentToken;
if (!checkResourceExists(tempPath)) {
createRegistryCollection(tempPath, currentToken);
}
lastToken = tempPath;
}
} catch (RegistryException e) {
throw new PermissionManagementException("Error occurred while persisting permission : " +
resourcePermission, e);
}
}
public static void createRegistryCollection(String path, String resourceName)
throws PermissionManagementException,
RegistryException {
Resource resource = PermissionUtils.getGovernanceRegistry().newCollection();
resource.addProperty(PERMISSION_PROPERTY_NAME, resourceName);
PermissionUtils.getGovernanceRegistry().beginTransaction();
PermissionUtils.getGovernanceRegistry().put(path, resource);
PermissionUtils.getGovernanceRegistry().commitTransaction();
}
public static boolean checkResourceExists(String path)
throws PermissionManagementException,
org.wso2.carbon.registry.core.exceptions.RegistryException {
return PermissionUtils.getGovernanceRegistry().resourceExists(path);
}
private static String getAbsolutePermissionPath(String permissionPath) {
return PermissionUtils.ADMIN_PERMISSION_REGISTRY_PATH + permissionPath;
}
}

@ -21,6 +21,7 @@ package org.wso2.carbon.device.mgt.analytics.dashboard;
import org.wso2.carbon.device.mgt.common.PaginationRequest; import org.wso2.carbon.device.mgt.common.PaginationRequest;
import org.wso2.carbon.device.mgt.common.PaginationResult; import org.wso2.carbon.device.mgt.common.PaginationResult;
import java.util.List;
import java.util.Map; import java.util.Map;
/** /**
@ -52,10 +53,35 @@ public interface GadgetDataService {
@SuppressWarnings("unused") @SuppressWarnings("unused")
int getDeviceCount(Map<String, Object> filters); int getDeviceCount(Map<String, Object> filters);
@SuppressWarnings("unused")
int getFeatureNonCompliantDeviceCount(String nonCompliantFeatureCode, Map<String, Object> filters);
@SuppressWarnings("unused") @SuppressWarnings("unused")
Map<String, Integer> getDeviceCountsByPlatforms(Map<String, Object> filters); Map<String, Integer> getDeviceCountsByPlatforms(Map<String, Object> filters);
@SuppressWarnings("unused")
Map<String, Integer> getFeatureNonCompliantDeviceCountsByPlatforms(String nonCompliantFeatureCode,
Map<String, Object> filters);
@SuppressWarnings("unused") @SuppressWarnings("unused")
Map<String, Integer> getDeviceCountsByOwnershipTypes(Map<String, Object> filters); Map<String, Integer> getDeviceCountsByOwnershipTypes(Map<String, Object> filters);
@SuppressWarnings("unused")
Map<String, Integer> getFeatureNonCompliantDeviceCountsByOwnershipTypes(String nonCompliantFeatureCode,
Map<String, Object> filters);
@SuppressWarnings("unused")
PaginationResult getDevicesWithDetails(Map<String, Object> filters, PaginationRequest paginationRequest);
@SuppressWarnings("unused")
PaginationResult getFeatureNonCompliantDevicesWithDetails(String nonCompliantFeatureCode,
Map<String, Object> filters, PaginationRequest paginationRequest);
@SuppressWarnings("unused")
List<Map<String, Object>> getDevicesWithDetails(Map<String, Object> filters);
@SuppressWarnings("unused")
List<Map<String, Object>> getFeatureNonCompliantDevicesWithDetails(String nonCompliantFeatureCode,
Map<String, Object> filters);
} }

@ -80,11 +80,19 @@ public interface GadgetDataServiceDAO {
Map<String, Integer> getFeatureNonCompliantDeviceCountsByOwnershipTypes(String nonCompliantFeatureCode, Map<String, Integer> getFeatureNonCompliantDeviceCountsByOwnershipTypes(String nonCompliantFeatureCode,
Map<String, Object> filters) throws GadgetDataServiceDAOException; Map<String, Object> filters) throws GadgetDataServiceDAOException;
@SuppressWarnings("unused")
PaginationResult getDevicesWithDetails(Map<String, Object> filters,
PaginationRequest paginationRequest) throws GadgetDataServiceDAOException;
@SuppressWarnings("unused")
PaginationResult getFeatureNonCompliantDevicesWithDetails(String nonCompliantFeatureCode,
Map<String, Object> filters, PaginationRequest paginationRequest) throws GadgetDataServiceDAOException;
@SuppressWarnings("unused") @SuppressWarnings("unused")
List<Map<String, Object>> getDevicesWithDetails(Map<String, Object> filters) throws GadgetDataServiceDAOException; List<Map<String, Object>> getDevicesWithDetails(Map<String, Object> filters) throws GadgetDataServiceDAOException;
@SuppressWarnings("unused") @SuppressWarnings("unused")
List<Map<String, Object>> getFeatureNonCompliantDevicesWithDetails(String nonCompliantFeatureCode, List<Map<String, Object>> getFeatureNonCompliantDevicesWithDetails(String nonCompliantFeatureCode,
Map<String, Object> filters) throws GadgetDataServiceDAOException; Map<String, Object> filters) throws GadgetDataServiceDAOException;
} }

@ -357,7 +357,8 @@ class GadgetDataServiceDAOImpl implements GadgetDataServiceDAO {
return filteredDeviceCountsByOwnershipTypes; return filteredDeviceCountsByOwnershipTypes;
} }
public Map<String, Integer> getFeatureNonCompliantDeviceCountsByOwnershipTypes(String nonCompliantFeatureCode, Map<String, Object> filters) throws GadgetDataServiceDAOException { public Map<String, Integer> getFeatureNonCompliantDeviceCountsByOwnershipTypes(String nonCompliantFeatureCode,
Map<String, Object> filters) throws GadgetDataServiceDAOException {
Connection con; Connection con;
PreparedStatement stmt = null; PreparedStatement stmt = null;
ResultSet rs = null; ResultSet rs = null;
@ -404,6 +405,155 @@ class GadgetDataServiceDAOImpl implements GadgetDataServiceDAO {
return filteredDeviceCountsByOwnershipTypes; return filteredDeviceCountsByOwnershipTypes;
} }
public PaginationResult getDevicesWithDetails(Map<String, Object> filters,
PaginationRequest paginationRequest) throws GadgetDataServiceDAOException {
Connection con;
PreparedStatement stmt = null;
ResultSet rs = null;
int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId();
Map<String, Object> filteredDeviceWithDetails = new HashMap<>();
List<Map<String, Object>> filteredDevicesWithDetails = new ArrayList<>();
int totalRecordsCount = 0;
try {
con = this.getConnection();
String sql, advancedSqlFiltering = "";
// appending filters if exist, to support advanced filtering options
// [1] appending filter columns, if exist
if (filters != null && filters.size() > 0) {
for (String column : filters.keySet()) {
advancedSqlFiltering = advancedSqlFiltering + "AND " + column + " = ? ";
}
}
sql = "SELECT DEVICE_ID, PLATFORM, OWNERSHIP, CONNECTIVITY_STATUS FROM DEVICES_VIEW_1 " +
"WHERE TENANT_ID = ? " + advancedSqlFiltering + "ORDER BY DEVICE_ID ASC LIMIT ?, ?";
stmt = con.prepareStatement(sql);
// [2] appending filter column values, if exist
stmt.setInt(1, tenantId);
if (filters != null && filters.values().size() > 0) {
int i = 2;
for (Object value : filters.values()) {
if (value instanceof Integer) {
stmt.setInt(i, (Integer) value);
} else if (value instanceof String) {
stmt.setString(i, (String) value);
}
i++;
}
stmt.setInt(i, paginationRequest.getStartIndex());
stmt.setInt(++i, paginationRequest.getRowCount());
} else {
stmt.setInt(2, paginationRequest.getStartIndex());
stmt.setInt(3, paginationRequest.getRowCount());
}
// executing query
rs = stmt.executeQuery();
// fetching query results
while (rs.next()) {
filteredDeviceWithDetails.put("device-id", rs.getInt("DEVICE_ID"));
filteredDeviceWithDetails.put("platform", rs.getString("PLATFORM"));
filteredDeviceWithDetails.put("ownership", rs.getString("OWNERSHIP"));
filteredDeviceWithDetails.put("connectivity-details", rs.getString("CONNECTIVITY_STATUS"));
filteredDevicesWithDetails.add(filteredDeviceWithDetails);
}
// fetching total records count
sql = "SELECT COUNT(DEVICE_ID) AS DEVICE_COUNT FROM DEVICES_VIEW_1 WHERE TENANT_ID = ?";
stmt = con.prepareStatement(sql);
stmt.setInt(1, tenantId);
// executing query
rs = stmt.executeQuery();
// fetching query results
while (rs.next()) {
totalRecordsCount = rs.getInt("DEVICE_COUNT");
}
} catch (SQLException e) {
throw new GadgetDataServiceDAOException("Error occurred while executing a selection query to the database", e);
} finally {
DeviceManagementDAOUtil.cleanupResources(stmt, rs);
}
PaginationResult paginationResult = new PaginationResult();
paginationResult.setData(filteredDevicesWithDetails);
paginationResult.setRecordsTotal(totalRecordsCount);
return paginationResult;
}
public PaginationResult getFeatureNonCompliantDevicesWithDetails(String nonCompliantFeatureCode,
Map<String, Object> filters, PaginationRequest paginationRequest) throws GadgetDataServiceDAOException {
Connection con;
PreparedStatement stmt = null;
ResultSet rs = null;
int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId();
Map<String, Object> filteredDeviceWithDetails = new HashMap<>();
List<Map<String, Object>> filteredDevicesWithDetails = new ArrayList<>();
int totalRecordsCount = 0;
try {
con = this.getConnection();
String sql, advancedSqlFiltering = "";
// appending filters if exist, to support advanced filtering options
// [1] appending filter columns, if exist
if (filters != null && filters.size() > 0) {
for (String column : filters.keySet()) {
advancedSqlFiltering = advancedSqlFiltering + "AND " + column + " = ? ";
}
}
sql = "SELECT DEVICE_ID, PLATFORM, OWNERSHIP, CONNECTIVITY_STATUS FROM DEVICES_VIEW_2 " +
"WHERE TENANT_ID = ? AND FEATURE_CODE = ? " + advancedSqlFiltering + "ORDER BY DEVICE_ID ASC LIMIT ?, ?";
stmt = con.prepareStatement(sql);
// [2] appending filter column values, if exist
stmt.setInt(1, tenantId);
stmt.setString(2, nonCompliantFeatureCode);
if (filters != null && filters.values().size() > 0) {
int i = 3;
for (Object value : filters.values()) {
if (value instanceof Integer) {
stmt.setInt(i, (Integer) value);
} else if (value instanceof String) {
stmt.setString(i, (String) value);
}
i++;
}
stmt.setInt(i, paginationRequest.getStartIndex());
stmt.setInt(++i, paginationRequest.getRowCount());
} else {
stmt.setInt(3, paginationRequest.getStartIndex());
stmt.setInt(4, paginationRequest.getRowCount());
}
// executing query
rs = stmt.executeQuery();
// fetching query results
while (rs.next()) {
filteredDeviceWithDetails.put("device-id", rs.getInt("DEVICE_ID"));
filteredDeviceWithDetails.put("platform", rs.getString("PLATFORM"));
filteredDeviceWithDetails.put("ownership", rs.getString("OWNERSHIP"));
filteredDeviceWithDetails.put("connectivity-details", rs.getString("CONNECTIVITY_STATUS"));
filteredDevicesWithDetails.add(filteredDeviceWithDetails);
}
// fetching total records count
sql = "SELECT COUNT(DEVICE_ID) AS DEVICE_COUNT FROM DEVICES_VIEW_2 " +
"WHERE TENANT_ID = ? AND FEATURE_CODE = ?";
stmt = con.prepareStatement(sql);
stmt.setInt(1, tenantId);
stmt.setString(2, nonCompliantFeatureCode);
// executing query
rs = stmt.executeQuery();
// fetching query results
while (rs.next()) {
totalRecordsCount = rs.getInt("DEVICE_COUNT");
}
} catch (SQLException e) {
throw new GadgetDataServiceDAOException("Error occurred while executing a selection query to the database", e);
} finally {
DeviceManagementDAOUtil.cleanupResources(stmt, rs);
}
PaginationResult paginationResult = new PaginationResult();
paginationResult.setData(filteredDevicesWithDetails);
paginationResult.setRecordsTotal(totalRecordsCount);
return paginationResult;
}
public List<Map<String, Object>> getDevicesWithDetails(Map<String, Object> filters) throws GadgetDataServiceDAOException { public List<Map<String, Object>> getDevicesWithDetails(Map<String, Object> filters) throws GadgetDataServiceDAOException {
Connection con; Connection con;
PreparedStatement stmt = null; PreparedStatement stmt = null;
@ -454,7 +604,8 @@ class GadgetDataServiceDAOImpl implements GadgetDataServiceDAO {
return filteredDevicesWithDetails; return filteredDevicesWithDetails;
} }
public List<Map<String, Object>> getFeatureNonCompliantDevicesWithDetails(String nonCompliantFeatureCode, Map<String, Object> filters) throws GadgetDataServiceDAOException { public List<Map<String, Object>> getFeatureNonCompliantDevicesWithDetails(String nonCompliantFeatureCode,
Map<String, Object> filters) throws GadgetDataServiceDAOException {
Connection con; Connection con;
PreparedStatement stmt = null; PreparedStatement stmt = null;
ResultSet rs = null; ResultSet rs = null;
@ -465,7 +616,7 @@ class GadgetDataServiceDAOImpl implements GadgetDataServiceDAO {
con = this.getConnection(); con = this.getConnection();
String sql; String sql;
sql = "SELECT DEVICE_ID, PLATFORM, OWNERSHIP, CONNECTIVITY_STATUS FROM DEVICES_VIEW_2 " + sql = "SELECT DEVICE_ID, PLATFORM, OWNERSHIP, CONNECTIVITY_STATUS FROM DEVICES_VIEW_2 " +
"WHERE TENANT_ID = ? AND FEATURE_CODE = ?"; "WHERE TENANT_ID = ? AND FEATURE_CODE = ?";
// appending filters to support advanced filtering options // appending filters to support advanced filtering options
// [1] appending filter columns, if exist // [1] appending filter columns, if exist
if (filters != null && filters.size() > 0) { if (filters != null && filters.size() > 0) {

@ -27,6 +27,7 @@ import org.wso2.carbon.device.mgt.common.PaginationRequest;
import org.wso2.carbon.device.mgt.common.PaginationResult; import org.wso2.carbon.device.mgt.common.PaginationResult;
import java.sql.SQLException; import java.sql.SQLException;
import java.util.List;
import java.util.Map; import java.util.Map;
/** /**
@ -42,8 +43,7 @@ class GadgetDataServiceImpl implements GadgetDataService {
int totalDeviceCount; int totalDeviceCount;
try { try {
GadgetDataServiceDAOFactory.openConnection(); GadgetDataServiceDAOFactory.openConnection();
totalDeviceCount = GadgetDataServiceDAOFactory. totalDeviceCount = GadgetDataServiceDAOFactory.getGadgetDataServiceDAO().getTotalDeviceCount();
getGadgetDataServiceDAO().getTotalDeviceCount();
} catch (GadgetDataServiceDAOException | SQLException e) { } catch (GadgetDataServiceDAOException | SQLException e) {
totalDeviceCount = -1; totalDeviceCount = -1;
return totalDeviceCount; return totalDeviceCount;
@ -58,8 +58,7 @@ class GadgetDataServiceImpl implements GadgetDataService {
int activeDeviceCount; int activeDeviceCount;
try { try {
GadgetDataServiceDAOFactory.openConnection(); GadgetDataServiceDAOFactory.openConnection();
activeDeviceCount = GadgetDataServiceDAOFactory. activeDeviceCount = GadgetDataServiceDAOFactory.getGadgetDataServiceDAO().getActiveDeviceCount();
getGadgetDataServiceDAO().getActiveDeviceCount();
} catch (GadgetDataServiceDAOException | SQLException e) { } catch (GadgetDataServiceDAOException | SQLException e) {
activeDeviceCount = -1; activeDeviceCount = -1;
return activeDeviceCount; return activeDeviceCount;
@ -74,8 +73,7 @@ class GadgetDataServiceImpl implements GadgetDataService {
int inactiveDeviceCount; int inactiveDeviceCount;
try { try {
GadgetDataServiceDAOFactory.openConnection(); GadgetDataServiceDAOFactory.openConnection();
inactiveDeviceCount = GadgetDataServiceDAOFactory. inactiveDeviceCount = GadgetDataServiceDAOFactory.getGadgetDataServiceDAO().getInactiveDeviceCount();
getGadgetDataServiceDAO().getInactiveDeviceCount();
} catch (GadgetDataServiceDAOException | SQLException e) { } catch (GadgetDataServiceDAOException | SQLException e) {
inactiveDeviceCount = -1; inactiveDeviceCount = -1;
return inactiveDeviceCount; return inactiveDeviceCount;
@ -90,8 +88,7 @@ class GadgetDataServiceImpl implements GadgetDataService {
int removedDeviceCount; int removedDeviceCount;
try { try {
GadgetDataServiceDAOFactory.openConnection(); GadgetDataServiceDAOFactory.openConnection();
removedDeviceCount = GadgetDataServiceDAOFactory. removedDeviceCount = GadgetDataServiceDAOFactory.getGadgetDataServiceDAO().getRemovedDeviceCount();
getGadgetDataServiceDAO().getRemovedDeviceCount();
} catch (GadgetDataServiceDAOException | SQLException e) { } catch (GadgetDataServiceDAOException | SQLException e) {
removedDeviceCount = -1; removedDeviceCount = -1;
return removedDeviceCount; return removedDeviceCount;
@ -106,8 +103,7 @@ class GadgetDataServiceImpl implements GadgetDataService {
int nonCompliantDeviceCount; int nonCompliantDeviceCount;
try { try {
GadgetDataServiceDAOFactory.openConnection(); GadgetDataServiceDAOFactory.openConnection();
nonCompliantDeviceCount = GadgetDataServiceDAOFactory. nonCompliantDeviceCount = GadgetDataServiceDAOFactory.getGadgetDataServiceDAO().getNonCompliantDeviceCount();
getGadgetDataServiceDAO().getNonCompliantDeviceCount();
} catch (GadgetDataServiceDAOException | SQLException e) { } catch (GadgetDataServiceDAOException | SQLException e) {
nonCompliantDeviceCount = -1; nonCompliantDeviceCount = -1;
return nonCompliantDeviceCount; return nonCompliantDeviceCount;
@ -122,8 +118,7 @@ class GadgetDataServiceImpl implements GadgetDataService {
int unmonitoredDeviceCount; int unmonitoredDeviceCount;
try { try {
GadgetDataServiceDAOFactory.openConnection(); GadgetDataServiceDAOFactory.openConnection();
unmonitoredDeviceCount = GadgetDataServiceDAOFactory. unmonitoredDeviceCount = GadgetDataServiceDAOFactory.getGadgetDataServiceDAO().getUnmonitoredDeviceCount();
getGadgetDataServiceDAO().getUnmonitoredDeviceCount();
} catch (GadgetDataServiceDAOException | SQLException e) { } catch (GadgetDataServiceDAOException | SQLException e) {
unmonitoredDeviceCount = -1; unmonitoredDeviceCount = -1;
return unmonitoredDeviceCount; return unmonitoredDeviceCount;
@ -153,8 +148,7 @@ class GadgetDataServiceImpl implements GadgetDataService {
int deviceCount; int deviceCount;
try { try {
GadgetDataServiceDAOFactory.openConnection(); GadgetDataServiceDAOFactory.openConnection();
deviceCount = GadgetDataServiceDAOFactory. deviceCount = GadgetDataServiceDAOFactory.getGadgetDataServiceDAO().getDeviceCount(filters);
getGadgetDataServiceDAO().getDeviceCount(filters);
} catch (GadgetDataServiceDAOException | SQLException e) { } catch (GadgetDataServiceDAOException | SQLException e) {
deviceCount = -1; deviceCount = -1;
return deviceCount; return deviceCount;
@ -164,13 +158,29 @@ class GadgetDataServiceImpl implements GadgetDataService {
return deviceCount; return deviceCount;
} }
@Override
public int getFeatureNonCompliantDeviceCount(String nonCompliantFeatureCode, Map<String, Object> filters) {
int featureNonCompliantDeviceCount;
try {
GadgetDataServiceDAOFactory.openConnection();
featureNonCompliantDeviceCount = GadgetDataServiceDAOFactory.
getGadgetDataServiceDAO().getFeatureNonCompliantDeviceCount(nonCompliantFeatureCode, filters);
} catch (GadgetDataServiceDAOException | SQLException e) {
featureNonCompliantDeviceCount = -1;
return featureNonCompliantDeviceCount;
} finally {
GadgetDataServiceDAOFactory.closeConnection();
}
return featureNonCompliantDeviceCount;
}
@Override @Override
public Map<String, Integer> getDeviceCountsByPlatforms(Map<String, Object> filters) { public Map<String, Integer> getDeviceCountsByPlatforms(Map<String, Object> filters) {
Map<String, Integer> deviceCountsByPlatforms = null; Map<String, Integer> deviceCountsByPlatforms = null;
try { try {
GadgetDataServiceDAOFactory.openConnection(); GadgetDataServiceDAOFactory.openConnection();
deviceCountsByPlatforms = GadgetDataServiceDAOFactory. deviceCountsByPlatforms = GadgetDataServiceDAOFactory.getGadgetDataServiceDAO().
getGadgetDataServiceDAO().getDeviceCountsByPlatforms(filters); getDeviceCountsByPlatforms(filters);
} catch (GadgetDataServiceDAOException | SQLException e) { } catch (GadgetDataServiceDAOException | SQLException e) {
return null; return null;
} finally { } finally {
@ -179,13 +189,29 @@ class GadgetDataServiceImpl implements GadgetDataService {
return deviceCountsByPlatforms; return deviceCountsByPlatforms;
} }
@Override
public Map<String, Integer> getFeatureNonCompliantDeviceCountsByPlatforms(String nonCompliantFeatureCode,
Map<String, Object> filters) {
Map<String, Integer> featureNonCompliantDeviceCountsByPlatforms = null;
try {
GadgetDataServiceDAOFactory.openConnection();
featureNonCompliantDeviceCountsByPlatforms = GadgetDataServiceDAOFactory.
getGadgetDataServiceDAO().getFeatureNonCompliantDeviceCountsByPlatforms(nonCompliantFeatureCode, filters);
} catch (GadgetDataServiceDAOException | SQLException e) {
return null;
} finally {
GadgetDataServiceDAOFactory.closeConnection();
}
return featureNonCompliantDeviceCountsByPlatforms;
}
@Override @Override
public Map<String, Integer> getDeviceCountsByOwnershipTypes(Map<String, Object> filters) { public Map<String, Integer> getDeviceCountsByOwnershipTypes(Map<String, Object> filters) {
Map<String, Integer> deviceCountsByOwnershipTypes = null; Map<String, Integer> deviceCountsByOwnershipTypes = null;
try { try {
GadgetDataServiceDAOFactory.openConnection(); GadgetDataServiceDAOFactory.openConnection();
deviceCountsByOwnershipTypes = GadgetDataServiceDAOFactory. deviceCountsByOwnershipTypes = GadgetDataServiceDAOFactory.getGadgetDataServiceDAO().
getGadgetDataServiceDAO().getDeviceCountsByOwnershipTypes(filters); getDeviceCountsByOwnershipTypes(filters);
} catch (GadgetDataServiceDAOException | SQLException e) { } catch (GadgetDataServiceDAOException | SQLException e) {
return null; return null;
} finally { } finally {
@ -194,4 +220,62 @@ class GadgetDataServiceImpl implements GadgetDataService {
return deviceCountsByOwnershipTypes; return deviceCountsByOwnershipTypes;
} }
@Override
public Map<String, Integer> getFeatureNonCompliantDeviceCountsByOwnershipTypes(String nonCompliantFeatureCode,
Map<String, Object> filters) {
Map<String, Integer> featureNonCompliantDeviceCountsByOwnershipTypes = null;
try {
GadgetDataServiceDAOFactory.openConnection();
featureNonCompliantDeviceCountsByOwnershipTypes =
GadgetDataServiceDAOFactory.getGadgetDataServiceDAO().
getFeatureNonCompliantDeviceCountsByOwnershipTypes(nonCompliantFeatureCode, filters);
} catch (GadgetDataServiceDAOException | SQLException e) {
return null;
} finally {
GadgetDataServiceDAOFactory.closeConnection();
}
return featureNonCompliantDeviceCountsByOwnershipTypes;
}
@Override
public PaginationResult getDevicesWithDetails(Map<String, Object> filters, PaginationRequest paginationRequest) {
PaginationResult paginationResult = null;
try {
GadgetDataServiceDAOFactory.openConnection();
paginationResult = GadgetDataServiceDAOFactory.getGadgetDataServiceDAO().
getDevicesWithDetails(filters, paginationRequest);
} catch (GadgetDataServiceDAOException | SQLException e) {
return null;
} finally {
GadgetDataServiceDAOFactory.closeConnection();
}
return paginationResult;
}
@Override
public PaginationResult getFeatureNonCompliantDevicesWithDetails(String nonCompliantFeatureCode,
Map<String, Object> filters, PaginationRequest paginationRequest) {
PaginationResult paginationResult = null;
try {
GadgetDataServiceDAOFactory.openConnection();
paginationResult = GadgetDataServiceDAOFactory.getGadgetDataServiceDAO().
getFeatureNonCompliantDevicesWithDetails(nonCompliantFeatureCode, filters, paginationRequest);
} catch (GadgetDataServiceDAOException | SQLException e) {
return null;
} finally {
GadgetDataServiceDAOFactory.closeConnection();
}
return paginationResult;
}
@Override
public List<Map<String, Object>> getDevicesWithDetails(Map<String, Object> filters) {
return null;
}
@Override
public List<Map<String, Object>> getFeatureNonCompliantDevicesWithDetails(String nonCompliantFeatureCode, Map<String, Object> filters) {
return null;
}
} }

@ -45,23 +45,23 @@ import java.util.List;
@SuppressWarnings("unused") @SuppressWarnings("unused")
public class WebAppDeploymentLifecycleListener implements LifecycleListener { public class WebAppDeploymentLifecycleListener implements LifecycleListener {
private static final String PERMISSION_CONFIG_PATH = "META-INF" + File.separator + "permissions.xml"; private static final String PERMISSION_CONFIG_PATH = "META-INF" + File.separator + "permissions.xml";
private static final Log log = LogFactory.getLog(WebAppDeploymentLifecycleListener.class); private static final Log log = LogFactory.getLog(WebAppDeploymentLifecycleListener.class);
@Override @Override
public void lifecycleEvent(LifecycleEvent lifecycleEvent) { public void lifecycleEvent(LifecycleEvent lifecycleEvent) {
if (Lifecycle.AFTER_START_EVENT.equals(lifecycleEvent.getType())) { if (Lifecycle.AFTER_START_EVENT.equals(lifecycleEvent.getType())) {
StandardContext context = (StandardContext) lifecycleEvent.getLifecycle(); StandardContext context = (StandardContext) lifecycleEvent.getLifecycle();
ServletContext servletContext = context.getServletContext(); ServletContext servletContext = context.getServletContext();
String contextPath = context.getServletContext().getContextPath(); String contextPath = context.getServletContext().getContextPath();
try { try {
InputStream permissionStream = servletContext.getResourceAsStream(PERMISSION_CONFIG_PATH); InputStream permissionStream = servletContext.getResourceAsStream(PERMISSION_CONFIG_PATH);
if (permissionStream != null) { if (permissionStream != null) {
/* Un-marshaling Device Management configuration */ /* Un-marshaling Device Management configuration */
JAXBContext cdmContext = JAXBContext.newInstance(PermissionConfiguration.class); JAXBContext cdmContext = JAXBContext.newInstance(PermissionConfiguration.class);
Unmarshaller unmarshaller = cdmContext.createUnmarshaller(); Unmarshaller unmarshaller = cdmContext.createUnmarshaller();
PermissionConfiguration permissionConfiguration = (PermissionConfiguration) PermissionConfiguration permissionConfiguration = (PermissionConfiguration)
unmarshaller.unmarshal(permissionStream); unmarshaller.unmarshal(permissionStream);
List<Permission> permissions = permissionConfiguration.getPermissions(); List<Permission> permissions = permissionConfiguration.getPermissions();
String apiVersion = permissionConfiguration.getApiVersion(); String apiVersion = permissionConfiguration.getApiVersion();
if (permissionConfiguration != null && permissions != null) { if (permissionConfiguration != null && permissions != null) {
@ -69,22 +69,22 @@ public class WebAppDeploymentLifecycleListener implements LifecycleListener {
// update the permission path to absolute permission path // update the permission path to absolute permission path
permission.setPath(PermissionUtils.getAbsolutePermissionPath(permission.getPath())); permission.setPath(PermissionUtils.getAbsolutePermissionPath(permission.getPath()));
permission.setUrl(PermissionUtils.getAbsoluteContextPathOfAPI(contextPath, apiVersion, permission.setUrl(PermissionUtils.getAbsoluteContextPathOfAPI(contextPath, apiVersion,
permission.getUrl()).toLowerCase()); permission.getUrl()).toLowerCase());
permission.setMethod(permission.getMethod().toUpperCase()); permission.setMethod(permission.getMethod().toUpperCase());
PermissionManagerServiceImpl.getInstance().addPermission(permission); PermissionManagerServiceImpl.getInstance().addPermission(permission);
} }
} }
} }
} catch (JAXBException e) { } catch (JAXBException e) {
log.error( log.error(
"Exception occurred while parsing the permission configuration of webapp : " "Exception occurred while parsing the permission configuration of webapp : "
+ context.getServletContext().getContextPath(), e); + context.getServletContext().getContextPath(), e);
} catch (PermissionManagementException e) { } catch (PermissionManagementException e) {
log.error("Exception occurred while adding the permissions from webapp : " log.error("Exception occurred while adding the permissions from webapp : "
+ servletContext.getContextPath(), e); + servletContext.getContextPath(), e);
} }
} }
} }
} }

@ -17,7 +17,8 @@
~ under the License. ~ 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/xsd/maven-4.0.0.xsd"> <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/xsd/maven-4.0.0.xsd">
<parent> <parent>
<groupId>org.wso2.carbon.devicemgt</groupId> <groupId>org.wso2.carbon.devicemgt</groupId>
@ -47,8 +48,12 @@
<artifactId>org.wso2.carbon.user.core</artifactId> <artifactId>org.wso2.carbon.user.core</artifactId>
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.wso2.carbon</groupId> <groupId>org.wso2.carbon.apimgt</groupId>
<artifactId>org.wso2.carbon.user.api</artifactId> <artifactId>org.wso2.carbon.apimgt.impl</artifactId>
</dependency>
<dependency>
<groupId>com.googlecode.json-simple.wso2</groupId>
<artifactId>json-simple</artifactId>
</dependency> </dependency>
</dependencies> </dependencies>
@ -89,8 +94,25 @@
org.wso2.carbon.user.api, org.wso2.carbon.user.api,
org.wso2.carbon.user.core.service, org.wso2.carbon.user.core.service,
org.wso2.carbon.identity.application.common.model, org.wso2.carbon.identity.application.common.model,
org.wso2.carbon.identity.application.authentication.framework.model, org.wso2.carbon.identity.application.authentication.framework.model,
org.wso2.carbon.user.core.tenant org.wso2.carbon.user.core.tenant,
org.json.simple,
javax.cache,
javax.xml.namespace,
org.apache.axiom.om,
org.wso2.carbon.apimgt.api,
org.wso2.carbon.apimgt.impl,
org.wso2.carbon.apimgt.impl.dao,
org.wso2.carbon.apimgt.impl.utils,
org.wso2.carbon.identity.application.common.cache,
org.wso2.carbon.identity.core.util,
org.wso2.carbon.identity.oauth2.dto,
org.wso2.carbon.identity.oauth2.token,
org.wso2.carbon.identity.oauth2.token.handlers.grant,
org.wso2.carbon.user.core,
org.wso2.carbon.user.core.config,
org.wso2.carbon.user.core.util,
org.wso2.carbon.utils
</Import-Package> </Import-Package>
</instructions> </instructions>
</configuration> </configuration>

@ -20,9 +20,23 @@ package org.wso2.carbon.device.mgt.oauth.extensions;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
import org.wso2.carbon.apimgt.api.APIManagementException;
import org.wso2.carbon.apimgt.impl.APIConstants;
import org.wso2.carbon.apimgt.impl.dao.ApiMgtDAO;
import org.wso2.carbon.apimgt.impl.utils.APIUtil;
import org.wso2.carbon.device.mgt.oauth.extensions.internal.OAuthExtensionsDataHolder; import org.wso2.carbon.device.mgt.oauth.extensions.internal.OAuthExtensionsDataHolder;
import org.wso2.carbon.identity.core.util.IdentityTenantUtil;
import org.wso2.carbon.identity.oauth2.token.OAuthTokenReqMessageContext;
import org.wso2.carbon.user.api.TenantManager; import org.wso2.carbon.user.api.TenantManager;
import org.wso2.carbon.user.api.UserRealm;
import org.wso2.carbon.user.api.UserStoreException; import org.wso2.carbon.user.api.UserStoreException;
import org.wso2.carbon.user.core.service.RealmService;
import javax.cache.Caching;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
/** /**
* This class holds util methods used by OAuth extension bundle. * This class holds util methods used by OAuth extension bundle.
@ -30,7 +44,16 @@ import org.wso2.carbon.user.api.UserStoreException;
public class OAuthExtUtils { public class OAuthExtUtils {
private static final Log log = LogFactory.getLog(OAuthExtUtils.class); private static final Log log = LogFactory.getLog(OAuthExtUtils.class);
private static final String DEFAULT_SCOPE_NAME = "default";
private static final String UI_EXECUTE = "ui.execute";
private static final String REST_API_SCOPE_CACHE = "REST_API_SCOPE_CACHE";
/**
* This method is used to get the tenant id when given tenant domain.
*
* @param tenantDomain Tenant domain name.
* @return Returns the tenant id.
*/
public static int getTenantId(String tenantDomain) { public static int getTenantId(String tenantDomain) {
int tenantId = 0; int tenantId = 0;
if (tenantDomain != null) { if (tenantDomain != null) {
@ -39,10 +62,202 @@ public class OAuthExtUtils {
tenantId = tenantManager.getTenantId(tenantDomain); tenantId = tenantManager.getTenantId(tenantDomain);
} catch (UserStoreException e) { } catch (UserStoreException e) {
String errorMsg = "Error when getting the tenant id from the tenant domain : " + String errorMsg = "Error when getting the tenant id from the tenant domain : " +
tenantDomain; tenantDomain;
log.error(errorMsg, e); log.error(errorMsg, e);
} }
} }
return tenantId; return tenantId;
} }
/**
* This method is used to set scopes that are authorized to the OAuth token request message context.
*
* @param tokReqMsgCtx OAuth token request message context
* @return Returns true if success.
*/
public static boolean setScopes(OAuthTokenReqMessageContext tokReqMsgCtx) {
String[] requestedScopes = tokReqMsgCtx.getScope();
String[] defaultScope = new String[]{DEFAULT_SCOPE_NAME};
//If no scopes were requested.
if (requestedScopes == null || requestedScopes.length == 0) {
tokReqMsgCtx.setScope(defaultScope);
return true;
}
String consumerKey = tokReqMsgCtx.getOauth2AccessTokenReqDTO().getClientId();
List<String> reqScopeList = Arrays.asList(requestedScopes);
Map<String, String> restAPIScopesOfCurrentTenant;
try {
Map<String, String> appScopes;
ApiMgtDAO apiMgtDAO = new ApiMgtDAO();
//Get all the scopes and permissions against the scopes defined for the APIs subscribed to the application.
appScopes = apiMgtDAO.getScopeRolesOfApplication(consumerKey);
//Add API Manager rest API scopes set. This list should be loaded at server start up and keep
//in memory and add it to each and every request coming.
String tenantDomain = tokReqMsgCtx.getAuthorizedUser().getTenantDomain();
restAPIScopesOfCurrentTenant = (Map) Caching.getCacheManager(APIConstants.API_MANAGER_CACHE_MANAGER)
.getCache(REST_API_SCOPE_CACHE)
.get(tenantDomain);
if (restAPIScopesOfCurrentTenant != null) {
appScopes.putAll(restAPIScopesOfCurrentTenant);
} else {
restAPIScopesOfCurrentTenant = APIUtil.
getRESTAPIScopesFromConfig(APIUtil.getTenantRESTAPIScopesConfig(tenantDomain));
//call load tenant config for rest API.
//then put cache
appScopes.putAll(restAPIScopesOfCurrentTenant);
Caching.getCacheManager(APIConstants.API_MANAGER_CACHE_MANAGER)
.getCache(REST_API_SCOPE_CACHE)
.put(tenantDomain, restAPIScopesOfCurrentTenant);
}
//If no scopes can be found in the context of the application
if (appScopes.isEmpty()) {
if (log.isDebugEnabled()) {
log.debug("No scopes defined for the Application " +
tokReqMsgCtx.getOauth2AccessTokenReqDTO().getClientId());
}
String[] allowedScopes = getAllowedScopes(reqScopeList);
tokReqMsgCtx.setScope(allowedScopes);
return true;
}
// check for authorized scopes
List<String> authorizedScopes = getAuthorizedScopes(tokReqMsgCtx, reqScopeList, appScopes);
if (!authorizedScopes.isEmpty()) {
String[] authScopesArr = authorizedScopes.toArray(new String[authorizedScopes.size()]);
tokReqMsgCtx.setScope(authScopesArr);
} else {
tokReqMsgCtx.setScope(defaultScope);
}
} catch (APIManagementException e) {
log.error("Error while getting scopes of application " + e.getMessage());
return false;
}
return true;
}
/**
* Determines if the scope is specified in the white list.
*
* @param scope - The scope key to check
* @return - 'true' if the scope is white listed. 'false' if not.
*/
private static boolean isWhiteListedScope(String scope) {
// load white listed scopes
List<String> scopeSkipList = OAuthExtensionsDataHolder.getInstance().getWhitelistedScopes();
for (String scopeTobeSkipped : scopeSkipList) {
if (scope.matches(scopeTobeSkipped)) {
return true;
}
}
return false;
}
/**
* Get the set of default scopes. If a requested scope is matches with the patterns specified in the white list,
* then such scopes will be issued without further validation. If the scope list is empty,
* token will be issued for default scope.
*
* @param requestedScopes - The set of requested scopes
* @return - The subset of scopes that are allowed
*/
private static String[] getAllowedScopes(List<String> requestedScopes) {
List<String> authorizedScopes = new ArrayList<>();
//Iterate the requested scopes list.
for (String scope : requestedScopes) {
if (isWhiteListedScope(scope)) {
authorizedScopes.add(scope);
}
}
if (authorizedScopes.isEmpty()) {
authorizedScopes.add(DEFAULT_SCOPE_NAME);
}
return authorizedScopes.toArray(new String[authorizedScopes.size()]);
}
/**
* This method is used to get the authorized scopes out of requested scopes. It checks requested scopes with app
* scopes whether user has permissions to take actions for the requested scopes.
*
* @param tokReqMsgCtx OAuth token request message context.
* @param reqScopeList Requested scope list.
* @param appScopes App scopes.
* @return Returns a list of scopes.
*/
private static List<String> getAuthorizedScopes(OAuthTokenReqMessageContext tokReqMsgCtx, List<String> reqScopeList,
Map<String, String> appScopes) {
boolean status;
List<String> authorizedScopes = new ArrayList<>();
int tenantId;
String username = tokReqMsgCtx.getAuthorizedUser().getUserName();
String tenantDomain = tokReqMsgCtx.getAuthorizedUser().getTenantDomain();
RealmService realmService = OAuthExtensionsDataHolder.getInstance().getRealmService();
try {
tenantId = realmService.getTenantManager().getTenantId(tenantDomain);
// If tenant Id is not set in the tokenReqContext, deriving it from username.
if (tenantId == 0 || tenantId == -1) {
tenantId = IdentityTenantUtil.getTenantIdOfUser(username);
}
UserRealm userRealm = OAuthExtensionsDataHolder.getInstance().getRealmService().getTenantUserRealm(tenantId);
//Iterate the requested scopes list.
for (String scope : reqScopeList) {
status = false;
//Get the set of roles associated with the requested scope.
String appPermissions = appScopes.get(scope);
//If the scope has been defined in the context of the App and if permissions have been defined for the scope
if (appPermissions != null && appPermissions.length() != 0) {
List<String> permissions = new ArrayList<>(Arrays.asList(appPermissions.replaceAll(" ", "").split(",")));
//Check if user has at least one of the permission associated with the scope
if (!permissions.isEmpty()) {
for (String permission : permissions) {
if (userRealm != null && userRealm.getAuthorizationManager() != null) {
String userStore = tokReqMsgCtx.getAuthorizedUser().getUserStoreDomain();
if (userStore != null) {
status = userRealm.getAuthorizationManager()
.isUserAuthorized(userStore + "/" + username, permission, UI_EXECUTE);
} else {
status = userRealm.getAuthorizationManager()
.isUserAuthorized(username, permission, UI_EXECUTE);
}
if (status) {
break;
}
}
}
if (status) {
authorizedScopes.add(scope);
}
}
}
//The scope string starts with 'device_'.
else if (appScopes.containsKey(scope) || isWhiteListedScope(scope)) {
authorizedScopes.add(scope);
}
}
} catch (UserStoreException e) {
log.error("Error occurred while initializing user store.", e);
}
return authorizedScopes;
}
} }

@ -0,0 +1,328 @@
/*
* 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.device.mgt.oauth.extensions.handlers.grant;
import org.apache.axiom.om.OMElement;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.wso2.carbon.device.mgt.oauth.extensions.OAuthExtUtils;
import org.wso2.carbon.device.mgt.oauth.extensions.internal.OAuthExtensionsDataHolder;
import org.wso2.carbon.identity.application.common.cache.BaseCache;
import org.wso2.carbon.identity.core.util.IdentityConfigParser;
import org.wso2.carbon.identity.core.util.IdentityCoreConstants;
import org.wso2.carbon.identity.core.util.IdentityTenantUtil;
import org.wso2.carbon.identity.oauth.common.OAuthConstants;
import org.wso2.carbon.identity.oauth2.IdentityOAuth2Exception;
import org.wso2.carbon.identity.oauth2.ResponseHeader;
import org.wso2.carbon.identity.oauth2.dto.OAuth2AccessTokenReqDTO;
import org.wso2.carbon.identity.oauth2.token.OAuthTokenReqMessageContext;
import org.wso2.carbon.identity.oauth2.token.handlers.grant.PasswordGrantHandler;
import org.wso2.carbon.user.api.Claim;
import org.wso2.carbon.user.api.UserStoreException;
import org.wso2.carbon.user.api.UserStoreManager;
import org.wso2.carbon.user.core.UserRealm;
import org.wso2.carbon.user.core.config.RealmConfiguration;
import org.wso2.carbon.user.core.service.RealmService;
import org.wso2.carbon.user.core.util.UserCoreUtil;
import javax.xml.namespace.QName;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
@SuppressWarnings("unused")
public class ExtendedPasswordGrantHandler extends PasswordGrantHandler {
private static Log log = LogFactory.getLog(ExtendedPasswordGrantHandler.class);
private static final String CONFIG_ELEM_OAUTH = "OAuth";
// Claims that are set as response headers of access token response
private static final String REQUIRED_CLAIM_URIS = "RequiredRespHeaderClaimUris";
private BaseCache<String, Claim[]> userClaimsCache;
// Primary/Secondary Login configuration
private static final String CLAIM_URI = "ClaimUri";
private static final String LOGIN_CONFIG = "LoginConfig";
private static final String USERID_LOGIN = "UserIdLogin";
private static final String EMAIL_LOGIN = "EmailLogin";
private static final String PRIMARY_LOGIN = "primary";
private Map<String, Map<String, String>> loginConfiguration = new ConcurrentHashMap<>();
private List<String> requiredHeaderClaimUris = new ArrayList<>();
public void init() throws IdentityOAuth2Exception {
super.init();
IdentityConfigParser configParser;
configParser = IdentityConfigParser.getInstance();
OMElement oauthElem = configParser.getConfigElement(CONFIG_ELEM_OAUTH);
// Get the required claim uris that needs to be included in the response.
parseRequiredHeaderClaimUris(oauthElem.getFirstChildWithName(getQNameWithIdentityNS(REQUIRED_CLAIM_URIS)));
// read login config
parseLoginConfig(oauthElem);
userClaimsCache = new BaseCache<>("UserClaimsCache");
if (log.isDebugEnabled()) {
log.debug("Successfully created UserClaimsCache under " + OAuthConstants.OAUTH_CACHE_MANAGER);
}
}
@Override
public boolean validateGrant(OAuthTokenReqMessageContext tokReqMsgCtx)
throws IdentityOAuth2Exception {
OAuth2AccessTokenReqDTO oAuth2AccessTokenReqDTO = tokReqMsgCtx.getOauth2AccessTokenReqDTO();
String username = oAuth2AccessTokenReqDTO.getResourceOwnerUsername();
String loginUserName = getLoginUserName(username);
tokReqMsgCtx.getOauth2AccessTokenReqDTO().setResourceOwnerUsername(loginUserName);
boolean isValidated = super.validateGrant(tokReqMsgCtx);
if (isValidated) {
int tenantId;
tenantId = IdentityTenantUtil.getTenantIdOfUser(username);
RealmService realmService = OAuthExtensionsDataHolder.getInstance().getRealmService();
UserStoreManager userStoreManager;
try {
userStoreManager = realmService.getTenantUserRealm(tenantId).getUserStoreManager();
} catch (UserStoreException e) {
log.error("Error when getting the tenant's UserStoreManager", e);
return false;
}
List<ResponseHeader> respHeaders = new ArrayList<>();
if (oAuth2AccessTokenReqDTO.getResourceOwnerUsername() != null) {
try {
if (requiredHeaderClaimUris != null && !requiredHeaderClaimUris.isEmpty()) {
// Get user's claim values from the default profile.
String userStoreDomain = tokReqMsgCtx.getAuthorizedUser().getUserStoreDomain();
String endUsernameWithDomain = UserCoreUtil.
addDomainToName(oAuth2AccessTokenReqDTO.getResourceOwnerUsername(), userStoreDomain);
Claim[] mapClaimValues = getUserClaimValues(endUsernameWithDomain, userStoreManager);
if (mapClaimValues != null && mapClaimValues.length > 0) {
ResponseHeader header;
for (String claimUri : requiredHeaderClaimUris) {
for (Claim claim : mapClaimValues) {
if (claimUri.equals(claim.getClaimUri())) {
header = new ResponseHeader();
header.setKey(claim.getDisplayTag());
header.setValue(claim.getValue());
respHeaders.add(header);
break;
}
}
}
} else if (log.isDebugEnabled()) {
log.debug("No claim values for user : " + endUsernameWithDomain);
}
}
} catch (Exception e) {
throw new IdentityOAuth2Exception("Error occurred while retrieving user claims", e);
}
}
tokReqMsgCtx.addProperty("RESPONSE_HEADERS", respHeaders.toArray(new ResponseHeader[respHeaders.size()]));
}
return isValidated;
}
@Override
public boolean validateScope(OAuthTokenReqMessageContext tokReqMsgCtx) {
return OAuthExtUtils.setScopes(tokReqMsgCtx);
}
private String getLoginUserName(String userID) {
String loginUserName = userID;
if (isSecondaryLogin(userID)) {
loginUserName = getPrimaryFromSecondary(userID);
}
return loginUserName;
}
/**
* Identify whether the logged in user used his Primary Login name or
* Secondary login name
*
* @param userId - The username used to login.
* @return <code>true</code> if secondary login name is used,
* <code>false</code> if primary login name has been used
*/
private boolean isSecondaryLogin(String userId) {
if (loginConfiguration.get(EMAIL_LOGIN) != null) {
Map<String, String> emailConf = loginConfiguration.get(EMAIL_LOGIN);
if ("true".equalsIgnoreCase(emailConf.get(PRIMARY_LOGIN))) {
return !isUserLoggedInEmail(userId);
} else if ("false".equalsIgnoreCase(emailConf.get(PRIMARY_LOGIN))) {
return isUserLoggedInEmail(userId);
}
} else if (loginConfiguration.get(USERID_LOGIN) != null) {
Map<String, String> userIdConf = loginConfiguration.get(USERID_LOGIN);
if ("true".equalsIgnoreCase(userIdConf.get(PRIMARY_LOGIN))) {
return isUserLoggedInEmail(userId);
} else if ("false".equalsIgnoreCase(userIdConf.get(PRIMARY_LOGIN))) {
return !isUserLoggedInEmail(userId);
}
}
return false;
}
/**
* Identify whether the logged in user used his ordinal username or email
*
* @param userId - username used to login.
* @return - <code>true</code> if userId contains '@'. <code>false</code> otherwise
*/
private boolean isUserLoggedInEmail(String userId) {
return userId.contains("@");
}
/**
* Get the primaryLogin name using secondary login name. Primary secondary
* Configuration is provided in the identitiy.xml. In the userstore, it is
* users responsibility TO MAINTAIN THE SECONDARY LOGIN NAME AS UNIQUE for
* each and every users. If it is not unique, we will pick the very first
* entry from the userlist.
*
* @param login - username used to login.
* @return -
*/
private String getPrimaryFromSecondary(String login) {
String claimURI, username = null;
if (isUserLoggedInEmail(login)) {
Map<String, String> emailConf = loginConfiguration.get(EMAIL_LOGIN);
claimURI = emailConf.get(CLAIM_URI);
} else {
Map<String, String> userIdConf = loginConfiguration.get(USERID_LOGIN);
claimURI = userIdConf.get(CLAIM_URI);
}
try {
RealmService realmSvc = OAuthExtensionsDataHolder.getInstance().getRealmService();
RealmConfiguration config = new RealmConfiguration();
UserRealm realm = realmSvc.getUserRealm(config);
org.wso2.carbon.user.core.UserStoreManager storeManager = realm.getUserStoreManager();
String[] user = storeManager.getUserList(claimURI, login, null);
if (user.length > 0) {
username = user[0];
}
} catch (UserStoreException e) {
log.error("Error while retrieving the primaryLogin name using secondary login name : " + login, e);
}
return username;
}
private Claim[] getUserClaimValues(String authorizedUser, UserStoreManager userStoreManager)
throws
UserStoreException {
Claim[] userClaims = userClaimsCache.getValueFromCache(authorizedUser);
if (userClaims != null) {
return userClaims;
} else {
if (log.isDebugEnabled()) {
log.debug("Cache miss for user claims. Username :" + authorizedUser);
}
userClaims = userStoreManager.getUserClaimValues(
authorizedUser, null);
userClaimsCache.addToCache(authorizedUser, userClaims);
return userClaims;
}
}
/**
* Read the required claim configuration from identity.xml
*/
private void parseRequiredHeaderClaimUris(OMElement requiredClaimUrisElem) {
if (requiredClaimUrisElem == null) {
return;
}
Iterator claimUris = requiredClaimUrisElem.getChildrenWithLocalName(CLAIM_URI);
if (claimUris != null) {
while (claimUris.hasNext()) {
OMElement claimUri = (OMElement) claimUris.next();
if (claimUri != null) {
requiredHeaderClaimUris.add(claimUri.getText());
}
}
}
}
/**
* Read the primary/secondary login configuration
* <OAuth>
* ....
* <LoginConfig>
* <UserIdLogin primary="true">
* <ClaimUri></ClaimUri>
* </UserIdLogin>
* <EmailLogin primary="false">
* <ClaimUri>http://wso2.org/claims/emailaddress</ClaimUri>
* </EmailLogin>
* </LoginConfig>
* .....
* </OAuth>
*
* @param oauthConfigElem - The '<LoginConfig>' xml configuration element in the api-manager.xml
*/
private void parseLoginConfig(OMElement oauthConfigElem) {
OMElement loginConfigElem = oauthConfigElem.getFirstChildWithName(getQNameWithIdentityNS(LOGIN_CONFIG));
if (loginConfigElem != null) {
if (log.isDebugEnabled()) {
log.debug("Login configuration is set ");
}
// Primary/Secondary supported login mechanisms
OMElement emailConfigElem = loginConfigElem.getFirstChildWithName(getQNameWithIdentityNS(EMAIL_LOGIN));
OMElement userIdConfigElem = loginConfigElem.getFirstChildWithName(getQNameWithIdentityNS(USERID_LOGIN));
Map<String, String> emailConf = new HashMap<String, String>(2);
emailConf.put(PRIMARY_LOGIN,
emailConfigElem.getAttributeValue(new QName(PRIMARY_LOGIN)));
emailConf.put(CLAIM_URI,
emailConfigElem.getFirstChildWithName(getQNameWithIdentityNS(CLAIM_URI))
.getText());
Map<String, String> userIdConf = new HashMap<String, String>(2);
userIdConf.put(PRIMARY_LOGIN,
userIdConfigElem.getAttributeValue(new QName(PRIMARY_LOGIN)));
userIdConf.put(CLAIM_URI,
userIdConfigElem.getFirstChildWithName(getQNameWithIdentityNS(CLAIM_URI))
.getText());
loginConfiguration.put(EMAIL_LOGIN, emailConf);
loginConfiguration.put(USERID_LOGIN, userIdConf);
}
}
private QName getQNameWithIdentityNS(String localPart) {
return new QName(IdentityCoreConstants.IDENTITY_DEFAULT_NAMESPACE, localPart);
}
}

@ -21,9 +21,17 @@ package org.wso2.carbon.device.mgt.oauth.extensions.internal;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
import org.osgi.service.component.ComponentContext; import org.osgi.service.component.ComponentContext;
import org.wso2.carbon.apimgt.api.APIManagementException;
import org.wso2.carbon.apimgt.impl.APIConstants;
import org.wso2.carbon.apimgt.impl.APIManagerConfiguration;
import org.wso2.carbon.device.mgt.common.permission.mgt.PermissionManagerService; import org.wso2.carbon.device.mgt.common.permission.mgt.PermissionManagerService;
import org.wso2.carbon.identity.oauth2.OAuth2TokenValidationService; import org.wso2.carbon.identity.oauth2.OAuth2TokenValidationService;
import org.wso2.carbon.user.core.service.RealmService; import org.wso2.carbon.user.core.service.RealmService;
import org.wso2.carbon.utils.CarbonUtils;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
/** /**
* @scr.component name="org.wso2.carbon.device.mgt.oauth.extensions" immediate="true" * @scr.component name="org.wso2.carbon.device.mgt.oauth.extensions" immediate="true"
@ -49,17 +57,51 @@ import org.wso2.carbon.user.core.service.RealmService;
public class OAuthExtensionServiceComponent { public class OAuthExtensionServiceComponent {
private static final Log log = LogFactory.getLog(OAuthExtensionServiceComponent.class); private static final Log log = LogFactory.getLog(OAuthExtensionServiceComponent.class);
private static final String REPOSITORY = "repository";
private static final String CONFIGURATION = "conf";
private static final String APIM_CONF_FILE = "api-manager.xml";
@SuppressWarnings("unused") @SuppressWarnings("unused")
protected void activate(ComponentContext componentContext) { protected void activate(ComponentContext componentContext) {
if(log.isDebugEnabled()){ if (log.isDebugEnabled()) {
log.debug("Starting OAuthExtensionBundle"); log.debug("Starting OAuthExtensionBundle");
} }
try {
APIManagerConfiguration configuration = new APIManagerConfiguration();
String filePath = new StringBuilder().
append(CarbonUtils.getCarbonHome()).
append(File.separator).
append(REPOSITORY).
append(File.separator).
append(CONFIGURATION).
append(File.separator).
append(APIM_CONF_FILE).toString();
configuration.load(filePath);
// loading white listed scopes
List<String> whiteList;
// Read scope whitelist from Configuration.
whiteList = configuration.getProperty(APIConstants.API_KEY_MANGER_SCOPE_WHITELIST);
// If whitelist is null, default scopes will be put.
if (whiteList == null) {
whiteList = new ArrayList<String>();
whiteList.add(APIConstants.OPEN_ID_SCOPE_NAME);
whiteList.add(APIConstants.DEVICE_SCOPE_PATTERN);
}
OAuthExtensionsDataHolder.getInstance().setWhitelistedScopes(whiteList);
} catch (APIManagementException e) {
log.error("Error occurred while loading APIM configurations", e);
}
} }
@SuppressWarnings("unused") @SuppressWarnings("unused")
protected void deactivate(ComponentContext componentContext) { protected void deactivate(ComponentContext componentContext) {
if(log.isDebugEnabled()){ if (log.isDebugEnabled()) {
log.debug("Stopping OAuthExtensionBundle"); log.debug("Stopping OAuthExtensionBundle");
} }
} }

@ -22,6 +22,8 @@ import org.wso2.carbon.device.mgt.common.permission.mgt.PermissionManagerService
import org.wso2.carbon.identity.oauth2.OAuth2TokenValidationService; import org.wso2.carbon.identity.oauth2.OAuth2TokenValidationService;
import org.wso2.carbon.user.core.service.RealmService; import org.wso2.carbon.user.core.service.RealmService;
import java.util.List;
/** /**
* This holds the OSGi service references required for oauth extensions bundle. * This holds the OSGi service references required for oauth extensions bundle.
*/ */
@ -30,6 +32,7 @@ public class OAuthExtensionsDataHolder {
private RealmService realmService; private RealmService realmService;
private OAuth2TokenValidationService oAuth2TokenValidationService; private OAuth2TokenValidationService oAuth2TokenValidationService;
private PermissionManagerService permissionManagerService; private PermissionManagerService permissionManagerService;
private List<String> whitelistedScopes;
private static OAuthExtensionsDataHolder thisInstance = new OAuthExtensionsDataHolder(); private static OAuthExtensionsDataHolder thisInstance = new OAuthExtensionsDataHolder();
@ -72,4 +75,12 @@ public class OAuthExtensionsDataHolder {
} }
return permissionManagerService; return permissionManagerService;
} }
public List<String> getWhitelistedScopes() {
return whitelistedScopes;
}
public void setWhitelistedScopes(List<String> whitelistedScopes) {
this.whitelistedScopes = whitelistedScopes;
}
} }

Loading…
Cancel
Save