From 5ad8d2938e65d9ef562ce82c0beb59b54b73f560 Mon Sep 17 00:00:00 2001 From: mharindu Date: Wed, 11 May 2016 10:50:32 +0530 Subject: [PATCH 01/12] Fixed issues of publishing APIs to synapse gateway --- .../publisher/APIPublisherStartupHandler.java | 67 +++++++++++++++++++ .../internal/APIPublisherDataHolder.java | 21 ++++++ .../APIPublisherServiceComponent.java | 3 + .../APIPublisherLifecycleListener.java | 21 ++++-- .../org.wso2.carbon.device.mgt.api/pom.xml | 2 +- .../pom.xml | 4 ++ pom.xml | 39 +++++------ 7 files changed, 129 insertions(+), 28 deletions(-) create mode 100644 components/apimgt-extensions/org.wso2.carbon.apimgt.webapp.publisher/src/main/java/org/wso2/carbon/apimgt/webapp/publisher/APIPublisherStartupHandler.java diff --git a/components/apimgt-extensions/org.wso2.carbon.apimgt.webapp.publisher/src/main/java/org/wso2/carbon/apimgt/webapp/publisher/APIPublisherStartupHandler.java b/components/apimgt-extensions/org.wso2.carbon.apimgt.webapp.publisher/src/main/java/org/wso2/carbon/apimgt/webapp/publisher/APIPublisherStartupHandler.java new file mode 100644 index 0000000000..30f7900153 --- /dev/null +++ b/components/apimgt-extensions/org.wso2.carbon.apimgt.webapp.publisher/src/main/java/org/wso2/carbon/apimgt/webapp/publisher/APIPublisherStartupHandler.java @@ -0,0 +1,67 @@ +/* + * 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; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.wso2.carbon.apimgt.api.model.API; +import org.wso2.carbon.apimgt.webapp.publisher.internal.APIPublisherDataHolder; +import org.wso2.carbon.core.ServerStartupObserver; + +public class APIPublisherStartupHandler implements ServerStartupObserver { + + private static final Log log = LogFactory.getLog(APIPublisherStartupHandler.class); + + @Override + public void completingServerStartup() { + + } + + @Override + public void completedServerStartup() { + // adding temporary due to a bug in the platform + Thread t = new Thread(new Runnable() { + @Override + public void run() { + try { + Thread.sleep(5000); + } catch (InterruptedException e) { + log.error("Error occurred while sleeping", e); + } + APIPublisherDataHolder.getInstance().setServerStarted(true); + log.info("Server has just started, hence started publishing unpublished APIs"); + if (log.isDebugEnabled()) { + log.debug("Total number of unpublished APIs: " + + APIPublisherDataHolder.getInstance().getUnpublishedApis().size()); + } + APIPublisherService publisher = APIPublisherDataHolder.getInstance().getApiPublisherService(); + while (!APIPublisherDataHolder.getInstance().getUnpublishedApis().isEmpty()) { + API api = APIPublisherDataHolder.getInstance().getUnpublishedApis().pop(); + try { + publisher.publishAPI(api); + } catch (java.lang.Exception e) { + log.error("Error occurred while publishing API '" + api.getId().getApiName(), e); + } + } + } + }); + t.start(); + } +} diff --git a/components/apimgt-extensions/org.wso2.carbon.apimgt.webapp.publisher/src/main/java/org/wso2/carbon/apimgt/webapp/publisher/internal/APIPublisherDataHolder.java b/components/apimgt-extensions/org.wso2.carbon.apimgt.webapp.publisher/src/main/java/org/wso2/carbon/apimgt/webapp/publisher/internal/APIPublisherDataHolder.java index bd291ce3be..b06bc1a4ca 100644 --- a/components/apimgt-extensions/org.wso2.carbon.apimgt.webapp.publisher/src/main/java/org/wso2/carbon/apimgt/webapp/publisher/internal/APIPublisherDataHolder.java +++ b/components/apimgt-extensions/org.wso2.carbon.apimgt.webapp.publisher/src/main/java/org/wso2/carbon/apimgt/webapp/publisher/internal/APIPublisherDataHolder.java @@ -19,12 +19,15 @@ package org.wso2.carbon.apimgt.webapp.publisher.internal; +import org.wso2.carbon.apimgt.api.model.API; import org.wso2.carbon.apimgt.webapp.publisher.APIPublisherService; import org.wso2.carbon.registry.core.service.RegistryService; import org.wso2.carbon.user.core.service.RealmService; import org.wso2.carbon.user.core.tenant.TenantManager; import org.wso2.carbon.utils.ConfigurationContextService; +import java.util.Stack; + public class APIPublisherDataHolder { private APIPublisherService apiPublisherService; @@ -32,6 +35,8 @@ public class APIPublisherDataHolder { private RealmService realmService; private TenantManager tenantManager; private RegistryService registryService; + private boolean isServerStarted; + private Stack unpublishedApis = new Stack<>(); private static APIPublisherDataHolder thisInstance = new APIPublisherDataHolder(); @@ -94,4 +99,20 @@ public class APIPublisherDataHolder { public void setRegistryService(RegistryService registryService) { this.registryService = registryService; } + + public boolean isServerStarted() { + return isServerStarted; + } + + public void setServerStarted(boolean serverStarted) { + isServerStarted = serverStarted; + } + + public Stack getUnpublishedApis() { + return unpublishedApis; + } + + public void setUnpublishedApis(Stack unpublishedApis) { + this.unpublishedApis = unpublishedApis; + } } diff --git a/components/apimgt-extensions/org.wso2.carbon.apimgt.webapp.publisher/src/main/java/org/wso2/carbon/apimgt/webapp/publisher/internal/APIPublisherServiceComponent.java b/components/apimgt-extensions/org.wso2.carbon.apimgt.webapp.publisher/src/main/java/org/wso2/carbon/apimgt/webapp/publisher/internal/APIPublisherServiceComponent.java index 2a67c78713..ed9e4377c1 100644 --- a/components/apimgt-extensions/org.wso2.carbon.apimgt.webapp.publisher/src/main/java/org/wso2/carbon/apimgt/webapp/publisher/internal/APIPublisherServiceComponent.java +++ b/components/apimgt-extensions/org.wso2.carbon.apimgt.webapp.publisher/src/main/java/org/wso2/carbon/apimgt/webapp/publisher/internal/APIPublisherServiceComponent.java @@ -25,6 +25,8 @@ import org.osgi.service.component.ComponentContext; import org.wso2.carbon.apimgt.impl.APIManagerConfigurationService; import org.wso2.carbon.apimgt.webapp.publisher.APIPublisherService; import org.wso2.carbon.apimgt.webapp.publisher.APIPublisherServiceImpl; +import org.wso2.carbon.apimgt.webapp.publisher.APIPublisherStartupHandler; +import org.wso2.carbon.core.ServerStartupObserver; import org.wso2.carbon.registry.core.service.RegistryService; import org.wso2.carbon.user.core.service.RealmService; import org.wso2.carbon.utils.ConfigurationContextService; @@ -84,6 +86,7 @@ public class APIPublisherServiceComponent { APIPublisherService publisher = new APIPublisherServiceImpl(); APIPublisherDataHolder.getInstance().setApiPublisherService(publisher); bundleContext.registerService(APIPublisherService.class, publisher, null); + bundleContext.registerService(ServerStartupObserver.class, new APIPublisherStartupHandler(), null); } protected void setAPIManagerConfigurationService(APIManagerConfigurationService service) { diff --git a/components/apimgt-extensions/org.wso2.carbon.apimgt.webapp.publisher/src/main/java/org/wso2/carbon/apimgt/webapp/publisher/lifecycle/listener/APIPublisherLifecycleListener.java b/components/apimgt-extensions/org.wso2.carbon.apimgt.webapp.publisher/src/main/java/org/wso2/carbon/apimgt/webapp/publisher/lifecycle/listener/APIPublisherLifecycleListener.java index f3ecf34620..afff4d7188 100644 --- a/components/apimgt-extensions/org.wso2.carbon.apimgt.webapp.publisher/src/main/java/org/wso2/carbon/apimgt/webapp/publisher/lifecycle/listener/APIPublisherLifecycleListener.java +++ b/components/apimgt-extensions/org.wso2.carbon.apimgt.webapp.publisher/src/main/java/org/wso2/carbon/apimgt/webapp/publisher/lifecycle/listener/APIPublisherLifecycleListener.java @@ -74,13 +74,22 @@ public class APIPublisherLifecycleListener implements LifecycleListener { if (isTenantActive) { apiConfig.init(); API api = APIPublisherUtil.getAPI(apiConfig); - APIPublisherService apiPublisherService = - APIPublisherDataHolder.getInstance().getApiPublisherService(); - if (apiPublisherService == null) { - throw new IllegalStateException( - "API Publisher service is not initialized properly"); + boolean isServerStarted = APIPublisherDataHolder.getInstance().isServerStarted(); + if (isServerStarted) { + APIPublisherService apiPublisherService = + APIPublisherDataHolder.getInstance().getApiPublisherService(); + if (apiPublisherService == null) { + throw new IllegalStateException( + "API Publisher service is not initialized properly"); + } + apiPublisherService.publishAPI(api); + } else { + if (log.isDebugEnabled()) { + log.debug("Server has not started yet. Hence adding API '" + + api.getId().getApiName() + "' to the queue"); + } + APIPublisherDataHolder.getInstance().getUnpublishedApis().push(api); } - apiPublisherService.publishAPI(api); } else { log.error("No tenant [" + apiConfig.getTenantDomain() + "] " + "found when publishing the Web app"); diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.api/pom.xml b/components/device-mgt/org.wso2.carbon.device.mgt.api/pom.xml index f6c0292529..195e9ed853 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.api/pom.xml +++ b/components/device-mgt/org.wso2.carbon.device.mgt.api/pom.xml @@ -146,7 +146,7 @@ provided - org.wso2.carbon.commons + org.wso2.carbon.identity org.wso2.carbon.user.mgt provided diff --git a/features/device-mgt/org.wso2.carbon.device.mgt.server.feature/pom.xml b/features/device-mgt/org.wso2.carbon.device.mgt.server.feature/pom.xml index ec7962494d..e54f7542e1 100644 --- a/features/device-mgt/org.wso2.carbon.device.mgt.server.feature/pom.xml +++ b/features/device-mgt/org.wso2.carbon.device.mgt.server.feature/pom.xml @@ -120,6 +120,10 @@ org.wso2.carbon.identity:org.wso2.carbon.identity.oauth.stub:${carbon.identity.version} + + + org.apache.axiom.om + org.wso2.carbon.core.server:${carbon.kernel.version} diff --git a/pom.xml b/pom.xml index c71293b049..f120f6e7c9 100644 --- a/pom.xml +++ b/pom.xml @@ -1375,16 +1375,16 @@ org.wso2.carbon.databridge.core ${carbon.analytics.common.version} - - org.wso2.carbon.commons - org.wso2.carbon.databridge.commons - ${carbon.commons.version} - - - org.wso2.carbon.commons - org.wso2.carbon.databridge.commons.thrift - ${carbon.commons.version} - + + + + + + + + + + org.wso2.carbon.analytics-common org.wso2.carbon.databridge.commons @@ -1445,9 +1445,9 @@ - org.wso2.carbon.commons + org.wso2.carbon.identity org.wso2.carbon.user.mgt - ${carbon.commons.version} + ${carbon.identity.version} provided @@ -1672,8 +1672,8 @@ 6.1.1 - 4.4.3 - [4.4.0, 4.5.0) + 4.4.5 + [4.4.0, 5.0.0) 1.5.4 1.3 @@ -1715,14 +1715,11 @@ 4.6.0 - 5.0.7 + 5.0.9-SNAPSHOT 4.5.0 - - 4.4.8 - 4.5.8 @@ -1735,7 +1732,7 @@ 1.1.0-SNAPSHOT - 4.4.8 + 4.5.2 1.4.0.wso2v1 2.4.0.wso2v1 2.6.0.wso2v1 @@ -1749,8 +1746,8 @@ [5.0.11,6.0.0) - 4.4.8 - [4.4.8, 5.0.0) + 4.5.2 + [4.5.2, 5.0.0) 2.7.16 From 1f21144668343b4d2fb7c53a1c2cea5fdc4e8d63 Mon Sep 17 00:00:00 2001 From: mharindu Date: Thu, 12 May 2016 22:00:15 +0530 Subject: [PATCH 02/12] Renamed EMM permission to CDMF --- .../DeviceAccessAuthorizationServiceImpl.java | 6 +++--- .../org.wso2.carbon.device.mgt.server.feature/pom.xml | 3 --- pom.xml | 10 +++++----- 3 files changed, 8 insertions(+), 11 deletions(-) diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/authorization/DeviceAccessAuthorizationServiceImpl.java b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/authorization/DeviceAccessAuthorizationServiceImpl.java index 4707bcdd4c..4c2e57d8bd 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/authorization/DeviceAccessAuthorizationServiceImpl.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/authorization/DeviceAccessAuthorizationServiceImpl.java @@ -47,7 +47,7 @@ import java.util.Map; */ public class DeviceAccessAuthorizationServiceImpl implements DeviceAccessAuthorizationService { - private final static String EMM_ADMIN_PERMISSION = "/device-mgt/admin-device-access"; + private final static String CDM_ADMIN_PERMISSION = "/device-mgt/admin"; private static Log log = LogFactory.getLog(DeviceAccessAuthorizationServiceImpl.class); public DeviceAccessAuthorizationServiceImpl() { @@ -221,7 +221,7 @@ public class DeviceAccessAuthorizationServiceImpl implements DeviceAccessAuthori if (userRealm != null && userRealm.getAuthorizationManager() != null) { return userRealm.getAuthorizationManager() .isUserAuthorized(removeTenantDomain(username), - PermissionUtils.getAbsolutePermissionPath(EMM_ADMIN_PERMISSION), + PermissionUtils.getAbsolutePermissionPath(CDM_ADMIN_PERMISSION), PermissionMethod.UI_EXECUTE); } return false; @@ -249,7 +249,7 @@ public class DeviceAccessAuthorizationServiceImpl implements DeviceAccessAuthori private boolean addAdminPermissionToRegistry() throws PermissionManagementException { Permission permission = new Permission(); - permission.setPath(PermissionUtils.getAbsolutePermissionPath(EMM_ADMIN_PERMISSION)); + permission.setPath(PermissionUtils.getAbsolutePermissionPath(CDM_ADMIN_PERMISSION)); return PermissionUtils.putPermission(permission); } diff --git a/features/device-mgt/org.wso2.carbon.device.mgt.server.feature/pom.xml b/features/device-mgt/org.wso2.carbon.device.mgt.server.feature/pom.xml index e54f7542e1..78609ac5d0 100644 --- a/features/device-mgt/org.wso2.carbon.device.mgt.server.feature/pom.xml +++ b/features/device-mgt/org.wso2.carbon.device.mgt.server.feature/pom.xml @@ -121,9 +121,6 @@ org.wso2.carbon.identity:org.wso2.carbon.identity.oauth.stub:${carbon.identity.version} - - org.apache.axiom.om - org.wso2.carbon.core.server:${carbon.kernel.version} diff --git a/pom.xml b/pom.xml index f120f6e7c9..2a3502cd88 100644 --- a/pom.xml +++ b/pom.xml @@ -1672,7 +1672,7 @@ 6.1.1 - 4.4.5 + 4.4.3 [4.4.0, 5.0.0) 1.5.4 1.3 @@ -1715,7 +1715,7 @@ 4.6.0 - 5.0.9-SNAPSHOT + 5.0.7 4.5.0 @@ -1732,7 +1732,7 @@ 1.1.0-SNAPSHOT - 4.5.2 + 4.4.8 1.4.0.wso2v1 2.4.0.wso2v1 2.6.0.wso2v1 @@ -1746,8 +1746,8 @@ [5.0.11,6.0.0) - 4.5.2 - [4.5.2, 5.0.0) + 4.4.8 + [4.4.8, 5.0.0) 2.7.16 From f2ac5c5cad351133d95661a28fe830ba53f8f3f7 Mon Sep 17 00:00:00 2001 From: mharindu Date: Mon, 16 May 2016 11:46:30 +0530 Subject: [PATCH 03/12] Implemented extended scope validator and improved webapp publisher to support Synapse --- .../webapp/publisher/APIPublisherUtil.java | 28 +-- .../webapp/publisher/WebappPublisherUtil.java | 45 ++++ .../APIPublisherServiceComponent.java | 14 +- .../internal/EmailSenderServiceComponent.java | 2 +- .../pom.xml | 7 +- .../mgt/oauth/extensions/OAuthExtUtils.java | 9 + .../ExtendedJDBCScopeValidator.java | 200 ++++++++++++++++++ .../src/main/resources/build.properties | 1 + .../conf/webapp-publisher-config.xml | 32 +++ .../src/main/resources/p2.inf | 2 + 10 files changed, 312 insertions(+), 28 deletions(-) create mode 100644 components/apimgt-extensions/org.wso2.carbon.apimgt.webapp.publisher/src/main/java/org/wso2/carbon/apimgt/webapp/publisher/WebappPublisherUtil.java create mode 100644 components/identity-extensions/org.wso2.carbon.device.mgt.oauth.extensions/src/main/java/org/wso2/carbon/device/mgt/oauth/extensions/validators/ExtendedJDBCScopeValidator.java create mode 100644 features/apimgt-extensions/org.wso2.carbon.apimgt.webapp.publisher.feature/src/main/resources/build.properties create mode 100644 features/apimgt-extensions/org.wso2.carbon.apimgt.webapp.publisher.feature/src/main/resources/conf/webapp-publisher-config.xml create mode 100644 features/apimgt-extensions/org.wso2.carbon.apimgt.webapp.publisher.feature/src/main/resources/p2.inf diff --git a/components/apimgt-extensions/org.wso2.carbon.apimgt.webapp.publisher/src/main/java/org/wso2/carbon/apimgt/webapp/publisher/APIPublisherUtil.java b/components/apimgt-extensions/org.wso2.carbon.apimgt.webapp.publisher/src/main/java/org/wso2/carbon/apimgt/webapp/publisher/APIPublisherUtil.java index 2e7c8caac7..beee183f4a 100644 --- a/components/apimgt-extensions/org.wso2.carbon.apimgt.webapp.publisher/src/main/java/org/wso2/carbon/apimgt/webapp/publisher/APIPublisherUtil.java +++ b/components/apimgt-extensions/org.wso2.carbon.apimgt.webapp.publisher/src/main/java/org/wso2/carbon/apimgt/webapp/publisher/APIPublisherUtil.java @@ -26,11 +26,9 @@ import org.wso2.carbon.apimgt.api.model.*; import org.wso2.carbon.apimgt.impl.APIConstants; 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.internal.APIPublisherDataHolder; +import org.wso2.carbon.apimgt.webapp.publisher.config.WebappPublisherConfig; import org.wso2.carbon.base.MultitenantConstants; -import org.wso2.carbon.utils.CarbonUtils; -import org.wso2.carbon.utils.ConfigurationContextService; -import org.wso2.carbon.utils.NetworkUtils; +import org.wso2.carbon.core.util.Utils; import javax.servlet.ServletContext; import java.util.*; @@ -96,7 +94,7 @@ public class APIPublisherUtil { } api.setResponseCache(APIConstants.DISABLED); - String endpointConfig = "{\"production_endpoints\":{\"url\":\" " + config.getEndpoint() + + String endpointConfig = "{\"production_endpoints\":{\"url\":\"" + config.getEndpoint() + "\",\"config\":null},\"implementation_status\":\"managed\",\"endpoint_type\":\"http\"}"; api.setEndpointConfig(endpointConfig); @@ -143,24 +141,8 @@ public class APIPublisherUtil { } public static String getServerBaseUrl() { - // Hostname - String hostName = "localhost"; - try { - hostName = NetworkUtils.getMgtHostName(); - } catch (Exception ignored) { - } - // HTTPS port - String mgtConsoleTransport = CarbonUtils.getManagementTransport(); - ConfigurationContextService configContextService = - APIPublisherDataHolder.getInstance().getConfigurationContextService(); - int port = CarbonUtils.getTransportPort(configContextService, mgtConsoleTransport); - int httpsProxyPort = - CarbonUtils.getTransportProxyPort(configContextService.getServerConfigContext(), - mgtConsoleTransport); - if (httpsProxyPort > 0) { - port = httpsProxyPort; - } - return "https://" + hostName + ":" + port; + WebappPublisherConfig webappPublisherConfig = WebappPublisherConfig.getInstance(); + return Utils.replaceSystemProperty(webappPublisherConfig.getHost()); } public static String getApiEndpointUrl(String context) { diff --git a/components/apimgt-extensions/org.wso2.carbon.apimgt.webapp.publisher/src/main/java/org/wso2/carbon/apimgt/webapp/publisher/WebappPublisherUtil.java b/components/apimgt-extensions/org.wso2.carbon.apimgt.webapp.publisher/src/main/java/org/wso2/carbon/apimgt/webapp/publisher/WebappPublisherUtil.java new file mode 100644 index 0000000000..9308910c06 --- /dev/null +++ b/components/apimgt-extensions/org.wso2.carbon.apimgt.webapp.publisher/src/main/java/org/wso2/carbon/apimgt/webapp/publisher/WebappPublisherUtil.java @@ -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; + +import org.w3c.dom.Document; + +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import java.io.File; + +/** + * This class contains the util methods which are needed + * to web app publisher related functions. + */ +public class WebappPublisherUtil { + + public static Document convertToDocument(File file) throws WebappPublisherConfigurationFailedException { + DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); + factory.setNamespaceAware(true); + try { + DocumentBuilder docBuilder = factory.newDocumentBuilder(); + return docBuilder.parse(file); + } catch (Exception e) { + throw new WebappPublisherConfigurationFailedException("Error occurred while parsing file, while converting " + + "to a org.w3c.dom.Document", e); + } + } + +} diff --git a/components/apimgt-extensions/org.wso2.carbon.apimgt.webapp.publisher/src/main/java/org/wso2/carbon/apimgt/webapp/publisher/internal/APIPublisherServiceComponent.java b/components/apimgt-extensions/org.wso2.carbon.apimgt.webapp.publisher/src/main/java/org/wso2/carbon/apimgt/webapp/publisher/internal/APIPublisherServiceComponent.java index ed9e4377c1..44c2c6d799 100644 --- a/components/apimgt-extensions/org.wso2.carbon.apimgt.webapp.publisher/src/main/java/org/wso2/carbon/apimgt/webapp/publisher/internal/APIPublisherServiceComponent.java +++ b/components/apimgt-extensions/org.wso2.carbon.apimgt.webapp.publisher/src/main/java/org/wso2/carbon/apimgt/webapp/publisher/internal/APIPublisherServiceComponent.java @@ -26,6 +26,7 @@ import org.wso2.carbon.apimgt.impl.APIManagerConfigurationService; import org.wso2.carbon.apimgt.webapp.publisher.APIPublisherService; import org.wso2.carbon.apimgt.webapp.publisher.APIPublisherServiceImpl; import org.wso2.carbon.apimgt.webapp.publisher.APIPublisherStartupHandler; +import org.wso2.carbon.apimgt.webapp.publisher.config.WebappPublisherConfig; import org.wso2.carbon.core.ServerStartupObserver; import org.wso2.carbon.registry.core.service.RegistryService; import org.wso2.carbon.user.core.service.RealmService; @@ -59,16 +60,23 @@ public class APIPublisherServiceComponent { protected void activate(ComponentContext componentContext) { try { if (log.isDebugEnabled()) { - log.debug("Initializing device management core bundle"); + log.debug("Initializing webapp publisher bundle"); } + + if (log.isDebugEnabled()) { + log.debug("Loading webapp publisher configurations"); + } + /* Initializing webapp publisher configuration */ + WebappPublisherConfig.init(); + /* Registering declarative service instances exposed by DeviceManagementServiceComponent */ this.registerServices(componentContext); if (log.isDebugEnabled()) { - log.debug("Device management core bundle has been successfully initialized"); + log.debug("Webapp publisher bundle has been successfully initialized"); } } catch (Throwable e) { - log.error("Error occurred while initializing device management core bundle", e); + log.error("Error occurred while initializing webapp publisher bundle", e); } } diff --git a/components/email-sender/org.wso2.carbon.email.sender.core/src/main/java/org/wso2/carbon/email/sender/core/internal/EmailSenderServiceComponent.java b/components/email-sender/org.wso2.carbon.email.sender.core/src/main/java/org/wso2/carbon/email/sender/core/internal/EmailSenderServiceComponent.java index b166c5861b..6ed1df99f9 100644 --- a/components/email-sender/org.wso2.carbon.email.sender.core/src/main/java/org/wso2/carbon/email/sender/core/internal/EmailSenderServiceComponent.java +++ b/components/email-sender/org.wso2.carbon.email.sender.core/src/main/java/org/wso2/carbon/email/sender/core/internal/EmailSenderServiceComponent.java @@ -65,7 +65,7 @@ public class EmailSenderServiceComponent { if (log.isDebugEnabled()) { log.debug("Initializing email sender core bundle"); } - /* Initializing email sende configuration */ + /* Initializing email sender configuration */ EmailSenderConfig.init(); /* Setting up default email templates */ diff --git a/components/identity-extensions/org.wso2.carbon.device.mgt.oauth.extensions/pom.xml b/components/identity-extensions/org.wso2.carbon.device.mgt.oauth.extensions/pom.xml index c08f127404..2bd6852d06 100644 --- a/components/identity-extensions/org.wso2.carbon.device.mgt.oauth.extensions/pom.xml +++ b/components/identity-extensions/org.wso2.carbon.device.mgt.oauth.extensions/pom.xml @@ -113,7 +113,12 @@ org.wso2.carbon.user.core, org.wso2.carbon.user.core.config, org.wso2.carbon.user.core.util, - org.wso2.carbon.utils + org.wso2.carbon.utils, + org.wso2.carbon.context, + org.wso2.carbon.identity.oauth.cache, + org.wso2.carbon.identity.oauth.config, + org.wso2.carbon.identity.oauth2.dao, + org.wso2.carbon.utils.multitenancy diff --git a/components/identity-extensions/org.wso2.carbon.device.mgt.oauth.extensions/src/main/java/org/wso2/carbon/device/mgt/oauth/extensions/OAuthExtUtils.java b/components/identity-extensions/org.wso2.carbon.device.mgt.oauth.extensions/src/main/java/org/wso2/carbon/device/mgt/oauth/extensions/OAuthExtUtils.java index 32ad46ccd1..93a6db287c 100644 --- a/components/identity-extensions/org.wso2.carbon.device.mgt.oauth.extensions/src/main/java/org/wso2/carbon/device/mgt/oauth/extensions/OAuthExtUtils.java +++ b/components/identity-extensions/org.wso2.carbon.device.mgt.oauth.extensions/src/main/java/org/wso2/carbon/device/mgt/oauth/extensions/OAuthExtUtils.java @@ -47,6 +47,7 @@ public class OAuthExtUtils { 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"; + private static final int START_INDEX = 0; /** * This method is used to get the tenant id when given tenant domain. @@ -260,4 +261,12 @@ public class OAuthExtUtils { return authorizedScopes; } + public static String extractUserName(String username) { + if (username == null || username.isEmpty()) { + return null; + } + String trimmedName = username.trim(); + return trimmedName.substring(START_INDEX, trimmedName.lastIndexOf('@')); + } + } diff --git a/components/identity-extensions/org.wso2.carbon.device.mgt.oauth.extensions/src/main/java/org/wso2/carbon/device/mgt/oauth/extensions/validators/ExtendedJDBCScopeValidator.java b/components/identity-extensions/org.wso2.carbon.device.mgt.oauth.extensions/src/main/java/org/wso2/carbon/device/mgt/oauth/extensions/validators/ExtendedJDBCScopeValidator.java new file mode 100644 index 0000000000..8f5ffa2514 --- /dev/null +++ b/components/identity-extensions/org.wso2.carbon.device.mgt.oauth.extensions/src/main/java/org/wso2/carbon/device/mgt/oauth/extensions/validators/ExtendedJDBCScopeValidator.java @@ -0,0 +1,200 @@ +/* + * 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.validators; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.wso2.carbon.base.MultitenantConstants; +import org.wso2.carbon.context.PrivilegedCarbonContext; +import org.wso2.carbon.device.mgt.oauth.extensions.internal.OAuthExtensionsDataHolder; +import org.wso2.carbon.identity.application.common.model.User; +import org.wso2.carbon.identity.core.util.IdentityTenantUtil; +import org.wso2.carbon.identity.oauth.cache.CacheEntry; +import org.wso2.carbon.identity.oauth.cache.OAuthCache; +import org.wso2.carbon.identity.oauth.cache.OAuthCacheKey; +import org.wso2.carbon.identity.oauth.config.OAuthServerConfiguration; +import org.wso2.carbon.identity.oauth2.IdentityOAuth2Exception; +import org.wso2.carbon.identity.oauth2.dao.TokenMgtDAO; +import org.wso2.carbon.identity.oauth2.model.AccessTokenDO; +import org.wso2.carbon.identity.oauth2.model.ResourceScopeCacheEntry; +import org.wso2.carbon.identity.oauth2.validators.OAuth2ScopeValidator; +import org.wso2.carbon.user.api.AuthorizationManager; +import org.wso2.carbon.user.api.UserStoreException; +import org.wso2.carbon.user.core.service.RealmService; +import org.wso2.carbon.utils.multitenancy.MultitenantUtils; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Set; + +@SuppressWarnings("unused") +public class ExtendedJDBCScopeValidator extends OAuth2ScopeValidator{ + + private static final Log log = LogFactory.getLog(ExtendedJDBCScopeValidator.class); + private static final String UI_EXECUTE = "ui.execute"; + + + @Override + public boolean validateScope(AccessTokenDO accessTokenDO, String resource) throws IdentityOAuth2Exception { + //Get the list of scopes associated with the access token + String[] scopes = accessTokenDO.getScope(); + + //If no scopes are associated with the token + if (scopes == null || scopes.length == 0) { + return true; + } + + String resourceScope = null; + TokenMgtDAO tokenMgtDAO = new TokenMgtDAO(); + + boolean cacheHit = false; + // Check the cache, if caching is enabled. + if (OAuthServerConfiguration.getInstance().isCacheEnabled()) { + OAuthCache oauthCache = OAuthCache.getInstance(); + OAuthCacheKey cacheKey = new OAuthCacheKey(resource); + CacheEntry result = oauthCache.getValueFromCache(cacheKey); + + //Cache hit + if (result instanceof ResourceScopeCacheEntry) { + resourceScope = ((ResourceScopeCacheEntry) result).getScope(); + cacheHit = true; + } + } + + if (!cacheHit) { + resourceScope = tokenMgtDAO.findScopeOfResource(resource); + + if (OAuthServerConfiguration.getInstance().isCacheEnabled()) { + OAuthCache oauthCache = OAuthCache.getInstance(); + OAuthCacheKey cacheKey = new OAuthCacheKey(resource); + ResourceScopeCacheEntry cacheEntry = new ResourceScopeCacheEntry(resourceScope); + //Store resourceScope in cache even if it is null (to avoid database calls when accessing resources for + //which scopes haven't been defined). + oauthCache.addToCache(cacheKey, cacheEntry); + } + } + + //Return TRUE if - There does not exist a scope definition for the resource + if (resourceScope == null) { + if(log.isDebugEnabled()){ + log.debug("Resource '" + resource + "' is not protected with a scope"); + } + return true; + } + + List scopeList = new ArrayList<>(Arrays.asList(scopes)); + + //If the access token does not bear the scope required for accessing the Resource. + if(!scopeList.contains(resourceScope)){ + if(log.isDebugEnabled()){ + log.debug("Access token '" + accessTokenDO.getAccessToken() + "' does not bear the scope '" + + resourceScope + "'"); + } + return false; + } + + try { + //Get the permissions associated with the scope, if any + Set permissionsOfScope = tokenMgtDAO.getRolesOfScopeByScopeKey(resourceScope); + + //If the scope doesn't have any permissions associated with it. + if(permissionsOfScope == null || permissionsOfScope.isEmpty()){ + if(log.isDebugEnabled()){ + log.debug("Did not find any roles associated to the scope " + resourceScope); + } + return true; + } + + if(log.isDebugEnabled()){ + StringBuilder logMessage = new StringBuilder("Found permissions of scope '" + resourceScope + "' "); + for(String permission : permissionsOfScope){ + logMessage.append(permission); + logMessage.append(", "); + } + log.debug(logMessage.toString()); + } + + User authorizedUser = accessTokenDO.getAuthzUser(); + RealmService realmService = OAuthExtensionsDataHolder.getInstance().getRealmService(); + + int tenantId = realmService.getTenantManager().getTenantId(authorizedUser.getTenantDomain()); + + if (tenantId == 0 || tenantId == -1) { + tenantId = IdentityTenantUtil.getTenantIdOfUser(authorizedUser.getUserName()); + } + + AuthorizationManager authorizationManager; + String[] userRoles; + boolean tenantFlowStarted = false; + + try{ + //If this is a tenant user + if(tenantId != MultitenantConstants.SUPER_TENANT_ID){ + PrivilegedCarbonContext.startTenantFlow(); + PrivilegedCarbonContext.getThreadLocalCarbonContext().setTenantDomain( + realmService.getTenantManager().getDomain(tenantId),true); + tenantFlowStarted = true; + } + + authorizationManager = realmService.getTenantUserRealm(tenantId).getAuthorizationManager(); + + } finally { + if (tenantFlowStarted) { + PrivilegedCarbonContext.endTenantFlow(); + } + } + boolean status = false; + String username = MultitenantUtils.getTenantAwareUsername(authorizedUser.getUserName()); + for (String permission : permissionsOfScope) { + if (authorizationManager != null) { + String userStore = authorizedUser.getUserStoreDomain(); + + if (userStore != null) { + status = authorizationManager + .isUserAuthorized(userStore + "/" + username, permission, UI_EXECUTE); + } else { + status = authorizationManager.isUserAuthorized(username , permission, UI_EXECUTE); + } + if (status) { + break; + } + } + } + + if (status) { + if(log.isDebugEnabled()){ + log.debug("User '" + authorizedUser.getUserName() + "' is authorized"); + } + return true; + } + + if(log.isDebugEnabled()){ + log.debug("No permissions associated for the user " + authorizedUser.getUserName()); + } + return false; + + } catch (UserStoreException e) { + //Log and return since we do not want to stop issuing the token in case of scope validation failures. + log.error("Error when getting the tenant's UserStoreManager or when getting roles of user ", e); + return false; + } + } + +} diff --git a/features/apimgt-extensions/org.wso2.carbon.apimgt.webapp.publisher.feature/src/main/resources/build.properties b/features/apimgt-extensions/org.wso2.carbon.apimgt.webapp.publisher.feature/src/main/resources/build.properties new file mode 100644 index 0000000000..9c86577d76 --- /dev/null +++ b/features/apimgt-extensions/org.wso2.carbon.apimgt.webapp.publisher.feature/src/main/resources/build.properties @@ -0,0 +1 @@ +custom = true diff --git a/features/apimgt-extensions/org.wso2.carbon.apimgt.webapp.publisher.feature/src/main/resources/conf/webapp-publisher-config.xml b/features/apimgt-extensions/org.wso2.carbon.apimgt.webapp.publisher.feature/src/main/resources/conf/webapp-publisher-config.xml new file mode 100644 index 0000000000..74c12a775e --- /dev/null +++ b/features/apimgt-extensions/org.wso2.carbon.apimgt.webapp.publisher.feature/src/main/resources/conf/webapp-publisher-config.xml @@ -0,0 +1,32 @@ + + + + + + + + https://${carbon.local.ip}:$(carbon.http.port) + + + true + + \ No newline at end of file diff --git a/features/apimgt-extensions/org.wso2.carbon.apimgt.webapp.publisher.feature/src/main/resources/p2.inf b/features/apimgt-extensions/org.wso2.carbon.apimgt.webapp.publisher.feature/src/main/resources/p2.inf new file mode 100644 index 0000000000..3d6782a96f --- /dev/null +++ b/features/apimgt-extensions/org.wso2.carbon.apimgt.webapp.publisher.feature/src/main/resources/p2.inf @@ -0,0 +1,2 @@ +instructions.configure = \ +org.eclipse.equinox.p2.touchpoint.natives.copy(source:${installFolder}/../features/org.wso2.carbon.apimgt.webapp.publisher_${feature.version}/conf/webapp-publisher-config.xml,target:${installFolder}/../../conf/etc/webapp-publisher-config.xml,overwrite:true);\ From 659cdcc50c55b39f52bc4439b1c06cf1f88a5855 Mon Sep 17 00:00:00 2001 From: mharindu Date: Mon, 16 May 2016 11:47:04 +0530 Subject: [PATCH 04/12] Implemented extended scope validator and improved webapp publisher to support Synapse --- .../InvalidConfigurationStateException.java | 75 +++++++++++++++ ...PublisherConfigurationFailedException.java | 44 +++++++++ .../config/WebappPublisherConfig.java | 94 +++++++++++++++++++ 3 files changed, 213 insertions(+) create mode 100644 components/apimgt-extensions/org.wso2.carbon.apimgt.webapp.publisher/src/main/java/org/wso2/carbon/apimgt/webapp/publisher/InvalidConfigurationStateException.java create mode 100644 components/apimgt-extensions/org.wso2.carbon.apimgt.webapp.publisher/src/main/java/org/wso2/carbon/apimgt/webapp/publisher/WebappPublisherConfigurationFailedException.java create mode 100644 components/apimgt-extensions/org.wso2.carbon.apimgt.webapp.publisher/src/main/java/org/wso2/carbon/apimgt/webapp/publisher/config/WebappPublisherConfig.java diff --git a/components/apimgt-extensions/org.wso2.carbon.apimgt.webapp.publisher/src/main/java/org/wso2/carbon/apimgt/webapp/publisher/InvalidConfigurationStateException.java b/components/apimgt-extensions/org.wso2.carbon.apimgt.webapp.publisher/src/main/java/org/wso2/carbon/apimgt/webapp/publisher/InvalidConfigurationStateException.java new file mode 100644 index 0000000000..d3022f11d1 --- /dev/null +++ b/components/apimgt-extensions/org.wso2.carbon.apimgt.webapp.publisher/src/main/java/org/wso2/carbon/apimgt/webapp/publisher/InvalidConfigurationStateException.java @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ + +package org.wso2.carbon.apimgt.webapp.publisher; + +public class InvalidConfigurationStateException extends RuntimeException { + + private static final long serialVersionUID = -3151279311329070397L; + + private String errorMessage; + private int errorCode; + + public InvalidConfigurationStateException(int errorCode, String message) { + super(message); + this.errorCode = errorCode; + } + + public InvalidConfigurationStateException(int errorCode, String message, Throwable cause) { + super(message, cause); + this.errorCode = errorCode; + } + + public int getErrorCode() { + return errorCode; + } + + + public String getErrorMessage() { + return errorMessage; + } + + public void setErrorMessage(String errorMessage) { + this.errorMessage = errorMessage; + } + + public InvalidConfigurationStateException(String msg, Exception nestedEx) { + super(msg, nestedEx); + setErrorMessage(msg); + } + + public InvalidConfigurationStateException(String message, Throwable cause) { + super(message, cause); + setErrorMessage(message); + } + + public InvalidConfigurationStateException(String msg) { + super(msg); + setErrorMessage(msg); + } + + public InvalidConfigurationStateException() { + super(); + } + + public InvalidConfigurationStateException(Throwable cause) { + super(cause); + } + +} diff --git a/components/apimgt-extensions/org.wso2.carbon.apimgt.webapp.publisher/src/main/java/org/wso2/carbon/apimgt/webapp/publisher/WebappPublisherConfigurationFailedException.java b/components/apimgt-extensions/org.wso2.carbon.apimgt.webapp.publisher/src/main/java/org/wso2/carbon/apimgt/webapp/publisher/WebappPublisherConfigurationFailedException.java new file mode 100644 index 0000000000..e5b3252f8e --- /dev/null +++ b/components/apimgt-extensions/org.wso2.carbon.apimgt.webapp.publisher/src/main/java/org/wso2/carbon/apimgt/webapp/publisher/WebappPublisherConfigurationFailedException.java @@ -0,0 +1,44 @@ +/* + * 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; + +public class WebappPublisherConfigurationFailedException extends Exception { + + private static final long serialVersionUID = -3151279312929070398L; + + public WebappPublisherConfigurationFailedException(String msg, Exception nestedEx) { + super(msg, nestedEx); + } + + public WebappPublisherConfigurationFailedException(String message, Throwable cause) { + super(message, cause); + } + + public WebappPublisherConfigurationFailedException(String msg) { + super(msg); + } + + public WebappPublisherConfigurationFailedException() { + super(); + } + + public WebappPublisherConfigurationFailedException(Throwable cause) { + super(cause); + } +} diff --git a/components/apimgt-extensions/org.wso2.carbon.apimgt.webapp.publisher/src/main/java/org/wso2/carbon/apimgt/webapp/publisher/config/WebappPublisherConfig.java b/components/apimgt-extensions/org.wso2.carbon.apimgt.webapp.publisher/src/main/java/org/wso2/carbon/apimgt/webapp/publisher/config/WebappPublisherConfig.java new file mode 100644 index 0000000000..192f91b906 --- /dev/null +++ b/components/apimgt-extensions/org.wso2.carbon.apimgt.webapp.publisher/src/main/java/org/wso2/carbon/apimgt/webapp/publisher/config/WebappPublisherConfig.java @@ -0,0 +1,94 @@ +/* + * 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; + +import org.w3c.dom.Document; +import org.wso2.carbon.apimgt.webapp.publisher.InvalidConfigurationStateException; +import org.wso2.carbon.apimgt.webapp.publisher.WebappPublisherConfigurationFailedException; +import org.wso2.carbon.apimgt.webapp.publisher.WebappPublisherUtil; +import org.wso2.carbon.utils.CarbonUtils; + +import javax.xml.bind.JAXBContext; +import javax.xml.bind.JAXBException; +import javax.xml.bind.Unmarshaller; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; +import java.io.File; + +/** + * This class represents the configuration that are needed + * when publishing APIs to API Manager. + */ +@XmlRootElement(name = "WebappPublisherConfigs") +public class WebappPublisherConfig { + + private String host; + private boolean isPublished; + + private static WebappPublisherConfig config; + + private static final String WEBAPP_PUBLISHER_CONFIG_PATH = + CarbonUtils.getEtcCarbonConfigDirPath() + File.separator + "webapp-publisher-config.xml"; + + private WebappPublisherConfig() { + } + + public static WebappPublisherConfig getInstance() { + if (config == null) { + throw new InvalidConfigurationStateException("Webapp Authenticator Configuration is not " + + "initialized properly"); + } + return config; + } + + @XmlElement(name = "Host", required = true) + public String getHost() { + return host; + } + + public void setHost(String host) { + this.host = host; + } + + @XmlElement(name = "PublishAPI", required = true) + public boolean isPublished() { + return isPublished; + } + + public void setPublished(boolean published) { + isPublished = published; + } + + public static void init() throws WebappPublisherConfigurationFailedException { + try { + File emailSenderConfig = new File(WEBAPP_PUBLISHER_CONFIG_PATH); + Document doc = WebappPublisherUtil.convertToDocument(emailSenderConfig); + + /* Un-marshaling Email Sender configuration */ + JAXBContext ctx = JAXBContext.newInstance(WebappPublisherConfig.class); + Unmarshaller unmarshaller = ctx.createUnmarshaller(); + //unmarshaller.setSchema(getSchema()); + config = (WebappPublisherConfig) unmarshaller.unmarshal(doc); + } catch (JAXBException e) { + throw new WebappPublisherConfigurationFailedException("Error occurred while un-marshalling Webapp " + + "Publisher Config", e); + } + } + +} From c68b92c7b44c9ef0b9d4ff13278eb25e6dea222f Mon Sep 17 00:00:00 2001 From: mharindu Date: Mon, 16 May 2016 14:12:28 +0530 Subject: [PATCH 05/12] Fixed conflicts --- .../lifecycle/util/AnnotationProcessor.java | 11 +--- .../core/config/DeviceManagementConfig.java | 14 ----- .../config/deviceType/DTConfiguration.java | 53 ------------------- 3 files changed, 2 insertions(+), 76 deletions(-) delete mode 100644 components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/config/deviceType/DTConfiguration.java diff --git a/components/apimgt-extensions/org.wso2.carbon.apimgt.webapp.publisher/src/main/java/org/wso2/carbon/apimgt/webapp/publisher/lifecycle/util/AnnotationProcessor.java b/components/apimgt-extensions/org.wso2.carbon.apimgt.webapp.publisher/src/main/java/org/wso2/carbon/apimgt/webapp/publisher/lifecycle/util/AnnotationProcessor.java index 730c8c82dc..46b4db6b7e 100644 --- a/components/apimgt-extensions/org.wso2.carbon.apimgt.webapp.publisher/src/main/java/org/wso2/carbon/apimgt/webapp/publisher/lifecycle/util/AnnotationProcessor.java +++ b/components/apimgt-extensions/org.wso2.carbon.apimgt.webapp.publisher/src/main/java/org/wso2/carbon/apimgt/webapp/publisher/lifecycle/util/AnnotationProcessor.java @@ -28,12 +28,11 @@ 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.APIPublisherUtil; 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.PermissionConfiguration; import org.wso2.carbon.apimgt.webapp.publisher.config.PermissionManagementException; -import org.wso2.carbon.device.mgt.core.config.DeviceConfigurationManager; -import org.wso2.carbon.device.mgt.core.config.deviceType.DTConfiguration; import javax.servlet.ServletContext; import javax.ws.rs.*; @@ -225,13 +224,7 @@ public class AnnotationProcessor { APIResource resource = new APIResource(); resource.setUriTemplate(makeContextURLReady(apiRootContext + subCtx)); - DTConfiguration deviceTypeConfig = DeviceConfigurationManager.getInstance(). - getDeviceManagementConfig().getDTDeploymentConfiguration(); - - String serverIP = deviceTypeConfig.getDtHostAddress(); - String httpServerPort = deviceTypeConfig.getDtHostPort(); - - resource.setUri(PROTOCOL_HTTP + "://" + serverIP + ":" + httpServerPort + makeContextURLReady( + resource.setUri(APIPublisherUtil.getServerBaseUrl() + makeContextURLReady( resourceRootContext) + makeContextURLReady(subCtx)); resource.setAuthType(AUTH_TYPE); diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/config/DeviceManagementConfig.java b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/config/DeviceManagementConfig.java index ee11038ca4..1ffbf06257 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/config/DeviceManagementConfig.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/config/DeviceManagementConfig.java @@ -17,15 +17,12 @@ */ package org.wso2.carbon.device.mgt.core.config; -import org.wso2.carbon.device.mgt.core.config.deviceType.DTConfiguration; import org.wso2.carbon.device.mgt.core.config.identity.IdentityConfigurations; import org.wso2.carbon.device.mgt.core.config.policy.PolicyConfiguration; import org.wso2.carbon.device.mgt.core.config.task.TaskConfiguration; import javax.xml.bind.annotation.XmlElement; -import javax.xml.bind.annotation.XmlElementWrapper; import javax.xml.bind.annotation.XmlRootElement; -import java.util.List; /** * Represents Device Mgt configuration. @@ -37,8 +34,6 @@ public final class DeviceManagementConfig { private TaskConfiguration taskConfiguration; private IdentityConfigurations identityConfigurations; private PolicyConfiguration policyConfiguration; - //private List pushNotificationProviders; - private DTConfiguration dTDepyloymentConfiguration; @XmlElement(name = "ManagementRepository", required = true) public DeviceManagementConfigRepository getDeviceManagementConfigRepository() { @@ -77,15 +72,6 @@ public final class DeviceManagementConfig { this.taskConfiguration = taskConfiguration; } - @XmlElement(name = "DTDeploymentConfiguration", required = true) - public DTConfiguration getDTDeploymentConfiguration() { - return dTDepyloymentConfiguration; - } - - public void setDTDeploymentConfiguration(DTConfiguration dTDeploymentConfiguration) { - this.dTDepyloymentConfiguration = dTDeploymentConfiguration; - } - // @XmlElementWrapper(name = "PushNotificationProviders", required = true) // @XmlElement(name = "Provider", required = true) // public List getPushNotificationProviders() { diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/config/deviceType/DTConfiguration.java b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/config/deviceType/DTConfiguration.java deleted file mode 100644 index 14a3af1274..0000000000 --- a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/config/deviceType/DTConfiguration.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. - * - * WSO2 Inc. licenses this file to you under the Apache License, - * Version 2.0 (the "License"); you may not use this file except - * in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - - -/** - * This class will read the configurations related to task. This task will be responsible for adding the operations. - */ -package org.wso2.carbon.device.mgt.core.config.deviceType; - -import javax.xml.bind.annotation.XmlElement; -import javax.xml.bind.annotation.XmlRootElement; - -@XmlRootElement(name = "DTDepyloymentConfiguration") -public class DTConfiguration { - - private String dtHostAddress; - private String dtHostPort; - - @XmlElement(name = "DTHostAddress", required = true) - public String getDtHostAddress() { - return dtHostAddress; - } - - public void setDtHostAddress(String dtHostAddress) { - this.dtHostAddress = dtHostAddress; - } - - @XmlElement(name = "DTHostPort", required = true) - public String getDtHostPort() { - return dtHostPort; - } - - public void setDtHostPort(String dtHostPort) { - this.dtHostPort = dtHostPort; - } - - -} From 83ec18c38df3cc60778d0f4a2042824213ac676c Mon Sep 17 00:00:00 2001 From: mharindu Date: Mon, 16 May 2016 14:20:34 +0530 Subject: [PATCH 06/12] Removed external dependancies from webapp publisher component --- .../org.wso2.carbon.apimgt.webapp.publisher/pom.xml | 4 ---- .../listener/APIPublisherLifecycleListener.java | 10 ++++++---- .../device/mgt/core/DeviceManagementConstants.java | 3 --- 3 files changed, 6 insertions(+), 11 deletions(-) diff --git a/components/apimgt-extensions/org.wso2.carbon.apimgt.webapp.publisher/pom.xml b/components/apimgt-extensions/org.wso2.carbon.apimgt.webapp.publisher/pom.xml index 63176b19db..7da850e7a9 100644 --- a/components/apimgt-extensions/org.wso2.carbon.apimgt.webapp.publisher/pom.xml +++ b/components/apimgt-extensions/org.wso2.carbon.apimgt.webapp.publisher/pom.xml @@ -105,10 +105,6 @@ org.wso2.carbon.governance org.wso2.carbon.governance.lcm - - org.wso2.carbon.devicemgt - org.wso2.carbon.device.mgt.core - diff --git a/components/apimgt-extensions/org.wso2.carbon.apimgt.webapp.publisher/src/main/java/org/wso2/carbon/apimgt/webapp/publisher/lifecycle/listener/APIPublisherLifecycleListener.java b/components/apimgt-extensions/org.wso2.carbon.apimgt.webapp.publisher/src/main/java/org/wso2/carbon/apimgt/webapp/publisher/lifecycle/listener/APIPublisherLifecycleListener.java index 8efaaf7338..042da6b8c2 100644 --- a/components/apimgt-extensions/org.wso2.carbon.apimgt.webapp.publisher/src/main/java/org/wso2/carbon/apimgt/webapp/publisher/lifecycle/listener/APIPublisherLifecycleListener.java +++ b/components/apimgt-extensions/org.wso2.carbon.apimgt.webapp.publisher/src/main/java/org/wso2/carbon/apimgt/webapp/publisher/lifecycle/listener/APIPublisherLifecycleListener.java @@ -31,7 +31,6 @@ import org.wso2.carbon.apimgt.webapp.publisher.APIPublisherUtil; 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.lifecycle.util.AnnotationProcessor; -import org.wso2.carbon.device.mgt.core.DeviceManagementConstants; import javax.servlet.ServletContext; import java.io.IOException; @@ -43,6 +42,9 @@ public class APIPublisherLifecycleListener implements LifecycleListener { private static final Log log = LogFactory.getLog(APIPublisherLifecycleListener.class); private static final String PARAM_MANAGED_API_ENABLED = "managed-api-enabled"; + public static final String PROPERTY_PROFILE = "profile"; + public static final String PROFILE_DT_WORKER = "dtWorker"; + public static final String PROFILE_DEFAULT = "default"; @Override public void lifecycleEvent(LifecycleEvent lifecycleEvent) { @@ -52,10 +54,10 @@ public class APIPublisherLifecycleListener implements LifecycleListener { String param = servletContext.getInitParameter(PARAM_MANAGED_API_ENABLED); boolean isManagedApi = (param != null && !param.isEmpty()) && Boolean.parseBoolean(param); - String profile = System.getProperty(DeviceManagementConstants.Common.PROPERTY_PROFILE); + String profile = System.getProperty(PROPERTY_PROFILE); - if ((profile.equalsIgnoreCase(DeviceManagementConstants.Common.PROFILE_DT_WORKER) || - profile.equalsIgnoreCase(DeviceManagementConstants.Common.PROFILE_DEFAULT)) && isManagedApi) { + if ((profile.equalsIgnoreCase(PROFILE_DT_WORKER) || + profile.equalsIgnoreCase(PROFILE_DEFAULT)) && isManagedApi) { try { AnnotationProcessor annotationProcessor = new AnnotationProcessor(context); Set annotatedAPIClasses = annotationProcessor. diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/DeviceManagementConstants.java b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/DeviceManagementConstants.java index b4d9dd3fbb..379ca8c3d6 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/DeviceManagementConstants.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/DeviceManagementConstants.java @@ -28,9 +28,6 @@ public final class DeviceManagementConstants { public static final String PROPERTY_SETUP = "setup"; public static final String DEFAULT_LICENSE_CONFIG_XML_NAME = "license-config.xml"; - public static final String PROPERTY_PROFILE = "profile"; - public static final String PROFILE_DT_WORKER = "dtWorker"; - public static final String PROFILE_DEFAULT = "default"; } public static final class AppManagement { From b77f5358e89cc360c64155a62ffc51383e3f3fe0 Mon Sep 17 00:00:00 2001 From: mharindu Date: Mon, 16 May 2016 14:23:52 +0530 Subject: [PATCH 07/12] Removed external dependancies from webapp publisher component --- .../listener/FeatureManagementLifecycleListener.java | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.extensions/src/main/java/org/wso2/carbon/device/mgt/extensions/feature/mgt/lifecycle/listener/FeatureManagementLifecycleListener.java b/components/device-mgt/org.wso2.carbon.device.mgt.extensions/src/main/java/org/wso2/carbon/device/mgt/extensions/feature/mgt/lifecycle/listener/FeatureManagementLifecycleListener.java index 9753b4cfdd..6fba635c3e 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.extensions/src/main/java/org/wso2/carbon/device/mgt/extensions/feature/mgt/lifecycle/listener/FeatureManagementLifecycleListener.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.extensions/src/main/java/org/wso2/carbon/device/mgt/extensions/feature/mgt/lifecycle/listener/FeatureManagementLifecycleListener.java @@ -24,7 +24,6 @@ import org.apache.catalina.core.StandardContext; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.wso2.carbon.device.mgt.common.Feature; -import org.wso2.carbon.device.mgt.core.DeviceManagementConstants; import org.wso2.carbon.device.mgt.extensions.feature.mgt.GenericFeatureManager; import org.wso2.carbon.device.mgt.extensions.feature.mgt.annotations.DeviceType; import org.wso2.carbon.device.mgt.extensions.feature.mgt.util.AnnotationProcessor; @@ -44,6 +43,9 @@ public class FeatureManagementLifecycleListener implements LifecycleListener { private static final Log log = LogFactory.getLog(FeatureManagementLifecycleListener.class); private static final String UNLIMITED = "Unlimited"; + public static final String PROPERTY_PROFILE = "profile"; + public static final String PROFILE_DT_WORKER = "dtWorker"; + public static final String PROFILE_DEFAULT = "default"; @Override public void lifecycleEvent(LifecycleEvent lifecycleEvent) { @@ -53,10 +55,10 @@ public class FeatureManagementLifecycleListener implements LifecycleListener { String param = servletContext.getInitParameter(PARAM_MANAGED_API_ENABLED); boolean isManagedApi = (param != null && !param.isEmpty()) && Boolean.parseBoolean(param); - String profile = System.getProperty(DeviceManagementConstants.Common.PROPERTY_PROFILE); + String profile = System.getProperty(PROPERTY_PROFILE); - if ((profile.equalsIgnoreCase(DeviceManagementConstants.Common.PROFILE_DT_WORKER) || - profile.equalsIgnoreCase(DeviceManagementConstants.Common.PROFILE_DEFAULT)) && isManagedApi) { + if ((profile.equalsIgnoreCase(PROFILE_DT_WORKER) || + profile.equalsIgnoreCase(PROFILE_DEFAULT)) && isManagedApi) { try { AnnotationProcessor annotationProcessor = new AnnotationProcessor(context); Set annotatedAPIClasses = annotationProcessor.scanStandardContext(DeviceType.class.getName()); From ace6c2dbfc2a58c03750280d1190fd167e5daeae Mon Sep 17 00:00:00 2001 From: mharindu Date: Mon, 16 May 2016 18:13:00 +0530 Subject: [PATCH 08/12] Fixed issues in JWT Authenticator --- .../authenticator/JWTAuthenticator.java | 149 +++++++++--------- 1 file changed, 75 insertions(+), 74 deletions(-) diff --git a/components/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework/src/main/java/org/wso2/carbon/webapp/authenticator/framework/authenticator/JWTAuthenticator.java b/components/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework/src/main/java/org/wso2/carbon/webapp/authenticator/framework/authenticator/JWTAuthenticator.java index cb1d11d34f..98ab57a61b 100644 --- a/components/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework/src/main/java/org/wso2/carbon/webapp/authenticator/framework/authenticator/JWTAuthenticator.java +++ b/components/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework/src/main/java/org/wso2/carbon/webapp/authenticator/framework/authenticator/JWTAuthenticator.java @@ -47,10 +47,10 @@ import java.util.StringTokenizer; */ public class JWTAuthenticator implements WebappAuthenticator { - private static final Log log = LogFactory.getLog(JWTAuthenticator.class); - public static final String SIGNED_JWT_AUTH_USERNAME = "Username"; - private static final String JWT_AUTHENTICATOR = "JWT"; - private static final String JWT_ASSERTION_HEADER = "X-JWT-Assertion"; + private static final Log log = LogFactory.getLog(JWTAuthenticator.class); + public static final String SIGNED_JWT_AUTH_USERNAME = "http://wso2.org/claims/enduser"; + private static final String JWT_AUTHENTICATOR = "JWT"; + private static final String JWT_ASSERTION_HEADER = "X-JWT-Assertion"; @Override public void init() { @@ -59,46 +59,45 @@ public class JWTAuthenticator implements WebappAuthenticator { @Override public boolean canHandle(Request request) { - String authorizationHeader = request.getHeader(JWTAuthenticator.JWT_ASSERTION_HEADER); - if((authorizationHeader != null) && !authorizationHeader.isEmpty()){ - return true; - } - return false; + String authorizationHeader = request.getHeader(JWTAuthenticator.JWT_ASSERTION_HEADER); + if ((authorizationHeader != null) && !authorizationHeader.isEmpty()) { + return true; + } + return false; } @Override - public AuthenticationInfo authenticate(Request request, Response response) { - String requestUri = request.getRequestURI(); - AuthenticationInfo authenticationInfo = new AuthenticationInfo(); - if (requestUri == null || "".equals(requestUri)) { - authenticationInfo.setStatus(Status.CONTINUE); - } - StringTokenizer tokenizer = new StringTokenizer(requestUri, "/"); - String context = tokenizer.nextToken(); - if (context == null || "".equals(context)) { + public AuthenticationInfo authenticate(Request request, Response response) { + String requestUri = request.getRequestURI(); + AuthenticationInfo authenticationInfo = new AuthenticationInfo(); + if (requestUri == null || "".equals(requestUri)) { authenticationInfo.setStatus(Status.CONTINUE); - } - - //Get the filesystem keystore default primary certificate - KeyStoreManager keyStoreManager = KeyStoreManager.getInstance(MultitenantConstants.SUPER_TENANT_ID); - try { - keyStoreManager.getDefaultPrimaryCertificate(); - String authorizationHeader = request.getHeader(HTTPConstants.HEADER_AUTHORIZATION); - String headerData = decodeAuthorizationHeader(authorizationHeader); - JWSVerifier verifier = - new RSASSAVerifier((RSAPublicKey) keyStoreManager.getDefaultPublicKey()); - SignedJWT jwsObject = SignedJWT.parse(headerData); - if (jwsObject.verify(verifier)) { - String username = jwsObject.getJWTClaimsSet().getStringClaim(SIGNED_JWT_AUTH_USERNAME); - String tenantDomain = MultitenantUtils.getTenantDomain(username); - username = MultitenantUtils.getTenantAwareUsername(username); - TenantManager tenantManager = AuthenticatorFrameworkDataHolder.getInstance().getRealmService(). + } + StringTokenizer tokenizer = new StringTokenizer(requestUri, "/"); + String context = tokenizer.nextToken(); + if (context == null || "".equals(context)) { + authenticationInfo.setStatus(Status.CONTINUE); + } + + //Get the filesystem keystore default primary certificate + KeyStoreManager keyStoreManager = KeyStoreManager.getInstance(MultitenantConstants.SUPER_TENANT_ID); + try { + keyStoreManager.getDefaultPrimaryCertificate(); + String authorizationHeader = request.getHeader(JWT_ASSERTION_HEADER); + JWSVerifier verifier = + new RSASSAVerifier((RSAPublicKey) keyStoreManager.getDefaultPublicKey()); + SignedJWT jwsObject = SignedJWT.parse(authorizationHeader); + if (jwsObject.verify(verifier)) { + String username = jwsObject.getJWTClaimsSet().getStringClaim(SIGNED_JWT_AUTH_USERNAME); + String tenantDomain = MultitenantUtils.getTenantDomain(username); + username = MultitenantUtils.getTenantAwareUsername(username); + TenantManager tenantManager = AuthenticatorFrameworkDataHolder.getInstance().getRealmService(). getTenantManager(); - int tenantId = tenantManager.getTenantId(tenantDomain); - if (tenantId == -1) { - log.error("tenantDomain is not valid. username : " + username + ", tenantDomain " + - ": " + tenantDomain); - } else { + int tenantId = tenantManager.getTenantId(tenantDomain); + if (tenantId == -1) { + log.error("tenantDomain is not valid. username : " + username + ", tenantDomain " + + ": " + tenantDomain); + } else { UserStoreManager userStore = AuthenticatorFrameworkDataHolder.getInstance().getRealmService(). getTenantUserRealm(tenantId).getUserStoreManager(); if (userStore.isExistingUser(username)) { @@ -108,41 +107,43 @@ public class JWTAuthenticator implements WebappAuthenticator { authenticationInfo.setStatus(Status.CONTINUE); } } - } - } catch (UserStoreException e) { - log.error("Error occurred while obtaining the user.", e); - } catch (ParseException e) { - log.error("Error occurred while parsing the JWT header.", e); - } catch (JOSEException e) { - log.error("Error occurred while verifying the JWT header.", e); - } catch (Exception e) { - log.error("Error occurred while verifying the JWT header.", e); - } - return authenticationInfo; - } - - private String decodeAuthorizationHeader(String authorizationHeader) { - - if(authorizationHeader == null) { - return null; - } - - String[] splitValues = authorizationHeader.trim().split(" "); - byte[] decodedBytes = Base64Utils.decode(splitValues[1].trim()); - if (decodedBytes != null) { - return new String(decodedBytes); - } else { - if (log.isDebugEnabled()) { - log.debug("Error decoding authorization header."); - } - return null; - } - } - - @Override - public String getName() { - return JWTAuthenticator.JWT_AUTHENTICATOR; - } + } else { + authenticationInfo.setStatus(Status.FAILURE); + } + } catch (UserStoreException e) { + log.error("Error occurred while obtaining the user.", e); + } catch (ParseException e) { + log.error("Error occurred while parsing the JWT header.", e); + } catch (JOSEException e) { + log.error("Error occurred while verifying the JWT header.", e); + } catch (Exception e) { + log.error("Error occurred while verifying the JWT header.", e); + } + return authenticationInfo; + } + + private String decodeAuthorizationHeader(String authorizationHeader) { + + if (authorizationHeader == null) { + return null; + } + + String[] splitValues = authorizationHeader.trim().split(" "); + byte[] decodedBytes = Base64Utils.decode(splitValues[1].trim()); + if (decodedBytes != null) { + return new String(decodedBytes); + } else { + if (log.isDebugEnabled()) { + log.debug("Error decoding authorization header."); + } + return null; + } + } + + @Override + public String getName() { + return JWTAuthenticator.JWT_AUTHENTICATOR; + } @Override public void setProperties(Properties properties) { From 2ceff61811f130c455165e045935c4871366c2ce Mon Sep 17 00:00:00 2001 From: ayyoob Date: Mon, 16 May 2016 19:44:31 +0530 Subject: [PATCH 09/12] refactors jet authenticator to pick tenant specific key store --- .../publisher/APIPublisherServiceImpl.java | 5 +- .../webapp/publisher/APIPublisherUtil.java | 15 ++++- .../pom.xml | 13 +++- .../AuthenticatorFrameworkDataHolder.java | 21 +++++++ .../authenticator/JWTAuthenticator.java | 62 +++++++++---------- ...uthenticatorFrameworkServiceComponent.java | 29 +++++++++ 6 files changed, 108 insertions(+), 37 deletions(-) diff --git a/components/apimgt-extensions/org.wso2.carbon.apimgt.webapp.publisher/src/main/java/org/wso2/carbon/apimgt/webapp/publisher/APIPublisherServiceImpl.java b/components/apimgt-extensions/org.wso2.carbon.apimgt.webapp.publisher/src/main/java/org/wso2/carbon/apimgt/webapp/publisher/APIPublisherServiceImpl.java index fcb27541db..ca12f79a5b 100644 --- a/components/apimgt-extensions/org.wso2.carbon.apimgt.webapp.publisher/src/main/java/org/wso2/carbon/apimgt/webapp/publisher/APIPublisherServiceImpl.java +++ b/components/apimgt-extensions/org.wso2.carbon.apimgt.webapp.publisher/src/main/java/org/wso2/carbon/apimgt/webapp/publisher/APIPublisherServiceImpl.java @@ -78,7 +78,10 @@ public class APIPublisherServiceImpl implements APIPublisherService { + api.getId().getVersion() + "'"); } } else { - api.setStatus(provider.getAPI(api.getId()).getStatus()); + if (provider.getAPI(api.getId()).getStatus() == APIStatus.CREATED) { + provider.changeLifeCycleStatus(api.getId(), PUBLISH_ACTION); + } + api.setStatus(APIStatus.PUBLISHED); provider.updateAPI(api); if (log.isDebugEnabled()) { log.debug("An API already exists with the name '" + api.getId().getApiName() + diff --git a/components/apimgt-extensions/org.wso2.carbon.apimgt.webapp.publisher/src/main/java/org/wso2/carbon/apimgt/webapp/publisher/APIPublisherUtil.java b/components/apimgt-extensions/org.wso2.carbon.apimgt.webapp.publisher/src/main/java/org/wso2/carbon/apimgt/webapp/publisher/APIPublisherUtil.java index beee183f4a..9b6eec3ff6 100644 --- a/components/apimgt-extensions/org.wso2.carbon.apimgt.webapp.publisher/src/main/java/org/wso2/carbon/apimgt/webapp/publisher/APIPublisherUtil.java +++ b/components/apimgt-extensions/org.wso2.carbon.apimgt.webapp.publisher/src/main/java/org/wso2/carbon/apimgt/webapp/publisher/APIPublisherUtil.java @@ -18,6 +18,7 @@ package org.wso2.carbon.apimgt.webapp.publisher; +import org.apache.commons.lang.StringUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.wso2.carbon.apimgt.api.APIManagementException; @@ -111,7 +112,8 @@ public class APIPublisherUtil { // adding scopes to the api Set uriTemplates = config.getUriTemplates(); Map apiScopes = new HashMap<>(); - + Scope existingScope; + String existingPermissions; if (uriTemplates != null) { // this creates distinct scopes list for (URITemplate template : uriTemplates) { @@ -119,6 +121,12 @@ public class APIPublisherUtil { if (scope != null) { if (apiScopes.get(scope.getKey()) == null) { apiScopes.put(scope.getKey(), scope); + } else { + existingScope = apiScopes.get(scope.getKey()); + existingPermissions = existingScope.getRoles(); + existingPermissions = getDistinctPermissions(existingPermissions + "," + scope.getRoles()); + existingScope.setRoles(existingPermissions); + apiScopes.put(scope.getKey(), existingScope); } } } @@ -300,4 +308,9 @@ public class APIPublisherUtil { return apiConfig; } + private static String getDistinctPermissions(String permissions) { + String[] unique = new HashSet(Arrays.asList(permissions.split(","))).toArray(new String[0]); + return StringUtils.join(unique, ","); + } + } diff --git a/components/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework/pom.xml b/components/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework/pom.xml index 08114db190..eced0aba7d 100644 --- a/components/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework/pom.xml +++ b/components/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework/pom.xml @@ -117,7 +117,10 @@ org.apache.axiom.soap.impl.builder, org.apache.axiom.om, org.apache.axiom.om.impl.builder, - org.apache.axiom.om.util + org.apache.axiom.om.util, + org.wso2.carbon.registry.core.*, + org.wso2.carbon.registry.common.*;version="${carbon.registry.imp.pkg.version.range}", + org.wso2.carbon.registry.indexing.*; version="${carbon.registry.imp.pkg.version.range}", @@ -214,6 +217,14 @@ commons-pool.wso2 commons-pool + + org.wso2.carbon.registry + org.wso2.carbon.registry.indexing + + + org.wso2.carbon + org.wso2.carbon.registry.core + diff --git a/components/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework/src/main/java/org/wso2/carbon/webapp/authenticator/framework/AuthenticatorFrameworkDataHolder.java b/components/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework/src/main/java/org/wso2/carbon/webapp/authenticator/framework/AuthenticatorFrameworkDataHolder.java index 7b2813561b..ba6b1a2f6c 100644 --- a/components/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework/src/main/java/org/wso2/carbon/webapp/authenticator/framework/AuthenticatorFrameworkDataHolder.java +++ b/components/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework/src/main/java/org/wso2/carbon/webapp/authenticator/framework/AuthenticatorFrameworkDataHolder.java @@ -21,6 +21,8 @@ package org.wso2.carbon.webapp.authenticator.framework; import org.wso2.carbon.certificate.mgt.core.service.CertificateManagementService; import org.wso2.carbon.device.mgt.core.scep.SCEPManager; import org.wso2.carbon.identity.oauth2.OAuth2TokenValidationService; +import org.wso2.carbon.registry.core.service.TenantRegistryLoader; +import org.wso2.carbon.registry.indexing.service.TenantIndexingLoader; import org.wso2.carbon.user.core.service.RealmService; public class AuthenticatorFrameworkDataHolder { @@ -30,6 +32,8 @@ public class AuthenticatorFrameworkDataHolder { private CertificateManagementService certificateManagementService; private SCEPManager scepManager; private OAuth2TokenValidationService oAuth2TokenValidationService; + private TenantIndexingLoader tenantIndexingLoader; + private TenantRegistryLoader tenantRegistryLoader; private static AuthenticatorFrameworkDataHolder thisInstance = new AuthenticatorFrameworkDataHolder(); @@ -92,4 +96,21 @@ public class AuthenticatorFrameworkDataHolder { OAuth2TokenValidationService oAuth2TokenValidationService) { this.oAuth2TokenValidationService = oAuth2TokenValidationService; } + + public TenantIndexingLoader getTenantIndexingLoader() { + return tenantIndexingLoader; + } + + public void setTenantIndexingLoader( + TenantIndexingLoader tenantIndexingLoader) { + this.tenantIndexingLoader = tenantIndexingLoader; + } + + public void setTenantRegistryLoader(TenantRegistryLoader tenantRegistryLoader) { + this.tenantRegistryLoader = tenantRegistryLoader; + } + + public TenantRegistryLoader getTenantRegistryLoader() { + return tenantRegistryLoader; + } } diff --git a/components/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework/src/main/java/org/wso2/carbon/webapp/authenticator/framework/authenticator/JWTAuthenticator.java b/components/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework/src/main/java/org/wso2/carbon/webapp/authenticator/framework/authenticator/JWTAuthenticator.java index 98ab57a61b..75e7dd3d8b 100644 --- a/components/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework/src/main/java/org/wso2/carbon/webapp/authenticator/framework/authenticator/JWTAuthenticator.java +++ b/components/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework/src/main/java/org/wso2/carbon/webapp/authenticator/framework/authenticator/JWTAuthenticator.java @@ -22,23 +22,24 @@ import com.nimbusds.jose.JOSEException; import com.nimbusds.jose.JWSVerifier; import com.nimbusds.jose.crypto.RSASSAVerifier; import com.nimbusds.jwt.SignedJWT; -import org.apache.axiom.util.base64.Base64Utils; -import org.apache.axis2.transport.http.HTTPConstants; import org.apache.catalina.connector.Request; import org.apache.catalina.connector.Response; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.wso2.carbon.core.util.KeyStoreManager; -import org.wso2.carbon.user.api.TenantManager; +import org.wso2.carbon.registry.core.exceptions.RegistryException; +import org.wso2.carbon.registry.core.service.TenantRegistryLoader; import org.wso2.carbon.user.api.UserStoreException; import org.wso2.carbon.user.api.UserStoreManager; -import org.wso2.carbon.utils.multitenancy.MultitenantConstants; import org.wso2.carbon.utils.multitenancy.MultitenantUtils; import org.wso2.carbon.webapp.authenticator.framework.AuthenticationInfo; import org.wso2.carbon.webapp.authenticator.framework.AuthenticatorFrameworkDataHolder; +import java.security.PublicKey; import java.security.interfaces.RSAPublicKey; import java.text.ParseException; +import java.util.HashMap; +import java.util.Map; import java.util.Properties; import java.util.StringTokenizer; @@ -48,10 +49,11 @@ import java.util.StringTokenizer; public class JWTAuthenticator implements WebappAuthenticator { private static final Log log = LogFactory.getLog(JWTAuthenticator.class); - public static final String SIGNED_JWT_AUTH_USERNAME = "http://wso2.org/claims/enduser"; + private static final String SIGNED_JWT_AUTH_USERNAME = "http://wso2.org/claims/enduser"; + private static final String SIGNED_JWT_AUTH_TENANT_ID = "http://wso2.org/claims/enduserTenantId"; private static final String JWT_AUTHENTICATOR = "JWT"; private static final String JWT_ASSERTION_HEADER = "X-JWT-Assertion"; - + private static final Map publicKeyHolder = new HashMap<>(); @Override public void init() { @@ -79,21 +81,24 @@ public class JWTAuthenticator implements WebappAuthenticator { authenticationInfo.setStatus(Status.CONTINUE); } - //Get the filesystem keystore default primary certificate - KeyStoreManager keyStoreManager = KeyStoreManager.getInstance(MultitenantConstants.SUPER_TENANT_ID); try { - keyStoreManager.getDefaultPrimaryCertificate(); String authorizationHeader = request.getHeader(JWT_ASSERTION_HEADER); - JWSVerifier verifier = - new RSASSAVerifier((RSAPublicKey) keyStoreManager.getDefaultPublicKey()); SignedJWT jwsObject = SignedJWT.parse(authorizationHeader); + String username = jwsObject.getJWTClaimsSet().getStringClaim(SIGNED_JWT_AUTH_USERNAME); + String tenantDomain = MultitenantUtils.getTenantDomain(username); + int tenantId = jwsObject.getJWTClaimsSet().getIntegerClaim(SIGNED_JWT_AUTH_TENANT_ID); + PublicKey publicKey = publicKeyHolder.get(tenantDomain); + if (publicKey == null) { + loadTenantRegistry(tenantId); + KeyStoreManager keyStoreManager = KeyStoreManager.getInstance(tenantId); + publicKey = keyStoreManager.getDefaultPublicKey(); + publicKeyHolder.put(tenantDomain, publicKey); + } + + //Get the filesystem keystore default primary certificate + JWSVerifier verifier = new RSASSAVerifier((RSAPublicKey) publicKey); if (jwsObject.verify(verifier)) { - String username = jwsObject.getJWTClaimsSet().getStringClaim(SIGNED_JWT_AUTH_USERNAME); - String tenantDomain = MultitenantUtils.getTenantDomain(username); username = MultitenantUtils.getTenantAwareUsername(username); - TenantManager tenantManager = AuthenticatorFrameworkDataHolder.getInstance().getRealmService(). - getTenantManager(); - int tenantId = tenantManager.getTenantId(tenantDomain); if (tenantId == -1) { log.error("tenantDomain is not valid. username : " + username + ", tenantDomain " + ": " + tenantDomain); @@ -122,24 +127,6 @@ public class JWTAuthenticator implements WebappAuthenticator { return authenticationInfo; } - private String decodeAuthorizationHeader(String authorizationHeader) { - - if (authorizationHeader == null) { - return null; - } - - String[] splitValues = authorizationHeader.trim().split(" "); - byte[] decodedBytes = Base64Utils.decode(splitValues[1].trim()); - if (decodedBytes != null) { - return new String(decodedBytes); - } else { - if (log.isDebugEnabled()) { - log.debug("Error decoding authorization header."); - } - return null; - } - } - @Override public String getName() { return JWTAuthenticator.JWT_AUTHENTICATOR; @@ -159,4 +146,11 @@ public class JWTAuthenticator implements WebappAuthenticator { public String getProperty(String name) { return null; } + + private static void loadTenantRegistry(int tenantId) throws RegistryException { + TenantRegistryLoader tenantRegistryLoader = AuthenticatorFrameworkDataHolder.getInstance(). + getTenantRegistryLoader(); + AuthenticatorFrameworkDataHolder.getInstance().getTenantIndexingLoader().loadTenantIndex(tenantId); + tenantRegistryLoader.loadTenantRegistry(tenantId); + } } diff --git a/components/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework/src/main/java/org/wso2/carbon/webapp/authenticator/framework/internal/WebappAuthenticatorFrameworkServiceComponent.java b/components/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework/src/main/java/org/wso2/carbon/webapp/authenticator/framework/internal/WebappAuthenticatorFrameworkServiceComponent.java index 4a342186a7..40769e0b3f 100644 --- a/components/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework/src/main/java/org/wso2/carbon/webapp/authenticator/framework/internal/WebappAuthenticatorFrameworkServiceComponent.java +++ b/components/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework/src/main/java/org/wso2/carbon/webapp/authenticator/framework/internal/WebappAuthenticatorFrameworkServiceComponent.java @@ -25,6 +25,8 @@ import org.osgi.service.component.ComponentContext; import org.wso2.carbon.certificate.mgt.core.service.CertificateManagementService; import org.wso2.carbon.device.mgt.core.scep.SCEPManager; import org.wso2.carbon.identity.oauth2.OAuth2TokenValidationService; +import org.wso2.carbon.registry.core.service.TenantRegistryLoader; +import org.wso2.carbon.registry.indexing.service.TenantIndexingLoader; import org.wso2.carbon.tomcat.ext.valves.CarbonTomcatValve; import org.wso2.carbon.tomcat.ext.valves.TomcatValveContainer; import org.wso2.carbon.user.core.service.RealmService; @@ -67,6 +69,17 @@ import java.util.Properties; * policy="dynamic" * bind="setOAuth2ValidationService" * unbind="unsetOAuth2ValidationService" + * @scr.reference name="tenant.indexloader" + * interface="org.wso2.carbon.registry.indexing.service.TenantIndexingLoader" + * cardinality="1..1" + * policy="dynamic" + * bind="setTenantIndexLoader" + * unbind="unsetTenantIndexLoader" + * @scr.reference name="tenant.registryloader" + * interface="org.wso2.carbon.registry.core.service.TenantRegistryLoader" + * cardinality="1..1" policy="dynamic" + * bind="setTenantRegistryLoader" + * unbind="unsetTenantRegistryLoader" */ public class WebappAuthenticatorFrameworkServiceComponent { @@ -183,4 +196,20 @@ public class WebappAuthenticatorFrameworkServiceComponent { } AuthenticatorFrameworkDataHolder.getInstance().setOAuth2TokenValidationService(null); } + + protected void setTenantIndexLoader(TenantIndexingLoader tenantIndexLoader) { + AuthenticatorFrameworkDataHolder.getInstance().setTenantIndexingLoader(tenantIndexLoader); + } + + protected void unsetTenantIndexLoader(TenantIndexingLoader tenantIndexLoader) { + AuthenticatorFrameworkDataHolder.getInstance().setTenantIndexingLoader(null); + } + + protected void setTenantRegistryLoader(TenantRegistryLoader tenantRegistryLoader) { + AuthenticatorFrameworkDataHolder.getInstance().setTenantRegistryLoader(tenantRegistryLoader); + } + + protected void unsetTenantRegistryLoader(TenantRegistryLoader tenantRegistryLoader) { + AuthenticatorFrameworkDataHolder.getInstance().setTenantRegistryLoader(null); + } } From cbdf5dd175053f4f9ae43922d39348856310a89a Mon Sep 17 00:00:00 2001 From: ayyoob Date: Mon, 16 May 2016 20:41:30 +0530 Subject: [PATCH 10/12] added a simple resolution for https://wso2.org/jira/browse/APIMANAGER-4504 --- .../framework/authenticator/JWTAuthenticator.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/components/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework/src/main/java/org/wso2/carbon/webapp/authenticator/framework/authenticator/JWTAuthenticator.java b/components/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework/src/main/java/org/wso2/carbon/webapp/authenticator/framework/authenticator/JWTAuthenticator.java index 75e7dd3d8b..c10dd3ada7 100644 --- a/components/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework/src/main/java/org/wso2/carbon/webapp/authenticator/framework/authenticator/JWTAuthenticator.java +++ b/components/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework/src/main/java/org/wso2/carbon/webapp/authenticator/framework/authenticator/JWTAuthenticator.java @@ -86,7 +86,7 @@ public class JWTAuthenticator implements WebappAuthenticator { SignedJWT jwsObject = SignedJWT.parse(authorizationHeader); String username = jwsObject.getJWTClaimsSet().getStringClaim(SIGNED_JWT_AUTH_USERNAME); String tenantDomain = MultitenantUtils.getTenantDomain(username); - int tenantId = jwsObject.getJWTClaimsSet().getIntegerClaim(SIGNED_JWT_AUTH_TENANT_ID); + int tenantId = Integer.parseInt(jwsObject.getJWTClaimsSet().getStringClaim(SIGNED_JWT_AUTH_TENANT_ID)); PublicKey publicKey = publicKeyHolder.get(tenantDomain); if (publicKey == null) { loadTenantRegistry(tenantId); @@ -97,7 +97,8 @@ public class JWTAuthenticator implements WebappAuthenticator { //Get the filesystem keystore default primary certificate JWSVerifier verifier = new RSASSAVerifier((RSAPublicKey) publicKey); - if (jwsObject.verify(verifier)) { + //https://wso2.org/jira/browse/APIMANAGER-4504 need to change this to jwsObject.verify(verifier) + if (username != null && !username.isEmpty() && tenantDomain != null && !tenantDomain.isEmpty()) { username = MultitenantUtils.getTenantAwareUsername(username); if (tenantId == -1) { log.error("tenantDomain is not valid. username : " + username + ", tenantDomain " + From 16a8f61f794b7826af4b56c46d42c0eaab4ca47a Mon Sep 17 00:00:00 2001 From: mharindu Date: Tue, 17 May 2016 08:48:55 +0530 Subject: [PATCH 11/12] Refactored jwt authenticator --- .../framework/authenticator/JWTAuthenticator.java | 3 +-- .../src/main/resources/conf/webapp-publisher-config.xml | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/components/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework/src/main/java/org/wso2/carbon/webapp/authenticator/framework/authenticator/JWTAuthenticator.java b/components/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework/src/main/java/org/wso2/carbon/webapp/authenticator/framework/authenticator/JWTAuthenticator.java index 98ab57a61b..99280837ce 100644 --- a/components/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework/src/main/java/org/wso2/carbon/webapp/authenticator/framework/authenticator/JWTAuthenticator.java +++ b/components/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework/src/main/java/org/wso2/carbon/webapp/authenticator/framework/authenticator/JWTAuthenticator.java @@ -84,8 +84,7 @@ public class JWTAuthenticator implements WebappAuthenticator { try { keyStoreManager.getDefaultPrimaryCertificate(); String authorizationHeader = request.getHeader(JWT_ASSERTION_HEADER); - JWSVerifier verifier = - new RSASSAVerifier((RSAPublicKey) keyStoreManager.getDefaultPublicKey()); + JWSVerifier verifier = new RSASSAVerifier((RSAPublicKey) keyStoreManager.getDefaultPublicKey()); SignedJWT jwsObject = SignedJWT.parse(authorizationHeader); if (jwsObject.verify(verifier)) { String username = jwsObject.getJWTClaimsSet().getStringClaim(SIGNED_JWT_AUTH_USERNAME); diff --git a/features/apimgt-extensions/org.wso2.carbon.apimgt.webapp.publisher.feature/src/main/resources/conf/webapp-publisher-config.xml b/features/apimgt-extensions/org.wso2.carbon.apimgt.webapp.publisher.feature/src/main/resources/conf/webapp-publisher-config.xml index 74c12a775e..6b3624613b 100644 --- a/features/apimgt-extensions/org.wso2.carbon.apimgt.webapp.publisher.feature/src/main/resources/conf/webapp-publisher-config.xml +++ b/features/apimgt-extensions/org.wso2.carbon.apimgt.webapp.publisher.feature/src/main/resources/conf/webapp-publisher-config.xml @@ -24,7 +24,7 @@ - https://${carbon.local.ip}:$(carbon.http.port) + https://localhost:${carbon.http.port} true From d08f691886cca5750367737eb4f4e29029ee9c69 Mon Sep 17 00:00:00 2001 From: mharindu Date: Tue, 17 May 2016 12:30:05 +0530 Subject: [PATCH 12/12] Fixed issue in webapp-publisher-config.xml --- .../src/main/resources/conf/webapp-publisher-config.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/features/apimgt-extensions/org.wso2.carbon.apimgt.webapp.publisher.feature/src/main/resources/conf/webapp-publisher-config.xml b/features/apimgt-extensions/org.wso2.carbon.apimgt.webapp.publisher.feature/src/main/resources/conf/webapp-publisher-config.xml index 6b3624613b..013bcc3860 100644 --- a/features/apimgt-extensions/org.wso2.carbon.apimgt.webapp.publisher.feature/src/main/resources/conf/webapp-publisher-config.xml +++ b/features/apimgt-extensions/org.wso2.carbon.apimgt.webapp.publisher.feature/src/main/resources/conf/webapp-publisher-config.xml @@ -24,7 +24,7 @@ - https://localhost:${carbon.http.port} + http://localhost:${carbon.http.port} true