diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/config/permission/Permission.java b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/config/permission/Permission.java index 76810771b8..271817cfd3 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/config/permission/Permission.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/config/permission/Permission.java @@ -21,27 +21,50 @@ package org.wso2.carbon.device.mgt.core.config.permission; import javax.xml.bind.annotation.XmlElement; import javax.xml.bind.annotation.XmlRootElement; -@XmlRootElement(name = "Permission") -public class Permission{ +/** + * This class represents the information related to permission. + */ +@XmlRootElement (name = "Permission") +public class Permission { + + private String name; // permission name + private String path; // permission string + private String url; // url of the resource + private String method; // http method + + public String getName() { + return name; + } + + @XmlElement (name = "name", required = true) + public void setName(String name) { + this.name = name; + } + + public String getPath() { + return path; + } - private String name; - private String path; + @XmlElement (name = "path", required = true) + public void setPath(String path) { + this.path = path; + } - public String getName() { - return name; - } + public String getUrl() { + return url; + } - @XmlElement(name = "name", required = true) - public void setName(String name) { - this.name = name; - } + @XmlElement (name = "url", required = true) + public void setUrl(String url) { + this.url = url; + } - public String getPath() { - return path; - } + public String getMethod() { + return method; + } - @XmlElement(name = "path", required = true) - public void setPath(String path) { - this.path = path; - } + @XmlElement (name = "method", required = true) + public void setMethod(String method) { + this.method = method; + } } diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/config/permission/PermissionConfiguration.java b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/config/permission/PermissionConfiguration.java index c2c9d08e3b..e5da6c5133 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/config/permission/PermissionConfiguration.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/config/permission/PermissionConfiguration.java @@ -22,17 +22,20 @@ import javax.xml.bind.annotation.XmlElement; import javax.xml.bind.annotation.XmlRootElement; import java.util.List; -@XmlRootElement(name = "PermissionConfiguration") +/** + * This class represents the information related to permission configuration. + */ +@XmlRootElement (name = "PermissionConfiguration") public class PermissionConfiguration { - private List permissions; + private List permissions; - public List getPermissions() { - return permissions; - } + public List getPermissions() { + return permissions; + } - @XmlElement(name = "Permission", required = true) - public void setPermissions(List permissions) { - this.permissions = permissions; - } + @XmlElement (name = "Permission", required = true) + public void setPermissions(List permissions) { + this.permissions = permissions; + } } diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/config/permission/PermissionManager.java b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/config/permission/PermissionManager.java index 4cdf10ad77..34e8105bd5 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/config/permission/PermissionManager.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/config/permission/PermissionManager.java @@ -31,51 +31,59 @@ import java.util.List; */ public class PermissionManager { - private static PermissionManager permissionManager; + private static PermissionManager permissionManager; + private static PermissionTree permissionTree; // holds the permissions at runtime. - private PermissionManager(){}; + private PermissionManager() { + } - public static PermissionManager getInstance() { - if (permissionManager == null) { - synchronized (PermissionManager.class) { - if (permissionManager == null) { - permissionManager = new PermissionManager(); - } - } - } - return permissionManager; - } + public static PermissionManager getInstance() { + if (permissionManager == null) { + synchronized (PermissionManager.class) { + if (permissionManager == null) { + permissionManager = new PermissionManager(); + permissionTree = new PermissionTree(); + } + } + } + return permissionManager; + } - public boolean addPermission(Permission permission) throws DeviceManagementException { - try { - return PermissionUtils.putPermission(permission); - } catch (DeviceManagementException e) { - throw new DeviceManagementException("Error occurred while adding the permission : " + - permission.getName(), e); - } - } + public boolean addPermission(Permission permission) throws DeviceManagementException { + permissionTree.addPermission(permission); // adding a permission to the tree + try { + return PermissionUtils.putPermission(permission); + } catch (DeviceManagementException e) { + throw new DeviceManagementException("Error occurred while adding the permission : " + + permission.getName(), e); + } + } - public boolean addPermissions(List permissions) throws DeviceManagementException{ - for(Permission permission:permissions){ - this.addPermission(permission); - } - return true; - } + public boolean addPermissions(List permissions) throws DeviceManagementException { + for (Permission permission : permissions) { + this.addPermission(permission); + } + return true; + } - public void initializePermissions(InputStream permissionStream) throws DeviceManagementException { - try { - if(permissionStream != null){ - /* Un-marshaling Device Management configuration */ - JAXBContext cdmContext = JAXBContext.newInstance(PermissionConfiguration.class); - Unmarshaller unmarshaller = cdmContext.createUnmarshaller(); - PermissionConfiguration permissionConfiguration = (PermissionConfiguration) - unmarshaller.unmarshal(permissionStream); - if((permissionConfiguration != null) && (permissionConfiguration.getPermissions() != null)){ - this.addPermissions(permissionConfiguration.getPermissions()); - } - } - } catch (JAXBException e) { - throw new DeviceManagementException("Error occurred while initializing Data Source config", e); - } - } + public void initializePermissions(InputStream permissionStream) throws DeviceManagementException { + try { + if (permissionStream != null) { + /* Un-marshaling Device Management configuration */ + JAXBContext cdmContext = JAXBContext.newInstance(PermissionConfiguration.class); + Unmarshaller unmarshaller = cdmContext.createUnmarshaller(); + PermissionConfiguration permissionConfiguration = (PermissionConfiguration) + unmarshaller.unmarshal(permissionStream); + if (permissionConfiguration != null && permissionConfiguration.getPermissions() != null) { + this.addPermissions(permissionConfiguration.getPermissions()); + } + } + } catch (JAXBException e) { + throw new DeviceManagementException("Error occurred while initializing Data Source config", e); + } + } + + public Permission getPermission(String url, String httpMethod) { + return permissionTree.getPermission(url, httpMethod); + } } diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/config/permission/PermissionNode.java b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/config/permission/PermissionNode.java new file mode 100644 index 0000000000..b3dc92b95f --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/config/permission/PermissionNode.java @@ -0,0 +1,79 @@ +/* + * 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.core.config.permission; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * This class represents the node of a permission tree. + * It holds the current path name, list of permissions associated with URL + * and the set of children. + */ +public class PermissionNode { + + private String pathName; + private Map permissions = new HashMap(); + private List children = new ArrayList(); + + public PermissionNode(String pathName) { + this.pathName = pathName; + } + + public String getPathName() { + return pathName; + } + + public void setPathName(String pathName) { + this.pathName = pathName; + } + + public List getChildren() { + return children; + } + + public PermissionNode getChild(String pathName) { + PermissionNode child = null; + for (PermissionNode node : children) { + if (node.getPathName().equals(pathName)) { + return node; + } + } + return child; + } + + public void addChild(PermissionNode node) { + children.add(node); + } + + public void addPermission(String httpMethod, Permission permission) { + permissions.put(httpMethod, permission); + } + + public Permission getPermission(String httpMethod) { + return permissions.get(httpMethod); + } + + public Collection getPermissions() { + return permissions.values(); + } +} diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/config/permission/PermissionTree.java b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/config/permission/PermissionTree.java new file mode 100644 index 0000000000..d74ae1505c --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/config/permission/PermissionTree.java @@ -0,0 +1,113 @@ +/* + * 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.core.config.permission; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import java.util.StringTokenizer; + +/** + * This class represents a tree data structure which will be used for adding and retrieving permissions. + */ +public class PermissionTree { + + private PermissionNode rootNode; + private static final String DYNAMIC_PATH_NOTATION = "*"; + private static final String ROOT = "/"; + private static final Log log = LogFactory.getLog(PermissionTree.class); + + public PermissionTree() { + rootNode = new PermissionNode(ROOT); // initializing the root node. + } + + /** + * This method is used to add permissions to the tree. Once it receives the permission + * it will traverse through the given request path with respect to the permission and place + * the permission in the appropriate place in the tree. + * + * @param permission Permission object. + */ + public void addPermission(Permission permission) { + StringTokenizer st = new StringTokenizer(permission.getUrl(), ROOT); + PermissionNode tempRoot = rootNode; + PermissionNode tempChild; + while (st.hasMoreTokens()) { + tempChild = new PermissionNode(st.nextToken()); + tempRoot = addPermissionNode(tempRoot, tempChild); + } + tempRoot.addPermission(permission.getMethod(), permission); //setting permission to the vertex + if (log.isDebugEnabled()) { + log.debug("Added permission '" + permission.getName() + "'"); + } + } + + /** + * This method is used to add vertex to the graph. The method will check for the given child + * whether exists within the list of children of the given parent. + * + * @param parent Parent PermissionNode. + * @param child Child PermissionNode. + * @return returns the newly created child or the existing child. + */ + private PermissionNode addPermissionNode(PermissionNode parent, PermissionNode child) { + PermissionNode existChild = parent.getChild(child.getPathName()); + if (existChild == null) { + parent.addChild(child); + return child; + } + return existChild; + } + + /** + * This method is used to retrieve the permission for a given url and http method. + * Breath First Search (BFS) is used to traverse the tree. + * + * @param url Request URL. + * @param httpMethod HTTP method of the request. + * @return returns the permission with related to the request path or null if there is + * no any permission that is stored with respected to the given request path. + */ + public Permission getPermission(String url, String httpMethod) { + StringTokenizer st = new StringTokenizer(url, ROOT); + PermissionNode tempRoot = rootNode; + while (st.hasMoreTokens()) { + String currentToken = st.nextToken(); + + // returns the child node which matches with the 'currentToken' path. + tempRoot = tempRoot.getChild(currentToken); + + // if tempRoot is null, that means 'currentToken' is not matched with the child's path. + // It means that it is at a point where the request must have dynamic path variables. + // Therefor it looks for '*' in the request path. ('*' denotes dynamic path variable). + if (tempRoot == null) { + tempRoot = tempRoot.getChild(DYNAMIC_PATH_NOTATION); + // if tempRoot is null, that means there is no any permission which matches with the + // given path + if (tempRoot == null) { + if (log.isDebugEnabled()) { + log.debug("Permission for request path '" + url + "' does not exist"); + } + return null; + } + } + } + return tempRoot.getPermission(httpMethod); + } +} diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/config/permission/PermissionUtils.java b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/config/permission/PermissionUtils.java index 7e1f45a833..78911ab1b1 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/config/permission/PermissionUtils.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/config/permission/PermissionUtils.java @@ -84,7 +84,7 @@ public class PermissionUtils { return status; } - public static boolean checkPermissionExistance(Permission permission) + public static boolean checkPermissionExistence(Permission permission) throws DeviceManagementException, org.wso2.carbon.registry.core.exceptions.RegistryException { return PermissionUtils.getGovernanceRegistry().resourceExists(permission.getPath()); diff --git a/components/dynamic-client-registration/org.wso2.carbon.dynamic.client.registration/pom.xml b/components/dynamic-client-registration/org.wso2.carbon.dynamic.client.registration/pom.xml index 206193a9b0..88b54304e8 100644 --- a/components/dynamic-client-registration/org.wso2.carbon.dynamic.client.registration/pom.xml +++ b/components/dynamic-client-registration/org.wso2.carbon.dynamic.client.registration/pom.xml @@ -84,6 +84,10 @@ org.wso2.carbon.identity org.wso2.carbon.identity.oauth + + org.wso2.carbon.identity + org.wso2.carbon.identity.sso.saml + com.googlecode.json-simple.wso2 json-simple diff --git a/components/dynamic-client-registration/org.wso2.carbon.dynamic.client.registration/src/main/java/org/wso2/carbon/dynamic/client/registration/impl/DynamicClientRegistrationImpl.java b/components/dynamic-client-registration/org.wso2.carbon.dynamic.client.registration/src/main/java/org/wso2/carbon/dynamic/client/registration/impl/DynamicClientRegistrationImpl.java index 28e9600aa6..0c846e081d 100644 --- a/components/dynamic-client-registration/org.wso2.carbon.dynamic.client.registration/src/main/java/org/wso2/carbon/dynamic/client/registration/impl/DynamicClientRegistrationImpl.java +++ b/components/dynamic-client-registration/org.wso2.carbon.dynamic.client.registration/src/main/java/org/wso2/carbon/dynamic/client/registration/impl/DynamicClientRegistrationImpl.java @@ -23,18 +23,19 @@ import org.json.JSONException; import org.json.JSONObject; import org.wso2.carbon.context.CarbonContext; import org.wso2.carbon.context.PrivilegedCarbonContext; +import org.wso2.carbon.context.RegistryType; import org.wso2.carbon.dynamic.client.registration.*; import org.wso2.carbon.dynamic.client.registration.profile.RegistrationProfile; import org.wso2.carbon.identity.application.common.IdentityApplicationManagementException; -import org.wso2.carbon.identity.application.common.model.InboundAuthenticationConfig; -import org.wso2.carbon.identity.application.common.model.InboundAuthenticationRequestConfig; -import org.wso2.carbon.identity.application.common.model.Property; -import org.wso2.carbon.identity.application.common.model.ServiceProvider; +import org.wso2.carbon.identity.application.common.model.*; import org.wso2.carbon.identity.application.mgt.ApplicationManagementService; import org.wso2.carbon.identity.base.IdentityException; import org.wso2.carbon.identity.oauth.IdentityOAuthAdminException; import org.wso2.carbon.identity.oauth.OAuthAdminService; import org.wso2.carbon.identity.oauth.dto.OAuthConsumerAppDTO; +import org.wso2.carbon.identity.sso.saml.admin.SAMLSSOConfigAdmin; +import org.wso2.carbon.identity.sso.saml.dto.SAMLSSOServiceProviderDTO; +import org.wso2.carbon.registry.core.Registry; import org.wso2.carbon.utils.multitenancy.MultitenantUtils; import java.util.Arrays; @@ -45,6 +46,13 @@ import java.util.Arrays; public class DynamicClientRegistrationImpl implements DynamicClientRegistrationService { private static final String TOKEN_SCOPE = "tokenScope"; + private static final String MDM = "mdm"; + private static final String SAML_SSO = "samlsso"; + private static final String BASIC_AUTHENTICATOR = "BasicAuthenticator"; + private static final String BASIC = "basic"; + private static final String LOCAL = "local"; + private static final String ASSERTION_CONSUMER_URI = "https://localhost:9443/mdm/sso/acs"; + private static final String AUDIENCE = "https://null:9443/oauth2/token"; private static final Log log = LogFactory.getLog(DynamicClientRegistrationService.class); @Override @@ -147,7 +155,12 @@ public class DynamicClientRegistrationImpl implements DynamicClientRegistrationS "Error occurred while retrieving Application Management" + "Service"); } - appMgtService.createApplication(serviceProvider, tenantDomain, userName); + + ServiceProvider existingServiceProvider = appMgtService.getServiceProvider(applicationName, tenantDomain); + + if (existingServiceProvider == null) { + appMgtService.createApplication(serviceProvider, userName, tenantDomain); + } ServiceProvider createdServiceProvider = appMgtService.getServiceProvider(applicationName, tenantDomain); if (createdServiceProvider == null) { @@ -167,7 +180,10 @@ public class DynamicClientRegistrationImpl implements DynamicClientRegistrationS log.debug("Creating OAuth App " + applicationName); } - oAuthAdminService.registerOAuthApplicationData(oAuthConsumerApp); + if (existingServiceProvider == null) { + oAuthAdminService.registerOAuthApplicationData(oAuthConsumerApp); + } + if (log.isDebugEnabled()) { log.debug("Created OAuth App " + applicationName); } @@ -181,10 +197,10 @@ public class DynamicClientRegistrationImpl implements DynamicClientRegistrationS InboundAuthenticationConfig inboundAuthenticationConfig = new InboundAuthenticationConfig(); InboundAuthenticationRequestConfig[] inboundAuthenticationRequestConfigs = new - InboundAuthenticationRequestConfig[1]; + InboundAuthenticationRequestConfig[2]; + InboundAuthenticationRequestConfig inboundAuthenticationRequestConfig = new InboundAuthenticationRequestConfig(); - inboundAuthenticationRequestConfig.setInboundAuthKey(createdApp.getOauthConsumerKey()); inboundAuthenticationRequestConfig.setInboundAuthType("oauth2"); if (createdApp.getOauthConsumerSecret() != null && !createdApp. @@ -197,10 +213,41 @@ public class DynamicClientRegistrationImpl implements DynamicClientRegistrationS inboundAuthenticationRequestConfig.setProperties(properties); } + SAMLSSOServiceProviderDTO samlssoServiceProviderDTO = new SAMLSSOServiceProviderDTO(); + samlssoServiceProviderDTO.setIssuer(MDM); + samlssoServiceProviderDTO.setAssertionConsumerUrl(ASSERTION_CONSUMER_URI); + samlssoServiceProviderDTO.setDoSignResponse(true); + samlssoServiceProviderDTO.setRequestedAudiences(new String[]{AUDIENCE}); + + SAMLSSOConfigAdmin configAdmin = new SAMLSSOConfigAdmin(getConfigSystemRegistry()); + configAdmin.addRelyingPartyServiceProvider(samlssoServiceProviderDTO); + + InboundAuthenticationRequestConfig samlAuthenticationRequest = new InboundAuthenticationRequestConfig(); + samlAuthenticationRequest.setInboundAuthKey(MDM); + samlAuthenticationRequest.setInboundAuthType(SAML_SSO); + + LocalAuthenticatorConfig localAuth = new LocalAuthenticatorConfig(); + localAuth.setName(BASIC_AUTHENTICATOR); + localAuth.setDisplayName(BASIC); + localAuth.setEnabled(true); + + AuthenticationStep authStep = new AuthenticationStep(); + authStep.setStepOrder(1); + authStep.setSubjectStep(true); + authStep.setAttributeStep(true); + + authStep.setLocalAuthenticatorConfigs(new LocalAuthenticatorConfig[]{localAuth}); + + LocalAndOutboundAuthenticationConfig localOutboundAuthConfig = new LocalAndOutboundAuthenticationConfig(); + localOutboundAuthConfig.setAuthenticationType(LOCAL); + localOutboundAuthConfig.setAuthenticationSteps(new AuthenticationStep[]{authStep}); + inboundAuthenticationRequestConfigs[0] = inboundAuthenticationRequestConfig; + inboundAuthenticationRequestConfigs[1] = samlAuthenticationRequest; inboundAuthenticationConfig .setInboundAuthenticationRequestConfigs(inboundAuthenticationRequestConfigs); createdServiceProvider.setInboundAuthenticationConfig(inboundAuthenticationConfig); + createdServiceProvider.setLocalAndOutBoundAuthenticationConfig(localOutboundAuthConfig); // Update the Service Provider app to add OAuthApp as an Inbound Authentication Config appMgtService.updateApplication(createdServiceProvider, tenantDomain, userName); @@ -217,6 +264,7 @@ public class DynamicClientRegistrationImpl implements DynamicClientRegistrationS oAuthApplicationInfo.addParameter( ApplicationConstants.ClientMetadata.OAUTH_CLIENT_GRANT, createdApp.getGrantTypes()); + return oAuthApplicationInfo; } catch (IdentityApplicationManagementException e) { throw new DynamicClientRegistrationException( @@ -230,6 +278,11 @@ public class DynamicClientRegistrationImpl implements DynamicClientRegistrationS } } + protected Registry getConfigSystemRegistry() { + return (Registry) PrivilegedCarbonContext.getThreadLocalCarbonContext(). + getRegistry(RegistryType.SYSTEM_CONFIGURATION); + } + @Override public boolean unregisterOAuthApplication(String userId, String applicationName, String consumerKey) throws DynamicClientRegistrationException { @@ -264,7 +317,14 @@ public class DynamicClientRegistrationImpl implements DynamicClientRegistrationS oAuthAdminService.removeOAuthApplicationData(consumerKey); ApplicationManagementService appMgtService = ApplicationManagementService.getInstance(); + + if (appMgtService == null) { + throw new IllegalStateException( + "Error occurred while retrieving Application Management" + + "Service"); + } ServiceProvider createdServiceProvider = appMgtService.getServiceProvider(applicationName, tenantDomain); + if (createdServiceProvider == null) { throw new DynamicClientRegistrationException( "Couldn't retrieve Service Provider Application " + applicationName); @@ -286,6 +346,12 @@ public class DynamicClientRegistrationImpl implements DynamicClientRegistrationS @Override public boolean isOAuthApplicationExists(String applicationName) throws DynamicClientRegistrationException { + ApplicationManagementService appMgtService = ApplicationManagementService.getInstance(); + if (appMgtService == null) { + throw new IllegalStateException( + "Error occurred while retrieving Application Management" + + "Service"); + } try { if (ApplicationManagementService.getInstance().getServiceProvider(applicationName, CarbonContext.getThreadLocalCarbonContext().getTenantDomain()) != null) { 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 66f49daea6..9e682370f8 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 @@ -95,6 +95,7 @@ org.wso2.carbon.apimgt.impl, org.wso2.carbon.certificate.mgt.core.service, org.wso2.carbon.certificate.mgt.core.exception, + org.wso2.carbon.device.mgt.core.config.permission, org.wso2.carbon.device.mgt.common, org.wso2.carbon.device.mgt.core.scep diff --git a/components/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework/src/main/java/org/wso2/carbon/webapp/authenticator/framework/Constants.java b/components/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework/src/main/java/org/wso2/carbon/webapp/authenticator/framework/Constants.java index a046c5280b..9d85c6bb46 100644 --- a/components/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework/src/main/java/org/wso2/carbon/webapp/authenticator/framework/Constants.java +++ b/components/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework/src/main/java/org/wso2/carbon/webapp/authenticator/framework/Constants.java @@ -40,4 +40,14 @@ public final class Constants { public static final String CONTENT_TYPE_APPLICATION_XML = "application/xml"; } + public static final class PermissionMethod { + private PermissionMethod() { + throw new AssertionError(); + } + + public static final String READ = "read"; + public static final String WRITE = "write"; + public static final String DELETE = "delete"; + public static final String ACTION = "action"; + } } diff --git a/components/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework/src/main/java/org/wso2/carbon/webapp/authenticator/framework/authorizer/PermissionAuthorizationValve.java b/components/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework/src/main/java/org/wso2/carbon/webapp/authenticator/framework/authorizer/PermissionAuthorizationValve.java new file mode 100644 index 0000000000..27042131a5 --- /dev/null +++ b/components/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework/src/main/java/org/wso2/carbon/webapp/authenticator/framework/authorizer/PermissionAuthorizationValve.java @@ -0,0 +1,76 @@ +/* + * 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.webapp.authenticator.framework.authorizer; + +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.tomcat.ext.valves.CarbonTomcatValve; +import org.wso2.carbon.tomcat.ext.valves.CompositeValve; +import org.wso2.carbon.webapp.authenticator.framework.AuthenticationFrameworkUtil; +import org.wso2.carbon.webapp.authenticator.framework.authenticator.WebappAuthenticator; + +import javax.servlet.http.HttpServletResponse; + +public class PermissionAuthorizationValve extends CarbonTomcatValve { + + private static final Log log = LogFactory.getLog(PermissionAuthorizationValve.class); + private static final String AUTHORIZATION_ENABLED = "authorization-enabled"; + + + @Override + public void invoke(Request request, Response response, CompositeValve compositeValve) { + + String permissionStatus = + request.getContext().findParameter(AUTHORIZATION_ENABLED); + if (permissionStatus == null || permissionStatus.isEmpty()) { + this.processResponse(request, response, compositeValve, WebappAuthenticator.Status.CONTINUE); + return; + } + // check whether the permission checking function is enabled in web.xml + boolean isEnabled = new Boolean(permissionStatus); + if (!isEnabled) { + this.processResponse(request, response, compositeValve, WebappAuthenticator.Status.CONTINUE); + return; + } + + if (log.isDebugEnabled()) { + log.debug("Checking permission of request: " + request.getRequestURI()); + } + PermissionAuthorizer permissionAuthorizer = new PermissionAuthorizer(); + WebappAuthenticator.Status status = permissionAuthorizer.authorize(request, response); + this.processResponse(request, response, compositeValve, status); + } + + private void processResponse(Request request, Response response, CompositeValve compositeValve, + WebappAuthenticator.Status status) { + switch (status) { + case SUCCESS: + case CONTINUE: + this.getNext().invoke(request, response, compositeValve); + break; + case FAILURE: + String msg = "Failed to authorize incoming request"; + log.error(msg); + AuthenticationFrameworkUtil.handleResponse(request, response, HttpServletResponse.SC_UNAUTHORIZED, msg); + break; + } + } +} diff --git a/components/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework/src/main/java/org/wso2/carbon/webapp/authenticator/framework/authorizer/PermissionAuthorizer.java b/components/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework/src/main/java/org/wso2/carbon/webapp/authenticator/framework/authorizer/PermissionAuthorizer.java new file mode 100644 index 0000000000..469b085e20 --- /dev/null +++ b/components/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework/src/main/java/org/wso2/carbon/webapp/authenticator/framework/authorizer/PermissionAuthorizer.java @@ -0,0 +1,90 @@ +/* + * 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.webapp.authenticator.framework.authorizer; + +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.context.CarbonContext; +import org.wso2.carbon.device.mgt.core.config.permission.Permission; +import org.wso2.carbon.device.mgt.core.config.permission.PermissionManager; +import org.wso2.carbon.user.api.UserStoreException; +import org.wso2.carbon.webapp.authenticator.framework.Constants; +import org.wso2.carbon.webapp.authenticator.framework.authenticator.WebappAuthenticator; + +import java.util.StringTokenizer; + +/** + * This class represents the methods that are used to authorize requests. + */ +public class PermissionAuthorizer { + + private static final Log log = LogFactory.getLog(PermissionAuthorizer.class); + + public WebappAuthenticator.Status authorize(Request request, Response response) { + + String requestUri = request.getRequestURI(); + String requestMethod = request.getMethod(); + + if (requestUri == null || requestUri.isEmpty() || + requestMethod == null || requestMethod.isEmpty()) { + return WebappAuthenticator.Status.CONTINUE; + } + + PermissionManager permissionManager = PermissionManager.getInstance(); + Permission requestPermission = permissionManager.getPermission(requestUri, requestMethod); + + if (requestPermission == null) { + if (log.isDebugEnabled()) { + log.debug("Permission to request '" + requestUri + "' is not defined in the configuration"); + } + return WebappAuthenticator.Status.FAILURE; + } + + String permissionString = requestPermission.getPath(); + + // This is added temporarily until authentication works. + // TODO remove below line. + String username = "admin"; + // TODO uncomment this once the authentication works. + //String username = CarbonContext.getThreadLocalCarbonContext().getUsername(); + + boolean isUserAuthorized; + try { + isUserAuthorized = CarbonContext.getThreadLocalCarbonContext().getUserRealm(). + getAuthorizationManager().isUserAuthorized(username, permissionString, + Constants.PermissionMethod.READ); + } catch (UserStoreException e) { + log.error("Error occurred while retrieving user store. " + e.getMessage()); + return WebappAuthenticator.Status.FAILURE; + } + + if (log.isDebugEnabled()) { + log.debug("Is user authorized: " + isUserAuthorized); + } + + if (isUserAuthorized) { + return WebappAuthenticator.Status.SUCCESS; + } else { + return WebappAuthenticator.Status.FAILURE; + } + } + +} 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 95f3dffab9..dbc3928760 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 @@ -23,14 +23,14 @@ import org.apache.commons.logging.LogFactory; 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.device.mgt.core.service.DeviceManagementProviderService; import org.wso2.carbon.tomcat.ext.valves.CarbonTomcatValve; import org.wso2.carbon.tomcat.ext.valves.TomcatValveContainer; import org.wso2.carbon.user.core.service.RealmService; import org.wso2.carbon.webapp.authenticator.framework.DataHolder; import org.wso2.carbon.webapp.authenticator.framework.WebappAuthenticationHandler; -import org.wso2.carbon.webapp.authenticator.framework.WebappAuthenticatorRepository; import org.wso2.carbon.webapp.authenticator.framework.authenticator.WebappAuthenticator; +import org.wso2.carbon.webapp.authenticator.framework.WebappAuthenticatorRepository; +import org.wso2.carbon.webapp.authenticator.framework.authorizer.PermissionAuthorizationValve; import org.wso2.carbon.webapp.authenticator.framework.config.AuthenticatorConfig; import org.wso2.carbon.webapp.authenticator.framework.config.WebappAuthenticatorConfig; @@ -79,6 +79,7 @@ public class WebappAuthenticatorFrameworkServiceComponent { List valves = new ArrayList(); valves.add(new WebappAuthenticationHandler()); + valves.add(new PermissionAuthorizationValve()); TomcatValveContainer.addValves(valves); if (log.isDebugEnabled()) { diff --git a/features/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework.server.feature/src/main/resources/p2.inf b/features/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework.server.feature/src/main/resources/p2.inf index 91ac161b4e..7b1ad15df1 100644 --- a/features/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework.server.feature/src/main/resources/p2.inf +++ b/features/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework.server.feature/src/main/resources/p2.inf @@ -1,2 +1,2 @@ instructions.configure = \ -org.eclipse.equinox.p2.touchpoint.natives.copy(source:${installFolder}/../features/org.wso2.carbon.webapp.authenticator.framework.server_${feature.version}/conf/webapp-authenticator-config.xml,target:${installFolder}/../../conf/etc/webapp-authenticator-config.xml,overwrite:true);\ \ No newline at end of file +org.eclipse.equinox.p2.touchpoint.natives.copy(source:${installFolder}/../features/org.wso2.carbon.webapp.authenticator.framework.server_${feature.version}/conf/webapp-authenticator-config.xml,target:${installFolder}/../../conf/etc/webapp-authenticator-config.xml,overwrite:true);\ diff --git a/pom.xml b/pom.xml index b9ea2c5d22..c72d68ede3 100644 --- a/pom.xml +++ b/pom.xml @@ -935,6 +935,11 @@ org.wso2.carbon.identity.oauth ${carbon.identity.version} + + org.wso2.carbon.identity + org.wso2.carbon.identity.sso.saml + ${carbon.identity.version} + com.googlecode.json-simple.wso2 json-simple