Modified authorization to support API gateway

4.x.x
mharindu 9 years ago
parent 4c50d4842d
commit ffc7542d4d

@ -0,0 +1,36 @@
/*
* 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 {
String scope();
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,122 @@ 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) {
Map<String, JsonObject> httpVerbsMap = new HashMap<>();
List<Scope> scopes = new ArrayList<>();
private String createSwaggerDefinition(API api) { for (URITemplate uriTemplate : api.getUriTemplates()) {
Map<String, JsonObject> httpVerbsMap = new HashMap<>(); JsonObject authType = new JsonObject();
authType.addProperty("x-auth-type", "Application%20%26%20Application%20User");
JsonObject response = new JsonObject();
response.addProperty("200", "");
for (URITemplate uriTemplate : api.getUriTemplates()) { JsonObject responses = new JsonObject();
JsonObject response = new JsonObject(); responses.add("responses", response);
response.addProperty("200", ""); JsonObject httpVerbs = httpVerbsMap.get(uriTemplate.getUriTemplate());
if (httpVerbs == null) {
httpVerbs = new JsonObject();
}
JsonObject httpVerb = new JsonObject();
httpVerb.add("responses", response);
JsonObject responses = new JsonObject(); httpVerb.addProperty("x-auth-type", "Application%20%26%20Application%20User");
responses.add("responses", response); httpVerb.addProperty("x-throttling-tier", "Unlimited");
JsonObject httpVerbs = httpVerbsMap.get(uriTemplate.getUriTemplate()); if (uriTemplate.getScope() != null) {
if (httpVerbs == null) { httpVerb.addProperty("x-scope", uriTemplate.getScope().getName());
httpVerbs = new JsonObject(); scopes.add(uriTemplate.getScope());
} }
httpVerbs.add(uriTemplate.getHTTPVerb().toLowerCase(), responses); httpVerbs.add(uriTemplate.getHTTPVerb().toLowerCase(), httpVerb);
httpVerbsMap.put(uriTemplate.getUriTemplate(), httpVerbs); httpVerbsMap.put(uriTemplate.getUriTemplate(), httpVerbs);
} }
Iterator it = httpVerbsMap.entrySet().iterator(); Iterator it = httpVerbsMap.entrySet().iterator();
JsonObject paths = new JsonObject(); JsonObject paths = new JsonObject();
while (it.hasNext()) { while (it.hasNext()) {
Map.Entry<String, JsonObject> pair = (Map.Entry) it.next(); Map.Entry<String, JsonObject> pair = (Map.Entry) it.next();
paths.add(pair.getKey(), pair.getValue()); paths.add(pair.getKey(), pair.getValue());
it.remove(); it.remove();
} }
JsonObject info = new JsonObject(); JsonObject info = new JsonObject();
info.addProperty("title", api.getId().getApiName()); info.addProperty("title", api.getId().getApiName());
info.addProperty("version", api.getId().getVersion()); info.addProperty("version", api.getId().getVersion());
JsonObject swaggerDefinition = new JsonObject(); JsonObject swaggerDefinition = new JsonObject();
swaggerDefinition.add("paths", paths); swaggerDefinition.add("paths", paths);
swaggerDefinition.addProperty("swagger", "2.0"); swaggerDefinition.addProperty("swagger", "2.0");
swaggerDefinition.add("info", info); swaggerDefinition.add("info", info);
return swaggerDefinition.toString(); // adding scopes to 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);
}
}
return swaggerDefinition.toString();
}
@Override @Override
public void removeAPI(APIIdentifier id) throws APIManagementException { public void removeAPI(APIIdentifier id) throws APIManagementException {

@ -24,35 +24,18 @@ import org.wso2.carbon.apimgt.api.model.*;
import org.wso2.carbon.apimgt.impl.APIConstants; import org.wso2.carbon.apimgt.impl.APIConstants;
import org.wso2.carbon.apimgt.webapp.publisher.internal.APIPublisherDataHolder; import org.wso2.carbon.apimgt.webapp.publisher.internal.APIPublisherDataHolder;
import org.wso2.carbon.base.MultitenantConstants; import org.wso2.carbon.base.MultitenantConstants;
import org.wso2.carbon.user.api.TenantManager;
import org.wso2.carbon.user.api.UserStoreException;
import org.wso2.carbon.utils.CarbonUtils; import org.wso2.carbon.utils.CarbonUtils;
import org.wso2.carbon.utils.ConfigurationContextService; import org.wso2.carbon.utils.ConfigurationContextService;
import org.wso2.carbon.utils.NetworkUtils; import org.wso2.carbon.utils.NetworkUtils;
import org.wso2.carbon.utils.multitenancy.MultitenantUtils;
import java.util.*; import java.util.*;
public class APIPublisherUtil { public class APIPublisherUtil {
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}"; private static final String API_VERSION_PARAM="{version}";
public static final String API_PUBLISH_ENVIRONEMENT = "Production and Sandbox"; private static final String API_PUBLISH_ENVIRONMENT = "Production and Sandbox";
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 {
APIProvider provider = config.getProvider(); APIProvider provider = config.getProvider();
@ -79,11 +62,10 @@ 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> environements = new HashSet<>(); environments.add(API_PUBLISH_ENVIRONMENT);
environements.add(API_PUBLISH_ENVIRONEMENT); api.setEnvironments(environments);
api.setEnvironments(environements); 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);
if (config.isSharedWithAllTenants()) { if (config.isSharedWithAllTenants()) {
@ -95,7 +77,8 @@ public class APIPublisherUtil {
} }
api.setResponseCache(APIConstants.DISABLED); api.setResponseCache(APIConstants.DISABLED);
String endpointConfig = "{\"production_endpoints\":{\"url\":\" " + config.getEndpoint() + "\",\"config\":null},\"implementation_status\":\"managed\",\"endpoint_type\":\"http\"}"; String endpointConfig = "{\"production_endpoints\":{\"url\":\" " + config.getEndpoint() +
"\",\"config\":null},\"implementation_status\":\"managed\",\"endpoint_type\":\"http\"}";
api.setEndpointConfig(endpointConfig); api.setEndpointConfig(endpointConfig);
if ("".equals(id.getVersion()) || (DEFAULT_API_VERSION.equals(id.getVersion()))) { if ("".equals(id.getVersion()) || (DEFAULT_API_VERSION.equals(id.getVersion()))) {
@ -106,35 +89,31 @@ 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 { } else {
for (HTTPMethod method : httpMethods) { // this has to be done because of the use of pass by reference
URITemplate template = new URITemplate(); // where same object reference of scope should be available for both
if (HTTPMethod.OPTIONS.equals(method)) { // api scope and uri template scope
template.setAuthType(APIConstants.AUTH_NO_AUTHENTICATION); template.setScope(apiScopes.get(scope.getKey()));
} else { }
template.setAuthType(APIConstants.AUTH_APPLICATION_OR_USER_LEVEL_TOKEN);
} }
template.setHTTPVerb(method.toString());
template.setResourceURI(endpoint);
template.setUriTemplate("/*");
uriTemplates.add(template);
} }
Set<Scope> scopes = new HashSet<>(apiScopes.values());
api.setScopes(scopes);
api.setUriTemplates(uriTemplates);
} }
return uriTemplates; return api;
} }
public static String getServerBaseUrl() { public static String getServerBaseUrl() {
@ -163,7 +142,8 @@ public class APIPublisherUtil {
} }
/** /**
* When an input is having '@',replace it with '-AT-' [This is required to persist API data in registry,as registry paths don't allow '@' sign.] * When an input is having '@',replace it with '-AT-'
* [This is required to persist API data in registry,as registry paths don't allow '@' sign.]
* @param input inputString * @param input inputString
* @return String modifiedString * @return String modifiedString
*/ */

@ -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);
}
}

@ -32,6 +32,7 @@ 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;
import org.wso2.carbon.base.MultitenantConstants; import org.wso2.carbon.base.MultitenantConstants;
import javax.servlet.ServletContext; import javax.servlet.ServletContext;
import java.io.IOException; import java.io.IOException;
import java.util.LinkedHashSet; import java.util.LinkedHashSet;
@ -41,189 +42,190 @@ import java.util.Set;
@SuppressWarnings("unused") @SuppressWarnings("unused")
public class APIPublisherLifecycleListener implements LifecycleListener { public class APIPublisherLifecycleListener implements LifecycleListener {
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_ENABLED = "managed-api-enabled"; private static final String PARAM_MANAGED_API_ENABLED = "managed-api-enabled";
private static final String PARAM_MANAGED_API_NAME = "managed-api-name"; 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_VERSION = "managed-api-version";
private static final String PARAM_MANAGED_API_CONTEXT = "managed-api-context"; 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_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";
private static final Log log = LogFactory.getLog(APIPublisherLifecycleListener.class); private static final Log log = LogFactory.getLog(APIPublisherLifecycleListener.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 param = servletContext.getInitParameter(PARAM_MANAGED_API_ENABLED); String param = servletContext.getInitParameter(PARAM_MANAGED_API_ENABLED);
boolean isManagedApi = (param != null && !param.isEmpty()) && Boolean.parseBoolean(param); boolean isManagedApi = (param != null && !param.isEmpty()) && Boolean.parseBoolean(param);
if (isManagedApi) { if (isManagedApi) {
try { try {
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, annotatedAPIClasses); List<APIResourceConfiguration> apiDefinitions = annotationUtil.extractAPIInfo(servletContext, annotatedAPIClasses);
for (APIResourceConfiguration apiDefinition : apiDefinitions) { for (APIResourceConfiguration apiDefinition : apiDefinitions) {
APIConfig apiConfig = this.buildApiConfig(servletContext, apiDefinition); APIConfig apiConfig = this.buildApiConfig(servletContext, apiDefinition);
try { try {
int tenantId = APIPublisherDataHolder.getInstance().getTenantManager().getTenantId(apiConfig.getTenantDomain()); int tenantId = APIPublisherDataHolder.getInstance().getTenantManager().getTenantId(apiConfig.getTenantDomain());
boolean isTenantActive = APIPublisherDataHolder.getInstance().getTenantManager().isTenantActive(tenantId); boolean isTenantActive = APIPublisherDataHolder.getInstance().getTenantManager().isTenantActive(tenantId);
if (isTenantActive) { if (isTenantActive) {
apiConfig.init(); apiConfig.init();
API api = APIPublisherUtil.getAPI(apiConfig); API api = APIPublisherUtil.getAPI(apiConfig);
APIPublisherService apiPublisherService = APIPublisherService apiPublisherService =
APIPublisherDataHolder.getInstance().getApiPublisherService(); APIPublisherDataHolder.getInstance().getApiPublisherService();
if (apiPublisherService == null) { if (apiPublisherService == null) {
throw new IllegalStateException( throw new IllegalStateException(
"API Publisher service is not initialized properly"); "API Publisher service is not initialized properly");
} }
apiPublisherService.publishAPI(api); apiPublisherService.publishAPI(api);
} else { } else {
log.error("No tenant [" + apiConfig.getTenantDomain() + "] found when publishing the webapp"); log.error("No tenant [" + apiConfig.getTenantDomain() + "] found when publishing the webapp");
} }
} catch (Throwable e) { } catch (Throwable e) {
log.error("Error occurred while publishing API '" + apiConfig.getName() + log.error("Error occurred while publishing API '" + apiConfig.getName() +
"' with the context '" + apiConfig.getContext() + "' with the context '" + apiConfig.getContext() +
"' and version '" + apiConfig.getVersion() + "'", e); "' and version '" + apiConfig.getVersion() + "'", e);
} }
} }
} catch (IOException e) { } catch (IOException e) {
log.error("Error enconterd while discovering annotated classes", e); log.error("Error encountered while discovering annotated classes", e);
} catch (ClassNotFoundException e) { } catch (ClassNotFoundException e) {
log.error("Error while scanning class for annotations", e); log.error("Error while scanning class for annotations", e);
} }
} }
} }
} }
private List<APIResourceConfiguration> mergeAPIDefinitions(List<APIResourceConfiguration> inputList) { private List<APIResourceConfiguration> mergeAPIDefinitions(List<APIResourceConfiguration> inputList) {
//TODO : Need to implemented, to merge API Definitions in cases where implementation of an API Lies in two //TODO : Need to implemented, to merge API Definitions in cases where implementation of an API Lies in two
// classes // classes
return null; return null;
} }
/** /**
* 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
* @return * @return
*/ */
private APIConfig buildApiConfig(ServletContext servletContext, APIResourceConfiguration apidef) { private 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");
} }
name = servletContext.getServletContextName(); name = servletContext.getServletContextName();
} }
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'");
} }
version = API_CONFIG_DEFAULT_VERSION; version = API_CONFIG_DEFAULT_VERSION;
} }
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'");
} }
context = servletContext.getContextPath(); context = servletContext.getContextPath();
} }
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'");
} }
} else { } else {
apiConfig.setTags(tags); apiConfig.setTags(tags);
} }
String tenantDomain = servletContext.getInitParameter(PARAM_PROVIDER_TENANT_DOMAIN); String tenantDomain = servletContext.getInitParameter(PARAM_PROVIDER_TENANT_DOMAIN);
tenantDomain = (tenantDomain != null && !tenantDomain.isEmpty()) ? tenantDomain : tenantDomain = (tenantDomain != null && !tenantDomain.isEmpty()) ? tenantDomain :
MultitenantConstants.SUPER_TENANT_DOMAIN_NAME; MultitenantConstants.SUPER_TENANT_DOMAIN_NAME;
apiConfig.setTenantDomain(tenantDomain); apiConfig.setTenantDomain(tenantDomain);
String contextTemplate = context + "/" + APIConstants.VERSION_PLACEHOLDER; String contextTemplate = context + "/" + APIConstants.VERSION_PLACEHOLDER;
if (!tenantDomain.equals(MultitenantConstants.SUPER_TENANT_DOMAIN_NAME)) { if (!tenantDomain.equals(MultitenantConstants.SUPER_TENANT_DOMAIN_NAME)) {
contextTemplate = context + "/t/" + tenantDomain + "/" + APIConstants.VERSION_PLACEHOLDER; contextTemplate = context + "/t/" + tenantDomain + "/" + APIConstants.VERSION_PLACEHOLDER;
} }
apiConfig.setContextTemplate(contextTemplate); apiConfig.setContextTemplate(contextTemplate);
String endpoint = servletContext.getInitParameter(PARAM_MANAGED_API_ENDPOINT); String endpoint = servletContext.getInitParameter(PARAM_MANAGED_API_ENDPOINT);
if (endpoint == null || endpoint.isEmpty()) { if (endpoint == null || endpoint.isEmpty()) {
if (log.isDebugEnabled()) { if (log.isDebugEnabled()) {
log.debug("'managed-api-endpoint' attribute is not configured"); log.debug("'managed-api-endpoint' attribute is not configured");
} }
String endpointContext = servletContext.getContextPath(); String endpointContext = servletContext.getContextPath();
endpoint = APIPublisherUtil.getApiEndpointUrl(endpointContext); endpoint = APIPublisherUtil.getApiEndpointUrl(endpointContext);
} }
apiConfig.setEndpoint(endpoint); apiConfig.setEndpoint(endpoint);
String owner = servletContext.getInitParameter(PARAM_MANAGED_API_OWNER); String owner = servletContext.getInitParameter(PARAM_MANAGED_API_OWNER);
if (owner == null || owner.isEmpty()) { if (owner == null || owner.isEmpty()) {
if (log.isDebugEnabled()) { if (log.isDebugEnabled()) {
log.debug("'managed-api-owner' attribute is not configured"); log.debug("'managed-api-owner' attribute is not configured");
} }
} }
apiConfig.setOwner(owner); apiConfig.setOwner(owner);
String isSecuredParam = servletContext.getInitParameter(PARAM_MANAGED_API_IS_SECURED); String isSecuredParam = servletContext.getInitParameter(PARAM_MANAGED_API_IS_SECURED);
boolean isSecured; boolean isSecured;
if (isSecuredParam == null || isSecuredParam.isEmpty()) { if (isSecuredParam == null || isSecuredParam.isEmpty()) {
if (log.isDebugEnabled()) { if (log.isDebugEnabled()) {
log.debug("'managed-api-isSecured' attribute is not configured. Therefore, using the default, " + log.debug("'managed-api-isSecured' attribute is not configured. Therefore, using the default, " +
"which is 'true'"); "which is 'true'");
} }
isSecured = false; isSecured = false;
} else { } else {
isSecured = Boolean.parseBoolean(isSecuredParam); isSecured = Boolean.parseBoolean(isSecuredParam);
} }
apiConfig.setSecured(isSecured); apiConfig.setSecured(isSecured);
String transports = servletContext.getInitParameter(PARAM_MANAGED_API_TRANSPORTS); String transports = servletContext.getInitParameter(PARAM_MANAGED_API_TRANSPORTS);
if (transports == null || transports.isEmpty()) { if (transports == null || transports.isEmpty()) {
if (log.isDebugEnabled()) { if (log.isDebugEnabled()) {
log.debug("'managed-api-transports' attribute is not configured. Therefore using the default, " + log.debug("'managed-api-transports' attribute is not configured. Therefore using the default, " +
"which is 'https'"); "which is 'https'");
} }
transports = "https"; transports = "https";
} }
apiConfig.setTransports(transports); apiConfig.setTransports(transports);
String sharingValueParam = servletContext.getInitParameter(PARAM_SHARED_WITH_ALL_TENANTS); String sharingValueParam = servletContext.getInitParameter(PARAM_SHARED_WITH_ALL_TENANTS);
boolean isSharedWithAllTenants = (sharingValueParam == null || (!sharingValueParam.isEmpty()) && Boolean.parseBoolean( boolean isSharedWithAllTenants = (sharingValueParam == null || (!sharingValueParam.isEmpty()) && Boolean.parseBoolean(
sharingValueParam)); sharingValueParam));
apiConfig.setSharedWithAllTenants(isSharedWithAllTenants); apiConfig.setSharedWithAllTenants(isSharedWithAllTenants);
Set<URITemplate> uriTemplates = new LinkedHashSet<URITemplate>(); Set<URITemplate> uriTemplates = new LinkedHashSet<URITemplate>();
for (APIResource apiResource : apidef.getResources()) { Scope scope;
URITemplate template = new URITemplate(); for (APIResource apiResource : apidef.getResources()) {
template.setAuthType(apiResource.getAuthType()); URITemplate template = new URITemplate();
template.setHTTPVerb(apiResource.getHttpVerb()); template.setAuthType(apiResource.getAuthType());
template.setResourceURI(apiResource.getUri()); template.setHTTPVerb(apiResource.getHttpVerb());
template.setUriTemplate(apiResource.getUriTemplate()); template.setResourceURI(apiResource.getUri());
uriTemplates.add(template); template.setUriTemplate(apiResource.getUriTemplate());;
} template.setScope(apiResource.getScope());
apiConfig.setUriTemplates(uriTemplates); uriTemplates.add(template);
}
return apiConfig; apiConfig.setUriTemplates(uriTemplates);
} return apiConfig;
}
} }

@ -20,12 +20,19 @@ 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.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.*;
import java.io.IOException; import java.io.IOException;
@ -36,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 {
@ -68,6 +77,7 @@ public class AnnotationUtil {
/** /**
* Scan the context for classes with annotations * Scan the context for classes with annotations
*
* @return * @return
* @throws IOException * @throws IOException
*/ */
@ -89,6 +99,7 @@ public class AnnotationUtil {
/** /**
* Method identifies the URL templates and context by reading the annotations of a class * Method identifies the URL templates and context by reading the annotations of a class
*
* @param entityClasses * @param entityClasses
* @return * @return
*/ */
@ -107,8 +118,8 @@ public class AnnotationUtil {
APIResourceConfiguration apiResourceConfig = null; APIResourceConfiguration apiResourceConfig = null;
try { try {
clazz = classLoader.loadClass(className); clazz = classLoader.loadClass(className);
Class<Path> apiClazz = (Class<Path>) Class<API> apiClazz = (Class<API>)
classLoader.loadClass(org.wso2.carbon.apimgt.annotations.api.API.class.getName()); classLoader.loadClass(API.class.getName());
Annotation apiAnno = clazz.getAnnotation(apiClazz); Annotation apiAnno = clazz.getAnnotation(apiClazz);
List<APIResource> resourceList; List<APIResource> resourceList;
@ -123,18 +134,18 @@ public class AnnotationUtil {
} }
try { try {
for(int k=0;k<apiClazzMethods.length;k++){ for (int k = 0; k < apiClazzMethods.length; k++) {
switch (apiClazzMethods[k].getName()){ switch (apiClazzMethods[k].getName()) {
case "name" : case "name":
apiResourceConfig.setName(invokeMethod(apiClazzMethods[k], apiAnno, STRING)); apiResourceConfig.setName(invokeMethod(apiClazzMethods[k], apiAnno, STRING));
break; break;
case "version" : case "version":
apiResourceConfig.setVersion(invokeMethod(apiClazzMethods[k], apiAnno, STRING)); apiResourceConfig.setVersion(invokeMethod(apiClazzMethods[k], apiAnno, STRING));
break; break;
case "context" : case "context":
apiResourceConfig.setContext(invokeMethod(apiClazzMethods[k], apiAnno, STRING)); apiResourceConfig.setContext(invokeMethod(apiClazzMethods[k], apiAnno, STRING));
break; break;
case "tags" : case "tags":
apiResourceConfig.setTags(invokeMethod(apiClazzMethods[k], apiAnno)); apiResourceConfig.setTags(invokeMethod(apiClazzMethods[k], apiAnno));
break; break;
} }
@ -195,35 +206,47 @@ public class AnnotationUtil {
resource.setAuthType(AUTH_TYPE); resource.setAuthType(AUTH_TYPE);
Annotation[] annotations = method.getDeclaredAnnotations(); Annotation[] annotations = method.getDeclaredAnnotations();
for(int i=0; i<annotations.length; i++){ for (int i = 0; i < annotations.length; i++) {
if(annotations[i].annotationType().getName().equals(GET.class.getName())){ if (annotations[i].annotationType().getName().equals(GET.class.getName())) {
resource.setHttpVerb(HttpMethod.GET); resource.setHttpVerb(HttpMethod.GET);
} }
if(annotations[i].annotationType().getName().equals(POST.class.getName())){ if (annotations[i].annotationType().getName().equals(POST.class.getName())) {
resource.setHttpVerb(HttpMethod.POST); resource.setHttpVerb(HttpMethod.POST);
} }
if(annotations[i].annotationType().getName().equals(OPTIONS.class.getName())){ if (annotations[i].annotationType().getName().equals(OPTIONS.class.getName())) {
resource.setHttpVerb(HttpMethod.OPTIONS); resource.setHttpVerb(HttpMethod.OPTIONS);
} }
if(annotations[i].annotationType().getName().equals(DELETE.class.getName())){ if (annotations[i].annotationType().getName().equals(DELETE.class.getName())) {
resource.setHttpVerb(HttpMethod.DELETE); resource.setHttpVerb(HttpMethod.DELETE);
} }
if(annotations[i].annotationType().getName().equals(PUT.class.getName())){ if (annotations[i].annotationType().getName().equals(PUT.class.getName())) {
resource.setHttpVerb(HttpMethod.PUT); resource.setHttpVerb(HttpMethod.PUT);
} }
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(Consumes.class.getName()); Class<Consumes> consumesClass = (Class<Consumes>) classLoader.loadClass(Consumes.class.getName());
Method[] consumesClassMethods = consumesClass.getMethods(); Method[] consumesClassMethods = consumesClass.getMethods();
Annotation consumesAnno = method.getAnnotation(consumesClass); Annotation consumesAnno = method.getAnnotation(consumesClass);
resource.setConsumes(invokeMethod(consumesClassMethods[0], consumesAnno, STRING_ARR)); resource.setConsumes(invokeMethod(consumesClassMethods[0], consumesAnno, STRING_ARR));
} }
if(annotations[i].annotationType().getName().equals(Produces.class.getName())){ if (annotations[i].annotationType().getName().equals(Produces.class.getName())) {
Class<Produces> producesClass = (Class<Produces>) classLoader.loadClass(Produces.class.getName()); Class<Produces> producesClass = (Class<Produces>) classLoader.loadClass(Produces.class.getName());
Method[] producesClassMethods = producesClass.getMethods(); Method[] producesClassMethods = producesClass.getMethods();
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);
} }
@ -231,12 +254,12 @@ public class AnnotationUtil {
return resourceList; return resourceList;
} }
private String makeContextURLReady(String context){ private String makeContextURLReady(String context) {
if(context != null && !context.equalsIgnoreCase("")){ if (context != null && !context.equalsIgnoreCase("")) {
if(context.startsWith("/")){ if (context.startsWith("/")) {
return context; return context;
}else{ } else {
return "/"+context; return "/" + context;
} }
} }
return ""; return "";
@ -244,6 +267,7 @@ public class AnnotationUtil {
/** /**
* When an annotation and method is passed, this method invokes that executes said method against the annotation * When an annotation and method is passed, this method invokes that executes said method against the annotation
*
* @param method * @param method
* @param annotation * @param annotation
* @param returnType * @param returnType
@ -252,11 +276,11 @@ public class AnnotationUtil {
*/ */
private String invokeMethod(Method method, Annotation annotation, String returnType) throws Throwable { private String invokeMethod(Method method, Annotation annotation, String returnType) throws Throwable {
InvocationHandler methodHandler = Proxy.getInvocationHandler(annotation); InvocationHandler methodHandler = Proxy.getInvocationHandler(annotation);
switch (returnType){ switch (returnType) {
case STRING: case STRING:
return (String) methodHandler.invoke(annotation, method, null); return (String) methodHandler.invoke(annotation, method, null);
case STRING_ARR: case STRING_ARR:
return ((String[])methodHandler.invoke(annotation, method, null))[0]; return ((String[]) methodHandler.invoke(annotation, method, null))[0];
default: default:
return null; return null;
} }
@ -267,6 +291,36 @@ public class AnnotationUtil {
*/ */
private String[] invokeMethod(Method method, Annotation annotation) throws Throwable { private String[] invokeMethod(Method method, Annotation annotation) throws Throwable {
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;
}
}

@ -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>
@ -46,10 +47,6 @@
<groupId>org.wso2.carbon</groupId> <groupId>org.wso2.carbon</groupId>
<artifactId>org.wso2.carbon.user.core</artifactId> <artifactId>org.wso2.carbon.user.core</artifactId>
</dependency> </dependency>
<dependency>
<groupId>org.wso2.carbon</groupId>
<artifactId>org.wso2.carbon.user.api</artifactId>
</dependency>
</dependencies> </dependencies>
<build> <build>
@ -89,7 +86,7 @@
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
</Import-Package> </Import-Package>
</instructions> </instructions>

Loading…
Cancel
Save