diff --git a/modules/components/org.wso2.carbon.appfactory.s4.integration/src/main/java/org/wso2/carbon/appfactory/s4/integration/utils/DomainMappingUtils.java b/modules/components/org.wso2.carbon.appfactory.s4.integration/src/main/java/org/wso2/carbon/appfactory/s4/integration/utils/DomainMappingUtils.java index 3b8d8a286..8b8f0113f 100644 --- a/modules/components/org.wso2.carbon.appfactory.s4.integration/src/main/java/org/wso2/carbon/appfactory/s4/integration/utils/DomainMappingUtils.java +++ b/modules/components/org.wso2.carbon.appfactory.s4.integration/src/main/java/org/wso2/carbon/appfactory/s4/integration/utils/DomainMappingUtils.java @@ -41,6 +41,8 @@ import org.wso2.carbon.appfactory.s4.integration.DomainMapperEventHandler; import org.wso2.carbon.appfactory.s4.integration.internal.ServiceReferenceHolder; import org.wso2.carbon.context.CarbonContext; +import org.wso2.carbon.user.core.UserCoreConstants; +import org.wso2.carbon.utils.multitenancy.MultitenantUtils; import java.io.IOException; import java.io.UnsupportedEncodingException; @@ -117,8 +119,10 @@ public static DomainMappingResponse sendPostRequest(String stage, String body, S * @return auth header in basic encode */ private static String getAuthHeaderValue() { - String userName = CarbonContext.getThreadLocalCarbonContext().getUsername() + "@" - + CarbonContext.getThreadLocalCarbonContext().getTenantDomain(); + String usernameInContext = CarbonContext.getThreadLocalCarbonContext().getUsername(); + String tenantLessUserName = MultitenantUtils.getTenantAwareUsername(usernameInContext); + String userName = tenantLessUserName+ UserCoreConstants.TENANT_DOMAIN_COMBINER+ + CarbonContext.getThreadLocalCarbonContext().getTenantDomain(); // password as garbage value since we authenticate with mutual ssl. // We need to set the auth header for requests with the username. diff --git a/modules/jaggery-apps/appmgt/src/modules/application/get/list.jag b/modules/jaggery-apps/appmgt/src/modules/application/get/list.jag index 74face407..67be23d25 100755 --- a/modules/jaggery-apps/appmgt/src/modules/application/get/list.jag +++ b/modules/jaggery-apps/appmgt/src/modules/application/get/list.jag @@ -956,6 +956,42 @@ } }; + var getAppVersionsByStage = function(applicationKey, stage){ + var allResults = getAppVersionsInStages(applicationKey); + return generateCustomUrlResponse(parse(allResults),stage); + }; + + function generateCustomUrlResponse(allResults, stage){ + var simplifiedAppInfo = {}; + if(allResults.length > 0){ + var appinfo = allResults[0]; + simplifiedAppInfo["key"] = appinfo.key; + simplifiedAppInfo["type"] = appinfo.type; + simplifiedAppInfo["mappedSubDomain"] = appinfo.mappedSubDomain; + simplifiedAppInfo["customUrl"] = appinfo.customUrl; + simplifiedAppInfo["customUrlVerificationCode"] = appinfo.customUrlVerificationCode; + simplifiedAppInfo["isUploadable"] = appinfo.isUploadable; + simplifiedAppInfo["name"] = appinfo.name; + simplifiedAppInfo["versions"] = getSimplifiedVersionArray(appinfo.versions, stage); + } + return simplifiedAppInfo; + } + + function getSimplifiedVersionArray(versionsArray, stage){ + var simplifiedVersionArray = []; + for (var i = 0; i < versionsArray.length; i++) { + var version = versionsArray[i]; + if (0 == version.stage.localeCompare(stage)) { + simplifiedVersionArray.push( + { + "version": version.version, + "productionMappedDomain": version.productionMappedDomain + }); + } + } + return simplifiedVersionArray; + } + var getStage = function(applicationKey, version) { jagg.module("permission").checkUserAuthenticated(); var tenantDomain = modManager.getTenantDomain(); diff --git a/modules/jaggery-apps/appmgt/src/modules/application/module.jag b/modules/jaggery-apps/appmgt/src/modules/application/module.jag index b6f55c084..e9872a2a0 100755 --- a/modules/jaggery-apps/appmgt/src/modules/application/module.jag +++ b/modules/jaggery-apps/appmgt/src/modules/application/module.jag @@ -94,6 +94,10 @@ jagg.module("application", { return jagg.require(jagg.getModulesDir() + "application/get/list.jag").getAppVersionsInStages.apply(this, arguments); }, + getAppVersionsByStage:function () { + return jagg.require(jagg.getModulesDir() + "application/get/list.jag").getAppVersionsByStage.apply(this, arguments); + }, + getAppCountInStage:function () { return jagg.require(jagg.getModulesDir() + "application/get/list.jag").getAppCountInStage.apply(this, arguments); }, diff --git a/modules/jaggery-apps/appmgt/src/site/blocks/application/get/ajax/list.jag b/modules/jaggery-apps/appmgt/src/site/blocks/application/get/ajax/list.jag index 232df7c07..e811ae570 100755 --- a/modules/jaggery-apps/appmgt/src/site/blocks/application/get/ajax/list.jag +++ b/modules/jaggery-apps/appmgt/src/site/blocks/application/get/ajax/list.jag @@ -252,6 +252,11 @@ var log=new Log(); var metaDataNeed = request.getParameter("metaDataNeed"); var buildable = request.getParameter("buildable"); print(mod.getAppVersionsInStages(applicationKey, userName, metaDataNeed, buildable, isRoleBasedPermissionAllowed)); + } else if (action === "getAppVersionsByStage") { + mod = jagg.module("application"); + var applicationKey = request.getParameter("applicationKey"); + var stage = request.getParameter("stage"); + print(mod.getAppVersionsByStage(applicationKey,stage)); } else if (action === "getAppVersionsInStagesWithMetaData") { mod = jagg.module("application"); var userName = request.getParameter("userName"); @@ -361,4 +366,36 @@ var log=new Log(); }()); +function generateCustomUrlResponse(allResults, stage){ + var simplifiedAppInfo = {}; + if(allResults.length > 0){ + var appinfo = allResults[0]; + simplifiedAppInfo["key"] = appinfo.key; + simplifiedAppInfo["type"] = appinfo.type; + simplifiedAppInfo["mappedSubDomain"] = appinfo.mappedSubDomain; + simplifiedAppInfo["customUrl"] = appinfo.customUrl; + simplifiedAppInfo["customUrlVerificationCode"] = appinfo.customUrlVerificationCode; + simplifiedAppInfo["isUploadable"] = appinfo.isUploadable; + simplifiedAppInfo["name"] = appinfo.name; + simplifiedAppInfo["versions"] = getSimplifiedVersionArray(appinfo.versions, stage); + } + return simplifiedAppInfo; +} + +function getSimplifiedVersionArray(versionsArray, stage){ + var simplifiedVersionArray = []; + log.info(versionsArray); + for (var i = 0; i < versionsArray.length; i++) { + var version = versionsArray[i]; + if (0 == version.stage.localeCompare(stage)) { + simplifiedVersionArray.push( + { + "version": version.version, + "productionMappedDomain": version.productionMappedDomain + }); + } + } + return simplifiedVersionArray; +} + %> \ No newline at end of file diff --git a/modules/jaggery-apps/appmgt/src/site/blocks/urlmapper/add/block.jag b/modules/jaggery-apps/appmgt/src/site/blocks/urlmapper/add/block.jag index d52eca2d3..16cda9da2 100755 --- a/modules/jaggery-apps/appmgt/src/site/blocks/urlmapper/add/block.jag +++ b/modules/jaggery-apps/appmgt/src/site/blocks/urlmapper/add/block.jag @@ -20,15 +20,48 @@ jagg.block("urlmapper/add", { initialize:function (data) { - } - - - + }, + getInputs:function () { + return { + "applicationKey":null + } + }, + getOutputs:function (inputs) { + var applicationKey = request.getParameter("applicationKey"); + var mod = jagg.module("manager"); + var modApplication = jagg.module("application"); + var userName = jagg.getUser(); + if(userName) { + var permissionModule = jagg.module("permission"); + var isTenantAdmin = permissionModule.hasTenantLevelUserMgtPermission(); + var tenantDomain = mod.getTenantDomain(); + var fineGrainedDomainMappingAllowedStage = getProperty(FINE_GRAINED_DOMAIN_MAPPING); + var hasDomainMappingPermission = jagg.module("permission").isUserAccessGranted(inputs.applicationKey, + PERMISSION_DOMAIN_MAPPING); + var applicationType = mod.getApplicationType(applicationKey); + var isAllowDomainMapping = mod.getApplicationTypeBean(applicationType).isAllowDomainMapping(); + var hasAppCreationPermission = jagg.module("permission").hasAppCreationPermission(); + var isUploadableAppType = mod.getApplicationTypeBean(applicationType).isUploadableAppType(); + var initialAppVersionInfo = modApplication.getAppVersionsByStage(applicationKey, + fineGrainedDomainMappingAllowedStage); + } + return { + "tenantDomain": tenantDomain, + "hasDomainMappingPermission": hasDomainMappingPermission, + "fineGrainedDomainMappingAllowedStage": fineGrainedDomainMappingAllowedStage, + "isAllowDomainMapping": isAllowDomainMapping, + "hasAppCreationPermission": hasAppCreationPermission, + "isUploadableAppType": isUploadableAppType, + "isTenantAdmin":isTenantAdmin, + "initialAppVersionInfo": initialAppVersionInfo + }; + } }); %> + diff --git a/modules/jaggery-apps/appmgt/src/site/blocks/urlmapper/get/ajax/get.jag b/modules/jaggery-apps/appmgt/src/site/blocks/urlmapper/get/ajax/get.jag new file mode 100755 index 000000000..7ff436a94 --- /dev/null +++ b/modules/jaggery-apps/appmgt/src/site/blocks/urlmapper/get/ajax/get.jag @@ -0,0 +1,91 @@ +<% +/* + * Copyright (c) 2014, 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. + */ + +include("/jagg/jagg.jag"); +include("/jagg/constants.jag"); +include("/jagg/config_reader.jag"); + +var lifeCycleModule = jagg.module("lifecycle"); +var log=new Log(); +var mod = jagg.module("urlmapper"); +var permission = jagg.module("permission"); +var manager = jagg.module("manager"); + +(function () { + action = request.getParameter("action"), + site = require("/site/conf/site.json"); + if (!jagg.getUser()) { + print(UNAUTHORIZED_ERROR_RESPONSE); + return; + } + if(action == "addNewCustomUrl"){ + var newCustomUrl = request.getParameter("newCustomUrl"); + newCustomUrl = newCustomUrl.toLowerCase(); + var applicationKey = request.getParameter("applicationKey"); + if (permission.isUserAccessGranted(applicationKey, PERMISSION_DOMAIN_MAPPING)){ + var stage = getProperty(FINE_GRAINED_DOMAIN_MAPPING); + try { + mod.addNewCustomUrl(stage, newCustomUrl, applicationKey, null, true); + } catch (e) { + // we are logging this as warn messages since this is caused, due a to user error. For example if the + // user entered a rubbish custom url(Or a url which CNAME record is not propagated at the time of + // adding the url), then url validation will fail but it is not an system error + var msg = "Error while adding new customer url: "+ newCustomUrl +" for application: "+applicationKey + +" in stage: " + stage+". New custom url: "+newCustomUrl+" might not a valid url(or non existing)"; + log.warn(msg); + log.warn(e); + response.status = 400; + response.content = e; + } + + } else { + response.status = 401; + response.content = "Unauthorized!!! Only Application Owner has permission to complete this action"; + } + } else if (action == "addDefaultProdUrl") { + var appKey = request.getParameter("applicationKey"); + var version = null; + var applicationType = manager.getApplicationType(appKey); + var isUploadableAppType = manager.getApplicationTypeBean(applicationType).isUploadableAppType(); + if (isUploadableAppType) { + version = UPLOADABLE_APPLICATION_INITIAL_VERSION; + } + try { + if(manager.getApplicationTypeBean(applicationType).isAllowDomainMapping()) { + mod.addDefaultProdUrl(appKey, version); + print(true); + } + print(false); + } catch (e) { + var msg = "Error while adding default production url"; + log.error(msg); + log.error(e); + response.status = 400; + response.content = e; + } + } + else { + throw new Error("No action specified"); + } +}()); + + + +%> + diff --git a/modules/jaggery-apps/appmgt/src/site/blocks/urlmapper/update/ajax/update.jag b/modules/jaggery-apps/appmgt/src/site/blocks/urlmapper/update/ajax/update.jag index 951e7d50c..7a6964f1f 100755 --- a/modules/jaggery-apps/appmgt/src/site/blocks/urlmapper/update/ajax/update.jag +++ b/modules/jaggery-apps/appmgt/src/site/blocks/urlmapper/update/ajax/update.jag @@ -100,6 +100,29 @@ var permission = jagg.module("permission"); } else { response.sendError(401, "Unauthorized!!! Only Application Owner has permission to complete this action"); } + } else if(action == "updateDomainMapping"){ + + var newCustomUrl = request.getParameter("productionCustom"); + newCustomUrl = newCustomUrl.toLowerCase(); + var newVersionToMap = request.getParameter("productionVersion"); + var applicationKey = request.getParameter("applicationKey"); + if (permission.isUserAccessGranted(applicationKey, PERMISSION_DOMAIN_MAPPING)){ + try { + changeDomainMapping(applicationKey, newVersionToMap, newCustomUrl); + } catch (e) { + var msg = "Error while updating the production/customer url(s) " + +( (newVersionToMap) ? " to version:"+newVersionToMap:"") + +( (newCustomUrl) ?" to new custom URL:"+newCustomUrl:"") + +" for application: "+applicationKey + +", tenantDomain:"+jagg.module("manager").getTenantDomain(); + log.error(msg); + log.error(e); + response.status = 400; + response.content = e; + } + } else { + response.sendError(401, "Unauthorized!!! Only Application Owner has permission to complete this action"); + } } else if(action == "removeCustomUrl"){ var applicationKey = request.getParameter("applicationKey"); var stage = getProperty(FINE_GRAINED_DOMAIN_MAPPING); @@ -122,6 +145,51 @@ var permission = jagg.module("permission"); }()); +function changeDomainMapping(applicationKey, newVersionToMap, newCustomUrl){ + var modApplication = jagg.module("application"); + var modUrlMapper = jagg.module("urlmapper"); + var domainMappingAllowedStage = getProperty(FINE_GRAINED_DOMAIN_MAPPING); + var initialAppVersionInfo = modApplication.getAppVersionsByStage(applicationKey, domainMappingAllowedStage); + + var existingCustomUrl = initialAppVersionInfo.customUrl; + var existingMappedVersion = getExistingMappedVersion(initialAppVersionInfo.versions); + if(newCustomUrl == existingCustomUrl && (existingMappedVersion) && ! newVersionToMap){ + throw "Cannot remove existing mapped version"; + } + if(newCustomUrl) { // if new custom Url is defined + if(existingMappedVersion){ // if there is already existing mapped version + modUrlMapper.mapNewCustomUrlToVersion( + domainMappingAllowedStage,newCustomUrl,applicationKey,newVersionToMap,true); + } else { // if there is no already existing mapped version + if(existingCustomUrl){ // if there is existing custom url + modUrlMapper.updateExistingUnmappedCustomUrl(domainMappingAllowedStage,newCustomUrl,applicationKey); + } else { // if there is no existing custom url + modUrlMapper.addNewCustomUrl(domainMappingAllowedStage, newCustomUrl, applicationKey, null, true); + } + modUrlMapper.remapDomainToVersion( + domainMappingAllowedStage, applicationKey, newVersionToMap,existingMappedVersion); + } + } else { // if new custom url is not defined + if(existingCustomUrl){ + modUrlMapper.removeDomainMappingFromApplication(domainMappingAllowedStage,applicationKey,null,true); + } else { + modUrlMapper.remapDomainToVersion( + domainMappingAllowedStage, applicationKey, newVersionToMap,existingMappedVersion); + } + + } +} + +function getExistingMappedVersion(versionsArray){ + for (var i = 0; i < versionsArray.length; i++) { + var version = versionsArray[i]; + if(version.productionMappedDomain){ + return version.version; + } + } + return null; +} + %> diff --git a/modules/jaggery-apps/appmgt/src/site/pages/customurl.jag b/modules/jaggery-apps/appmgt/src/site/pages/customurl.jag new file mode 100644 index 000000000..deb46087e --- /dev/null +++ b/modules/jaggery-apps/appmgt/src/site/pages/customurl.jag @@ -0,0 +1,87 @@ +<% +/* + * Copyright (c) 2014, 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. + */ + +include("/jagg/jagg.jag"); +var site = require("/site/conf/site.json"); + +(function () { + var applicationName = request.getParameter("applicationName"); + var applicationKey = request.getParameter("applicationKey"); + jagg.render({ + "name":"page/master", + "inputs":{ + "title":"WSO2 App Factory", + "pagePath":"/site/pages/customurl.jag", + "pageName":"Custom URL", + "body":[ + { + "name":"layout/master", + "inputs":{ + "title":"WSO2 App Factory", + "middle":[ + { + "name":"urlmapper/add", + "inputs":{ + "applicationKey":applicationKey, + "applicationName": applicationName + } + } + ], + "breadcrumb":[ + { + "name":"breadcrumb", + "inputs":{ + "linkParams": [ + { + "basePath":"/site/pages/application.jag", + "displayName": applicationName, + "params": { + "applicationKey":applicationKey, + "applicationName":applicationName + } + }, + { + "basePath":"/site/pages/customurl.jag", + "displayName": "Custom URL", + "params": { + "applicationKey":applicationKey, + "applicationName":applicationName + } + } + ] + } + } + ], + "tablinks":[ + { + "name":"tablinks", + "inputs":{ + "applicationKey":applicationKey, + "applicationName":applicationName, + "pageName":"CustomURL" + } + } + ] + } + } + ] + } + }); +}()); +%> \ No newline at end of file diff --git a/modules/jaggery-apps/appmgt/src/site/themes/default/templates/application/get/template.jag b/modules/jaggery-apps/appmgt/src/site/themes/default/templates/application/get/template.jag index 039a376c7..ef4fc331f 100755 --- a/modules/jaggery-apps/appmgt/src/site/themes/default/templates/application/get/template.jag +++ b/modules/jaggery-apps/appmgt/src/site/themes/default/templates/application/get/template.jag @@ -83,7 +83,8 @@ if (customUrl) { %>
<%}%> diff --git a/modules/jaggery-apps/appmgt/src/site/themes/default/templates/tablinks/template.jag b/modules/jaggery-apps/appmgt/src/site/themes/default/templates/tablinks/template.jag index bb4d55880..e1819da52 100755 --- a/modules/jaggery-apps/appmgt/src/site/themes/default/templates/tablinks/template.jag +++ b/modules/jaggery-apps/appmgt/src/site/themes/default/templates/tablinks/template.jag @@ -96,6 +96,12 @@ include("/jagg/constants.jag"); <% } %> + +