diff --git a/components/identity-extensions/org.wso2.carbon.device.mgt.oauth.extensions/pom.xml b/components/identity-extensions/org.wso2.carbon.device.mgt.oauth.extensions/pom.xml index e36f684f364..a40e30b63ff 100644 --- a/components/identity-extensions/org.wso2.carbon.device.mgt.oauth.extensions/pom.xml +++ b/components/identity-extensions/org.wso2.carbon.device.mgt.oauth.extensions/pom.xml @@ -47,6 +47,14 @@ org.wso2.carbon org.wso2.carbon.user.core + + org.wso2.carbon.apimgt + org.wso2.carbon.apimgt.impl + + + com.googlecode.json-simple.wso2 + json-simple + @@ -87,7 +95,24 @@ org.wso2.carbon.user.core.service, org.wso2.carbon.identity.application.common.model, org.wso2.carbon.identity.application.authentication.framework.model, - org.wso2.carbon.user.core.tenant + org.wso2.carbon.user.core.tenant, + org.json.simple, + javax.cache, + javax.xml.namespace, + org.apache.axiom.om, + org.wso2.carbon.apimgt.api, + org.wso2.carbon.apimgt.impl, + org.wso2.carbon.apimgt.impl.dao, + org.wso2.carbon.apimgt.impl.utils, + org.wso2.carbon.identity.application.common.cache, + org.wso2.carbon.identity.core.util, + org.wso2.carbon.identity.oauth2.dto, + org.wso2.carbon.identity.oauth2.token, + org.wso2.carbon.identity.oauth2.token.handlers.grant, + org.wso2.carbon.user.core, + org.wso2.carbon.user.core.config, + org.wso2.carbon.user.core.util, + org.wso2.carbon.utils diff --git a/components/identity-extensions/org.wso2.carbon.device.mgt.oauth.extensions/src/main/java/org/wso2/carbon/device/mgt/oauth/extensions/OAuthExtUtils.java b/components/identity-extensions/org.wso2.carbon.device.mgt.oauth.extensions/src/main/java/org/wso2/carbon/device/mgt/oauth/extensions/OAuthExtUtils.java index aa5a73b1401..c6a626db0d2 100644 --- a/components/identity-extensions/org.wso2.carbon.device.mgt.oauth.extensions/src/main/java/org/wso2/carbon/device/mgt/oauth/extensions/OAuthExtUtils.java +++ b/components/identity-extensions/org.wso2.carbon.device.mgt.oauth.extensions/src/main/java/org/wso2/carbon/device/mgt/oauth/extensions/OAuthExtUtils.java @@ -20,9 +20,23 @@ package org.wso2.carbon.device.mgt.oauth.extensions; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import org.wso2.carbon.apimgt.api.APIManagementException; +import org.wso2.carbon.apimgt.impl.APIConstants; +import org.wso2.carbon.apimgt.impl.dao.ApiMgtDAO; +import org.wso2.carbon.apimgt.impl.utils.APIUtil; import org.wso2.carbon.device.mgt.oauth.extensions.internal.OAuthExtensionsDataHolder; +import org.wso2.carbon.identity.core.util.IdentityTenantUtil; +import org.wso2.carbon.identity.oauth2.token.OAuthTokenReqMessageContext; import org.wso2.carbon.user.api.TenantManager; +import org.wso2.carbon.user.api.UserRealm; import org.wso2.carbon.user.api.UserStoreException; +import org.wso2.carbon.user.core.service.RealmService; + +import javax.cache.Caching; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Map; /** * This class holds util methods used by OAuth extension bundle. @@ -30,6 +44,8 @@ import org.wso2.carbon.user.api.UserStoreException; public class OAuthExtUtils { private static final Log log = LogFactory.getLog(OAuthExtUtils.class); + private static final String DEFAULT_SCOPE_NAME = "default"; + private static final String UI_EXECUTE = "ui.execute"; public static int getTenantId(String tenantDomain) { int tenantId = 0; @@ -39,10 +55,175 @@ public class OAuthExtUtils { tenantId = tenantManager.getTenantId(tenantDomain); } catch (UserStoreException e) { String errorMsg = "Error when getting the tenant id from the tenant domain : " + - tenantDomain; + tenantDomain; log.error(errorMsg, e); } } return tenantId; } + + public static boolean setScopes(OAuthTokenReqMessageContext tokReqMsgCtx) { + String[] requestedScopes = tokReqMsgCtx.getScope(); + String[] defaultScope = new String[]{DEFAULT_SCOPE_NAME}; + //If no scopes were requested. + if (requestedScopes == null || requestedScopes.length == 0) { + tokReqMsgCtx.setScope(defaultScope); + return true; + } + + String consumerKey = tokReqMsgCtx.getOauth2AccessTokenReqDTO().getClientId(); + String username = tokReqMsgCtx.getAuthorizedUser().getUserName(); + List reqScopeList = Arrays.asList(requestedScopes); + Map restAPIScopesOfCurrentTenant; + + try { + + Map appScopes; + ApiMgtDAO apiMgtDAO = new ApiMgtDAO(); + //Get all the scopes and roles against the scopes defined for the APIs subscribed to the application. + appScopes = apiMgtDAO.getScopeRolesOfApplication(consumerKey); + //Add API Manager rest API scopes set. This list should be loaded at server start up and keep + //in memory and add it to each and every request coming. + String tenantDomain = tokReqMsgCtx.getAuthorizedUser().getTenantDomain(); + restAPIScopesOfCurrentTenant = (Map) Caching.getCacheManager(APIConstants.API_MANAGER_CACHE_MANAGER) + .getCache("REST_API_SCOPE_CACHE") + .get(tenantDomain); + if (restAPIScopesOfCurrentTenant != null) { + appScopes.putAll(restAPIScopesOfCurrentTenant); + } else { + restAPIScopesOfCurrentTenant = APIUtil.getRESTAPIScopesFromConfig(APIUtil.getTenantRESTAPIScopesConfig(tenantDomain)); + //call load tenant config for rest API. + //then put cache + appScopes.putAll(restAPIScopesOfCurrentTenant); + Caching.getCacheManager(APIConstants.API_MANAGER_CACHE_MANAGER) + .getCache("REST_API_SCOPE_CACHE") + .put(tenantDomain, restAPIScopesOfCurrentTenant); + } + //If no scopes can be found in the context of the application + if (appScopes.isEmpty()) { + if (log.isDebugEnabled()) { + log.debug("No scopes defined for the Application " + + tokReqMsgCtx.getOauth2AccessTokenReqDTO().getClientId()); + } + + String[] allowedScopes = getAllowedScopes(reqScopeList); + tokReqMsgCtx.setScope(allowedScopes); + return true; + } + + int tenantId; + RealmService realmService = OAuthExtensionsDataHolder.getInstance().getRealmService(); + + try { + tenantId = realmService.getTenantManager().getTenantId(tenantDomain); + + // If tenant Id is not set in the tokenReqContext, deriving it from username. + if (tenantId == 0 || tenantId == -1) { + tenantId = IdentityTenantUtil.getTenantIdOfUser(username); + } + + } catch (UserStoreException e) { + //Log and return since we do not want to stop issuing the token in case of scope validation failures. + log.error("Error when getting the tenant's UserStoreManager or when getting roles of user ", e); + return false; + } + + UserRealm userRealm = OAuthExtensionsDataHolder.getInstance().getRealmService().getTenantUserRealm(tenantId); + List authorizedScopes = new ArrayList<>(); + boolean status; + //List userRoleList = new ArrayList<>(Arrays.asList(userRoles)); + + //Iterate the requested scopes list. + for (String scope : reqScopeList) { + status = false; + //Get the set of roles associated with the requested scope. + String appPermissions = appScopes.get(scope); + //If the scope has been defined in the context of the App and if roles have been defined for the scope + if (appPermissions != null && appPermissions.length() != 0) { + List permissions = new ArrayList<>(Arrays.asList(appPermissions.replaceAll(" ", "").split(","))); + //Check if user has at least one of the roles associated with the scope + if (!permissions.isEmpty()) { + for (String permission : permissions) { + if (userRealm != null && userRealm.getAuthorizationManager() != null) { + String userStore = tokReqMsgCtx.getAuthorizedUser().getUserStoreDomain(); + + if (userStore != null) { + status = userRealm.getAuthorizationManager() + .isUserAuthorized(userStore + "/" + username, permission, UI_EXECUTE); + } else { + status = userRealm.getAuthorizationManager() + .isUserAuthorized(username, permission, UI_EXECUTE); + } + if (status) { + break; + } + } + } + if (status) { + authorizedScopes.add(scope); + } + } + } + //The requested scope is defined for the context of the App but no roles have been associated with the scope + //OR + //The scope string starts with 'device_'. + else if (appScopes.containsKey(scope) || isWhiteListedScope(scope)) { + authorizedScopes.add(scope); + } + } + if (!authorizedScopes.isEmpty()) { + String[] authScopesArr = authorizedScopes.toArray(new String[authorizedScopes.size()]); + tokReqMsgCtx.setScope(authScopesArr); + } else { + tokReqMsgCtx.setScope(defaultScope); + } + } catch (APIManagementException e) { + log.error("Error while getting scopes of application " + e.getMessage()); + return false; + } catch (UserStoreException e) { + e.printStackTrace(); + } + return true; + } + + /** + * Determines if the scope is specified in the whitelist. + * + * @param scope - The scope key to check + * @return - 'true' if the scope is white listed. 'false' if not. + */ + public static boolean isWhiteListedScope(String scope) { + // load white listed scopes + List scopeSkipList = OAuthExtensionsDataHolder.getInstance().getWhitelistedScopes(); + for (String scopeTobeSkipped : scopeSkipList) { + if (scope.matches(scopeTobeSkipped)) { + return true; + } + } + return false; + } + + /** + * Get the set of default scopes. If a requested scope is matches with the patterns specified in the whitelist, + * then such scopes will be issued without further validation. If the scope list is empty, + * token will be issued for default scope. + * + * @param requestedScopes - The set of requested scopes + * @return - The subset of scopes that are allowed + */ + private static String[] getAllowedScopes(List requestedScopes) { + List authorizedScopes = new ArrayList(); + + //Iterate the requested scopes list. + for (String scope : requestedScopes) { + if (isWhiteListedScope(scope)) { + authorizedScopes.add(scope); + } + } + if (authorizedScopes.isEmpty()) { + authorizedScopes.add(DEFAULT_SCOPE_NAME); + } + return authorizedScopes.toArray(new String[authorizedScopes.size()]); + } + } diff --git a/components/identity-extensions/org.wso2.carbon.device.mgt.oauth.extensions/src/main/java/org/wso2/carbon/device/mgt/oauth/extensions/handlers/grant/ExtendedPasswordGrantHandler.java b/components/identity-extensions/org.wso2.carbon.device.mgt.oauth.extensions/src/main/java/org/wso2/carbon/device/mgt/oauth/extensions/handlers/grant/ExtendedPasswordGrantHandler.java new file mode 100644 index 00000000000..2223a915bc1 --- /dev/null +++ b/components/identity-extensions/org.wso2.carbon.device.mgt.oauth.extensions/src/main/java/org/wso2/carbon/device/mgt/oauth/extensions/handlers/grant/ExtendedPasswordGrantHandler.java @@ -0,0 +1,340 @@ +/* + * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.wso2.carbon.device.mgt.oauth.extensions.handlers.grant; + +import org.apache.axiom.om.OMElement; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.wso2.carbon.device.mgt.oauth.extensions.OAuthExtUtils; +import org.wso2.carbon.device.mgt.oauth.extensions.internal.OAuthExtensionsDataHolder; +import org.wso2.carbon.identity.application.common.cache.BaseCache; +import org.wso2.carbon.identity.core.util.IdentityConfigParser; +import org.wso2.carbon.identity.core.util.IdentityCoreConstants; +import org.wso2.carbon.identity.core.util.IdentityTenantUtil; +import org.wso2.carbon.identity.oauth.common.OAuthConstants; +import org.wso2.carbon.identity.oauth2.IdentityOAuth2Exception; +import org.wso2.carbon.identity.oauth2.ResponseHeader; +import org.wso2.carbon.identity.oauth2.dto.OAuth2AccessTokenReqDTO; +import org.wso2.carbon.identity.oauth2.token.OAuthTokenReqMessageContext; +import org.wso2.carbon.identity.oauth2.token.handlers.grant.PasswordGrantHandler; +import org.wso2.carbon.user.api.Claim; +import org.wso2.carbon.user.api.UserStoreException; +import org.wso2.carbon.user.api.UserStoreManager; +import org.wso2.carbon.user.core.UserRealm; +import org.wso2.carbon.user.core.config.RealmConfiguration; +import org.wso2.carbon.user.core.service.RealmService; +import org.wso2.carbon.user.core.util.UserCoreUtil; + +import javax.xml.namespace.QName; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +@SuppressWarnings("unused") +public class ExtendedPasswordGrantHandler extends PasswordGrantHandler { + + private static Log log = LogFactory.getLog(ExtendedPasswordGrantHandler.class); + + private static final String CONFIG_ELEM_OAUTH = "OAuth"; + + // Claims that are set as response headers of access token response + private static final String REQUIRED_CLAIM_URIS = "RequiredRespHeaderClaimUris"; + private BaseCache userClaimsCache; + + // Primary/Secondary Login configuration + private static final String CLAIM_URI = "ClaimUri"; + private static final String LOGIN_CONFIG = "LoginConfig"; + private static final String USERID_LOGIN = "UserIdLogin"; + private static final String EMAIL_LOGIN = "EmailLogin"; + private static final String PRIMARY_LOGIN = "primary"; + + private Map> loginConfiguration = new ConcurrentHashMap<>(); + + private List requiredHeaderClaimUris = new ArrayList<>(); + + public void init() throws IdentityOAuth2Exception { + + super.init(); + + IdentityConfigParser configParser; + configParser = IdentityConfigParser.getInstance(); + OMElement oauthElem = configParser.getConfigElement(CONFIG_ELEM_OAUTH); + + // Get the required claim uris that needs to be included in the response. + parseRequiredHeaderClaimUris(oauthElem.getFirstChildWithName(getQNameWithIdentityNS(REQUIRED_CLAIM_URIS))); + + // read login config + parseLoginConfig(oauthElem); + + userClaimsCache = new BaseCache<>("UserClaimsCache"); + if (log.isDebugEnabled()) { + log.debug("Successfully created UserClaimsCache under " + OAuthConstants.OAUTH_CACHE_MANAGER); + } + } + + @Override + public boolean validateGrant(OAuthTokenReqMessageContext tokReqMsgCtx) + throws IdentityOAuth2Exception { + + OAuth2AccessTokenReqDTO oAuth2AccessTokenReqDTO = tokReqMsgCtx.getOauth2AccessTokenReqDTO(); + String username = oAuth2AccessTokenReqDTO.getResourceOwnerUsername(); + String loginUserName = getLoginUserName(username); + tokReqMsgCtx.getOauth2AccessTokenReqDTO().setResourceOwnerUsername(loginUserName); + + boolean isValidated = super.validateGrant(tokReqMsgCtx); + + if(isValidated){ + + int tenantId; + tenantId = IdentityTenantUtil.getTenantIdOfUser(username); + + RealmService realmService = OAuthExtensionsDataHolder.getInstance().getRealmService(); + UserStoreManager userStoreManager; + try { + userStoreManager = realmService.getTenantUserRealm(tenantId).getUserStoreManager(); + } catch (UserStoreException e) { + log.error("Error when getting the tenant's UserStoreManager", e); + return false; + } + + List respHeaders = new ArrayList<>(); + + if (oAuth2AccessTokenReqDTO.getResourceOwnerUsername() != null) { + + try { + + if (requiredHeaderClaimUris != null && !requiredHeaderClaimUris.isEmpty()) { + // Get user's claim values from the default profile. + String userStoreDomain = tokReqMsgCtx.getAuthorizedUser().getUserStoreDomain(); + + String endUsernameWithDomain = UserCoreUtil.addDomainToName + (oAuth2AccessTokenReqDTO.getResourceOwnerUsername(), + userStoreDomain); + + Claim[] mapClaimValues = getUserClaimValues(endUsernameWithDomain,userStoreManager); + + if(mapClaimValues != null && mapClaimValues.length > 0){ + ResponseHeader header; + for (String claimUri : requiredHeaderClaimUris) { + for (Claim claim : mapClaimValues) { + if (claimUri.equals(claim.getClaimUri())) { + header = new ResponseHeader(); + header.setKey(claim.getDisplayTag()); + header.setValue(claim.getValue()); + respHeaders.add(header); + break; + } + } + } + } + else if(log.isDebugEnabled()){ + log.debug("No claim values for user : "+endUsernameWithDomain); + } + + } + } catch (Exception e) { + throw new IdentityOAuth2Exception(e.getMessage(), e); + } + } + + tokReqMsgCtx.addProperty("RESPONSE_HEADERS", respHeaders.toArray( + new ResponseHeader[respHeaders.size()])); + } + + return isValidated; + } + + @Override + public boolean validateScope(OAuthTokenReqMessageContext tokReqMsgCtx){ + return OAuthExtUtils.setScopes(tokReqMsgCtx); + } + + private String getLoginUserName(String userID) { + String loginUserName = userID; + if (isSecondaryLogin(userID)) { + loginUserName = getPrimaryFromSecondary(userID); + } + return loginUserName; + } + + /** + * Identify whether the logged in user used his Primary Login name or + * Secondary login name + * + * @param userId - The username used to login. + * @return true if secondary login name is used, + * false if primary login name has been used + */ + private boolean isSecondaryLogin(String userId) { + + if (loginConfiguration.get(EMAIL_LOGIN) != null) { + Map emailConf = loginConfiguration.get(EMAIL_LOGIN); + if ("true".equalsIgnoreCase(emailConf.get(PRIMARY_LOGIN))) { + return !isUserLoggedInEmail(userId); + } + else if ("false".equalsIgnoreCase(emailConf.get(PRIMARY_LOGIN))) { + return isUserLoggedInEmail(userId); + } + } + else if (loginConfiguration.get(USERID_LOGIN) != null) { + Map userIdConf = loginConfiguration.get(USERID_LOGIN); + if ("true".equalsIgnoreCase(userIdConf.get(PRIMARY_LOGIN))) { + return isUserLoggedInEmail(userId); + } + else if ("false".equalsIgnoreCase(userIdConf.get(PRIMARY_LOGIN))) { + return !isUserLoggedInEmail(userId); + } + } + return false; + } + + /** + * Identify whether the logged in user used his ordinal username or email + * + * @param userId - username used to login. + * @return - true if userId contains '@'. false otherwise + */ + private boolean isUserLoggedInEmail(String userId) { + return userId.contains("@"); + } + + /** + * Get the primaryLogin name using secondary login name. Primary secondary + * Configuration is provided in the identitiy.xml. In the userstore, it is + * users responsibility TO MAINTAIN THE SECONDARY LOGIN NAME AS UNIQUE for + * each and every users. If it is not unique, we will pick the very first + * entry from the userlist. + * + * @param login - username used to login. + * @return - + */ + private String getPrimaryFromSecondary(String login) { + + String claimURI, username = null; + if (isUserLoggedInEmail(login)) { + Map emailConf = loginConfiguration.get(EMAIL_LOGIN); + claimURI = emailConf.get(CLAIM_URI); + } else { + Map userIdConf = loginConfiguration.get(USERID_LOGIN); + claimURI = userIdConf.get(CLAIM_URI); + } + + try { + RealmService realmSvc = OAuthExtensionsDataHolder.getInstance().getRealmService(); + RealmConfiguration config = new RealmConfiguration(); + UserRealm realm = realmSvc.getUserRealm(config); + org.wso2.carbon.user.core.UserStoreManager storeManager = realm.getUserStoreManager(); + String[] user = storeManager.getUserList(claimURI, login, null); + if (user.length > 0) { + username = user[0]; + } + } catch (UserStoreException e) { + log.error("Error while retrieving the primaryLogin name using secondary login name : " + login, e); + } + return username; + } + + private Claim[] getUserClaimValues(String authorizedUser, UserStoreManager userStoreManager) + throws + UserStoreException { + Claim[] userClaims = userClaimsCache.getValueFromCache(authorizedUser); + if(userClaims != null){ + return userClaims; + }else{ + if(log.isDebugEnabled()){ + log.debug("Cache miss for user claims. Username :" + authorizedUser); + } + userClaims = userStoreManager.getUserClaimValues( + authorizedUser, null); + userClaimsCache.addToCache(authorizedUser,userClaims); + return userClaims; + } + } + + // Read the required claim configuration from identity.xml + private void parseRequiredHeaderClaimUris(OMElement requiredClaimUrisElem) { + if (requiredClaimUrisElem == null) { + return; + } + + Iterator claimUris = requiredClaimUrisElem.getChildrenWithLocalName(CLAIM_URI); + if (claimUris != null) { + while (claimUris.hasNext()) { + OMElement claimUri = (OMElement) claimUris.next(); + if (claimUri != null) { + requiredHeaderClaimUris.add(claimUri.getText()); + } + } + } + } + + /** + * Read the primary/secondary login configuration + * + * .... + * + * + * + * + * + * http://wso2.org/claims/emailaddress + * + * + * ..... + * + * @param oauthConfigElem - The '' xml configuration element in the api-manager.xml + */ + private void parseLoginConfig(OMElement oauthConfigElem) { + OMElement loginConfigElem = oauthConfigElem.getFirstChildWithName(getQNameWithIdentityNS(LOGIN_CONFIG)); + if (loginConfigElem != null) { + if (log.isDebugEnabled()) { + log.debug("Login configuration is set "); + } + // Primary/Secondary supported login mechanisms + OMElement emailConfigElem = loginConfigElem.getFirstChildWithName(getQNameWithIdentityNS(EMAIL_LOGIN)); + + OMElement userIdConfigElem = loginConfigElem.getFirstChildWithName(getQNameWithIdentityNS(USERID_LOGIN)); + + Map emailConf = new HashMap(2); + emailConf.put(PRIMARY_LOGIN, + emailConfigElem.getAttributeValue(new QName(PRIMARY_LOGIN))); + emailConf.put(CLAIM_URI, + emailConfigElem.getFirstChildWithName(getQNameWithIdentityNS(CLAIM_URI)) + .getText()); + + Map userIdConf = new HashMap(2); + userIdConf.put(PRIMARY_LOGIN, + userIdConfigElem.getAttributeValue(new QName(PRIMARY_LOGIN))); + userIdConf.put(CLAIM_URI, + userIdConfigElem.getFirstChildWithName(getQNameWithIdentityNS(CLAIM_URI)) + .getText()); + + loginConfiguration.put(EMAIL_LOGIN, emailConf); + loginConfiguration.put(USERID_LOGIN, userIdConf); + } + } + + private QName getQNameWithIdentityNS(String localPart) { + return new QName(IdentityCoreConstants.IDENTITY_DEFAULT_NAMESPACE, localPart); + } +} diff --git a/components/identity-extensions/org.wso2.carbon.device.mgt.oauth.extensions/src/main/java/org/wso2/carbon/device/mgt/oauth/extensions/internal/OAuthExtensionServiceComponent.java b/components/identity-extensions/org.wso2.carbon.device.mgt.oauth.extensions/src/main/java/org/wso2/carbon/device/mgt/oauth/extensions/internal/OAuthExtensionServiceComponent.java index b8be1c467ff..3cdeeb5e8df 100644 --- a/components/identity-extensions/org.wso2.carbon.device.mgt.oauth.extensions/src/main/java/org/wso2/carbon/device/mgt/oauth/extensions/internal/OAuthExtensionServiceComponent.java +++ b/components/identity-extensions/org.wso2.carbon.device.mgt.oauth.extensions/src/main/java/org/wso2/carbon/device/mgt/oauth/extensions/internal/OAuthExtensionServiceComponent.java @@ -21,9 +21,17 @@ package org.wso2.carbon.device.mgt.oauth.extensions.internal; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.osgi.service.component.ComponentContext; +import org.wso2.carbon.apimgt.api.APIManagementException; +import org.wso2.carbon.apimgt.impl.APIConstants; +import org.wso2.carbon.apimgt.impl.APIManagerConfiguration; import org.wso2.carbon.device.mgt.common.permission.mgt.PermissionManagerService; import org.wso2.carbon.identity.oauth2.OAuth2TokenValidationService; import org.wso2.carbon.user.core.service.RealmService; +import org.wso2.carbon.utils.CarbonUtils; + +import java.io.File; +import java.util.ArrayList; +import java.util.List; /** * @scr.component name="org.wso2.carbon.device.mgt.oauth.extensions" immediate="true" @@ -49,17 +57,51 @@ import org.wso2.carbon.user.core.service.RealmService; public class OAuthExtensionServiceComponent { private static final Log log = LogFactory.getLog(OAuthExtensionServiceComponent.class); + private static final String REPOSITORY = "repository"; + private static final String CONFIGURATION = "conf"; + private static final String APIM_CONF_FILE = "api-manager.xml"; + @SuppressWarnings("unused") protected void activate(ComponentContext componentContext) { - if(log.isDebugEnabled()){ + if (log.isDebugEnabled()) { log.debug("Starting OAuthExtensionBundle"); } + try { + APIManagerConfiguration configuration = new APIManagerConfiguration(); + String filePath = new StringBuilder(). + append(CarbonUtils.getCarbonHome()). + append(File.separator). + append(REPOSITORY). + append(File.separator). + append(CONFIGURATION). + append(File.separator). + append(APIM_CONF_FILE).toString(); + + configuration.load(filePath); + // loading white listed scopes + List whiteList; + + // Read scope whitelist from Configuration. + whiteList = configuration.getProperty(APIConstants.API_KEY_MANGER_SCOPE_WHITELIST); + + // If whitelist is null, default scopes will be put. + if (whiteList == null) { + whiteList = new ArrayList(); + whiteList.add(APIConstants.OPEN_ID_SCOPE_NAME); + whiteList.add(APIConstants.DEVICE_SCOPE_PATTERN); + } + + OAuthExtensionsDataHolder.getInstance().setWhitelistedScopes(whiteList); + + } catch (APIManagementException e) { + log.error("Error occurred while loading APIM configurations", e); + } } @SuppressWarnings("unused") protected void deactivate(ComponentContext componentContext) { - if(log.isDebugEnabled()){ + if (log.isDebugEnabled()) { log.debug("Stopping OAuthExtensionBundle"); } } diff --git a/components/identity-extensions/org.wso2.carbon.device.mgt.oauth.extensions/src/main/java/org/wso2/carbon/device/mgt/oauth/extensions/internal/OAuthExtensionsDataHolder.java b/components/identity-extensions/org.wso2.carbon.device.mgt.oauth.extensions/src/main/java/org/wso2/carbon/device/mgt/oauth/extensions/internal/OAuthExtensionsDataHolder.java index f87ac765d38..f5916880016 100644 --- a/components/identity-extensions/org.wso2.carbon.device.mgt.oauth.extensions/src/main/java/org/wso2/carbon/device/mgt/oauth/extensions/internal/OAuthExtensionsDataHolder.java +++ b/components/identity-extensions/org.wso2.carbon.device.mgt.oauth.extensions/src/main/java/org/wso2/carbon/device/mgt/oauth/extensions/internal/OAuthExtensionsDataHolder.java @@ -22,6 +22,8 @@ import org.wso2.carbon.device.mgt.common.permission.mgt.PermissionManagerService import org.wso2.carbon.identity.oauth2.OAuth2TokenValidationService; import org.wso2.carbon.user.core.service.RealmService; +import java.util.List; + /** * This holds the OSGi service references required for oauth extensions bundle. */ @@ -30,6 +32,7 @@ public class OAuthExtensionsDataHolder { private RealmService realmService; private OAuth2TokenValidationService oAuth2TokenValidationService; private PermissionManagerService permissionManagerService; + private List whitelistedScopes; private static OAuthExtensionsDataHolder thisInstance = new OAuthExtensionsDataHolder(); @@ -72,4 +75,12 @@ public class OAuthExtensionsDataHolder { } return permissionManagerService; } + + public List getWhitelistedScopes() { + return whitelistedScopes; + } + + public void setWhitelistedScopes(List whitelistedScopes) { + this.whitelistedScopes = whitelistedScopes; + } }