From 22f4a9e2af934c3ad9b0182bad7a8fc60f262882 Mon Sep 17 00:00:00 2001 From: ayyoob Date: Thu, 21 Jul 2016 20:40:32 +0530 Subject: [PATCH] added mqtt and web socket authorisation --- .../pom.xml | 15 ---- .../java/SuperTenantSubscriptionEndpoint.java | 29 +++--- .../main/java/TenantSubscriptionEndpoint.java | 28 +++--- .../src/main/java/util/ServiceHolder.java | 16 ++++ .../pom.xml | 12 +++ .../iot/output/adapter/ui/UIEventAdapter.java | 22 ++--- ...UIOutputCallbackControllerServiceImpl.java | 25 +++--- .../authentication}/AuthenticationInfo.java | 18 +++- .../ui/authentication/Authenticator.java | 30 +++++++ .../ui/authentication/OAuthAuthenticator.java | 26 ++++++ .../oauth/OAuthTokenValdiator.java | 30 ++++--- .../oauth/OAuthTokenValidaterStubFactory.java | 16 ++-- .../OAuthTokenValidationException.java | 2 +- .../adapter/ui/authorization/Authorizer.java | 35 ++++++++ .../ui/authorization/DeviceAuthorizer.java | 51 +++++++++++ .../adapter/ui/config/Authenticator.java | 90 +++++++++++++++++++ .../output/adapter/ui/config/Authorizer.java | 90 +++++++++++++++++++ .../output/adapter/ui/config/Properties.java | 69 ++++++++++++++ .../output/adapter/ui/config/Property.java | 87 ++++++++++++++++++ .../adapter/ui/config/WebsocketConfig.java | 57 ++++++++++++ .../ui/config/WebsocketValidationConfigs.java | 90 +++++++++++++++++++ ...alidationConfigurationFailedException.java | 44 +++++++++ .../ui/constants/WebsocketConstants.java | 36 ++++++++ .../UILocalEventAdapterServiceComponent.java | 32 +++++++ .../service/WebsocketValidationService.java | 15 ++++ .../WebsocketValidationServiceImpl.java | 30 +++++++ ...Util.java => WebSocketSessionRequest.java} | 10 +-- .../adapter/ui/util/WebsocketUtils.java | 45 ++++++++++ .../impl/RaspberrypiManagerService.java | 21 ++++- .../src/main/resources/p2.inf | 2 +- .../resources/websocket-validation.properties | 25 ------ .../main/resources/websocket-validation.xml | 39 ++++++++ 32 files changed, 1021 insertions(+), 116 deletions(-) rename components/iot-plugins/iot-base-plugin/{org.wso2.carbon.device.mgt.iot.output.adapter.ui.endpoint/src/main/java/util => org.wso2.carbon.device.mgt.iot.output.adapter.ui/src/main/java/org/wso2/carbon/device/mgt/iot/output/adapter/ui/authentication}/AuthenticationInfo.java (79%) create mode 100644 components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.output.adapter.ui/src/main/java/org/wso2/carbon/device/mgt/iot/output/adapter/ui/authentication/Authenticator.java create mode 100644 components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.output.adapter.ui/src/main/java/org/wso2/carbon/device/mgt/iot/output/adapter/ui/authentication/OAuthAuthenticator.java rename components/iot-plugins/iot-base-plugin/{org.wso2.carbon.device.mgt.iot.output.adapter.ui.endpoint/src/main/java => org.wso2.carbon.device.mgt.iot.output.adapter.ui/src/main/java/org/wso2/carbon/device/mgt/iot/output/adapter/ui/authentication}/oauth/OAuthTokenValdiator.java (86%) rename components/iot-plugins/iot-base-plugin/{org.wso2.carbon.device.mgt.iot.output.adapter.ui.endpoint/src/main/java => org.wso2.carbon.device.mgt.iot.output.adapter.ui/src/main/java/org/wso2/carbon/device/mgt/iot/output/adapter/ui/authentication}/oauth/OAuthTokenValidaterStubFactory.java (91%) rename components/iot-plugins/iot-base-plugin/{org.wso2.carbon.device.mgt.iot.output.adapter.ui.endpoint/src/main/java => org.wso2.carbon.device.mgt.iot.output.adapter.ui/src/main/java/org/wso2/carbon/device/mgt/iot/output/adapter/ui/authentication}/oauth/exception/OAuthTokenValidationException.java (94%) create mode 100644 components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.output.adapter.ui/src/main/java/org/wso2/carbon/device/mgt/iot/output/adapter/ui/authorization/Authorizer.java create mode 100644 components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.output.adapter.ui/src/main/java/org/wso2/carbon/device/mgt/iot/output/adapter/ui/authorization/DeviceAuthorizer.java create mode 100644 components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.output.adapter.ui/src/main/java/org/wso2/carbon/device/mgt/iot/output/adapter/ui/config/Authenticator.java create mode 100644 components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.output.adapter.ui/src/main/java/org/wso2/carbon/device/mgt/iot/output/adapter/ui/config/Authorizer.java create mode 100644 components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.output.adapter.ui/src/main/java/org/wso2/carbon/device/mgt/iot/output/adapter/ui/config/Properties.java create mode 100644 components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.output.adapter.ui/src/main/java/org/wso2/carbon/device/mgt/iot/output/adapter/ui/config/Property.java create mode 100644 components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.output.adapter.ui/src/main/java/org/wso2/carbon/device/mgt/iot/output/adapter/ui/config/WebsocketConfig.java create mode 100644 components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.output.adapter.ui/src/main/java/org/wso2/carbon/device/mgt/iot/output/adapter/ui/config/WebsocketValidationConfigs.java create mode 100644 components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.output.adapter.ui/src/main/java/org/wso2/carbon/device/mgt/iot/output/adapter/ui/config/WebsocketValidationConfigurationFailedException.java create mode 100644 components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.output.adapter.ui/src/main/java/org/wso2/carbon/device/mgt/iot/output/adapter/ui/constants/WebsocketConstants.java create mode 100644 components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.output.adapter.ui/src/main/java/org/wso2/carbon/device/mgt/iot/output/adapter/ui/service/WebsocketValidationService.java create mode 100644 components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.output.adapter.ui/src/main/java/org/wso2/carbon/device/mgt/iot/output/adapter/ui/service/WebsocketValidationServiceImpl.java rename components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.output.adapter.ui/src/main/java/org/wso2/carbon/device/mgt/iot/output/adapter/ui/util/{WebSocketSessionUtil.java => WebSocketSessionRequest.java} (94%) create mode 100644 components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.output.adapter.ui/src/main/java/org/wso2/carbon/device/mgt/iot/output/adapter/ui/util/WebsocketUtils.java delete mode 100644 features/iot-plugins-feature/iot-base-plugin-feature/org.wso2.carbon.device.mgt.iot.adapter.feature/src/main/resources/websocket-validation.properties create mode 100644 features/iot-plugins-feature/iot-base-plugin-feature/org.wso2.carbon.device.mgt.iot.adapter.feature/src/main/resources/websocket-validation.xml diff --git a/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.output.adapter.ui.endpoint/pom.xml b/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.output.adapter.ui.endpoint/pom.xml index 449706e39..10afa3e7c 100644 --- a/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.output.adapter.ui.endpoint/pom.xml +++ b/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.output.adapter.ui.endpoint/pom.xml @@ -55,21 +55,6 @@ org.apache.cxf cxf-rt-frontend-jaxrs - - org.apache.httpcomponents.wso2 - httpcore - provided - - - org.wso2.orbit.org.apache.httpcomponents - httpclient - provided - - - org.wso2.carbon.identity - org.wso2.carbon.identity.oauth.stub - provided - diff --git a/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.output.adapter.ui.endpoint/src/main/java/SuperTenantSubscriptionEndpoint.java b/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.output.adapter.ui.endpoint/src/main/java/SuperTenantSubscriptionEndpoint.java index 546473cd3..f2556ca95 100644 --- a/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.output.adapter.ui.endpoint/src/main/java/SuperTenantSubscriptionEndpoint.java +++ b/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.output.adapter.ui.endpoint/src/main/java/SuperTenantSubscriptionEndpoint.java @@ -16,13 +16,14 @@ * under the License. */ -import oauth.OAuthTokenValdiator; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.wso2.carbon.context.PrivilegedCarbonContext; +import org.wso2.carbon.device.mgt.iot.output.adapter.ui.authentication.AuthenticationInfo; +import org.wso2.carbon.device.mgt.iot.output.adapter.ui.authentication.Authenticator; +import org.wso2.carbon.device.mgt.iot.output.adapter.ui.authorization.Authorizer; import util.ServiceHolder; import org.wso2.carbon.utils.multitenancy.MultitenantConstants; -import util.AuthenticationInfo; import javax.websocket.CloseReason; import javax.websocket.OnClose; @@ -56,16 +57,22 @@ public class SuperTenantSubscriptionEndpoint extends SubscriptionEndpoint { if (log.isDebugEnabled()) { log.debug("WebSocket opened, for Session id: " + session.getId() + ", for the Stream:" + streamName); } - AuthenticationInfo authenticationInfo = OAuthTokenValdiator.getInstance().validateToken(session); - //TODO Authorization + Authenticator authenticator = ServiceHolder.getWebsocketValidationService().getAuthenticator(); + AuthenticationInfo authenticationInfo = authenticator.isAutenticated(session); if (authenticationInfo != null && authenticationInfo.isAuthenticated()) { - try { - PrivilegedCarbonContext.startTenantFlow(); - PrivilegedCarbonContext.getThreadLocalCarbonContext().setTenantId(MultitenantConstants.SUPER_TENANT_ID); - ServiceHolder.getInstance().getUiOutputCallbackControllerService().subscribeWebsocket(streamName, - version, session); - } finally { - PrivilegedCarbonContext.endTenantFlow(); + Authorizer authorizer = ServiceHolder.getWebsocketValidationService().getAuthorizer(); + boolean isAuthorized = authorizer.isAuthorized(authenticationInfo, session, streamName); + if (isAuthorized) { + try { + PrivilegedCarbonContext.startTenantFlow(); + PrivilegedCarbonContext.getThreadLocalCarbonContext().setTenantId( + MultitenantConstants.SUPER_TENANT_ID); + ServiceHolder.getInstance().getUiOutputCallbackControllerService().subscribeWebsocket(streamName, + version, + session); + } finally { + PrivilegedCarbonContext.endTenantFlow(); + } } } else { try { diff --git a/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.output.adapter.ui.endpoint/src/main/java/TenantSubscriptionEndpoint.java b/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.output.adapter.ui.endpoint/src/main/java/TenantSubscriptionEndpoint.java index 837e75f00..a4ca1da4b 100644 --- a/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.output.adapter.ui.endpoint/src/main/java/TenantSubscriptionEndpoint.java +++ b/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.output.adapter.ui.endpoint/src/main/java/TenantSubscriptionEndpoint.java @@ -16,12 +16,13 @@ * under the License. */ -import oauth.OAuthTokenValdiator; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.wso2.carbon.context.PrivilegedCarbonContext; +import org.wso2.carbon.device.mgt.iot.output.adapter.ui.authentication.AuthenticationInfo; +import org.wso2.carbon.device.mgt.iot.output.adapter.ui.authentication.Authenticator; +import org.wso2.carbon.device.mgt.iot.output.adapter.ui.authorization.Authorizer; import util.ServiceHolder; -import util.AuthenticationInfo; import javax.websocket.CloseReason; import javax.websocket.OnClose; @@ -56,16 +57,21 @@ public class TenantSubscriptionEndpoint extends SubscriptionEndpoint { if (log.isDebugEnabled()) { log.debug("WebSocket opened, for Session id: "+session.getId()+", for the Stream:"+streamName); } - AuthenticationInfo authenticationInfo = OAuthTokenValdiator.getInstance().validateToken(session); - //TODO Authorization + Authenticator authenticator = ServiceHolder.getWebsocketValidationService().getAuthenticator(); + AuthenticationInfo authenticationInfo = authenticator.isAutenticated(session); if (authenticationInfo != null && authenticationInfo.isAuthenticated()) { - try { - PrivilegedCarbonContext.startTenantFlow(); - PrivilegedCarbonContext.getThreadLocalCarbonContext().setTenantDomain(tdomain, true); - ServiceHolder.getInstance().getUiOutputCallbackControllerService().subscribeWebsocket(streamName, - version, session); - } finally { - PrivilegedCarbonContext.endTenantFlow(); + Authorizer authorizer = ServiceHolder.getWebsocketValidationService().getAuthorizer(); + boolean isAuthorized = authorizer.isAuthorized(authenticationInfo, session, streamName); + if (isAuthorized) { + try { + PrivilegedCarbonContext.startTenantFlow(); + PrivilegedCarbonContext.getThreadLocalCarbonContext().setTenantDomain(tdomain, true); + ServiceHolder.getInstance().getUiOutputCallbackControllerService().subscribeWebsocket(streamName, + version, + session); + } finally { + PrivilegedCarbonContext.endTenantFlow(); + } } } else { try { diff --git a/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.output.adapter.ui.endpoint/src/main/java/util/ServiceHolder.java b/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.output.adapter.ui.endpoint/src/main/java/util/ServiceHolder.java index 1f35b27d0..0f6d81df5 100644 --- a/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.output.adapter.ui.endpoint/src/main/java/util/ServiceHolder.java +++ b/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.output.adapter.ui.endpoint/src/main/java/util/ServiceHolder.java @@ -1,13 +1,17 @@ package util; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; import org.wso2.carbon.context.PrivilegedCarbonContext; import org.wso2.carbon.device.mgt.iot.output.adapter.ui.UIOutputCallbackControllerService; +import org.wso2.carbon.device.mgt.iot.output.adapter.ui.service.WebsocketValidationService; public class ServiceHolder { private static ServiceHolder instance; private UIOutputCallbackControllerService uiOutputCallbackControllerService; + private static final Log log = LogFactory.getLog(ServiceHolder.class); private ServiceHolder(){ uiOutputCallbackControllerService = (UIOutputCallbackControllerService) PrivilegedCarbonContext @@ -24,4 +28,16 @@ public class ServiceHolder { public UIOutputCallbackControllerService getUiOutputCallbackControllerService() { return uiOutputCallbackControllerService; } + + public static WebsocketValidationService getWebsocketValidationService() { + PrivilegedCarbonContext ctx = PrivilegedCarbonContext.getThreadLocalCarbonContext(); + WebsocketValidationService deviceManagementProviderService = + (WebsocketValidationService) ctx.getOSGiService(WebsocketValidationService.class, null); + if (deviceManagementProviderService == null) { + String msg = "Websocket Validation service has not initialized."; + log.error(msg); + throw new IllegalStateException(msg); + } + return deviceManagementProviderService; + } } diff --git a/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.output.adapter.ui/pom.xml b/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.output.adapter.ui/pom.xml index 0739a96d4..69181134b 100644 --- a/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.output.adapter.ui/pom.xml +++ b/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.output.adapter.ui/pom.xml @@ -63,6 +63,18 @@ org.wso2.carbon.analytics-common org.wso2.carbon.event.stream.core + + org.apache.httpcomponents.wso2 + httpcore + + + org.wso2.orbit.org.apache.httpcomponents + httpclient + + + org.wso2.carbon.identity + org.wso2.carbon.identity.oauth.stub + diff --git a/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.output.adapter.ui/src/main/java/org/wso2/carbon/device/mgt/iot/output/adapter/ui/UIEventAdapter.java b/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.output.adapter.ui/src/main/java/org/wso2/carbon/device/mgt/iot/output/adapter/ui/UIEventAdapter.java index 4f2898795..d92bc406f 100644 --- a/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.output.adapter.ui/src/main/java/org/wso2/carbon/device/mgt/iot/output/adapter/ui/UIEventAdapter.java +++ b/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.output.adapter.ui/src/main/java/org/wso2/carbon/device/mgt/iot/output/adapter/ui/UIEventAdapter.java @@ -34,7 +34,7 @@ import org.wso2.carbon.event.output.adapter.core.OutputEventAdapterConfiguration import org.wso2.carbon.event.output.adapter.core.exception.OutputEventAdapterException; import org.wso2.carbon.event.output.adapter.core.exception.OutputEventAdapterRuntimeException; import org.wso2.carbon.event.output.adapter.core.exception.TestConnectionNotSupportedException; -import org.wso2.carbon.device.mgt.iot.output.adapter.ui.util.WebSocketSessionUtil; +import org.wso2.carbon.device.mgt.iot.output.adapter.ui.util.WebSocketSessionRequest; import org.wso2.carbon.event.stream.core.EventStreamService; import org.wso2.carbon.event.stream.core.exception.EventStreamConfigurationException; @@ -257,7 +257,7 @@ public class UIEventAdapter implements OutputEventAdapter { streamSpecificEvents.add(eventValues); // fetch all valid sessions checked against any queryParameters provided when subscribing. - CopyOnWriteArrayList validSessions = getValidSessions(event); + CopyOnWriteArrayList validSessions = getValidSessions(event); try { executorService.execute(new WebSocketSender(validSessions, eventString)); @@ -331,15 +331,15 @@ public class UIEventAdapter implements OutputEventAdapter { * @param event the current event received and that which needs to be published to subscribed sessions. * @return a list of all validated web-socket sessions against the queryString values. */ - private CopyOnWriteArrayList getValidSessions(Event event) { - CopyOnWriteArrayList validSessions = new CopyOnWriteArrayList<>(); + private CopyOnWriteArrayList getValidSessions(Event event) { + CopyOnWriteArrayList validSessions = new CopyOnWriteArrayList<>(); UIOutputCallbackControllerServiceImpl uiOutputCallbackControllerServiceImpl = UIEventAdaptorServiceDataHolder.getUIOutputCallbackRegisterServiceImpl(); // get all subscribed web-socket sessions. - CopyOnWriteArrayList webSocketSessionUtils = + CopyOnWriteArrayList webSocketSessionUtils = uiOutputCallbackControllerServiceImpl.getSessions(tenantId, streamId); if (webSocketSessionUtils != null) { - for (WebSocketSessionUtil webSocketSessionUtil : webSocketSessionUtils) { + for (WebSocketSessionRequest webSocketSessionUtil : webSocketSessionUtils) { boolean isValidSession = validateEventAgainstSessionFilters(event, webSocketSessionUtil); if (isValidSession) { validSessions.add(webSocketSessionUtil); @@ -360,7 +360,7 @@ public class UIEventAdapter implements OutputEventAdapter { * @param webSocketSessionUtil the session which needs validated for its authenticity to receive this event. * @return "true" if the session is valid to receive the event else "false". */ - private boolean validateEventAgainstSessionFilters(Event event, WebSocketSessionUtil webSocketSessionUtil) { + private boolean validateEventAgainstSessionFilters(Event event, WebSocketSessionRequest webSocketSessionUtil) { // fetch the queryString Key:Value pair map of the given session. Map queryParamValuePairs = webSocketSessionUtil.getQueryParamValuePairs(); @@ -412,9 +412,9 @@ public class UIEventAdapter implements OutputEventAdapter { private class WebSocketSender implements Runnable { private String message; - private CopyOnWriteArrayList webSocketSessionUtils; + private CopyOnWriteArrayList webSocketSessionUtils; - public WebSocketSender(CopyOnWriteArrayList webSocketSessionUtils, String message) { + public WebSocketSender(CopyOnWriteArrayList webSocketSessionUtils, String message) { this.webSocketSessionUtils = webSocketSessionUtils; this.message = message; } @@ -434,8 +434,8 @@ public class UIEventAdapter implements OutputEventAdapter { public void run() { if (webSocketSessionUtils != null) { doLogDroppedMessage = true; - for (WebSocketSessionUtil webSocketSessionUtil : webSocketSessionUtils) { - synchronized (WebSocketSessionUtil.class) { + for (WebSocketSessionRequest webSocketSessionUtil : webSocketSessionUtils) { + synchronized (WebSocketSessionRequest.class) { try { webSocketSessionUtil.getSession().getBasicRemote().sendText(message); } catch (IOException e) { diff --git a/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.output.adapter.ui/src/main/java/org/wso2/carbon/device/mgt/iot/output/adapter/ui/UIOutputCallbackControllerServiceImpl.java b/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.output.adapter.ui/src/main/java/org/wso2/carbon/device/mgt/iot/output/adapter/ui/UIOutputCallbackControllerServiceImpl.java index 0c9602033..382af8655 100644 --- a/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.output.adapter.ui/src/main/java/org/wso2/carbon/device/mgt/iot/output/adapter/ui/UIOutputCallbackControllerServiceImpl.java +++ b/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.output.adapter.ui/src/main/java/org/wso2/carbon/device/mgt/iot/output/adapter/ui/UIOutputCallbackControllerServiceImpl.java @@ -19,10 +19,9 @@ */ package org.wso2.carbon.device.mgt.iot.output.adapter.ui; -import com.google.gson.JsonObject; import org.wso2.carbon.context.PrivilegedCarbonContext; import org.wso2.carbon.device.mgt.iot.output.adapter.ui.internal.UIEventAdaptorServiceDataHolder; -import org.wso2.carbon.device.mgt.iot.output.adapter.ui.util.WebSocketSessionUtil; +import org.wso2.carbon.device.mgt.iot.output.adapter.ui.util.WebSocketSessionRequest; import org.wso2.carbon.device.mgt.iot.output.adapter.ui.util.UIEventAdapterConstants; import javax.websocket.Session; @@ -36,7 +35,7 @@ import java.util.concurrent.LinkedBlockingDeque; */ public class UIOutputCallbackControllerServiceImpl implements UIOutputCallbackControllerService { - private ConcurrentHashMap>> + private ConcurrentHashMap>> outputEventAdaptorSessionMap; public UIOutputCallbackControllerServiceImpl() { @@ -58,7 +57,7 @@ public class UIOutputCallbackControllerServiceImpl implements UIOutputCallbackCo version = UIEventAdapterConstants.ADAPTER_UI_DEFAULT_OUTPUT_STREAM_VERSION; } String streamId = streamName + UIEventAdapterConstants.ADAPTER_UI_COLON + version; - ConcurrentHashMap> tenantSpecificAdaptorMap = + ConcurrentHashMap> tenantSpecificAdaptorMap = outputEventAdaptorSessionMap.get(tenantId); if (tenantSpecificAdaptorMap == null) { tenantSpecificAdaptorMap = new ConcurrentHashMap<>(); @@ -66,7 +65,7 @@ public class UIOutputCallbackControllerServiceImpl implements UIOutputCallbackCo tenantSpecificAdaptorMap = outputEventAdaptorSessionMap.get(tenantId); } } - CopyOnWriteArrayList adapterSpecificSessions = tenantSpecificAdaptorMap.get(streamId); + CopyOnWriteArrayList adapterSpecificSessions = tenantSpecificAdaptorMap.get(streamId); if (adapterSpecificSessions == null) { adapterSpecificSessions = new CopyOnWriteArrayList<>(); if (null != tenantSpecificAdaptorMap.putIfAbsent(streamId, adapterSpecificSessions)) { @@ -74,7 +73,7 @@ public class UIOutputCallbackControllerServiceImpl implements UIOutputCallbackCo } } - WebSocketSessionUtil webSocketSessionUtil = new WebSocketSessionUtil(session); + WebSocketSessionRequest webSocketSessionUtil = new WebSocketSessionRequest(session); adapterSpecificSessions.add(webSocketSessionUtil); } @@ -85,8 +84,8 @@ public class UIOutputCallbackControllerServiceImpl implements UIOutputCallbackCo * @param streamId - Stream name and version which user register to. * @return the sessions list. */ - public CopyOnWriteArrayList getSessions(int tenantId, String streamId) { - ConcurrentHashMap> tenantSpecificAdaptorMap + public CopyOnWriteArrayList getSessions(int tenantId, String streamId) { + ConcurrentHashMap> tenantSpecificAdaptorMap = outputEventAdaptorSessionMap.get(tenantId); if (tenantSpecificAdaptorMap != null) { return tenantSpecificAdaptorMap.get(streamId); @@ -125,15 +124,15 @@ public class UIOutputCallbackControllerServiceImpl implements UIOutputCallbackCo version = UIEventAdapterConstants.ADAPTER_UI_DEFAULT_OUTPUT_STREAM_VERSION; } String id = streamName + UIEventAdapterConstants.ADAPTER_UI_COLON + version; - ConcurrentHashMap> tenantSpecificAdaptorMap + ConcurrentHashMap> tenantSpecificAdaptorMap = outputEventAdaptorSessionMap.get(tenantId); if (tenantSpecificAdaptorMap != null) { - CopyOnWriteArrayList adapterSpecificSessions = tenantSpecificAdaptorMap.get(id); + CopyOnWriteArrayList adapterSpecificSessions = tenantSpecificAdaptorMap.get(id); if (adapterSpecificSessions != null) { - WebSocketSessionUtil sessionToRemove = null; - Iterator iterator = adapterSpecificSessions.iterator(); + WebSocketSessionRequest sessionToRemove = null; + Iterator iterator = adapterSpecificSessions.iterator(); while (iterator.hasNext()) { - WebSocketSessionUtil webSocketSessionUtil = iterator.next(); + WebSocketSessionRequest webSocketSessionUtil = iterator.next(); if (session.getId().equals(webSocketSessionUtil.getSession().getId())) { sessionToRemove = webSocketSessionUtil; break; diff --git a/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.output.adapter.ui.endpoint/src/main/java/util/AuthenticationInfo.java b/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.output.adapter.ui/src/main/java/org/wso2/carbon/device/mgt/iot/output/adapter/ui/authentication/AuthenticationInfo.java similarity index 79% rename from components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.output.adapter.ui.endpoint/src/main/java/util/AuthenticationInfo.java rename to components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.output.adapter.ui/src/main/java/org/wso2/carbon/device/mgt/iot/output/adapter/ui/authentication/AuthenticationInfo.java index 4e2115cf0..b533c9225 100644 --- a/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.output.adapter.ui.endpoint/src/main/java/util/AuthenticationInfo.java +++ b/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.output.adapter.ui/src/main/java/org/wso2/carbon/device/mgt/iot/output/adapter/ui/authentication/AuthenticationInfo.java @@ -12,7 +12,9 @@ * */ -package util; +package org.wso2.carbon.device.mgt.iot.output.adapter.ui.authentication; + +import java.util.Map; /** * This is returned after authentication. @@ -25,6 +27,12 @@ public class AuthenticationInfo { private boolean authenticated; private String username; private String tenantDomain; + + /** + * To hold authentication related properties eg: scopes in oauth + */ + private Map properties; + /** * returns whether the client is authenticated */ @@ -57,4 +65,12 @@ public class AuthenticationInfo { public void setTenantDomain(String tenantDomain) { this.tenantDomain = tenantDomain; } + + public Map getProperties() { + return properties; + } + + public void setProperties(Map properties) { + this.properties = properties; + } } diff --git a/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.output.adapter.ui/src/main/java/org/wso2/carbon/device/mgt/iot/output/adapter/ui/authentication/Authenticator.java b/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.output.adapter.ui/src/main/java/org/wso2/carbon/device/mgt/iot/output/adapter/ui/authentication/Authenticator.java new file mode 100644 index 000000000..56af71cb8 --- /dev/null +++ b/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.output.adapter.ui/src/main/java/org/wso2/carbon/device/mgt/iot/output/adapter/ui/authentication/Authenticator.java @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * Licensed 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.iot.output.adapter.ui.authentication; + +import javax.websocket.Session; + +/** + * This interface is used to authenticate a websocket session + */ +public interface Authenticator { + + /** + * Check whether the client is authenticated to connect. + * @param session user object. + * @return AuthenicationInfo which contains authentication client information. + */ + AuthenticationInfo isAutenticated(Session session); +} diff --git a/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.output.adapter.ui/src/main/java/org/wso2/carbon/device/mgt/iot/output/adapter/ui/authentication/OAuthAuthenticator.java b/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.output.adapter.ui/src/main/java/org/wso2/carbon/device/mgt/iot/output/adapter/ui/authentication/OAuthAuthenticator.java new file mode 100644 index 000000000..a3d38d7dd --- /dev/null +++ b/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.output.adapter.ui/src/main/java/org/wso2/carbon/device/mgt/iot/output/adapter/ui/authentication/OAuthAuthenticator.java @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * Licensed 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.iot.output.adapter.ui.authentication; + +import org.wso2.carbon.device.mgt.iot.output.adapter.ui.authentication.oauth.OAuthTokenValdiator; +import javax.websocket.Session; + +public class OAuthAuthenticator implements Authenticator { + + @Override + public AuthenticationInfo isAutenticated(Session session) { + return OAuthTokenValdiator.getInstance().validateToken(session); + } +} diff --git a/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.output.adapter.ui.endpoint/src/main/java/oauth/OAuthTokenValdiator.java b/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.output.adapter.ui/src/main/java/org/wso2/carbon/device/mgt/iot/output/adapter/ui/authentication/oauth/OAuthTokenValdiator.java similarity index 86% rename from components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.output.adapter.ui.endpoint/src/main/java/oauth/OAuthTokenValdiator.java rename to components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.output.adapter.ui/src/main/java/org/wso2/carbon/device/mgt/iot/output/adapter/ui/authentication/oauth/OAuthTokenValdiator.java index e33bb39fa..9532f6dcd 100644 --- a/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.output.adapter.ui.endpoint/src/main/java/oauth/OAuthTokenValdiator.java +++ b/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.output.adapter.ui/src/main/java/org/wso2/carbon/device/mgt/iot/output/adapter/ui/authentication/oauth/OAuthTokenValdiator.java @@ -12,13 +12,17 @@ * */ -package oauth; +package org.wso2.carbon.device.mgt.iot.output.adapter.ui.authentication.oauth; import org.apache.axis2.context.ServiceContext; import org.apache.axis2.transport.http.HTTPConstants; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.commons.pool.impl.GenericObjectPool; +import org.wso2.carbon.device.mgt.iot.output.adapter.ui.authentication.AuthenticationInfo; +import org.wso2.carbon.device.mgt.iot.output.adapter.ui.config.Property; +import org.wso2.carbon.device.mgt.iot.output.adapter.ui.config.WebsocketConfig; +import org.wso2.carbon.device.mgt.iot.output.adapter.ui.constants.WebsocketConstants; import org.wso2.carbon.identity.oauth2.stub.OAuth2TokenValidationServiceStub; import org.wso2.carbon.identity.oauth2.stub.dto.OAuth2TokenValidationRequestDTO; import org.wso2.carbon.identity.oauth2.stub.dto.OAuth2TokenValidationRequestDTO_OAuth2AccessToken; @@ -26,14 +30,14 @@ import org.wso2.carbon.identity.oauth2.stub.dto.OAuth2TokenValidationResponseDTO import org.wso2.carbon.user.api.UserStoreException; import org.wso2.carbon.utils.CarbonUtils; import org.wso2.carbon.utils.multitenancy.MultitenantUtils; -import util.AuthenticationInfo; import javax.websocket.Session; import java.io.File; -import java.io.FileInputStream; import java.io.IOException; -import java.io.InputStream; import java.rmi.RemoteException; +import java.util.HashMap; +import java.util.List; +import java.util.Map; import java.util.Properties; /** @@ -68,7 +72,7 @@ public class OAuthTokenValdiator { Properties properties = getWebSocketConfig(); this.stubs = new GenericObjectPool(new OAuthTokenValidaterStubFactory(properties)); } catch (IOException e) { - log.error("Failed to parse the web socket config file " + WEBSOCKET_CONFIG_LOCATION); + log.error("Failed to parse the web socket org.wso2.carbon.device.mgt.iot.output.adapter.ui.config file " + WEBSOCKET_CONFIG_LOCATION); } } @@ -152,6 +156,12 @@ public class OAuthTokenValdiator { String tenantDomain = MultitenantUtils.getTenantDomain(authorizedUser); authenticationInfo.setUsername(username); authenticationInfo.setTenantDomain(tenantDomain); + String scopes[] = tokenValidationResponse.getScope(); + if (scopes != null) { + Map properties = new HashMap<>(); + properties.put(WebsocketConstants.SCOPE_IDENTIFIER, scopes); + authenticationInfo.setProperties(properties); + } } else { if (log.isDebugEnabled()) { log.debug("Token validation failed for token: " + token); @@ -169,12 +179,10 @@ public class OAuthTokenValdiator { */ private Properties getWebSocketConfig() throws IOException { Properties properties = new Properties(); - File configFile =new File(WEBSOCKET_CONFIG_LOCATION); - if (configFile.exists()) { - InputStream fileInputStream = new FileInputStream(configFile); - if (fileInputStream != null) { - properties.load(fileInputStream); - } + List propertyList = WebsocketConfig.getInstance().getWebsocketValidationConfigs().getAuthenticator() + .getProperties().getProperty(); + for (Property property : propertyList) { + properties.put(property.getName(), property.getValue()); } return properties; } diff --git a/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.output.adapter.ui.endpoint/src/main/java/oauth/OAuthTokenValidaterStubFactory.java b/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.output.adapter.ui/src/main/java/org/wso2/carbon/device/mgt/iot/output/adapter/ui/authentication/oauth/OAuthTokenValidaterStubFactory.java similarity index 91% rename from components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.output.adapter.ui.endpoint/src/main/java/oauth/OAuthTokenValidaterStubFactory.java rename to components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.output.adapter.ui/src/main/java/org/wso2/carbon/device/mgt/iot/output/adapter/ui/authentication/oauth/OAuthTokenValidaterStubFactory.java index a43f87472..d791af42a 100644 --- a/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.output.adapter.ui.endpoint/src/main/java/oauth/OAuthTokenValidaterStubFactory.java +++ b/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.output.adapter.ui/src/main/java/org/wso2/carbon/device/mgt/iot/output/adapter/ui/authentication/oauth/OAuthTokenValidaterStubFactory.java @@ -15,9 +15,8 @@ * specific language governing permissions and limitations * under the License. */ -package oauth; +package org.wso2.carbon.device.mgt.iot.output.adapter.ui.authentication.oauth; -import oauth.exception.OAuthTokenValidationException; import org.apache.axis2.AxisFault; import org.apache.axis2.Constants; import org.apache.axis2.client.Options; @@ -33,8 +32,9 @@ import org.apache.commons.httpclient.protocol.Protocol; import org.apache.commons.httpclient.protocol.ProtocolSocketFactory; import org.apache.commons.pool.BasePoolableObjectFactory; import org.apache.log4j.Logger; +import org.wso2.carbon.device.mgt.iot.output.adapter.ui.authentication.oauth.exception.OAuthTokenValidationException; +import org.wso2.carbon.device.mgt.iot.output.adapter.ui.constants.WebsocketConstants; import org.wso2.carbon.identity.oauth2.stub.OAuth2TokenValidationServiceStub; -import util.UIConstants; import java.io.IOException; import java.net.MalformedURLException; @@ -91,7 +91,7 @@ public class OAuthTokenValidaterStubFactory extends BasePoolableObjectFactory { private OAuth2TokenValidationServiceStub generateStub() throws OAuthTokenValidationException { OAuth2TokenValidationServiceStub stub; try { - URL hostURL = new URL(tokenValidationProperties.getProperty((UIConstants.TOKEN_VALIDATION_ENDPOINT_URL))); + URL hostURL = new URL(tokenValidationProperties.getProperty((WebsocketConstants.TOKEN_VALIDATION_ENDPOINT_URL))); if (hostURL != null) { stub = new OAuth2TokenValidationServiceStub(hostURL.toString()); if (stub != null) { @@ -102,8 +102,8 @@ public class OAuthTokenValidaterStubFactory extends BasePoolableObjectFactory { HttpTransportProperties.Authenticator auth = new HttpTransportProperties.Authenticator(); auth.setPreemptiveAuthentication(true); - String username = tokenValidationProperties.getProperty(UIConstants.USERNAME); - String password = tokenValidationProperties.getProperty(UIConstants.PASSWORD); + String username = tokenValidationProperties.getProperty(WebsocketConstants.USERNAME); + String password = tokenValidationProperties.getProperty(WebsocketConstants.PASSWORD); auth.setPassword(username); auth.setUsername(password); Options options = client.getOptions(); @@ -167,9 +167,9 @@ public class OAuthTokenValidaterStubFactory extends BasePoolableObjectFactory { private HttpClient createHttpClient() { HttpConnectionManagerParams params = new HttpConnectionManagerParams(); params.setDefaultMaxConnectionsPerHost(Integer.parseInt(tokenValidationProperties.getProperty( - UIConstants.MAXIMUM_HTTP_CONNECTION_PER_HOST))); + WebsocketConstants.MAXIMUM_HTTP_CONNECTION_PER_HOST))); params.setMaxTotalConnections(Integer.parseInt(tokenValidationProperties.getProperty( - UIConstants.MAXIMUM_TOTAL_HTTP_CONNECTION))); + WebsocketConstants.MAXIMUM_TOTAL_HTTP_CONNECTION))); HttpConnectionManager connectionManager = new MultiThreadedHttpConnectionManager(); connectionManager.setParams(params); return new HttpClient(connectionManager); diff --git a/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.output.adapter.ui.endpoint/src/main/java/oauth/exception/OAuthTokenValidationException.java b/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.output.adapter.ui/src/main/java/org/wso2/carbon/device/mgt/iot/output/adapter/ui/authentication/oauth/exception/OAuthTokenValidationException.java similarity index 94% rename from components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.output.adapter.ui.endpoint/src/main/java/oauth/exception/OAuthTokenValidationException.java rename to components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.output.adapter.ui/src/main/java/org/wso2/carbon/device/mgt/iot/output/adapter/ui/authentication/oauth/exception/OAuthTokenValidationException.java index 3f54c5244..514afe35a 100644 --- a/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.output.adapter.ui.endpoint/src/main/java/oauth/exception/OAuthTokenValidationException.java +++ b/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.output.adapter.ui/src/main/java/org/wso2/carbon/device/mgt/iot/output/adapter/ui/authentication/oauth/exception/OAuthTokenValidationException.java @@ -15,7 +15,7 @@ * specific language governing permissions and limitations * under the License. */ -package oauth.exception; +package org.wso2.carbon.device.mgt.iot.output.adapter.ui.authentication.oauth.exception; /** * This Exception will be thrown, when there any interference with token validation flow. diff --git a/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.output.adapter.ui/src/main/java/org/wso2/carbon/device/mgt/iot/output/adapter/ui/authorization/Authorizer.java b/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.output.adapter.ui/src/main/java/org/wso2/carbon/device/mgt/iot/output/adapter/ui/authorization/Authorizer.java new file mode 100644 index 000000000..f6f812609 --- /dev/null +++ b/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.output.adapter.ui/src/main/java/org/wso2/carbon/device/mgt/iot/output/adapter/ui/authorization/Authorizer.java @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * Licensed 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.iot.output.adapter.ui.authorization; + +import org.wso2.carbon.device.mgt.iot.output.adapter.ui.authentication.AuthenticationInfo; + +import javax.websocket.Session; +import java.util.Map; + +/** + * Check whether the client is authorized to connect. + */ +public interface Authorizer { + + /** + * Check whether the client is authorized to connect with the stream. + * @param authenticationInfo authenticated client information. + * @param session request session of the client. + * @param stream stream name of the client connecting to. + * @return true if authorized else return false. + */ + boolean isAuthorized(AuthenticationInfo authenticationInfo, Session session, String stream); +} diff --git a/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.output.adapter.ui/src/main/java/org/wso2/carbon/device/mgt/iot/output/adapter/ui/authorization/DeviceAuthorizer.java b/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.output.adapter.ui/src/main/java/org/wso2/carbon/device/mgt/iot/output/adapter/ui/authorization/DeviceAuthorizer.java new file mode 100644 index 000000000..8cd92568a --- /dev/null +++ b/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.output.adapter.ui/src/main/java/org/wso2/carbon/device/mgt/iot/output/adapter/ui/authorization/DeviceAuthorizer.java @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * Licensed 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.iot.output.adapter.ui.authorization; + +import org.wso2.carbon.device.mgt.iot.output.adapter.ui.authentication.AuthenticationInfo; +import org.wso2.carbon.device.mgt.iot.output.adapter.ui.constants.WebsocketConstants; +import org.wso2.carbon.device.mgt.iot.output.adapter.ui.util.WebSocketSessionRequest; + +import javax.websocket.Session; +import java.util.Map; + +/** + * This authorizer crossvalidates the request with device id and device type. + */ +public class DeviceAuthorizer implements Authorizer { + private static final String STATS_SCOPE_IDENTIFIER = "stats"; + private static final String DEVICE_MGT_SCOPE_IDENTIFIER = "device-mgt"; + + @Override + public boolean isAuthorized(AuthenticationInfo authenticationInfo, Session session, String stream) { + WebSocketSessionRequest webSocketSessionRequest = new WebSocketSessionRequest(session); + Map queryParams = webSocketSessionRequest.getQueryParamValuePairs(); + String deviceId = queryParams.get("deviceId"); + String deviceType = queryParams.get("deviceType"); + Object scopeObject = authenticationInfo.getProperties().get(WebsocketConstants.SCOPE_IDENTIFIER); + + if (deviceId != null && !deviceId.isEmpty() && deviceType != null && !deviceType.isEmpty() + && scopeObject != null) { + String scopes[] = (String[]) scopeObject; + String requiredScope = DEVICE_MGT_SCOPE_IDENTIFIER + ":" + deviceType + ":" + deviceId + ":" + + STATS_SCOPE_IDENTIFIER; + for (String scope : scopes) { + if (requiredScope.equals(scope)) { + return true; + } + } + } + return false; + } +} \ No newline at end of file diff --git a/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.output.adapter.ui/src/main/java/org/wso2/carbon/device/mgt/iot/output/adapter/ui/config/Authenticator.java b/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.output.adapter.ui/src/main/java/org/wso2/carbon/device/mgt/iot/output/adapter/ui/config/Authenticator.java new file mode 100644 index 000000000..c6e743666 --- /dev/null +++ b/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.output.adapter.ui/src/main/java/org/wso2/carbon/device/mgt/iot/output/adapter/ui/config/Authenticator.java @@ -0,0 +1,90 @@ + +package org.wso2.carbon.device.mgt.iot.output.adapter.ui.config; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlAttribute; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlType; + + +/** + *

Java class for Authenticator complex type. + * + *

The following schema fragment specifies the expected content contained within this class. + * + *

+ * <complexType name="Authenticator">
+ *   <complexContent>
+ *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *       <sequence>
+ *         <element name="Properties" type="{}Properties"/>
+ *       </sequence>
+ *       <attribute name="class" type="{http://www.w3.org/2001/XMLSchema}string" />
+ *     </restriction>
+ *   </complexContent>
+ * </complexType>
+ * 
+ * + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "Authenticator", propOrder = { + "properties" +}) +public class Authenticator { + + @XmlElement(name = "Properties", required = true) + protected Properties properties; + @XmlAttribute(name = "class") + protected String clazz; + + /** + * Gets the value of the properties property. + * + * @return + * possible object is + * {@link Properties } + * + */ + public Properties getProperties() { + return properties; + } + + /** + * Sets the value of the properties property. + * + * @param value + * allowed object is + * {@link Properties } + * + */ + public void setProperties(Properties value) { + this.properties = value; + } + + /** + * Gets the value of the clazz property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getClazz() { + return clazz; + } + + /** + * Sets the value of the clazz property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setClazz(String value) { + this.clazz = value; + } + +} diff --git a/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.output.adapter.ui/src/main/java/org/wso2/carbon/device/mgt/iot/output/adapter/ui/config/Authorizer.java b/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.output.adapter.ui/src/main/java/org/wso2/carbon/device/mgt/iot/output/adapter/ui/config/Authorizer.java new file mode 100644 index 000000000..5f3de1345 --- /dev/null +++ b/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.output.adapter.ui/src/main/java/org/wso2/carbon/device/mgt/iot/output/adapter/ui/config/Authorizer.java @@ -0,0 +1,90 @@ + +package org.wso2.carbon.device.mgt.iot.output.adapter.ui.config; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlAttribute; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlType; + + +/** + *

Java class for Authorizer complex type. + * + *

The following schema fragment specifies the expected content contained within this class. + * + *

+ * <complexType name="Authorizer">
+ *   <complexContent>
+ *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *       <sequence>
+ *         <element name="Properties" type="{}Properties"/>
+ *       </sequence>
+ *       <attribute name="class" type="{http://www.w3.org/2001/XMLSchema}string" />
+ *     </restriction>
+ *   </complexContent>
+ * </complexType>
+ * 
+ * + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "Authorizer", propOrder = { + "properties" +}) +public class Authorizer { + + @XmlElement(name = "Properties", required = true) + protected Properties properties; + @XmlAttribute(name = "class") + protected String clazz; + + /** + * Gets the value of the properties property. + * + * @return + * possible object is + * {@link Properties } + * + */ + public Properties getProperties() { + return properties; + } + + /** + * Sets the value of the properties property. + * + * @param value + * allowed object is + * {@link Properties } + * + */ + public void setProperties(Properties value) { + this.properties = value; + } + + /** + * Gets the value of the clazz property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getClazz() { + return clazz; + } + + /** + * Sets the value of the clazz property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setClazz(String value) { + this.clazz = value; + } + +} diff --git a/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.output.adapter.ui/src/main/java/org/wso2/carbon/device/mgt/iot/output/adapter/ui/config/Properties.java b/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.output.adapter.ui/src/main/java/org/wso2/carbon/device/mgt/iot/output/adapter/ui/config/Properties.java new file mode 100644 index 000000000..e383da5cd --- /dev/null +++ b/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.output.adapter.ui/src/main/java/org/wso2/carbon/device/mgt/iot/output/adapter/ui/config/Properties.java @@ -0,0 +1,69 @@ + +package org.wso2.carbon.device.mgt.iot.output.adapter.ui.config; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlType; +import java.util.ArrayList; +import java.util.List; + + +/** + *

Java class for Properties complex type. + * + *

The following schema fragment specifies the expected content contained within this class. + * + *

+ * <complexType name="Properties">
+ *   <complexContent>
+ *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *       <sequence>
+ *         <element name="Property" type="{}Property" maxOccurs="unbounded" minOccurs="0"/>
+ *       </sequence>
+ *     </restriction>
+ *   </complexContent>
+ * </complexType>
+ * 
+ * + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "Properties", propOrder = { + "property" +}) +public class Properties { + + @XmlElement(name = "Property") + protected List property; + + /** + * Gets the value of the property property. + * + *

+ * This accessor method returns a reference to the live list, + * not a snapshot. Therefore any modification you make to the + * returned list will be present inside the JAXB object. + * This is why there is not a set method for the property property. + * + *

+ * For example, to add a new item, do as follows: + *

+     *    getProperty().add(newItem);
+     * 
+ * + * + *

+ * Objects of the following type(s) are allowed in the list + * {@link Property } + * + * + */ + public List getProperty() { + if (property == null) { + property = new ArrayList(); + } + return this.property; + } + +} diff --git a/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.output.adapter.ui/src/main/java/org/wso2/carbon/device/mgt/iot/output/adapter/ui/config/Property.java b/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.output.adapter.ui/src/main/java/org/wso2/carbon/device/mgt/iot/output/adapter/ui/config/Property.java new file mode 100644 index 000000000..1bd22c728 --- /dev/null +++ b/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.output.adapter.ui/src/main/java/org/wso2/carbon/device/mgt/iot/output/adapter/ui/config/Property.java @@ -0,0 +1,87 @@ + +package org.wso2.carbon.device.mgt.iot.output.adapter.ui.config; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlAttribute; +import javax.xml.bind.annotation.XmlType; +import javax.xml.bind.annotation.XmlValue; + + +/** + *

Java class for Property complex type. + * + *

The following schema fragment specifies the expected content contained within this class. + * + *

+ * <complexType name="Property">
+ *   <simpleContent>
+ *     <extension base="<http://www.w3.org/2001/XMLSchema>string">
+ *       <attribute name="name" type="{http://www.w3.org/2001/XMLSchema}string" />
+ *     </extension>
+ *   </simpleContent>
+ * </complexType>
+ * 
+ * + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "Property", propOrder = { + "value" +}) +public class Property { + + @XmlValue + protected String value; + @XmlAttribute(name = "name") + protected String name; + + /** + * Gets the value of the value property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getValue() { + return value; + } + + /** + * Sets the value of the value property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setValue(String value) { + this.value = value; + } + + /** + * Gets the value of the name property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getName() { + return name; + } + + /** + * Sets the value of the name property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setName(String value) { + this.name = value; + } + +} diff --git a/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.output.adapter.ui/src/main/java/org/wso2/carbon/device/mgt/iot/output/adapter/ui/config/WebsocketConfig.java b/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.output.adapter.ui/src/main/java/org/wso2/carbon/device/mgt/iot/output/adapter/ui/config/WebsocketConfig.java new file mode 100644 index 000000000..faf2d789b --- /dev/null +++ b/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.output.adapter.ui/src/main/java/org/wso2/carbon/device/mgt/iot/output/adapter/ui/config/WebsocketConfig.java @@ -0,0 +1,57 @@ + +package org.wso2.carbon.device.mgt.iot.output.adapter.ui.config; + +import org.w3c.dom.Document; +import org.wso2.carbon.device.mgt.iot.output.adapter.ui.util.WebsocketUtils; +import org.wso2.carbon.utils.CarbonUtils; + +import javax.xml.bind.JAXBContext; +import javax.xml.bind.JAXBException; +import javax.xml.bind.Unmarshaller; +import java.io.File; + +/** + * This class represents the configuration that are needed for scopes to permission map. + */ +public class WebsocketConfig { + + private static WebsocketConfig config = new WebsocketConfig(); + private WebsocketValidationConfigs websocketValidationConfigs; + + private static final String WEBSOCKET_VALIDATION_CONFIG_PATH = + CarbonUtils.getEtcCarbonConfigDirPath() + File.separator + "websocket-validation.xml"; + + private WebsocketConfig() { + } + + public static WebsocketConfig getInstance() { + return config; + } + + public void init() throws WebsocketValidationConfigurationFailedException { + try { + File deviceMgtConfig = new File(WEBSOCKET_VALIDATION_CONFIG_PATH); + Document doc = WebsocketUtils.convertToDocument(deviceMgtConfig); + + /* Un-marshaling DeviceMGtScope configuration */ + JAXBContext ctx = JAXBContext.newInstance(WebsocketValidationConfigs.class); + Unmarshaller unmarshaller = ctx.createUnmarshaller(); + //unmarshaller.setSchema(getSchema()); + websocketValidationConfigs = (WebsocketValidationConfigs) unmarshaller.unmarshal(doc); + if (websocketValidationConfigs != null) { + + } + } catch (JAXBException e) { + throw new WebsocketValidationConfigurationFailedException("Error occurred while un-marshalling Websocket" + + " Config", e); + } + } + + public WebsocketValidationConfigs getWebsocketValidationConfigs() { + return websocketValidationConfigs; + } + + public void setWebsocketValidationConfigs(WebsocketValidationConfigs websocketValidationConfigs) { + websocketValidationConfigs = websocketValidationConfigs; + } +} diff --git a/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.output.adapter.ui/src/main/java/org/wso2/carbon/device/mgt/iot/output/adapter/ui/config/WebsocketValidationConfigs.java b/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.output.adapter.ui/src/main/java/org/wso2/carbon/device/mgt/iot/output/adapter/ui/config/WebsocketValidationConfigs.java new file mode 100644 index 000000000..08bdab872 --- /dev/null +++ b/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.output.adapter.ui/src/main/java/org/wso2/carbon/device/mgt/iot/output/adapter/ui/config/WebsocketValidationConfigs.java @@ -0,0 +1,90 @@ + +package org.wso2.carbon.device.mgt.iot.output.adapter.ui.config; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlType; + + +/** + *

Java class for WebsocketValidationConfigs complex type. + * + *

The following schema fragment specifies the expected content contained within this class. + * + *

+ * <complexType name="WebsocketValidationConfigs">
+ *   <complexContent>
+ *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *       <sequence>
+ *         <element name="Authenticator" type="{}Authenticator"/>
+ *         <element name="Authorizer" type="{}Authorizer"/>
+ *       </sequence>
+ *     </restriction>
+ *   </complexContent>
+ * </complexType>
+ * 
+ * + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "WebsocketValidationConfigs", propOrder = { + "authenticator", + "authorizer" +}) +public class WebsocketValidationConfigs { + + @XmlElement(name = "Authenticator", required = true) + protected Authenticator authenticator; + @XmlElement(name = "Authorizer", required = true) + protected Authorizer authorizer; + + /** + * Gets the value of the authenticator property. + * + * @return + * possible object is + * {@link Authenticator } + * + */ + public Authenticator getAuthenticator() { + return authenticator; + } + + /** + * Sets the value of the authenticator property. + * + * @param value + * allowed object is + * {@link Authenticator } + * + */ + public void setAuthenticator(Authenticator value) { + this.authenticator = value; + } + + /** + * Gets the value of the authorizer property. + * + * @return + * possible object is + * {@link Authorizer } + * + */ + public Authorizer getAuthorizer() { + return authorizer; + } + + /** + * Sets the value of the authorizer property. + * + * @param value + * allowed object is + * {@link Authorizer } + * + */ + public void setAuthorizer(Authorizer value) { + this.authorizer = value; + } + +} diff --git a/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.output.adapter.ui/src/main/java/org/wso2/carbon/device/mgt/iot/output/adapter/ui/config/WebsocketValidationConfigurationFailedException.java b/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.output.adapter.ui/src/main/java/org/wso2/carbon/device/mgt/iot/output/adapter/ui/config/WebsocketValidationConfigurationFailedException.java new file mode 100644 index 000000000..766eea3ee --- /dev/null +++ b/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.output.adapter.ui/src/main/java/org/wso2/carbon/device/mgt/iot/output/adapter/ui/config/WebsocketValidationConfigurationFailedException.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.device.mgt.iot.output.adapter.ui.config; + +public class WebsocketValidationConfigurationFailedException extends Exception { + + private static final long serialVersionUID = -3151279329290703928L; + + public WebsocketValidationConfigurationFailedException(String msg, Exception nestedEx) { + super(msg, nestedEx); + } + + public WebsocketValidationConfigurationFailedException(String message, Throwable cause) { + super(message, cause); + } + + public WebsocketValidationConfigurationFailedException(String msg) { + super(msg); + } + + public WebsocketValidationConfigurationFailedException() { + super(); + } + + public WebsocketValidationConfigurationFailedException(Throwable cause) { + super(cause); + } +} diff --git a/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.output.adapter.ui/src/main/java/org/wso2/carbon/device/mgt/iot/output/adapter/ui/constants/WebsocketConstants.java b/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.output.adapter.ui/src/main/java/org/wso2/carbon/device/mgt/iot/output/adapter/ui/constants/WebsocketConstants.java new file mode 100644 index 000000000..9242e28f7 --- /dev/null +++ b/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.output.adapter.ui/src/main/java/org/wso2/carbon/device/mgt/iot/output/adapter/ui/constants/WebsocketConstants.java @@ -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.device.mgt.iot.output.adapter.ui.constants; + +/** + * This holds the constants related to this feature + */ +public class WebsocketConstants { + + private WebsocketConstants() { + } + + public static final String SCOPE_IDENTIFIER = "scopes"; + public static final String MAXIMUM_TOTAL_HTTP_CONNECTION = "maximumTotalHttpConnection"; + public static final String MAXIMUM_HTTP_CONNECTION_PER_HOST = "maximumHttpConnectionPerHost"; + public static final String TOKEN_VALIDATION_ENDPOINT_URL = "tokenValidationEndpoint"; + public static final String USERNAME = "username"; + public static final String PASSWORD = "password"; +} diff --git a/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.output.adapter.ui/src/main/java/org/wso2/carbon/device/mgt/iot/output/adapter/ui/internal/UILocalEventAdapterServiceComponent.java b/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.output.adapter.ui/src/main/java/org/wso2/carbon/device/mgt/iot/output/adapter/ui/internal/UILocalEventAdapterServiceComponent.java index 341d4b377..71897510e 100644 --- a/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.output.adapter.ui/src/main/java/org/wso2/carbon/device/mgt/iot/output/adapter/ui/internal/UILocalEventAdapterServiceComponent.java +++ b/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.output.adapter.ui/src/main/java/org/wso2/carbon/device/mgt/iot/output/adapter/ui/internal/UILocalEventAdapterServiceComponent.java @@ -24,6 +24,12 @@ import org.apache.commons.logging.LogFactory; import org.osgi.service.component.ComponentContext; import org.wso2.carbon.device.mgt.iot.output.adapter.ui.UIEventAdapterFactory; import org.wso2.carbon.device.mgt.iot.output.adapter.ui.UIOutputCallbackControllerServiceImpl; +import org.wso2.carbon.device.mgt.iot.output.adapter.ui.authentication.Authenticator; +import org.wso2.carbon.device.mgt.iot.output.adapter.ui.authorization.Authorizer; +import org.wso2.carbon.device.mgt.iot.output.adapter.ui.config.WebsocketConfig; +import org.wso2.carbon.device.mgt.iot.output.adapter.ui.config.WebsocketValidationConfigurationFailedException; +import org.wso2.carbon.device.mgt.iot.output.adapter.ui.service.WebsocketValidationService; +import org.wso2.carbon.device.mgt.iot.output.adapter.ui.service.WebsocketValidationServiceImpl; import org.wso2.carbon.event.output.adapter.core.OutputEventAdapterFactory; import org.wso2.carbon.device.mgt.iot.output.adapter.ui.UIOutputCallbackControllerService; import org.wso2.carbon.event.stream.core.EventStreamService; @@ -58,6 +64,32 @@ public class UILocalEventAdapterServiceComponent { if (log.isDebugEnabled()) { log.debug("Successfully deployed the output ui adapter service"); } + try { + WebsocketConfig.getInstance().init(); + WebsocketValidationServiceImpl websocketValidationService = new WebsocketValidationServiceImpl(); + String authenticatorClassName = WebsocketConfig.getInstance().getWebsocketValidationConfigs() + .getAuthenticator().getClazz(); + String authorizerClassName = WebsocketConfig.getInstance().getWebsocketValidationConfigs() + .getAuthorizer().getClazz(); + if (authenticatorClassName != null && !authenticatorClassName.isEmpty()) { + Class authenticatorClass = Class.forName(authenticatorClassName) + .asSubclass(Authenticator.class); + Authenticator authenticator = authenticatorClass.newInstance(); + websocketValidationService.setAuthenticator(authenticator); + } + if (authorizerClassName != null && !authorizerClassName.isEmpty()) { + Class authorizerClass = Class.forName(authorizerClassName) + .asSubclass(Authorizer.class); + Authorizer authorizer = authorizerClass.newInstance(); + websocketValidationService.setAuthorizer(authorizer); + } + context.getBundleContext().registerService( + WebsocketValidationService.class.getName(), websocketValidationService, null); + } catch (WebsocketValidationConfigurationFailedException e) { + log.error("Failed to initialize configuration for websocket.", e); + } catch (ClassNotFoundException | InstantiationException | IllegalAccessException e) { + e.printStackTrace(); + } } catch (RuntimeException e) { log.error("Can not create the output ui adapter service ", e); } diff --git a/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.output.adapter.ui/src/main/java/org/wso2/carbon/device/mgt/iot/output/adapter/ui/service/WebsocketValidationService.java b/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.output.adapter.ui/src/main/java/org/wso2/carbon/device/mgt/iot/output/adapter/ui/service/WebsocketValidationService.java new file mode 100644 index 000000000..927c34515 --- /dev/null +++ b/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.output.adapter.ui/src/main/java/org/wso2/carbon/device/mgt/iot/output/adapter/ui/service/WebsocketValidationService.java @@ -0,0 +1,15 @@ +package org.wso2.carbon.device.mgt.iot.output.adapter.ui.service; + +import org.wso2.carbon.device.mgt.iot.output.adapter.ui.authentication.Authenticator; +import org.wso2.carbon.device.mgt.iot.output.adapter.ui.authorization.Authorizer; + +/** + * This returns the configured authenticator and authorizer for websocket. + */ +public interface WebsocketValidationService { + + Authenticator getAuthenticator(); + + Authorizer getAuthorizer(); + +} diff --git a/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.output.adapter.ui/src/main/java/org/wso2/carbon/device/mgt/iot/output/adapter/ui/service/WebsocketValidationServiceImpl.java b/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.output.adapter.ui/src/main/java/org/wso2/carbon/device/mgt/iot/output/adapter/ui/service/WebsocketValidationServiceImpl.java new file mode 100644 index 000000000..b459b6851 --- /dev/null +++ b/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.output.adapter.ui/src/main/java/org/wso2/carbon/device/mgt/iot/output/adapter/ui/service/WebsocketValidationServiceImpl.java @@ -0,0 +1,30 @@ +package org.wso2.carbon.device.mgt.iot.output.adapter.ui.service; + +import org.wso2.carbon.device.mgt.iot.output.adapter.ui.authentication.Authenticator; +import org.wso2.carbon.device.mgt.iot.output.adapter.ui.authorization.Authorizer; + +/** + * This returns the configured authenticator and authorizer for websocket. + */ +public class WebsocketValidationServiceImpl implements WebsocketValidationService{ + private Authenticator authenticator; + private Authorizer authorizer; + + @Override + public Authenticator getAuthenticator() { + return authenticator; + } + + @Override + public Authorizer getAuthorizer() { + return authorizer; + } + + public void setAuthenticator(Authenticator authenticator) { + this.authenticator = authenticator; + } + + public void setAuthorizer(Authorizer authorizer) { + this.authorizer = authorizer; + } +} diff --git a/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.output.adapter.ui/src/main/java/org/wso2/carbon/device/mgt/iot/output/adapter/ui/util/WebSocketSessionUtil.java b/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.output.adapter.ui/src/main/java/org/wso2/carbon/device/mgt/iot/output/adapter/ui/util/WebSocketSessionRequest.java similarity index 94% rename from components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.output.adapter.ui/src/main/java/org/wso2/carbon/device/mgt/iot/output/adapter/ui/util/WebSocketSessionUtil.java rename to components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.output.adapter.ui/src/main/java/org/wso2/carbon/device/mgt/iot/output/adapter/ui/util/WebSocketSessionRequest.java index 7c083f8f0..f6966835a 100644 --- a/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.output.adapter.ui/src/main/java/org/wso2/carbon/device/mgt/iot/output/adapter/ui/util/WebSocketSessionUtil.java +++ b/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.output.adapter.ui/src/main/java/org/wso2/carbon/device/mgt/iot/output/adapter/ui/util/WebSocketSessionRequest.java @@ -13,15 +13,15 @@ import java.util.Map; * of the Session object derived from processing some of the (default) existing attributes. * Ex: Query-String's [Key:Value] Map derived from the queryString attribute of the original class. */ -public class WebSocketSessionUtil { - private static final Log log = LogFactory.getLog(WebSocketSessionUtil.class); +public class WebSocketSessionRequest { + private static final Log log = LogFactory.getLog(WebSocketSessionRequest.class); private static final String QUERY_STRING_SEPERATOR = "&"; private static final String QUERY_KEY_VALUE_SEPERATOR = "="; private Map queryParamValuePairs = null; private Session session; - public WebSocketSessionUtil(Session session) { + public WebSocketSessionRequest(Session session) { this.session = session; setQueryParamValuePairs(); } @@ -42,19 +42,15 @@ public class WebSocketSessionUtil { if (session.getQueryString() != null) { String queryString = session.getQueryString(); String[] allQueryParamPairs = queryString.split(QUERY_STRING_SEPERATOR); - for (String keyValuePair : allQueryParamPairs) { String[] thisQueryParamPair = keyValuePair.split(QUERY_KEY_VALUE_SEPERATOR); - if (thisQueryParamPair.length != 2) { log.warn("Invalid query string [" + queryString + "] passed in."); break; } - if (queryParamValuePairs == null) { queryParamValuePairs = new HashMap<>(); } - queryParamValuePairs.put(thisQueryParamPair[0], thisQueryParamPair[1]); } } diff --git a/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.output.adapter.ui/src/main/java/org/wso2/carbon/device/mgt/iot/output/adapter/ui/util/WebsocketUtils.java b/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.output.adapter.ui/src/main/java/org/wso2/carbon/device/mgt/iot/output/adapter/ui/util/WebsocketUtils.java new file mode 100644 index 000000000..c049e4540 --- /dev/null +++ b/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.output.adapter.ui/src/main/java/org/wso2/carbon/device/mgt/iot/output/adapter/ui/util/WebsocketUtils.java @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2015, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * you may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.wso2.carbon.device.mgt.iot.output.adapter.ui.util; + +import org.w3c.dom.Document; +import org.wso2.carbon.device.mgt.iot.output.adapter.ui.config.WebsocketValidationConfigurationFailedException; + +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import java.io.File; + +/** + * This class holds util methods used by OAuth extension bundle. + */ +public class WebsocketUtils { + + public static Document convertToDocument(File file) throws WebsocketValidationConfigurationFailedException { + DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); + factory.setNamespaceAware(true); + try { + DocumentBuilder docBuilder = factory.newDocumentBuilder(); + return docBuilder.parse(file); + } catch (Exception e) { + throw new WebsocketValidationConfigurationFailedException("Error occurred while parsing file, while converting " + + "to a org.w3c.dom.Document", e); + } + } + +} diff --git a/components/iot-plugins/raspberrypi-plugin/org.wso2.carbon.device.mgt.iot.raspberrypi.plugin/src/main/java/org/wso2/carbon/device/mgt/iot/raspberrypi/plugin/impl/RaspberrypiManagerService.java b/components/iot-plugins/raspberrypi-plugin/org.wso2.carbon.device.mgt.iot.raspberrypi.plugin/src/main/java/org/wso2/carbon/device/mgt/iot/raspberrypi/plugin/impl/RaspberrypiManagerService.java index c5b26e978..b0c3858c7 100644 --- a/components/iot-plugins/raspberrypi-plugin/org.wso2.carbon.device.mgt.iot.raspberrypi.plugin/src/main/java/org/wso2/carbon/device/mgt/iot/raspberrypi/plugin/impl/RaspberrypiManagerService.java +++ b/components/iot-plugins/raspberrypi-plugin/org.wso2.carbon.device.mgt.iot.raspberrypi.plugin/src/main/java/org/wso2/carbon/device/mgt/iot/raspberrypi/plugin/impl/RaspberrypiManagerService.java @@ -28,9 +28,13 @@ import org.wso2.carbon.device.mgt.iot.devicetype.config.DeviceManagementConfigur import org.wso2.carbon.device.mgt.iot.raspberrypi.plugin.constants.RaspberrypiConstants; import org.wso2.carbon.device.mgt.iot.raspberrypi.plugin.internal.RaspberrypiManagementDataHolder; +import java.util.HashMap; +import java.util.Map; + public class RaspberrypiManagerService implements DeviceManagementService { private DeviceManager deviceManager; + private PushNotificationConfig pushNotificationConfig; @Override public String getType() { @@ -40,6 +44,21 @@ public class RaspberrypiManagerService implements DeviceManagementService { @Override public void init() throws DeviceManagementException { deviceManager = new RaspberrypiManager(); + this.pushNotificationConfig = this.populatePushNotificationConfig(); + } + + private PushNotificationConfig populatePushNotificationConfig() { + DeviceManagementConfiguration deviceManagementConfiguration = RaspberrypiManagementDataHolder.getInstance() + .getDeviceTypeConfigService().getConfiguration(RaspberrypiConstants.DEVICE_TYPE, + RaspberrypiConstants.DEVICE_TYPE_PROVIDER_DOMAIN); + org.wso2.carbon.device.mgt.iot.devicetype.config.PushNotificationConfig sourceConfig = + deviceManagementConfiguration.getPushNotificationConfig(); + Map staticProps = new HashMap<>(); + for (org.wso2.carbon.device.mgt.iot.devicetype.config.PushNotificationConfig.Property + property : sourceConfig.getProperties()) { + staticProps.put(property.getName(), property.getValue()); + } + return new PushNotificationConfig(sourceConfig.getPushNotificationProvider(), staticProps); } @Override @@ -64,7 +83,7 @@ public class RaspberrypiManagerService implements DeviceManagementService { @Override public PushNotificationConfig getPushNotificationConfig() { - return null; + return pushNotificationConfig; } diff --git a/features/iot-plugins-feature/iot-base-plugin-feature/org.wso2.carbon.device.mgt.iot.adapter.feature/src/main/resources/p2.inf b/features/iot-plugins-feature/iot-base-plugin-feature/org.wso2.carbon.device.mgt.iot.adapter.feature/src/main/resources/p2.inf index c1df69e78..833314fd0 100644 --- a/features/iot-plugins-feature/iot-base-plugin-feature/org.wso2.carbon.device.mgt.iot.adapter.feature/src/main/resources/p2.inf +++ b/features/iot-plugins-feature/iot-base-plugin-feature/org.wso2.carbon.device.mgt.iot.adapter.feature/src/main/resources/p2.inf @@ -1,4 +1,4 @@ instructions.configure = \ org.eclipse.equinox.p2.touchpoint.natives.mkdir(path:${installFolder}/../../deployment/server/webapps/);\ org.eclipse.equinox.p2.touchpoint.natives.copy(source:${installFolder}/../features/org.wso2.carbon.device.mgt.iot.adapter_${feature.version}/webapps/,target:${installFolder}/../../deployment/server/webapps/,overwrite:true);\ -org.eclipse.equinox.p2.touchpoint.natives.copy(source:${installFolder}/../features/org.wso2.carbon.device.mgt.iot.adapter_${feature.version}/websocket-validation.properties,target:${installFolder}/../../conf/etc/websocket-validation.properties,overwrite:true);\ +org.eclipse.equinox.p2.touchpoint.natives.copy(source:${installFolder}/../features/org.wso2.carbon.device.mgt.iot.adapter_${feature.version}/websocket-validation.xml,target:${installFolder}/../../conf/etc/websocket-validation.xml,overwrite:true);\ diff --git a/features/iot-plugins-feature/iot-base-plugin-feature/org.wso2.carbon.device.mgt.iot.adapter.feature/src/main/resources/websocket-validation.properties b/features/iot-plugins-feature/iot-base-plugin-feature/org.wso2.carbon.device.mgt.iot.adapter.feature/src/main/resources/websocket-validation.properties deleted file mode 100644 index f4b75e2a1..000000000 --- a/features/iot-plugins-feature/iot-base-plugin-feature/org.wso2.carbon.device.mgt.iot.adapter.feature/src/main/resources/websocket-validation.properties +++ /dev/null @@ -1,25 +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 hold the properties that is used for token validation for the the websocket - -tokenValidationEndpoint=https://localhost:9443/services/OAuth2TokenValidationService -username=admin -password=admin -maximumHttpConnectionPerHost=2 -maximumTotalHttpConnection=100 \ No newline at end of file diff --git a/features/iot-plugins-feature/iot-base-plugin-feature/org.wso2.carbon.device.mgt.iot.adapter.feature/src/main/resources/websocket-validation.xml b/features/iot-plugins-feature/iot-base-plugin-feature/org.wso2.carbon.device.mgt.iot.adapter.feature/src/main/resources/websocket-validation.xml new file mode 100644 index 000000000..ec880fe00 --- /dev/null +++ b/features/iot-plugins-feature/iot-base-plugin-feature/org.wso2.carbon.device.mgt.iot.adapter.feature/src/main/resources/websocket-validation.xml @@ -0,0 +1,39 @@ + + + + + + + + + + https://localhost:9443/services/OAuth2TokenValidationService + admin + admin + 2 + 100 + + + + + + \ No newline at end of file