@ -1,57 +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.
|
||||
#
|
||||
|
||||
#issuer of the JWT
|
||||
iss=wso2.org/products/iot
|
||||
|
||||
TokenEndpoint=https://${iot.keymanager.host}:${iot.keymanager.https.port}/oauth2/token
|
||||
|
||||
#audience of JWT claim
|
||||
#comma seperated values
|
||||
aud=devicemgt
|
||||
|
||||
#expiration time of JWT (number of minutes from the current time)
|
||||
exp=1000
|
||||
|
||||
#issued at time of JWT (number of minutes from the current time)
|
||||
iat=0
|
||||
|
||||
#nbf time of JWT (number of minutes from current time)
|
||||
nbf=0
|
||||
|
||||
#skew between IDP and issuer(seconds)
|
||||
skew=0
|
||||
|
||||
# JWT Id
|
||||
#jti=token123
|
||||
|
||||
#KeyStore to cryptographic credentials
|
||||
#KeyStore=repository/resources/security/wso2carbon.jks
|
||||
|
||||
#Password of the KeyStore
|
||||
#KeyStorePassword=wso2carbon
|
||||
|
||||
#Alias of the SP's private key
|
||||
#PrivateKeyAlias=wso2carbon
|
||||
|
||||
#Private key password to retrieve the private key used to sign
|
||||
#AuthnRequest and LogoutRequest messages
|
||||
#PrivateKeyPassword=wso2carbon
|
||||
|
||||
#this will be used as the default IDP config if there isn't any config available for tenants.
|
||||
default-jwt-client=true
|
@ -0,0 +1,78 @@
|
||||
<?xml version="1.0" encoding="ISO-8859-1"?>
|
||||
|
||||
<!--
|
||||
~ Copyright 2005-2011 WSO2, Inc. (http://wso2.com)
|
||||
~
|
||||
~ 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.
|
||||
-->
|
||||
|
||||
<!--
|
||||
This is the configuration file for Carbon authenticators. All the authenticator related configurations
|
||||
should go here.
|
||||
-->
|
||||
<Authenticators xmlns="http://wso2.org/projects/carbon/authenticators.xml">
|
||||
|
||||
<!-- Authenticator Configurations for TokenUIAuthenticator -->
|
||||
<Authenticator name="TokenUIAuthenticator" disabled="true">
|
||||
<Priority>5</Priority>
|
||||
</Authenticator>
|
||||
|
||||
<!-- Authenticator Configurations for SAML2SSOAuthenticator -->
|
||||
<Authenticator name="SAML2SSOAuthenticator" disabled="true">
|
||||
<Priority>10</Priority>
|
||||
<Config>
|
||||
<Parameter name="LoginPage">/carbon/admin/login.jsp</Parameter>
|
||||
<Parameter name="ServiceProviderID">carbonServer</Parameter>
|
||||
<Parameter name="IdentityProviderSSOServiceURL">https://localhost:9443/samlsso</Parameter>
|
||||
<Parameter name="NameIDPolicyFormat">urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified</Parameter>
|
||||
<Parameter name="AssertionConsumerServiceURL">https://localhost:9443/acs</Parameter>
|
||||
|
||||
<!-- <Parameter name="IdPCertAlias">wso2carbon</Parameter> -->
|
||||
<!-- <Parameter name="ResponseSignatureValidationEnabled">false</Parameter> -->
|
||||
<!-- <Parameter name="AssertionSignatureValidationEnabled">false</Parameter> -->
|
||||
<!-- <Parameter name="LoginAttributeName"></Parameter> -->
|
||||
<!-- <Parameter name="RoleClaimAttribute"></Parameter> -->
|
||||
<!-- <Parameter name="AttributeValueSeparator">,</Parameter> -->
|
||||
|
||||
<!-- <Parameter name="JITUserProvisioning">true</Parameter> -->
|
||||
<!-- <Parameter name="ProvisioningDefaultUserstore">PRIMARY</Parameter> -->
|
||||
<!-- <Parameter name="ProvisioningDefaultRole">admin</Parameter> -->
|
||||
<!-- <Parameter name="IsSuperAdminRoleRequired">true</Parameter> -->
|
||||
</Config>
|
||||
|
||||
<!-- If this authenticator should skip any URI from authentication, specify it under "SkipAuthentication"
|
||||
<SkipAuthentication>
|
||||
<UrlContains></UrlContains>
|
||||
</SkipAuthentication> -->
|
||||
|
||||
<!-- If this authenticator should skip any URI from session validation, specify it under "SkipAuthentication
|
||||
<SkipSessionValidation>
|
||||
<UrlContains></UrlContains>
|
||||
</SkipSessionValidation> -->
|
||||
</Authenticator>
|
||||
|
||||
<Authenticator name="SignedJWTAuthenticator" disabled="false">
|
||||
<Priority>5</Priority>
|
||||
</Authenticator>
|
||||
|
||||
<!-- Authenticator Configurations for MutualSSLAuthenticator -->
|
||||
<!--Authenticator name="MutualSSLAuthenticator" disabled="false">
|
||||
<Priority>5</Priority>
|
||||
<Config>
|
||||
<Parameter name="UsernameHeader">UserName</Parameter>
|
||||
<Parameter name="WhiteListEnabled">false</Parameter>
|
||||
<Parameter name="WhiteList"/>
|
||||
</Config>
|
||||
</Authenticator-->
|
||||
|
||||
</Authenticators>
|
@ -0,0 +1,598 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
var utils = function () {
|
||||
var log = new Log("/modules/oauth/token-handler-utils.js");
|
||||
|
||||
var configs = require('/configs/portal.js').config();
|
||||
var constants = require("/modules/constants.js");
|
||||
var carbon = require("carbon");
|
||||
|
||||
//noinspection JSUnresolvedVariable
|
||||
var Base64 = Packages.org.apache.commons.codec.binary.Base64;
|
||||
//noinspection JSUnresolvedVariable
|
||||
var String = Packages.java.lang.String;
|
||||
|
||||
var publicMethods = {};
|
||||
var privateMethods = {};
|
||||
|
||||
publicMethods["encode"] = function (payload) {
|
||||
return String(Base64.encodeBase64(String(payload).getBytes()));
|
||||
};
|
||||
|
||||
publicMethods["decode"] = function (payload) {
|
||||
return String(Base64.decodeBase64(String(payload).getBytes()));
|
||||
};
|
||||
|
||||
/**
|
||||
* Check whether this application is oauth enable or not
|
||||
* @returns boolean if oauth enable
|
||||
*/
|
||||
publicMethods["checkOAuthEnabled"] = function () {
|
||||
if (constants.AUTHORIZATION_TYPE_OAUTH === configs["authorization"]["activeMethod"]) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
/**
|
||||
* Set access token into xml http request header
|
||||
* @param xhr xml http request
|
||||
* @returns {*} xhr which has access token it's header
|
||||
*/
|
||||
publicMethods["setAccessToken"] = function (xhr, callback) {
|
||||
var accessToken;
|
||||
if (publicMethods.checkOAuthEnabled()) {
|
||||
try {
|
||||
accessToken = parse(session.get(constants.ACCESS_TOKEN_PAIR_IDENTIFIER_FOR_PORTAL))["accessToken"];
|
||||
xhr.setRequestHeader(constants.AUTHORIZATION_HEADER, constants.BEARER_PREFIX + accessToken);
|
||||
} catch (exception) {
|
||||
log.error("Access token hasn't been set yet, " + exception);
|
||||
} finally {
|
||||
callback(xhr);
|
||||
}
|
||||
}
|
||||
callback(xhr);
|
||||
};
|
||||
|
||||
/**
|
||||
* Get access token of current logged user
|
||||
* @param callBack response with access token
|
||||
*/
|
||||
publicMethods["getAccessToken"] = function (callBack) {
|
||||
var accessToken = null;
|
||||
if (publicMethods.checkOAuthEnabled()) {
|
||||
try {
|
||||
accessToken = parse(session.get(constants.ACCESS_TOKEN_PAIR_IDENTIFIER_FOR_PORTAL))["accessToken"];
|
||||
} catch (exception) {
|
||||
log.error("Access token hasn't been set yet, " + exception);
|
||||
} finally {
|
||||
callBack(accessToken);
|
||||
}
|
||||
}
|
||||
callBack(accessToken);
|
||||
};
|
||||
|
||||
/**
|
||||
* Create error message which adhere to xml http response object
|
||||
* @param statusCode response status code
|
||||
* @param status response status
|
||||
* @param responseText response message
|
||||
* @returns {{statusCode: *, status: *, responseText: *}}
|
||||
*/
|
||||
publicMethods["createXHRObject"] = function (statusCode, status, responseText) {
|
||||
return {"statusCode": statusCode, "status": status, "responseText": responseText};
|
||||
};
|
||||
|
||||
/**
|
||||
* check whether user already logged to system before invoking any apis
|
||||
* @param callBack
|
||||
*/
|
||||
publicMethods["isUserAuthorized"] = function (callBack) {
|
||||
if (session.get("Loged") !== constants.LOGIN_MESSAGE) {
|
||||
callBack(false);
|
||||
} else {
|
||||
callBack(true);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Get identity provider uir
|
||||
* @returns {*}
|
||||
*/
|
||||
publicMethods["getIdPServerURL"] = function () {
|
||||
return configs["authorization"]["methods"]["oauth"]["attributes"]["oauthProvider"]["tokenServiceURL"];
|
||||
};
|
||||
|
||||
/**
|
||||
* Get an Access token pair based on client secret
|
||||
* @param encodedClientKeys {{clientId:"", clientSecret:""}}
|
||||
* @param scope eg: PRODUCTION
|
||||
* @param idPServer identity provider url
|
||||
* @returns {{accessToken: *, refreshToken: *}}
|
||||
*/
|
||||
publicMethods["getTokenWithClientSecretType"] = function (encodedClientKeys, scope, idPServer) {
|
||||
var xhr = new XMLHttpRequest();
|
||||
var tokenEndpoint = idPServer;
|
||||
xhr.open(constants.HTTP_POST, tokenEndpoint, false);
|
||||
xhr.setRequestHeader(constants.CONTENT_TYPE_IDENTIFIER, constants.APPLICATION_X_WWW_FOR_URLENCODED);
|
||||
xhr.setRequestHeader(constants.AUTHORIZATION_HEADER, constants.BASIC_PREFIX + encodedClientKeys);
|
||||
xhr.send("grant_type=client_credentials&scope=" + scope);
|
||||
var tokenPair = {};
|
||||
if (xhr.status == constants.HTTP_ACCEPTED) {
|
||||
var data = parse(xhr.responseText);
|
||||
tokenPair.refreshToken = data.refresh_token;
|
||||
tokenPair.accessToken = data.access_token;
|
||||
} else if (xhr.status == constants.HTTP_USER_NOT_AUTHENTICATED) {
|
||||
log.error("Error in obtaining token with client secret grant type, You are not authenticated yet");
|
||||
return null;
|
||||
} else {
|
||||
log.error("Error in obtaining token with client secret grant type, This might be a problem with client meta " +
|
||||
"data which required for client secret grant type");
|
||||
return null;
|
||||
}
|
||||
return tokenPair;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* This will create client id and client secret for a given application
|
||||
* @param properties "callbackUrl": "",
|
||||
* "clientName": "",
|
||||
* "owner": "",
|
||||
* "applicationType": "",
|
||||
* "grantType": "",
|
||||
* "saasApp" :"",
|
||||
* "dynamicClientRegistrationEndPoint" : ""
|
||||
*
|
||||
* @returns {{clientId:*, clientSecret:*}}
|
||||
*/
|
||||
publicMethods["getDynamicClientAppCredentials"] = function (username) {
|
||||
// setting up dynamic client application properties
|
||||
var dcAppProperties = {
|
||||
"applicationType": configs["authorization"]["methods"]["oauth"]["attributes"]["oauthProvider"]["appRegistration"]["appType"],
|
||||
"clientName": configs["authorization"]["methods"]["oauth"]["attributes"]["oauthProvider"]["appRegistration"]["clientName"],
|
||||
"owner": configs["authorization"]["methods"]["oauth"]["attributes"]["oauthProvider"]["appRegistration"]["owner"],
|
||||
"tokenScope": configs["authorization"]["methods"]["oauth"]["attributes"]["oauthProvider"]["appRegistration"]["tokenScope"],
|
||||
"grantType": configs["authorization"]["methods"]["oauth"]["attributes"]["oauthProvider"]["appRegistration"]["grantType"],
|
||||
"callbackUrl": configs["authorization"]["methods"]["oauth"]["attributes"]["oauthProvider"]["appRegistration"]["callbackUrl"],
|
||||
"saasApp" : configs["authorization"]["methods"]["oauth"]["attributes"]["oauthProvider"]["appRegistration"]["saasApp"]
|
||||
};
|
||||
|
||||
var tenantDomain = carbon.server.tenantDomain({username: username});
|
||||
if (!tenantDomain) {
|
||||
log.error("{/modules/oauth/token-handler-utils.js} Error in retrieving tenant " +
|
||||
"based client application credentials. Unable to obtain a valid tenant domain for provided username "+
|
||||
username +"- getDynamicClientAppCredentials(x)");
|
||||
return null;
|
||||
} else {
|
||||
var cachedTenantBasedClientAppCredentials = privateMethods.
|
||||
getCachedTenantBasedClientAppCredentials(tenantDomain);
|
||||
if (cachedTenantBasedClientAppCredentials) {
|
||||
return cachedTenantBasedClientAppCredentials;
|
||||
} else {
|
||||
// calling dynamic client app registration service endpoint
|
||||
var requestURL = configs["authorization"]["methods"]["oauth"]["attributes"]["oauthProvider"]["appRegistration"]
|
||||
["dynamicClientAppRegistrationServiceURL"];
|
||||
var requestPayload = dcAppProperties;
|
||||
var token = publicMethods.encode(configs["authorization"]["methods"]["oauth"]["attributes"]["oauthProvider"]
|
||||
["appRegistration"]["owner"] + ":" + configs["authorization"]["methods"]["oauth"]["attributes"]
|
||||
["oauthProvider"]["appRegistration"]["password"]);
|
||||
var xhr = new XMLHttpRequest();
|
||||
xhr.open("POST", requestURL, false);
|
||||
xhr.setRequestHeader("Content-Type", "application/json");
|
||||
xhr.setRequestHeader("Authorization", "Basic "+ token);
|
||||
xhr.send(stringify(requestPayload));
|
||||
var dynamicClientAppCredentials = {};
|
||||
if (xhr["status"] == 201 || xhr["status"] == 200 && xhr["responseText"]) {
|
||||
var responsePayload = parse(xhr["responseText"]);
|
||||
var clientId = responsePayload["client_id"];
|
||||
var clientSecret = responsePayload["client_secret"];
|
||||
if(typeof clientId == "undefined"){
|
||||
clientId = responsePayload["clientId"];
|
||||
}
|
||||
if(typeof clientSecret == "undefined"){
|
||||
clientSecret = responsePayload["clientSecret"];
|
||||
}
|
||||
dynamicClientAppCredentials["clientId"] = clientId;
|
||||
dynamicClientAppCredentials["clientSecret"] = clientSecret;
|
||||
privateMethods.
|
||||
setCachedTenantBasedClientAppCredentials(tenantDomain, dynamicClientAppCredentials);
|
||||
} else if (xhr["status"] == 400) {
|
||||
log.error("{/modules/oauth/token-handler-utils.js - getDynamicClientAppCredentials()} " +
|
||||
"Bad request. Invalid data provided as dynamic client application properties.");
|
||||
dynamicClientAppCredentials = null;
|
||||
} else {
|
||||
log.error("{/modules/oauth/token-handler-utils.js - getDynamicClientAppCredentials()} " +
|
||||
"Error in retrieving dynamic client credentials.");
|
||||
dynamicClientAppCredentials = null;
|
||||
}
|
||||
// returning dynamic client credentials
|
||||
return dynamicClientAppCredentials;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* If gateway is enable, apiManagerClientAppRegistrationServiceURL is used to create oauth application
|
||||
* @param username username of current logged user
|
||||
* @returns {{clientId:*, clientSecret:*}}
|
||||
*/
|
||||
publicMethods["getTenantBasedClientAppCredentials"] = function (username) {
|
||||
if (!username) {
|
||||
log.error("{/modules/oauth/token-handler-utils.js} Error in retrieving tenant " +
|
||||
"based client app credentials. No username " +
|
||||
"as input - getTenantBasedClientAppCredentials(x)");
|
||||
return null;
|
||||
} else {
|
||||
//noinspection JSUnresolvedFunction, JSUnresolvedVariable
|
||||
var tenantDomain = carbon.server.tenantDomain({username: username});
|
||||
|
||||
if (!tenantDomain) {
|
||||
log.error("{/modules/oauth/token-handler-utils.js} Error in retrieving tenant " +
|
||||
"based client application credentials. Unable to obtain a valid tenant domain for provided " +
|
||||
"username - getTenantBasedClientAppCredentials(x, y)");
|
||||
return null;
|
||||
} else {
|
||||
var cachedTenantBasedClientAppCredentials = privateMethods.
|
||||
getCachedTenantBasedClientAppCredentials(tenantDomain);
|
||||
if (cachedTenantBasedClientAppCredentials) {
|
||||
return cachedTenantBasedClientAppCredentials;
|
||||
} else {
|
||||
var adminUsername = configs["authorization"]["methods"]["oauth"]["attributes"]["adminUser"];
|
||||
var adminUserTenantId = configs["authorization"]["methods"]["oauth"]["attributes"]
|
||||
["adminUserTenantId"];
|
||||
//claims required for jwtAuthenticator.
|
||||
var claims = {"http://wso2.org/claims/enduserTenantId": adminUserTenantId,
|
||||
"http://wso2.org/claims/enduser": adminUsername};
|
||||
var jwtToken = publicMethods.getJwtToken(adminUsername, claims);
|
||||
// register a tenant based client app at API Manager
|
||||
var applicationName = configs["authorization"]["methods"]["oauth"]["attributes"]["oauthProvider"]
|
||||
["appRegistration"]["clientName"] + "_" + tenantDomain;
|
||||
var requestURL = configs["authorization"]["methods"]["oauth"]["attributes"]["oauthProvider"]
|
||||
["appRegistration"]["apiManagerClientAppRegistrationServiceURL"] +
|
||||
"?tenantDomain=" + tenantDomain + "&applicationName=" + applicationName;
|
||||
var xhr = new XMLHttpRequest();
|
||||
xhr.open("POST", requestURL, false);
|
||||
xhr.setRequestHeader("Content-Type", "application/json");
|
||||
xhr.setRequestHeader("X-JWT-Assertion", "" + jwtToken);
|
||||
xhr.send();
|
||||
if ((xhr["status"] == 201 || xhr["status"] == 200) && xhr["responseText"]) {
|
||||
var responsePayload = parse(xhr["responseText"]);
|
||||
var tenantBasedClientAppCredentials = {};
|
||||
var clientId = responsePayload["client_id"];
|
||||
var clientSecret = responsePayload["client_secret"];
|
||||
if(typeof clientId == "undefined"){
|
||||
clientId = responsePayload["clientId"];
|
||||
}
|
||||
if(typeof clientSecret == "undefined"){
|
||||
clientSecret = responsePayload["clientSecret"];
|
||||
}
|
||||
tenantBasedClientAppCredentials["clientId"] = clientId;
|
||||
tenantBasedClientAppCredentials["clientSecret"] = clientSecret;
|
||||
privateMethods.
|
||||
setCachedTenantBasedClientAppCredentials(tenantDomain, tenantBasedClientAppCredentials);
|
||||
return tenantBasedClientAppCredentials;
|
||||
} else {
|
||||
log.error("{/modules/oauth/token-handler-utils.js} Error in retrieving tenant " +
|
||||
"based client application credentials from API " +
|
||||
"Manager - getTenantBasedClientAppCredentials(x, y)");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Caching oauth application credentials
|
||||
* @param tenantDomain tenant domain where application is been created
|
||||
* @param clientAppCredentials {{clientId:*, clientSecret:*}}
|
||||
*/
|
||||
privateMethods["setCachedTenantBasedClientAppCredentials"] = function (tenantDomain, clientAppCredentials) {
|
||||
var cachedTenantBasedClientAppCredentialsMap = application.get(constants["CACHED_CREDENTIALS_PORTAL_APP"]);
|
||||
if (!cachedTenantBasedClientAppCredentialsMap) {
|
||||
cachedTenantBasedClientAppCredentialsMap = {};
|
||||
cachedTenantBasedClientAppCredentialsMap[tenantDomain] = clientAppCredentials;
|
||||
application.put(constants["CACHED_CREDENTIALS_PORTAL_APP"], cachedTenantBasedClientAppCredentialsMap);
|
||||
} else if (!cachedTenantBasedClientAppCredentialsMap[tenantDomain]) {
|
||||
cachedTenantBasedClientAppCredentialsMap[tenantDomain] = clientAppCredentials;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Get oauth application credentials from cache
|
||||
* @param tenantDomain tenant domain where application is been created
|
||||
* @returns {{clientId:*, clientSecret:*}}
|
||||
*/
|
||||
privateMethods["getCachedTenantBasedClientAppCredentials"] = function (tenantDomain) {
|
||||
var cachedTenantBasedClientAppCredentialsMap = application.get(constants["CACHED_CREDENTIALS_PORTAL_APP"]);
|
||||
if (!cachedTenantBasedClientAppCredentialsMap ||
|
||||
!cachedTenantBasedClientAppCredentialsMap[tenantDomain]) {
|
||||
return null;
|
||||
} else {
|
||||
return cachedTenantBasedClientAppCredentialsMap[tenantDomain];
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Get access token and refresh token using password grant type
|
||||
* @param username username of the logged user
|
||||
* @param password password of the logged user
|
||||
* @param encodedClientAppCredentials {{clientId:*, clientSecret:*}}
|
||||
* @param scopes scopes list
|
||||
* @returns {{accessToken: *, refreshToken: *}}
|
||||
*/
|
||||
publicMethods["getTokenPairAndScopesByPasswordGrantType"] = function (username, password
|
||||
, encodedClientAppCredentials, scopes) {
|
||||
if (!username || !password || !encodedClientAppCredentials || !scopes) {
|
||||
log.error("{/modules/oauth/token-handler-utils.js} Error in retrieving access token by password " +
|
||||
"grant type. No username, password, encoded client app credentials or scopes are " +
|
||||
"found - getTokenPairAndScopesByPasswordGrantType(a, b, c, d)");
|
||||
return null;
|
||||
} else {
|
||||
// calling oauth provider token service endpoint
|
||||
var requestURL = configs["authorization"]["methods"]["oauth"]["attributes"]["oauthProvider"]
|
||||
["tokenServiceURL"];
|
||||
var requestPayload = "grant_type=password&username=" +
|
||||
username + "&password=" + password + "&scope=" + scopes;
|
||||
|
||||
var xhr = new XMLHttpRequest();
|
||||
xhr.open("POST", requestURL, false);
|
||||
xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
|
||||
xhr.setRequestHeader("Authorization", "Basic " + encodedClientAppCredentials);
|
||||
xhr.send(requestPayload);
|
||||
|
||||
if (xhr["status"] == 200 && xhr["responseText"]) {
|
||||
var responsePayload = parse(xhr["responseText"]);
|
||||
var tokenData = {};
|
||||
tokenData["accessToken"] = responsePayload["access_token"];
|
||||
tokenData["refreshToken"] = responsePayload["refresh_token"];
|
||||
tokenData["scopes"] = responsePayload["scope"];
|
||||
return tokenData;
|
||||
} else {
|
||||
log.error("{/modules/oauth/token-handler-utils.js} Error in retrieving access token " +
|
||||
"by password grant type - getTokenPairAndScopesByPasswordGrantType(a, b, c, d)");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Get access token and refresh token using SAML grant type
|
||||
* @param assertion
|
||||
* @param encodedClientAppCredentials
|
||||
* @param scopes
|
||||
* @returns {{accessToken: *, refreshToken: *}}
|
||||
*/
|
||||
publicMethods["getTokenPairAndScopesByJWTGrantType"] = function (username, encodedClientAppCredentials, scopes) {
|
||||
if (!username || !encodedClientAppCredentials || !scopes) {
|
||||
log.error("{/app/modules/oauth/token-handler-utils.js} Error in retrieving access token by jwt " +
|
||||
"grant type. No assertion, encoded client app credentials or scopes are " +
|
||||
"found - getTokenPairAndScopesByJWTGrantType(x, y, z)");
|
||||
return null;
|
||||
} else {
|
||||
var JWTClientManagerServicePackagePath =
|
||||
"org.wso2.carbon.identity.jwt.client.extension.service.JWTClientManagerService";
|
||||
//noinspection JSUnresolvedFunction, JSUnresolvedVariable
|
||||
var JWTClientManagerService = carbon.server.osgiService(JWTClientManagerServicePackagePath);
|
||||
//noinspection JSUnresolvedFunction
|
||||
var jwtClient = JWTClientManagerService.getJWTClient();
|
||||
// returning access token by JWT grant type
|
||||
var tokenInfo = jwtClient.getAccessToken(encodedClientAppCredentials,
|
||||
username, scopes);
|
||||
var tokenData = {};
|
||||
tokenData["accessToken"] = tokenInfo.getAccessToken();
|
||||
tokenData["refreshToken"] = tokenInfo.getRefreshToken();
|
||||
tokenData["scopes"] = tokenInfo.getScopes();
|
||||
return tokenData;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Get access token and refresh token using SAML grant type
|
||||
* @param assertion
|
||||
* @param encodedClientAppCredentials
|
||||
* @param scopes
|
||||
* @returns {{accessToken: *, refreshToken: *}}
|
||||
*/
|
||||
publicMethods["getTokenPairAndScopesBySAMLGrantType"] = function (assertion, encodedClientAppCredentials, scopes) {
|
||||
if (!assertion || !encodedClientAppCredentials || !scopes) {
|
||||
log.error("{/modules/oauth/token-handler-utils.js} Error in retrieving access token by saml " +
|
||||
"grant type. No assertion, encoded client app credentials or scopes are " +
|
||||
"found - getTokenPairAndScopesBySAMLGrantType(x, y, z)");
|
||||
return null;
|
||||
} else {
|
||||
|
||||
var assertionXML = publicMethods.decode(assertion);
|
||||
/*
|
||||
TODO: make assertion extraction with proper parsing.
|
||||
Since Jaggery XML parser seem to add formatting which causes signature verification to fail.
|
||||
*/
|
||||
var assertionStartMarker = "<saml2:Assertion";
|
||||
var assertionEndMarker = "<\/saml2:Assertion>";
|
||||
var assertionStartIndex = assertionXML.indexOf(assertionStartMarker);
|
||||
var assertionEndIndex = assertionXML.indexOf(assertionEndMarker);
|
||||
|
||||
var extractedAssertion;
|
||||
if (assertionStartIndex == -1 || assertionEndIndex == -1) {
|
||||
log.error("{/modules/oauth/token-handler-utils.js} Error in retrieving access token by saml grant " +
|
||||
"type. Issue in assertion format - getTokenPairAndScopesBySAMLGrantType(x, y, z)");
|
||||
return null;
|
||||
} else {
|
||||
extractedAssertion = assertionXML.
|
||||
substring(assertionStartIndex, assertionEndIndex) + assertionEndMarker;
|
||||
var encodedAssertion = publicMethods.encode(extractedAssertion);
|
||||
// calling oauth provider token service endpoint
|
||||
var requestURL = configs["authorization"]["methods"]["oauth"]["attributes"]["oauthProvider"]
|
||||
["tokenServiceURL"];
|
||||
var requestPayload = "grant_type=urn:ietf:params:oauth:grant-type:saml2-bearer&" +
|
||||
"assertion=" + encodeURIComponent(encodedAssertion) + "&scope=" + scopes;
|
||||
var xhr = new XMLHttpRequest();
|
||||
xhr.open("POST", requestURL, false);
|
||||
xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
|
||||
xhr.setRequestHeader("Authorization", "Basic " + encodedClientAppCredentials);
|
||||
xhr.send(requestPayload);
|
||||
|
||||
if (xhr["status"] == 200 && xhr["responseText"]) {
|
||||
var responsePayload = parse(xhr["responseText"]);
|
||||
var tokenData = {};
|
||||
tokenData["accessToken"] = responsePayload["access_token"];
|
||||
tokenData["refreshToken"] = responsePayload["refresh_token"];
|
||||
tokenData["scopes"] = responsePayload["scope"];
|
||||
return tokenData;
|
||||
} else {
|
||||
log.error("{/modules/oauth/token-handler-utils.js} Error in retrieving access token " +
|
||||
"by password grant type - getTokenPairAndScopesBySAMLGrantType(x, y, z)");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* If access token is expired, try to refresh it using existing refresh token
|
||||
* @param callback
|
||||
*/
|
||||
publicMethods["refreshAccessToken"] = function (callback) {
|
||||
try {
|
||||
if (publicMethods.checkOAuthEnabled()) {
|
||||
var currentTokenPair = parse(session.get(constants["ACCESS_TOKEN_PAIR_IDENTIFIER_FOR_PORTAL"]));
|
||||
// currentTokenPair includes current access token as well as current refresh token
|
||||
var encodedClientAppCredentials
|
||||
= session.get(constants["ENCODED_TENANT_BASED_CLIENT_APP_CREDENTIALS_PORTAL_APP"]);
|
||||
if (!currentTokenPair || !encodedClientAppCredentials) {
|
||||
callback(false);
|
||||
throw new Error("{/modules/oauth/token-handlers.js} Error in refreshing tokens. Either the " +
|
||||
"token pair, encoded client app credentials or both input are not found under " +
|
||||
"session context - refreshTokenPair()");
|
||||
} else {
|
||||
var newTokenPair = publicMethods.
|
||||
getNewTokenPairByRefreshToken(currentTokenPair["refreshToken"], encodedClientAppCredentials);
|
||||
if (!newTokenPair) {
|
||||
log.error("{/app/modules/oauth/token-handlers.js} Error in refreshing token pair. " +
|
||||
"Unable to update session context with new access token pair - refreshTokenPair()");
|
||||
callback(false);
|
||||
} else {
|
||||
session.put(constants["ACCESS_TOKEN_PAIR_IDENTIFIER_FOR_PORTAL"], stringify(newTokenPair));
|
||||
callback(true);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
log.error("You have not enable dynamic client yet");
|
||||
callback(false);
|
||||
}
|
||||
} catch (exception) {
|
||||
callback(false);
|
||||
throw "Error while refreshing existing access token, " + exception;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Get access token and refresh token using refresh token grant type
|
||||
* @param refreshToken refresh token
|
||||
* @param encodedClientAppCredentials {{clientId:*, clientSecret:*}}
|
||||
* @param scopes
|
||||
* @returns {{accessToken: *, refreshToken: *}}
|
||||
*/
|
||||
publicMethods["getNewTokenPairByRefreshToken"] = function (refreshToken, encodedClientAppCredentials, scopes) {
|
||||
if (!refreshToken || !encodedClientAppCredentials) {
|
||||
log.error("{/modules/oauth/token-handler-utils.js} Error in retrieving new access token " +
|
||||
"by current refresh token. No refresh token or encoded client app credentials are " +
|
||||
"found - getNewTokenPairByRefreshToken(x, y, z)");
|
||||
return null;
|
||||
} else {
|
||||
var requestURL = configs["authorization"]["methods"]["oauth"]["attributes"]["oauthProvider"]
|
||||
["tokenServiceURL"];
|
||||
var requestPayload = "grant_type=refresh_token&refresh_token=" + refreshToken;
|
||||
if (scopes) {
|
||||
requestPayload = requestPayload + "&scope=" + scopes;
|
||||
}
|
||||
|
||||
var xhr = new XMLHttpRequest();
|
||||
xhr.open("POST", requestURL, false);
|
||||
xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
|
||||
xhr.setRequestHeader("Authorization", "Basic " + encodedClientAppCredentials);
|
||||
xhr.send(requestPayload);
|
||||
|
||||
if (xhr["status"] == 200 && xhr["responseText"]) {
|
||||
var responsePayload = parse(xhr["responseText"]);
|
||||
var tokenPair = {};
|
||||
tokenPair["accessToken"] = responsePayload["access_token"];
|
||||
tokenPair["refreshToken"] = responsePayload["refresh_token"];
|
||||
return tokenPair;
|
||||
} else {
|
||||
log.error("{/modules/oauth/token-handler-utils.js} Error in retrieving new access token by " +
|
||||
"current refresh token - getNewTokenPairByRefreshToken(x, y, z)");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Get access token using JWT grant type
|
||||
* @param clientAppCredentials {{clientId:*, clientSecret:*}}
|
||||
* @returns {{accessToken: *, refreshToken: *}}
|
||||
*/
|
||||
publicMethods["getAccessTokenByJWTGrantType"] = function (clientAppCredentials) {
|
||||
if (!clientAppCredentials) {
|
||||
log.error("{/modules/oauth/token-handler-utils.js} Error in retrieving new access token " +
|
||||
"by current refresh token. No client app credentials are found " +
|
||||
"as input - getAccessTokenByJWTGrantType(x)");
|
||||
return null;
|
||||
} else {
|
||||
var JWTClientManagerServicePackagePath =
|
||||
"org.wso2.carbon.identity.jwt.client.extension.service.JWTClientManagerService";
|
||||
//noinspection JSUnresolvedFunction, JSUnresolvedVariable
|
||||
var JWTClientManagerService = carbon.server.osgiService(JWTClientManagerServicePackagePath);
|
||||
//noinspection JSUnresolvedFunction
|
||||
var jwtClient = JWTClientManagerService.getJWTClient();
|
||||
// returning access token by JWT grant type
|
||||
return jwtClient.getAccessToken(clientAppCredentials["clientId"], clientAppCredentials["clientSecret"],
|
||||
configs["authorization"]["methods"]["oauth"]["attributes"]["oauthProvider"]["appRegistration"]["owner"],
|
||||
null)["accessToken"];
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Get jwt token
|
||||
* @param username username of logged user
|
||||
* @param claims claims which are required
|
||||
* @returns {"jwtToken"}
|
||||
*/
|
||||
publicMethods["getJwtToken"] = function (username, claims) {
|
||||
if (!username) {
|
||||
log.error("{/modules/oauth/token-handler-utils.js} Error in retrieving new jwt token");
|
||||
return null;
|
||||
} else {
|
||||
var JWTClientManagerServicePackagePath =
|
||||
"org.wso2.carbon.identity.jwt.client.extension.service.JWTClientManagerService";
|
||||
//noinspection JSUnresolvedFunction, JSUnresolvedVariable
|
||||
var JWTClientManagerService = carbon.server.osgiService(JWTClientManagerServicePackagePath);
|
||||
//noinspection JSUnresolvedFunction
|
||||
var jwtClient = JWTClientManagerService.getJWTClient();
|
||||
// returning access token by JWT grant type
|
||||
if (claims) {
|
||||
return jwtClient.getJwtToken(username, claims);
|
||||
} else {
|
||||
return jwtClient.getJwtToken(username);
|
||||
}
|
||||
}
|
||||
};
|
||||
return publicMethods;
|
||||
}();
|
@ -0,0 +1,192 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* -----------------------------------------------------
|
||||
* Following module includes handlers
|
||||
* at Jaggery Layer for handling OAuth tokens.
|
||||
* -----------------------------------------------------
|
||||
*/
|
||||
var handlers = function () {
|
||||
var log = new Log("/modules/oauth/token-handlers.js");
|
||||
|
||||
var tokenUtil = require("/modules/oauth/token-handler-utils.js")["utils"];
|
||||
var constants = require("/modules/constants.js");
|
||||
var configs = require('/configs/portal.js').config();
|
||||
|
||||
var publicMethods = {};
|
||||
var privateMethods = {};
|
||||
|
||||
/**
|
||||
* Get an AccessToken pair based on username and password
|
||||
* @param username username of the logged user
|
||||
* @param password password of the logged user
|
||||
*/
|
||||
publicMethods["setupTokenPairByPasswordGrantType"] = function (username, password) {
|
||||
if (!username || !password) {
|
||||
throw new Error("{/modules/oauth/token-handlers.js} Could not set up access token pair by " +
|
||||
"password grant type. Either username of logged in user, password or both are missing " +
|
||||
"as input - setupTokenPairByPasswordGrantType(x, y)");
|
||||
} else {
|
||||
privateMethods.setUpEncodedTenantBasedClientAppCredentials(username);
|
||||
var encodedClientAppCredentials =
|
||||
session.get(constants["ENCODED_TENANT_BASED_CLIENT_APP_CREDENTIALS_PORTAL_APP"]);
|
||||
if (!encodedClientAppCredentials) {
|
||||
throw new Error("{/modules/oauth/token-handlers.js} Could not set up access token pair by " +
|
||||
"password grant type. Encoded client credentials are " +
|
||||
"missing - setupTokenPairByPasswordGrantType(x, y)");
|
||||
} else {
|
||||
var tokenData;
|
||||
// tokenPair will include current access token as well as current refresh token
|
||||
var arrayOfScopes = configs["authorization"]["methods"]["oauth"]["attributes"]["scopes"];
|
||||
var stringOfScopes = "";
|
||||
arrayOfScopes.forEach(function (entry) {
|
||||
stringOfScopes += entry + " ";
|
||||
});
|
||||
tokenData = tokenUtil.
|
||||
getTokenPairAndScopesByPasswordGrantType(username,
|
||||
encodeURIComponent(password), encodedClientAppCredentials, stringOfScopes);
|
||||
if (!tokenData) {
|
||||
throw new Error("{/app/modules/oauth/token-handlers.js} Could not set up " +
|
||||
"token pair by password grant type. Error in token " +
|
||||
"retrieval - setupTokenPairByPasswordGrantType(x, y)");
|
||||
} else {
|
||||
var tokenPair = {};
|
||||
tokenPair["accessToken"] = tokenData["accessToken"];
|
||||
tokenPair["refreshToken"] = tokenData["refreshToken"];
|
||||
// setting up token pair into session context as a string
|
||||
session.put(constants["ACCESS_TOKEN_PAIR_IDENTIFIER_FOR_PORTAL"], stringify(tokenPair));
|
||||
var scopes = tokenData.scopes.split(" ");
|
||||
// adding allowed scopes to the session
|
||||
session.put(constants["ALLOWED_SCOPES"], scopes);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Get an AccessToken pair based on SAML assertion
|
||||
* @param samlToken SAML assertion
|
||||
* @param username {{clientId:"", clientSecret:""}}
|
||||
*/
|
||||
publicMethods["setupTokenPairBySamlGrantType"] = function (username, samlToken) {
|
||||
if (!username || !samlToken) {
|
||||
throw new Error("{/modules/oauth/token-handlers.js} Could not set up access token pair by " +
|
||||
"saml grant type. Either username of logged in user, samlToken or both are missing " +
|
||||
"as input - setupTokenPairBySamlGrantType(x, y)");
|
||||
} else {
|
||||
privateMethods.setUpEncodedTenantBasedClientAppCredentials(username);
|
||||
var encodedClientAppCredentials =
|
||||
session.get(constants["ENCODED_TENANT_BASED_CLIENT_APP_CREDENTIALS_PORTAL_APP"]);
|
||||
if (!encodedClientAppCredentials) {
|
||||
throw new Error("{/app/modules/oauth/token-handlers.js} Could not set up access token pair " +
|
||||
"by saml grant type. Encoded client credentials are " +
|
||||
"missing - setupTokenPairBySamlGrantType(x, y)");
|
||||
} else {
|
||||
var tokenData;
|
||||
// accessTokenPair will include current access token as well as current refresh token
|
||||
tokenData = tokenUtil.
|
||||
getTokenPairAndScopesByJWTGrantType(username, encodedClientAppCredentials, "PRODUCTION");
|
||||
if (!tokenData) {
|
||||
throw new Error("{/modules/oauth/token-handlers.js} Could not set up token " +
|
||||
"pair by saml grant type. Error in token " +
|
||||
"retrieval - setupTokenPairBySamlGrantType(x, y)");
|
||||
} else {
|
||||
var tokenPair = {};
|
||||
tokenPair["accessToken"] = tokenData["accessToken"];
|
||||
tokenPair["refreshToken"] = tokenData["refreshToken"];
|
||||
// setting up access token pair into session context as a string
|
||||
session.put(constants["ACCESS_TOKEN_PAIR_IDENTIFIER_FOR_PORTAL"], stringify(tokenPair));
|
||||
|
||||
var scopes = tokenData.scopes.split(" ");
|
||||
// adding allowed scopes to the session
|
||||
session.put(constants["ALLOWED_SCOPES"], scopes);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Set access token and refresh token using refresh token grant type
|
||||
*/
|
||||
publicMethods["refreshTokenPair"] = function () {
|
||||
var currentTokenPair = parse(session.get(constants["ACCESS_TOKEN_PAIR_IDENTIFIER_FOR_PORTAL"]));
|
||||
// currentTokenPair includes current access token as well as current refresh token
|
||||
var encodedClientAppCredentials
|
||||
= session.get(constants["ENCODED_TENANT_BASED_CLIENT_APP_CREDENTIALS_PORTAL_APP"]);
|
||||
if (!currentTokenPair || !encodedClientAppCredentials) {
|
||||
throw new Error("{/modules/oauth/token-handlers.js} Error in refreshing tokens. Either the " +
|
||||
"token pair, encoded client app credentials or both input are not found under " +
|
||||
"session context - refreshTokenPair()");
|
||||
} else {
|
||||
var newTokenPair = tokenUtil.
|
||||
getNewTokenPairByRefreshToken(currentTokenPair["refreshToken"], encodedClientAppCredentials);
|
||||
if (!newTokenPair) {
|
||||
log.error("{/app/modules/oauth/token-handlers.js} Error in refreshing token pair. " +
|
||||
"Unable to update session context with new access token pair - refreshTokenPair()");
|
||||
} else {
|
||||
session.put(constants["ACCESS_TOKEN_PAIR_IDENTIFIER_FOR_PORTAL"], stringify(newTokenPair));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* If gateway is enable, apiManagerClientAppRegistrationServiceURL is used to create an oauth application or
|
||||
* else DCR endpoint is used to create an oauth application
|
||||
* @param username username of current logged user
|
||||
*/
|
||||
privateMethods["setUpEncodedTenantBasedClientAppCredentials"] = function (username) {
|
||||
if (!username) {
|
||||
throw new Error("{/modules/oauth/token-handlers.js} Could not set up encoded tenant based " +
|
||||
"client credentials to session context. No username of logged in user is found as " +
|
||||
"input - setUpEncodedTenantBasedClientAppCredentials(x)");
|
||||
} else {
|
||||
if (configs["authorization"]["methods"]["oauth"]["attributes"]["apimgt-gateway"]) {
|
||||
var tenantBasedClientAppCredentials = tokenUtil.getTenantBasedClientAppCredentials(username);
|
||||
if (!tenantBasedClientAppCredentials) {
|
||||
throw new Error("{/modules/oauth/token-handlers.js} Could not set up encoded tenant " +
|
||||
"based client credentials to session context as the server is unable " +
|
||||
"to obtain such credentials - setUpEncodedTenantBasedClientAppCredentials(x)");
|
||||
} else {
|
||||
var encodedTenantBasedClientAppCredentials =
|
||||
tokenUtil.encode(tenantBasedClientAppCredentials["clientId"] + ":" +
|
||||
tenantBasedClientAppCredentials["clientSecret"]);
|
||||
// setting up encoded tenant based client credentials to session context.
|
||||
session.put(constants["ENCODED_TENANT_BASED_CLIENT_APP_CREDENTIALS_PORTAL_APP"],
|
||||
encodedTenantBasedClientAppCredentials);
|
||||
}
|
||||
} else {
|
||||
var dynamicClientAppCredentials = tokenUtil.getDynamicClientAppCredentials(username);
|
||||
if (!dynamicClientAppCredentials) {
|
||||
throw new Error("{/modules/oauth/token-handlers.js} Could not set up encoded tenant based " +
|
||||
"client credentials to session context as the server is unable to obtain " +
|
||||
"dynamic client credentials - setUpEncodedTenantBasedClientAppCredentials(x)");
|
||||
}
|
||||
var encodedTenantBasedClientAppCredentials =
|
||||
tokenUtil.encode(dynamicClientAppCredentials["clientId"] + ":" +
|
||||
dynamicClientAppCredentials["clientSecret"]);
|
||||
// setting up encoded tenant based client credentials to session context.
|
||||
session.put(constants["ENCODED_TENANT_BASED_CLIENT_APP_CREDENTIALS_PORTAL_APP"],
|
||||
encodedTenantBasedClientAppCredentials);
|
||||
}
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
return publicMethods;
|
||||
}();
|
@ -0,0 +1,245 @@
|
||||
/*
|
||||
* Copyright (c) 2015, 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.
|
||||
*/
|
||||
|
||||
.truncate {
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validation messages
|
||||
*/
|
||||
.required {
|
||||
color: #e74c3c;
|
||||
}
|
||||
|
||||
.required-error {
|
||||
background: #a94442;
|
||||
border: 1px solid #a94442;
|
||||
padding: 6px 12px;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
/**
|
||||
* Theme overrides
|
||||
*/
|
||||
.breadcrumb li .fw-home {
|
||||
float: left;
|
||||
padding-top: 2px;
|
||||
margin-right: 5px;
|
||||
}
|
||||
|
||||
/**
|
||||
* Auth menu
|
||||
*/
|
||||
.auth .hidden-xs {
|
||||
line-height: 38px;
|
||||
}
|
||||
|
||||
.auth-xs {
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.auth-xs ul {
|
||||
list-style: none;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
line-height: 28px;
|
||||
background-color: #2a80b9;
|
||||
}
|
||||
|
||||
.auth-xs li {
|
||||
color: #ccc;
|
||||
}
|
||||
|
||||
.auth-xs li a {
|
||||
display: block;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.auth-xs li a:hover {
|
||||
background-color: #499dd5;
|
||||
}
|
||||
|
||||
ul.dropdown-menu.more-actions-button {
|
||||
list-style-type: none;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
overflow: hidden;
|
||||
width: 40px;
|
||||
background: #F9F9F9;
|
||||
border-bottom: 1px solid #EFEFEF;
|
||||
min-width: 45px;
|
||||
|
||||
}
|
||||
|
||||
ul.dropdown-menu.more-actions-button > li {
|
||||
height: 40px;
|
||||
width: 40px;
|
||||
border: 1px;
|
||||
}
|
||||
|
||||
ul.dropdown-menu.more-actions-button > li > button {
|
||||
border-bottom: 1px solid #e4e4e4;
|
||||
border-top: 1px solid darkred;
|
||||
}
|
||||
|
||||
.btn-group.open .dropdown-toggle {
|
||||
-webkit-box-shadow: none;
|
||||
box-shadow: none;
|
||||
border: 0px;
|
||||
}
|
||||
|
||||
.btn-custom {
|
||||
border-width: 1px;
|
||||
}
|
||||
|
||||
|
||||
.cloud-menu .popover {
|
||||
border-radius: 0px;
|
||||
width: 24em;
|
||||
left: -21.1em !important;
|
||||
max-width: 32em;
|
||||
background-color: #006690
|
||||
}
|
||||
.cloud-menu .popover-title,.navbar-header .popover-title {
|
||||
background-color: #006690;
|
||||
font-size: 16px;
|
||||
border-bottom: none;
|
||||
font-weight: 400;
|
||||
}
|
||||
.cloud-menu .popover.bottom>.arrow{
|
||||
margin-left:-2px;
|
||||
}
|
||||
.cloud-menu .popover.bottom>.arrow:after,.navbar-header .popover.bottom>.arrow:after{
|
||||
border-bottom-color: #006690;
|
||||
}
|
||||
.cloud-block {
|
||||
float: left;
|
||||
width: 8.2em;
|
||||
height: 8.2em;
|
||||
background-color: #fff;
|
||||
margin: 0.5em 0em 0.5em 0.5em;
|
||||
text-align: center;
|
||||
vertical-align: middle;
|
||||
}
|
||||
.cloud-name {
|
||||
font-size:14px;
|
||||
margin-top: .5em;
|
||||
font-weight: 400;
|
||||
}
|
||||
.cloud-menu-popover {
|
||||
position: relative;
|
||||
float: right;
|
||||
padding: 0px 8px;
|
||||
background-color: transparent;
|
||||
background-image: none;
|
||||
border: 1px solid transparent;
|
||||
border-radius: 4px;
|
||||
color: #fff;
|
||||
cursor: pointer;
|
||||
}
|
||||
#cloud-menu-popover-xs {
|
||||
color: #fff;
|
||||
line-height:24px;
|
||||
border: none;
|
||||
margin-right: 15px!important;
|
||||
}
|
||||
.navbar-toggle{
|
||||
border:none;
|
||||
border-radius: 0px;
|
||||
}
|
||||
.navbar-header .popover {
|
||||
border-radius: 0px;
|
||||
width: 21em;
|
||||
max-width:32em;
|
||||
background-color: #006690;
|
||||
}
|
||||
.navbar-header .popover .popover-content{
|
||||
padding:0px;
|
||||
}
|
||||
.cloud-menu .popover-content {
|
||||
padding: 0px;
|
||||
}
|
||||
.cloud-actions {
|
||||
background-color: #005578;
|
||||
float: left;
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
left: 0px;
|
||||
overflow:hidden;
|
||||
}
|
||||
.cloud-actions h3 {
|
||||
font-size: 16px;
|
||||
font-weight: 400;
|
||||
padding-left: 14px;
|
||||
margin-top: 10px;
|
||||
}
|
||||
.cloud-block-invert {
|
||||
color: #fff;
|
||||
float: left;
|
||||
width: 8.2em;
|
||||
height: 8.2em;
|
||||
background-color: #1f1f1f;
|
||||
margin: 0.5em 0em 0.5em 0.5em;
|
||||
text-align: center;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.cloud-block-default {
|
||||
color: #006690;
|
||||
background-color: #fff;
|
||||
cursor: pointer;
|
||||
}
|
||||
.cloud-actions a:hover {
|
||||
color: #d7d5d5;
|
||||
background-color: #3d3d3d;
|
||||
text-decoration: none
|
||||
}
|
||||
.cloud-apps a {
|
||||
text-decoration: none;
|
||||
color: #006690 !important;
|
||||
cursor: pointer
|
||||
}
|
||||
.cloud-apps a:hover {
|
||||
text-decoration: none;
|
||||
color: #006690;
|
||||
background-color: #c5c5c5;
|
||||
}
|
||||
.cloud-apps .cloud-actions a {
|
||||
color: #fff
|
||||
}
|
||||
|
||||
.add-padding-top-3x {
|
||||
padding-top: 15px !important;
|
||||
}
|
||||
|
||||
.nav li a{
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.cloud-menu-content li a{
|
||||
color:inherit;
|
||||
}
|
||||
|
||||
html{
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
body{
|
||||
height: calc(100% - 50px);
|
||||
}
|
@ -0,0 +1,204 @@
|
||||
/*
|
||||
* Copyright (c) 2015, 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.
|
||||
*/
|
||||
$(function () {
|
||||
|
||||
var dashboardsApi = ues.utils.tenantPrefix() + 'apis/dashboards';
|
||||
var dashboards = [];
|
||||
var isStillLoading = false;
|
||||
var nextStart = 0;
|
||||
var hasMore = true;
|
||||
|
||||
/**
|
||||
* Page count.
|
||||
* @const
|
||||
*/
|
||||
var PAGE_COUNT = 10;
|
||||
|
||||
// Pre-compiling handlebar templates
|
||||
var dashboardsListHbs = Handlebars.compile($("#ues-dashboards-list-hbs").html());
|
||||
var dashboardThumbnailHbs = Handlebars.compile($("#ues-dashboard-thumbnail-hbs").html());
|
||||
var dashboardConfirmHbs = Handlebars.compile($("#ues-dashboard-confirm-hbs").html());
|
||||
var dashboardsEmptyHbs = Handlebars.compile($("#ues-dashboards-empty-hbs").html());
|
||||
Handlebars.registerPartial('ues-dashboard-thumbnail-hbs', dashboardThumbnailHbs);
|
||||
|
||||
/**
|
||||
* Find the dashboard using dashboard id.
|
||||
* @param id
|
||||
* @return {object}
|
||||
* @private
|
||||
* */
|
||||
var findDashboard = function (id) {
|
||||
var i;
|
||||
var dashboard;
|
||||
var length = dashboards.length;
|
||||
for (i = 0; i < length; i++) {
|
||||
dashboard = dashboards[i];
|
||||
if (dashboard.id === id) {
|
||||
return dashboard;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Delete the selected dashboard
|
||||
* @param el:-selected dashboard element
|
||||
* @private
|
||||
* */
|
||||
var deleteDashboard = function (el) {
|
||||
var button = Ladda.create(el[0]);
|
||||
button.start();
|
||||
var id = el.closest('.ues-dashboard').data('id');
|
||||
$.ajax({
|
||||
url: dashboardsApi + '/' + id,
|
||||
method: 'DELETE',
|
||||
async : false,
|
||||
success: function () {
|
||||
button.stop();
|
||||
location.reload();
|
||||
},
|
||||
error: function () {
|
||||
button.stop();
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Load the list of dashboards available.
|
||||
* @private
|
||||
* */
|
||||
var loadDashboards = function () {
|
||||
isStillLoading = true;
|
||||
|
||||
if (!hasMore) {
|
||||
isStillLoading = false;
|
||||
$('.ues-dashboard').each(function (i, obj) {
|
||||
if ($(this).find('.ues-dashboard-share').length) {
|
||||
$(this).addClass("shared");
|
||||
}
|
||||
});
|
||||
return;
|
||||
}
|
||||
ues.store.assets('dashboard', {
|
||||
start: nextStart,
|
||||
count: PAGE_COUNT
|
||||
}, function (err, data) {
|
||||
var dashboardsEl = $('#ues-portal').find('.ues-dashboards');
|
||||
hasMore = data.length;
|
||||
if (!hasMore && nextStart === 0) {
|
||||
dashboardsEl.append(dashboardsEmptyHbs());
|
||||
return;
|
||||
}
|
||||
|
||||
nextStart += PAGE_COUNT;
|
||||
dashboards = dashboards.concat(data);
|
||||
dashboardsEl.append(dashboardsListHbs(data));
|
||||
|
||||
var win = $(window);
|
||||
var doc = $(document);
|
||||
isStillLoading = false;
|
||||
if (doc.height() > win.height()) {
|
||||
return;
|
||||
}
|
||||
|
||||
loadDashboards();
|
||||
|
||||
$(".disable").on('click', function (event) {
|
||||
event.preventDefault();
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Initialize the UI functionality such as binding events.
|
||||
* @private
|
||||
* */
|
||||
var initUI = function () {
|
||||
var portal = $('#ues-portal');
|
||||
portal.on('click', '.ues-dashboards .ues-dashboard-trash-handle', function (e) {
|
||||
e.preventDefault();
|
||||
var thiz = $(this);
|
||||
var dashboardEl = thiz.closest('.ues-dashboard');
|
||||
var id = dashboardEl.data('id');
|
||||
var dashboard = findDashboard(id);
|
||||
dashboardEl.html(dashboardConfirmHbs(dashboard));
|
||||
});
|
||||
|
||||
portal.on('click', '.ues-dashboards .ues-dashboard-trash-confirm', function (e) {
|
||||
e.preventDefault();
|
||||
deleteDashboard($(this));
|
||||
});
|
||||
|
||||
portal.on('click', '.ues-dashboards .ues-dashboard-trash-cancel', function (e) {
|
||||
e.preventDefault();
|
||||
var thiz = $(this);
|
||||
var dashboardEl = thiz.closest('.ues-dashboard');
|
||||
var id = dashboardEl.data('id');
|
||||
var dashboard = findDashboard(id);
|
||||
dashboardEl.html(dashboardThumbnailHbs(dashboard));
|
||||
});
|
||||
|
||||
portal.on('click', '.ues-view:not(.disable)', function(e) {
|
||||
e.preventDefault();
|
||||
window.open($(this).attr('href'), '_blank');
|
||||
});
|
||||
|
||||
$('#filter-dashboards a').on('click', function () {
|
||||
$('#filter').html($(this).text());
|
||||
var filter = $(this).data('filter');
|
||||
|
||||
$('.ues-dashboard-container').each(function (i, obj) {
|
||||
if (filter === "All") {
|
||||
$(this).show();
|
||||
} else {
|
||||
if ($(this).find('.ues-dashboard-share').length) {
|
||||
filter === "Shared" ? $(this).show() : $(this).hide();
|
||||
} else {
|
||||
filter === "Shared" ? $(this).hide() : $(this).show();
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
$(window).scroll(function () {
|
||||
var win = $(window);
|
||||
var doc = $(document);
|
||||
if (win.scrollTop() + win.height() < doc.height() - 100) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!isStillLoading) {
|
||||
loadDashboards();
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
$(document).ready(function () {
|
||||
if($('#cloud-menu-popover').length) {
|
||||
$('#cloud-menu-popover i.fw-tiles').popover({
|
||||
html: true,
|
||||
trigger:'click',
|
||||
title: function() {
|
||||
return $("#popover-head").html();
|
||||
},
|
||||
content: function() {
|
||||
return $("#popover-content").html();
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
initUI();
|
||||
loadDashboards();
|
||||
});
|
@ -1,63 +0,0 @@
|
||||
<?xml version="1.0" encoding="ISO-8859-1"?>
|
||||
<!--
|
||||
~ 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.
|
||||
-->
|
||||
|
||||
<DeviceMgtConfiguration>
|
||||
<ManagementRepository>
|
||||
<DataSourceConfiguration>
|
||||
<JndiLookupDefinition>
|
||||
<Name>jdbc/DM_DS</Name>
|
||||
</JndiLookupDefinition>
|
||||
</DataSourceConfiguration>
|
||||
</ManagementRepository>
|
||||
<PushNotificationProviders>
|
||||
<Provider>org.wso2.carbon.device.mgt.extensions.push.notification.provider.mqtt.MQTTBasedPushNotificationProvider</Provider>
|
||||
<Provider>org.wso2.carbon.device.mgt.extensions.push.notification.provider.xmpp.XMPPBasedPushNotificationProvider</Provider>
|
||||
<!--<Provider>org.wso2.carbon.device.mgt.extensions.push.notification.provider.gcm.GCMBasedPushNotificationProvider</Provider>-->
|
||||
<!--<Provider>org.wso2.carbon.device.mgt.mobile.impl.ios.apns.APNSBasedPushNotificationProvider</Provider>-->
|
||||
</PushNotificationProviders>
|
||||
<IdentityConfiguration>
|
||||
<ServerUrl>https://localhost:9443</ServerUrl>
|
||||
<AdminUsername>admin</AdminUsername>
|
||||
<AdminPassword>admin</AdminPassword>
|
||||
</IdentityConfiguration>
|
||||
<PolicyConfiguration>
|
||||
<MonitoringClass>org.wso2.carbon.policy.mgt</MonitoringClass>
|
||||
<MonitoringEnable>false</MonitoringEnable>
|
||||
<MonitoringFrequency>60000</MonitoringFrequency>
|
||||
<MaxRetries>5</MaxRetries>
|
||||
<MinRetriesToMarkUnreachable>8</MinRetriesToMarkUnreachable>
|
||||
<MinRetriesToMarkInactive>20</MinRetriesToMarkInactive>
|
||||
<!--Set the policy evaluation point name (Simple/Merged)-->
|
||||
<!--Simple - Simple policy evaluation point-->
|
||||
<!--Merged - Merged policy evaluation point -->
|
||||
<PolicyEvaluationPoint>Simple</PolicyEvaluationPoint>
|
||||
</PolicyConfiguration>
|
||||
<TaskConfiguration>
|
||||
<Enable>true</Enable>
|
||||
<Frequency>60000</Frequency>
|
||||
<TaskClass>org.wso2.carbon.device.mgt.core.task.impl.DeviceDetailsRetrieverTask</TaskClass>
|
||||
</TaskConfiguration>
|
||||
<!-- Default Page size configuration for paginated DM APIs-->
|
||||
<PaginationConfiguration>
|
||||
<DeviceListPageSize>20</DeviceListPageSize>
|
||||
<NotificationListPageSize>20</NotificationListPageSize>
|
||||
<ActivityListPageSize>20</ActivityListPageSize>
|
||||
<OperationListPageSize>20</OperationListPageSize>
|
||||
</PaginationConfiguration>
|
||||
</DeviceMgtConfiguration>
|
@ -0,0 +1,99 @@
|
||||
<?xml version='1.0' encoding='utf-8'?>
|
||||
<!--
|
||||
Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
contributor license agreements. See the NOTICE file distributed with
|
||||
this work for additional information regarding copyright ownership.
|
||||
The ASF 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.
|
||||
-->
|
||||
|
||||
<Server port="8005" shutdown="SHUTDOWN">
|
||||
|
||||
<Service className="org.wso2.carbon.tomcat.ext.service.ExtendedStandardService" name="Catalina">
|
||||
|
||||
<!--
|
||||
optional attributes:
|
||||
|
||||
proxyPort="80"
|
||||
-->
|
||||
<Connector protocol="org.apache.coyote.http11.Http11NioProtocol"
|
||||
port="9763"
|
||||
redirectPort="9443"
|
||||
bindOnInit="false"
|
||||
maxHttpHeaderSize="8192"
|
||||
acceptorThreadCount="2"
|
||||
maxThreads="250"
|
||||
minSpareThreads="50"
|
||||
disableUploadTimeout="false"
|
||||
connectionUploadTimeout="120000"
|
||||
maxKeepAliveRequests="200"
|
||||
acceptCount="200"
|
||||
server="WSO2 Carbon Server"
|
||||
compression="on"
|
||||
compressionMinSize="2048"
|
||||
noCompressionUserAgents="gozilla, traviata"
|
||||
compressableMimeType="text/html,text/javascript,application/x-javascript,application/javascript,application/xml,text/css,application/xslt+xml,text/xsl,image/gif,image/jpg,image/jpeg"
|
||||
URIEncoding="UTF-8"/>
|
||||
|
||||
<!--
|
||||
optional attributes:
|
||||
|
||||
proxyPort="443"
|
||||
Added sslEnabledProtocols="TLSv1,TLSv1.1,TLSv1.2" for poodle vulnerability fix
|
||||
-->
|
||||
<Connector protocol="org.apache.coyote.http11.Http11NioProtocol"
|
||||
port="9443"
|
||||
bindOnInit="false"
|
||||
sslProtocol="TLS"
|
||||
sslEnabledProtocols="TLSv1,TLSv1.1,TLSv1.2"
|
||||
maxHttpHeaderSize="8192"
|
||||
acceptorThreadCount="2"
|
||||
maxThreads="250"
|
||||
minSpareThreads="50"
|
||||
disableUploadTimeout="false"
|
||||
enableLookups="false"
|
||||
connectionUploadTimeout="120000"
|
||||
maxKeepAliveRequests="200"
|
||||
acceptCount="200"
|
||||
server="WSO2 Carbon Server"
|
||||
clientAuth="want"
|
||||
compression="on"
|
||||
scheme="https"
|
||||
secure="true"
|
||||
SSLEnabled="true"
|
||||
compressionMinSize="2048"
|
||||
noCompressionUserAgents="gozilla, traviata"
|
||||
compressableMimeType="text/html,text/javascript,application/x-javascript,application/javascript,application/xml,text/css,application/xslt+xml,text/xsl,image/gif,image/jpg,image/jpeg"
|
||||
keystoreFile="${carbon.home}/repository/resources/security/wso2carbon.jks"
|
||||
keystorePass="wso2carbon"
|
||||
URIEncoding="UTF-8"/>
|
||||
|
||||
|
||||
<Engine name="Catalina" defaultHost="localhost">
|
||||
|
||||
<!--Realm className="org.apache.catalina.realm.MemoryRealm" pathname="${carbon.home}/repository/conf/tomcat/tomcat-users.xml"/-->
|
||||
|
||||
<Realm className="org.wso2.carbon.tomcat.ext.realms.CarbonTomcatRealm"/>
|
||||
|
||||
<Host name="localhost" unpackWARs="true" deployOnStartup="false" autoDeploy="false"
|
||||
appBase="${carbon.home}/repository/deployment/server/webapps/">
|
||||
<Valve className="org.wso2.carbon.tomcat.ext.valves.CarbonContextCreatorValve"/>
|
||||
<Valve className="org.apache.catalina.valves.AccessLogValve" directory="${carbon.home}/repository/logs"
|
||||
prefix="http_access_" suffix=".log"
|
||||
pattern="combined"/>
|
||||
<Valve className="org.wso2.carbon.tomcat.ext.valves.CarbonStuckThreadDetectionValve" threshold="600"/>
|
||||
<Valve className="org.wso2.carbon.tomcat.ext.valves.CompositeValve"/>
|
||||
</Host>
|
||||
</Engine>
|
||||
</Service>
|
||||
</Server>
|
||||
|
@ -0,0 +1,598 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
var utils = function () {
|
||||
var log = new Log("/modules/oauth/token-handler-utils.js");
|
||||
|
||||
var configs = require('/configs/portal.js').config();
|
||||
var constants = require("/modules/constants.js");
|
||||
var carbon = require("carbon");
|
||||
|
||||
//noinspection JSUnresolvedVariable
|
||||
var Base64 = Packages.org.apache.commons.codec.binary.Base64;
|
||||
//noinspection JSUnresolvedVariable
|
||||
var String = Packages.java.lang.String;
|
||||
|
||||
var publicMethods = {};
|
||||
var privateMethods = {};
|
||||
|
||||
publicMethods["encode"] = function (payload) {
|
||||
return String(Base64.encodeBase64(String(payload).getBytes()));
|
||||
};
|
||||
|
||||
publicMethods["decode"] = function (payload) {
|
||||
return String(Base64.decodeBase64(String(payload).getBytes()));
|
||||
};
|
||||
|
||||
/**
|
||||
* Check whether this application is oauth enable or not
|
||||
* @returns boolean if oauth enable
|
||||
*/
|
||||
publicMethods["checkOAuthEnabled"] = function () {
|
||||
if (constants.AUTHORIZATION_TYPE_OAUTH === configs["authorization"]["activeMethod"]) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
/**
|
||||
* Set access token into xml http request header
|
||||
* @param xhr xml http request
|
||||
* @returns {*} xhr which has access token it's header
|
||||
*/
|
||||
publicMethods["setAccessToken"] = function (xhr, callback) {
|
||||
var accessToken;
|
||||
if (publicMethods.checkOAuthEnabled()) {
|
||||
try {
|
||||
accessToken = parse(session.get(constants.ACCESS_TOKEN_PAIR_IDENTIFIER_FOR_PORTAL))["accessToken"];
|
||||
xhr.setRequestHeader(constants.AUTHORIZATION_HEADER, constants.BEARER_PREFIX + accessToken);
|
||||
} catch (exception) {
|
||||
log.error("Access token hasn't been set yet, " + exception);
|
||||
} finally {
|
||||
callback(xhr);
|
||||
}
|
||||
}
|
||||
callback(xhr);
|
||||
};
|
||||
|
||||
/**
|
||||
* Get access token of current logged user
|
||||
* @param callBack response with access token
|
||||
*/
|
||||
publicMethods["getAccessToken"] = function (callBack) {
|
||||
var accessToken = null;
|
||||
if (publicMethods.checkOAuthEnabled()) {
|
||||
try {
|
||||
accessToken = parse(session.get(constants.ACCESS_TOKEN_PAIR_IDENTIFIER_FOR_PORTAL))["accessToken"];
|
||||
} catch (exception) {
|
||||
log.error("Access token hasn't been set yet, " + exception);
|
||||
} finally {
|
||||
callBack(accessToken);
|
||||
}
|
||||
}
|
||||
callBack(accessToken);
|
||||
};
|
||||
|
||||
/**
|
||||
* Create error message which adhere to xml http response object
|
||||
* @param statusCode response status code
|
||||
* @param status response status
|
||||
* @param responseText response message
|
||||
* @returns {{statusCode: *, status: *, responseText: *}}
|
||||
*/
|
||||
publicMethods["createXHRObject"] = function (statusCode, status, responseText) {
|
||||
return {"statusCode": statusCode, "status": status, "responseText": responseText};
|
||||
};
|
||||
|
||||
/**
|
||||
* check whether user already logged to system before invoking any apis
|
||||
* @param callBack
|
||||
*/
|
||||
publicMethods["isUserAuthorized"] = function (callBack) {
|
||||
if (session.get("Loged") !== constants.LOGIN_MESSAGE) {
|
||||
callBack(false);
|
||||
} else {
|
||||
callBack(true);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Get identity provider uir
|
||||
* @returns {*}
|
||||
*/
|
||||
publicMethods["getIdPServerURL"] = function () {
|
||||
return configs["authorization"]["methods"]["oauth"]["attributes"]["oauthProvider"]["tokenServiceURL"];
|
||||
};
|
||||
|
||||
/**
|
||||
* Get an Access token pair based on client secret
|
||||
* @param encodedClientKeys {{clientId:"", clientSecret:""}}
|
||||
* @param scope eg: PRODUCTION
|
||||
* @param idPServer identity provider url
|
||||
* @returns {{accessToken: *, refreshToken: *}}
|
||||
*/
|
||||
publicMethods["getTokenWithClientSecretType"] = function (encodedClientKeys, scope, idPServer) {
|
||||
var xhr = new XMLHttpRequest();
|
||||
var tokenEndpoint = idPServer;
|
||||
xhr.open(constants.HTTP_POST, tokenEndpoint, false);
|
||||
xhr.setRequestHeader(constants.CONTENT_TYPE_IDENTIFIER, constants.APPLICATION_X_WWW_FOR_URLENCODED);
|
||||
xhr.setRequestHeader(constants.AUTHORIZATION_HEADER, constants.BASIC_PREFIX + encodedClientKeys);
|
||||
xhr.send("grant_type=client_credentials&scope=" + scope);
|
||||
var tokenPair = {};
|
||||
if (xhr.status == constants.HTTP_ACCEPTED) {
|
||||
var data = parse(xhr.responseText);
|
||||
tokenPair.refreshToken = data.refresh_token;
|
||||
tokenPair.accessToken = data.access_token;
|
||||
} else if (xhr.status == constants.HTTP_USER_NOT_AUTHENTICATED) {
|
||||
log.error("Error in obtaining token with client secret grant type, You are not authenticated yet");
|
||||
return null;
|
||||
} else {
|
||||
log.error("Error in obtaining token with client secret grant type, This might be a problem with client meta " +
|
||||
"data which required for client secret grant type");
|
||||
return null;
|
||||
}
|
||||
return tokenPair;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* This will create client id and client secret for a given application
|
||||
* @param properties "callbackUrl": "",
|
||||
* "clientName": "",
|
||||
* "owner": "",
|
||||
* "applicationType": "",
|
||||
* "grantType": "",
|
||||
* "saasApp" :"",
|
||||
* "dynamicClientRegistrationEndPoint" : ""
|
||||
*
|
||||
* @returns {{clientId:*, clientSecret:*}}
|
||||
*/
|
||||
publicMethods["getDynamicClientAppCredentials"] = function (username) {
|
||||
// setting up dynamic client application properties
|
||||
var dcAppProperties = {
|
||||
"applicationType": configs["authorization"]["methods"]["oauth"]["attributes"]["oauthProvider"]["appRegistration"]["appType"],
|
||||
"clientName": configs["authorization"]["methods"]["oauth"]["attributes"]["oauthProvider"]["appRegistration"]["clientName"],
|
||||
"owner": configs["authorization"]["methods"]["oauth"]["attributes"]["oauthProvider"]["appRegistration"]["owner"],
|
||||
"tokenScope": configs["authorization"]["methods"]["oauth"]["attributes"]["oauthProvider"]["appRegistration"]["tokenScope"],
|
||||
"grantType": configs["authorization"]["methods"]["oauth"]["attributes"]["oauthProvider"]["appRegistration"]["grantType"],
|
||||
"callbackUrl": configs["authorization"]["methods"]["oauth"]["attributes"]["oauthProvider"]["appRegistration"]["callbackUrl"],
|
||||
"saasApp" : configs["authorization"]["methods"]["oauth"]["attributes"]["oauthProvider"]["appRegistration"]["saasApp"]
|
||||
};
|
||||
|
||||
var tenantDomain = carbon.server.tenantDomain({username: username});
|
||||
if (!tenantDomain) {
|
||||
log.error("{/modules/oauth/token-handler-utils.js} Error in retrieving tenant " +
|
||||
"based client application credentials. Unable to obtain a valid tenant domain for provided username "+
|
||||
username +"- getDynamicClientAppCredentials(x)");
|
||||
return null;
|
||||
} else {
|
||||
var cachedTenantBasedClientAppCredentials = privateMethods.
|
||||
getCachedTenantBasedClientAppCredentials(tenantDomain);
|
||||
if (cachedTenantBasedClientAppCredentials) {
|
||||
return cachedTenantBasedClientAppCredentials;
|
||||
} else {
|
||||
// calling dynamic client app registration service endpoint
|
||||
var requestURL = configs["authorization"]["methods"]["oauth"]["attributes"]["oauthProvider"]["appRegistration"]
|
||||
["dynamicClientAppRegistrationServiceURL"];
|
||||
var requestPayload = dcAppProperties;
|
||||
var token = publicMethods.encode(configs["authorization"]["methods"]["oauth"]["attributes"]["oauthProvider"]
|
||||
["appRegistration"]["owner"] + ":" + configs["authorization"]["methods"]["oauth"]["attributes"]
|
||||
["oauthProvider"]["appRegistration"]["password"]);
|
||||
var xhr = new XMLHttpRequest();
|
||||
xhr.open("POST", requestURL, false);
|
||||
xhr.setRequestHeader("Content-Type", "application/json");
|
||||
xhr.setRequestHeader("Authorization", "Basic "+ token);
|
||||
xhr.send(stringify(requestPayload));
|
||||
var dynamicClientAppCredentials = {};
|
||||
if (xhr["status"] == 201 || xhr["status"] == 200 && xhr["responseText"]) {
|
||||
var responsePayload = parse(xhr["responseText"]);
|
||||
var clientId = responsePayload["client_id"];
|
||||
var clientSecret = responsePayload["client_secret"];
|
||||
if(typeof clientId == "undefined"){
|
||||
clientId = responsePayload["clientId"];
|
||||
}
|
||||
if(typeof clientSecret == "undefined"){
|
||||
clientSecret = responsePayload["clientSecret"];
|
||||
}
|
||||
dynamicClientAppCredentials["clientId"] = clientId;
|
||||
dynamicClientAppCredentials["clientSecret"] = clientSecret;
|
||||
privateMethods.
|
||||
setCachedTenantBasedClientAppCredentials(tenantDomain, dynamicClientAppCredentials);
|
||||
} else if (xhr["status"] == 400) {
|
||||
log.error("{/modules/oauth/token-handler-utils.js - getDynamicClientAppCredentials()} " +
|
||||
"Bad request. Invalid data provided as dynamic client application properties.");
|
||||
dynamicClientAppCredentials = null;
|
||||
} else {
|
||||
log.error("{/modules/oauth/token-handler-utils.js - getDynamicClientAppCredentials()} " +
|
||||
"Error in retrieving dynamic client credentials.");
|
||||
dynamicClientAppCredentials = null;
|
||||
}
|
||||
// returning dynamic client credentials
|
||||
return dynamicClientAppCredentials;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* If gateway is enable, apiManagerClientAppRegistrationServiceURL is used to create oauth application
|
||||
* @param username username of current logged user
|
||||
* @returns {{clientId:*, clientSecret:*}}
|
||||
*/
|
||||
publicMethods["getTenantBasedClientAppCredentials"] = function (username) {
|
||||
if (!username) {
|
||||
log.error("{/modules/oauth/token-handler-utils.js} Error in retrieving tenant " +
|
||||
"based client app credentials. No username " +
|
||||
"as input - getTenantBasedClientAppCredentials(x)");
|
||||
return null;
|
||||
} else {
|
||||
//noinspection JSUnresolvedFunction, JSUnresolvedVariable
|
||||
var tenantDomain = carbon.server.tenantDomain({username: username});
|
||||
|
||||
if (!tenantDomain) {
|
||||
log.error("{/modules/oauth/token-handler-utils.js} Error in retrieving tenant " +
|
||||
"based client application credentials. Unable to obtain a valid tenant domain for provided " +
|
||||
"username - getTenantBasedClientAppCredentials(x, y)");
|
||||
return null;
|
||||
} else {
|
||||
var cachedTenantBasedClientAppCredentials = privateMethods.
|
||||
getCachedTenantBasedClientAppCredentials(tenantDomain);
|
||||
if (cachedTenantBasedClientAppCredentials) {
|
||||
return cachedTenantBasedClientAppCredentials;
|
||||
} else {
|
||||
var adminUsername = configs["authorization"]["methods"]["oauth"]["attributes"]["adminUser"];
|
||||
var adminUserTenantId = configs["authorization"]["methods"]["oauth"]["attributes"]
|
||||
["adminUserTenantId"];
|
||||
//claims required for jwtAuthenticator.
|
||||
var claims = {"http://wso2.org/claims/enduserTenantId": adminUserTenantId,
|
||||
"http://wso2.org/claims/enduser": adminUsername};
|
||||
var jwtToken = publicMethods.getJwtToken(adminUsername, claims);
|
||||
// register a tenant based client app at API Manager
|
||||
var applicationName = configs["authorization"]["methods"]["oauth"]["attributes"]["oauthProvider"]
|
||||
["appRegistration"]["clientName"] + "_" + tenantDomain;
|
||||
var requestURL = configs["authorization"]["methods"]["oauth"]["attributes"]["oauthProvider"]
|
||||
["appRegistration"]["apiManagerClientAppRegistrationServiceURL"] +
|
||||
"?tenantDomain=" + tenantDomain + "&applicationName=" + applicationName;
|
||||
var xhr = new XMLHttpRequest();
|
||||
xhr.open("POST", requestURL, false);
|
||||
xhr.setRequestHeader("Content-Type", "application/json");
|
||||
xhr.setRequestHeader("X-JWT-Assertion", "" + jwtToken);
|
||||
xhr.send();
|
||||
if ((xhr["status"] == 201 || xhr["status"] == 200) && xhr["responseText"]) {
|
||||
var responsePayload = parse(xhr["responseText"]);
|
||||
var tenantBasedClientAppCredentials = {};
|
||||
var clientId = responsePayload["client_id"];
|
||||
var clientSecret = responsePayload["client_secret"];
|
||||
if(typeof clientId == "undefined"){
|
||||
clientId = responsePayload["clientId"];
|
||||
}
|
||||
if(typeof clientSecret == "undefined"){
|
||||
clientSecret = responsePayload["clientSecret"];
|
||||
}
|
||||
tenantBasedClientAppCredentials["clientId"] = clientId;
|
||||
tenantBasedClientAppCredentials["clientSecret"] = clientSecret;
|
||||
privateMethods.
|
||||
setCachedTenantBasedClientAppCredentials(tenantDomain, tenantBasedClientAppCredentials);
|
||||
return tenantBasedClientAppCredentials;
|
||||
} else {
|
||||
log.error("{/modules/oauth/token-handler-utils.js} Error in retrieving tenant " +
|
||||
"based client application credentials from API " +
|
||||
"Manager - getTenantBasedClientAppCredentials(x, y)");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Caching oauth application credentials
|
||||
* @param tenantDomain tenant domain where application is been created
|
||||
* @param clientAppCredentials {{clientId:*, clientSecret:*}}
|
||||
*/
|
||||
privateMethods["setCachedTenantBasedClientAppCredentials"] = function (tenantDomain, clientAppCredentials) {
|
||||
var cachedTenantBasedClientAppCredentialsMap = application.get(constants["CACHED_CREDENTIALS_PORTAL_APP"]);
|
||||
if (!cachedTenantBasedClientAppCredentialsMap) {
|
||||
cachedTenantBasedClientAppCredentialsMap = {};
|
||||
cachedTenantBasedClientAppCredentialsMap[tenantDomain] = clientAppCredentials;
|
||||
application.put(constants["CACHED_CREDENTIALS_PORTAL_APP"], cachedTenantBasedClientAppCredentialsMap);
|
||||
} else if (!cachedTenantBasedClientAppCredentialsMap[tenantDomain]) {
|
||||
cachedTenantBasedClientAppCredentialsMap[tenantDomain] = clientAppCredentials;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Get oauth application credentials from cache
|
||||
* @param tenantDomain tenant domain where application is been created
|
||||
* @returns {{clientId:*, clientSecret:*}}
|
||||
*/
|
||||
privateMethods["getCachedTenantBasedClientAppCredentials"] = function (tenantDomain) {
|
||||
var cachedTenantBasedClientAppCredentialsMap = application.get(constants["CACHED_CREDENTIALS_PORTAL_APP"]);
|
||||
if (!cachedTenantBasedClientAppCredentialsMap ||
|
||||
!cachedTenantBasedClientAppCredentialsMap[tenantDomain]) {
|
||||
return null;
|
||||
} else {
|
||||
return cachedTenantBasedClientAppCredentialsMap[tenantDomain];
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Get access token and refresh token using password grant type
|
||||
* @param username username of the logged user
|
||||
* @param password password of the logged user
|
||||
* @param encodedClientAppCredentials {{clientId:*, clientSecret:*}}
|
||||
* @param scopes scopes list
|
||||
* @returns {{accessToken: *, refreshToken: *}}
|
||||
*/
|
||||
publicMethods["getTokenPairAndScopesByPasswordGrantType"] = function (username, password
|
||||
, encodedClientAppCredentials, scopes) {
|
||||
if (!username || !password || !encodedClientAppCredentials || !scopes) {
|
||||
log.error("{/modules/oauth/token-handler-utils.js} Error in retrieving access token by password " +
|
||||
"grant type. No username, password, encoded client app credentials or scopes are " +
|
||||
"found - getTokenPairAndScopesByPasswordGrantType(a, b, c, d)");
|
||||
return null;
|
||||
} else {
|
||||
// calling oauth provider token service endpoint
|
||||
var requestURL = configs["authorization"]["methods"]["oauth"]["attributes"]["oauthProvider"]
|
||||
["tokenServiceURL"];
|
||||
var requestPayload = "grant_type=password&username=" +
|
||||
username + "&password=" + password + "&scope=" + scopes;
|
||||
|
||||
var xhr = new XMLHttpRequest();
|
||||
xhr.open("POST", requestURL, false);
|
||||
xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
|
||||
xhr.setRequestHeader("Authorization", "Basic " + encodedClientAppCredentials);
|
||||
xhr.send(requestPayload);
|
||||
|
||||
if (xhr["status"] == 200 && xhr["responseText"]) {
|
||||
var responsePayload = parse(xhr["responseText"]);
|
||||
var tokenData = {};
|
||||
tokenData["accessToken"] = responsePayload["access_token"];
|
||||
tokenData["refreshToken"] = responsePayload["refresh_token"];
|
||||
tokenData["scopes"] = responsePayload["scope"];
|
||||
return tokenData;
|
||||
} else {
|
||||
log.error("{/modules/oauth/token-handler-utils.js} Error in retrieving access token " +
|
||||
"by password grant type - getTokenPairAndScopesByPasswordGrantType(a, b, c, d)");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Get access token and refresh token using SAML grant type
|
||||
* @param assertion
|
||||
* @param encodedClientAppCredentials
|
||||
* @param scopes
|
||||
* @returns {{accessToken: *, refreshToken: *}}
|
||||
*/
|
||||
publicMethods["getTokenPairAndScopesByJWTGrantType"] = function (username, encodedClientAppCredentials, scopes) {
|
||||
if (!username || !encodedClientAppCredentials || !scopes) {
|
||||
log.error("{/app/modules/oauth/token-handler-utils.js} Error in retrieving access token by jwt " +
|
||||
"grant type. No assertion, encoded client app credentials or scopes are " +
|
||||
"found - getTokenPairAndScopesByJWTGrantType(x, y, z)");
|
||||
return null;
|
||||
} else {
|
||||
var JWTClientManagerServicePackagePath =
|
||||
"org.wso2.carbon.identity.jwt.client.extension.service.JWTClientManagerService";
|
||||
//noinspection JSUnresolvedFunction, JSUnresolvedVariable
|
||||
var JWTClientManagerService = carbon.server.osgiService(JWTClientManagerServicePackagePath);
|
||||
//noinspection JSUnresolvedFunction
|
||||
var jwtClient = JWTClientManagerService.getJWTClient();
|
||||
// returning access token by JWT grant type
|
||||
var tokenInfo = jwtClient.getAccessToken(encodedClientAppCredentials,
|
||||
username, scopes);
|
||||
var tokenData = {};
|
||||
tokenData["accessToken"] = tokenInfo.getAccessToken();
|
||||
tokenData["refreshToken"] = tokenInfo.getRefreshToken();
|
||||
tokenData["scopes"] = tokenInfo.getScopes();
|
||||
return tokenData;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Get access token and refresh token using SAML grant type
|
||||
* @param assertion
|
||||
* @param encodedClientAppCredentials
|
||||
* @param scopes
|
||||
* @returns {{accessToken: *, refreshToken: *}}
|
||||
*/
|
||||
publicMethods["getTokenPairAndScopesBySAMLGrantType"] = function (assertion, encodedClientAppCredentials, scopes) {
|
||||
if (!assertion || !encodedClientAppCredentials || !scopes) {
|
||||
log.error("{/modules/oauth/token-handler-utils.js} Error in retrieving access token by saml " +
|
||||
"grant type. No assertion, encoded client app credentials or scopes are " +
|
||||
"found - getTokenPairAndScopesBySAMLGrantType(x, y, z)");
|
||||
return null;
|
||||
} else {
|
||||
|
||||
var assertionXML = publicMethods.decode(assertion);
|
||||
/*
|
||||
TODO: make assertion extraction with proper parsing.
|
||||
Since Jaggery XML parser seem to add formatting which causes signature verification to fail.
|
||||
*/
|
||||
var assertionStartMarker = "<saml2:Assertion";
|
||||
var assertionEndMarker = "<\/saml2:Assertion>";
|
||||
var assertionStartIndex = assertionXML.indexOf(assertionStartMarker);
|
||||
var assertionEndIndex = assertionXML.indexOf(assertionEndMarker);
|
||||
|
||||
var extractedAssertion;
|
||||
if (assertionStartIndex == -1 || assertionEndIndex == -1) {
|
||||
log.error("{/modules/oauth/token-handler-utils.js} Error in retrieving access token by saml grant " +
|
||||
"type. Issue in assertion format - getTokenPairAndScopesBySAMLGrantType(x, y, z)");
|
||||
return null;
|
||||
} else {
|
||||
extractedAssertion = assertionXML.
|
||||
substring(assertionStartIndex, assertionEndIndex) + assertionEndMarker;
|
||||
var encodedAssertion = publicMethods.encode(extractedAssertion);
|
||||
// calling oauth provider token service endpoint
|
||||
var requestURL = configs["authorization"]["methods"]["oauth"]["attributes"]["oauthProvider"]
|
||||
["tokenServiceURL"];
|
||||
var requestPayload = "grant_type=urn:ietf:params:oauth:grant-type:saml2-bearer&" +
|
||||
"assertion=" + encodeURIComponent(encodedAssertion) + "&scope=" + scopes;
|
||||
var xhr = new XMLHttpRequest();
|
||||
xhr.open("POST", requestURL, false);
|
||||
xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
|
||||
xhr.setRequestHeader("Authorization", "Basic " + encodedClientAppCredentials);
|
||||
xhr.send(requestPayload);
|
||||
|
||||
if (xhr["status"] == 200 && xhr["responseText"]) {
|
||||
var responsePayload = parse(xhr["responseText"]);
|
||||
var tokenData = {};
|
||||
tokenData["accessToken"] = responsePayload["access_token"];
|
||||
tokenData["refreshToken"] = responsePayload["refresh_token"];
|
||||
tokenData["scopes"] = responsePayload["scope"];
|
||||
return tokenData;
|
||||
} else {
|
||||
log.error("{/modules/oauth/token-handler-utils.js} Error in retrieving access token " +
|
||||
"by password grant type - getTokenPairAndScopesBySAMLGrantType(x, y, z)");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* If access token is expired, try to refresh it using existing refresh token
|
||||
* @param callback
|
||||
*/
|
||||
publicMethods["refreshAccessToken"] = function (callback) {
|
||||
try {
|
||||
if (publicMethods.checkOAuthEnabled()) {
|
||||
var currentTokenPair = parse(session.get(constants["ACCESS_TOKEN_PAIR_IDENTIFIER_FOR_PORTAL"]));
|
||||
// currentTokenPair includes current access token as well as current refresh token
|
||||
var encodedClientAppCredentials
|
||||
= session.get(constants["ENCODED_TENANT_BASED_CLIENT_APP_CREDENTIALS_PORTAL_APP"]);
|
||||
if (!currentTokenPair || !encodedClientAppCredentials) {
|
||||
callback(false);
|
||||
throw new Error("{/modules/oauth/token-handlers.js} Error in refreshing tokens. Either the " +
|
||||
"token pair, encoded client app credentials or both input are not found under " +
|
||||
"session context - refreshTokenPair()");
|
||||
} else {
|
||||
var newTokenPair = publicMethods.
|
||||
getNewTokenPairByRefreshToken(currentTokenPair["refreshToken"], encodedClientAppCredentials);
|
||||
if (!newTokenPair) {
|
||||
log.error("{/app/modules/oauth/token-handlers.js} Error in refreshing token pair. " +
|
||||
"Unable to update session context with new access token pair - refreshTokenPair()");
|
||||
callback(false);
|
||||
} else {
|
||||
session.put(constants["ACCESS_TOKEN_PAIR_IDENTIFIER_FOR_PORTAL"], stringify(newTokenPair));
|
||||
callback(true);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
log.error("You have not enable dynamic client yet");
|
||||
callback(false);
|
||||
}
|
||||
} catch (exception) {
|
||||
callback(false);
|
||||
throw "Error while refreshing existing access token, " + exception;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Get access token and refresh token using refresh token grant type
|
||||
* @param refreshToken refresh token
|
||||
* @param encodedClientAppCredentials {{clientId:*, clientSecret:*}}
|
||||
* @param scopes
|
||||
* @returns {{accessToken: *, refreshToken: *}}
|
||||
*/
|
||||
publicMethods["getNewTokenPairByRefreshToken"] = function (refreshToken, encodedClientAppCredentials, scopes) {
|
||||
if (!refreshToken || !encodedClientAppCredentials) {
|
||||
log.error("{/modules/oauth/token-handler-utils.js} Error in retrieving new access token " +
|
||||
"by current refresh token. No refresh token or encoded client app credentials are " +
|
||||
"found - getNewTokenPairByRefreshToken(x, y, z)");
|
||||
return null;
|
||||
} else {
|
||||
var requestURL = configs["authorization"]["methods"]["oauth"]["attributes"]["oauthProvider"]
|
||||
["tokenServiceURL"];
|
||||
var requestPayload = "grant_type=refresh_token&refresh_token=" + refreshToken;
|
||||
if (scopes) {
|
||||
requestPayload = requestPayload + "&scope=" + scopes;
|
||||
}
|
||||
|
||||
var xhr = new XMLHttpRequest();
|
||||
xhr.open("POST", requestURL, false);
|
||||
xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
|
||||
xhr.setRequestHeader("Authorization", "Basic " + encodedClientAppCredentials);
|
||||
xhr.send(requestPayload);
|
||||
|
||||
if (xhr["status"] == 200 && xhr["responseText"]) {
|
||||
var responsePayload = parse(xhr["responseText"]);
|
||||
var tokenPair = {};
|
||||
tokenPair["accessToken"] = responsePayload["access_token"];
|
||||
tokenPair["refreshToken"] = responsePayload["refresh_token"];
|
||||
return tokenPair;
|
||||
} else {
|
||||
log.error("{/modules/oauth/token-handler-utils.js} Error in retrieving new access token by " +
|
||||
"current refresh token - getNewTokenPairByRefreshToken(x, y, z)");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Get access token using JWT grant type
|
||||
* @param clientAppCredentials {{clientId:*, clientSecret:*}}
|
||||
* @returns {{accessToken: *, refreshToken: *}}
|
||||
*/
|
||||
publicMethods["getAccessTokenByJWTGrantType"] = function (clientAppCredentials) {
|
||||
if (!clientAppCredentials) {
|
||||
log.error("{/modules/oauth/token-handler-utils.js} Error in retrieving new access token " +
|
||||
"by current refresh token. No client app credentials are found " +
|
||||
"as input - getAccessTokenByJWTGrantType(x)");
|
||||
return null;
|
||||
} else {
|
||||
var JWTClientManagerServicePackagePath =
|
||||
"org.wso2.carbon.identity.jwt.client.extension.service.JWTClientManagerService";
|
||||
//noinspection JSUnresolvedFunction, JSUnresolvedVariable
|
||||
var JWTClientManagerService = carbon.server.osgiService(JWTClientManagerServicePackagePath);
|
||||
//noinspection JSUnresolvedFunction
|
||||
var jwtClient = JWTClientManagerService.getJWTClient();
|
||||
// returning access token by JWT grant type
|
||||
return jwtClient.getAccessToken(clientAppCredentials["clientId"], clientAppCredentials["clientSecret"],
|
||||
configs["authorization"]["methods"]["oauth"]["attributes"]["oauthProvider"]["appRegistration"]["owner"],
|
||||
null)["accessToken"];
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Get jwt token
|
||||
* @param username username of logged user
|
||||
* @param claims claims which are required
|
||||
* @returns {"jwtToken"}
|
||||
*/
|
||||
publicMethods["getJwtToken"] = function (username, claims) {
|
||||
if (!username) {
|
||||
log.error("{/modules/oauth/token-handler-utils.js} Error in retrieving new jwt token");
|
||||
return null;
|
||||
} else {
|
||||
var JWTClientManagerServicePackagePath =
|
||||
"org.wso2.carbon.identity.jwt.client.extension.service.JWTClientManagerService";
|
||||
//noinspection JSUnresolvedFunction, JSUnresolvedVariable
|
||||
var JWTClientManagerService = carbon.server.osgiService(JWTClientManagerServicePackagePath);
|
||||
//noinspection JSUnresolvedFunction
|
||||
var jwtClient = JWTClientManagerService.getJWTClient();
|
||||
// returning access token by JWT grant type
|
||||
if (claims) {
|
||||
return jwtClient.getJwtToken(username, claims);
|
||||
} else {
|
||||
return jwtClient.getJwtToken(username);
|
||||
}
|
||||
}
|
||||
};
|
||||
return publicMethods;
|
||||
}();
|
@ -0,0 +1,192 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* -----------------------------------------------------
|
||||
* Following module includes handlers
|
||||
* at Jaggery Layer for handling OAuth tokens.
|
||||
* -----------------------------------------------------
|
||||
*/
|
||||
var handlers = function () {
|
||||
var log = new Log("/modules/oauth/token-handlers.js");
|
||||
|
||||
var tokenUtil = require("/modules/oauth/token-handler-utils.js")["utils"];
|
||||
var constants = require("/modules/constants.js");
|
||||
var configs = require('/configs/portal.js').config();
|
||||
|
||||
var publicMethods = {};
|
||||
var privateMethods = {};
|
||||
|
||||
/**
|
||||
* Get an AccessToken pair based on username and password
|
||||
* @param username username of the logged user
|
||||
* @param password password of the logged user
|
||||
*/
|
||||
publicMethods["setupTokenPairByPasswordGrantType"] = function (username, password) {
|
||||
if (!username || !password) {
|
||||
throw new Error("{/modules/oauth/token-handlers.js} Could not set up access token pair by " +
|
||||
"password grant type. Either username of logged in user, password or both are missing " +
|
||||
"as input - setupTokenPairByPasswordGrantType(x, y)");
|
||||
} else {
|
||||
privateMethods.setUpEncodedTenantBasedClientAppCredentials(username);
|
||||
var encodedClientAppCredentials =
|
||||
session.get(constants["ENCODED_TENANT_BASED_CLIENT_APP_CREDENTIALS_PORTAL_APP"]);
|
||||
if (!encodedClientAppCredentials) {
|
||||
throw new Error("{/modules/oauth/token-handlers.js} Could not set up access token pair by " +
|
||||
"password grant type. Encoded client credentials are " +
|
||||
"missing - setupTokenPairByPasswordGrantType(x, y)");
|
||||
} else {
|
||||
var tokenData;
|
||||
// tokenPair will include current access token as well as current refresh token
|
||||
var arrayOfScopes = configs["authorization"]["methods"]["oauth"]["attributes"]["scopes"];
|
||||
var stringOfScopes = "";
|
||||
arrayOfScopes.forEach(function (entry) {
|
||||
stringOfScopes += entry + " ";
|
||||
});
|
||||
tokenData = tokenUtil.
|
||||
getTokenPairAndScopesByPasswordGrantType(username,
|
||||
encodeURIComponent(password), encodedClientAppCredentials, stringOfScopes);
|
||||
if (!tokenData) {
|
||||
throw new Error("{/app/modules/oauth/token-handlers.js} Could not set up " +
|
||||
"token pair by password grant type. Error in token " +
|
||||
"retrieval - setupTokenPairByPasswordGrantType(x, y)");
|
||||
} else {
|
||||
var tokenPair = {};
|
||||
tokenPair["accessToken"] = tokenData["accessToken"];
|
||||
tokenPair["refreshToken"] = tokenData["refreshToken"];
|
||||
// setting up token pair into session context as a string
|
||||
session.put(constants["ACCESS_TOKEN_PAIR_IDENTIFIER_FOR_PORTAL"], stringify(tokenPair));
|
||||
var scopes = tokenData.scopes.split(" ");
|
||||
// adding allowed scopes to the session
|
||||
session.put(constants["ALLOWED_SCOPES"], scopes);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Get an AccessToken pair based on SAML assertion
|
||||
* @param samlToken SAML assertion
|
||||
* @param username {{clientId:"", clientSecret:""}}
|
||||
*/
|
||||
publicMethods["setupTokenPairBySamlGrantType"] = function (username, samlToken) {
|
||||
if (!username || !samlToken) {
|
||||
throw new Error("{/modules/oauth/token-handlers.js} Could not set up access token pair by " +
|
||||
"saml grant type. Either username of logged in user, samlToken or both are missing " +
|
||||
"as input - setupTokenPairBySamlGrantType(x, y)");
|
||||
} else {
|
||||
privateMethods.setUpEncodedTenantBasedClientAppCredentials(username);
|
||||
var encodedClientAppCredentials =
|
||||
session.get(constants["ENCODED_TENANT_BASED_CLIENT_APP_CREDENTIALS_PORTAL_APP"]);
|
||||
if (!encodedClientAppCredentials) {
|
||||
throw new Error("{/app/modules/oauth/token-handlers.js} Could not set up access token pair " +
|
||||
"by saml grant type. Encoded client credentials are " +
|
||||
"missing - setupTokenPairBySamlGrantType(x, y)");
|
||||
} else {
|
||||
var tokenData;
|
||||
// accessTokenPair will include current access token as well as current refresh token
|
||||
tokenData = tokenUtil.
|
||||
getTokenPairAndScopesByJWTGrantType(username, encodedClientAppCredentials, "PRODUCTION");
|
||||
if (!tokenData) {
|
||||
throw new Error("{/modules/oauth/token-handlers.js} Could not set up token " +
|
||||
"pair by saml grant type. Error in token " +
|
||||
"retrieval - setupTokenPairBySamlGrantType(x, y)");
|
||||
} else {
|
||||
var tokenPair = {};
|
||||
tokenPair["accessToken"] = tokenData["accessToken"];
|
||||
tokenPair["refreshToken"] = tokenData["refreshToken"];
|
||||
// setting up access token pair into session context as a string
|
||||
session.put(constants["ACCESS_TOKEN_PAIR_IDENTIFIER_FOR_PORTAL"], stringify(tokenPair));
|
||||
|
||||
var scopes = tokenData.scopes.split(" ");
|
||||
// adding allowed scopes to the session
|
||||
session.put(constants["ALLOWED_SCOPES"], scopes);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Set access token and refresh token using refresh token grant type
|
||||
*/
|
||||
publicMethods["refreshTokenPair"] = function () {
|
||||
var currentTokenPair = parse(session.get(constants["ACCESS_TOKEN_PAIR_IDENTIFIER_FOR_PORTAL"]));
|
||||
// currentTokenPair includes current access token as well as current refresh token
|
||||
var encodedClientAppCredentials
|
||||
= session.get(constants["ENCODED_TENANT_BASED_CLIENT_APP_CREDENTIALS_PORTAL_APP"]);
|
||||
if (!currentTokenPair || !encodedClientAppCredentials) {
|
||||
throw new Error("{/modules/oauth/token-handlers.js} Error in refreshing tokens. Either the " +
|
||||
"token pair, encoded client app credentials or both input are not found under " +
|
||||
"session context - refreshTokenPair()");
|
||||
} else {
|
||||
var newTokenPair = tokenUtil.
|
||||
getNewTokenPairByRefreshToken(currentTokenPair["refreshToken"], encodedClientAppCredentials);
|
||||
if (!newTokenPair) {
|
||||
log.error("{/app/modules/oauth/token-handlers.js} Error in refreshing token pair. " +
|
||||
"Unable to update session context with new access token pair - refreshTokenPair()");
|
||||
} else {
|
||||
session.put(constants["ACCESS_TOKEN_PAIR_IDENTIFIER_FOR_PORTAL"], stringify(newTokenPair));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* If gateway is enable, apiManagerClientAppRegistrationServiceURL is used to create an oauth application or
|
||||
* else DCR endpoint is used to create an oauth application
|
||||
* @param username username of current logged user
|
||||
*/
|
||||
privateMethods["setUpEncodedTenantBasedClientAppCredentials"] = function (username) {
|
||||
if (!username) {
|
||||
throw new Error("{/modules/oauth/token-handlers.js} Could not set up encoded tenant based " +
|
||||
"client credentials to session context. No username of logged in user is found as " +
|
||||
"input - setUpEncodedTenantBasedClientAppCredentials(x)");
|
||||
} else {
|
||||
if (configs["authorization"]["methods"]["oauth"]["attributes"]["apimgt-gateway"]) {
|
||||
var tenantBasedClientAppCredentials = tokenUtil.getTenantBasedClientAppCredentials(username);
|
||||
if (!tenantBasedClientAppCredentials) {
|
||||
throw new Error("{/modules/oauth/token-handlers.js} Could not set up encoded tenant " +
|
||||
"based client credentials to session context as the server is unable " +
|
||||
"to obtain such credentials - setUpEncodedTenantBasedClientAppCredentials(x)");
|
||||
} else {
|
||||
var encodedTenantBasedClientAppCredentials =
|
||||
tokenUtil.encode(tenantBasedClientAppCredentials["clientId"] + ":" +
|
||||
tenantBasedClientAppCredentials["clientSecret"]);
|
||||
// setting up encoded tenant based client credentials to session context.
|
||||
session.put(constants["ENCODED_TENANT_BASED_CLIENT_APP_CREDENTIALS_PORTAL_APP"],
|
||||
encodedTenantBasedClientAppCredentials);
|
||||
}
|
||||
} else {
|
||||
var dynamicClientAppCredentials = tokenUtil.getDynamicClientAppCredentials(username);
|
||||
if (!dynamicClientAppCredentials) {
|
||||
throw new Error("{/modules/oauth/token-handlers.js} Could not set up encoded tenant based " +
|
||||
"client credentials to session context as the server is unable to obtain " +
|
||||
"dynamic client credentials - setUpEncodedTenantBasedClientAppCredentials(x)");
|
||||
}
|
||||
var encodedTenantBasedClientAppCredentials =
|
||||
tokenUtil.encode(dynamicClientAppCredentials["clientId"] + ":" +
|
||||
dynamicClientAppCredentials["clientSecret"]);
|
||||
// setting up encoded tenant based client credentials to session context.
|
||||
session.put(constants["ENCODED_TENANT_BASED_CLIENT_APP_CREDENTIALS_PORTAL_APP"],
|
||||
encodedTenantBasedClientAppCredentials);
|
||||
}
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
return publicMethods;
|
||||
}();
|
@ -1,10 +1,7 @@
|
||||
IoTs 3.0.0 QSG Setup guide
|
||||
|
||||
1. Navigate to this folder using the terminal, Note that this (Readme.txt) flie should be located under <IoTS_HOME>/core/samples/mobile-qsg/ directory.
|
||||
2. Stop the WSO2 IoTS if already runing
|
||||
3. Then execute the copy-files.sh script
|
||||
4. Start the WSO2 IoTS server
|
||||
5. Once server is started execute the mobile-qsg.sh script
|
||||
6. Then login to the https://<your-server>:9443/devicemgt/ and use the username,password as alex alex@IoTS, Note that for this sample we have configured above user from the script. If you want to run this script again you have to login as admin and remove the user alex, chris and role iotMobileUser from the IoT Server.
|
||||
|
||||
IoTs 3.1.0 QSG Setup guide
|
||||
|
||||
1. Start the WSO2 IoTS server
|
||||
2. Navigate to <IoTS_HOME>/core/samples/mobile-qsg/ directory using the terminal.
|
||||
3. Once server is started execute the mobile-qsg.sh script
|
||||
4. Then login to the https://<your-server>:9443/devicemgt/ and use the username,password as alex alex@IoTS,
|
||||
+Note that for this sample we have configured above user from the script. If you want to run this script again you have to login as admin and remove the user alex, chris and role iotMobileUser from the IoT Server.
|
After Width: | Height: | Size: 58 KiB |
After Width: | Height: | Size: 58 KiB |
After Width: | Height: | Size: 58 KiB |
After Width: | Height: | Size: 58 KiB |
After Width: | Height: | Size: 58 KiB |
After Width: | Height: | Size: 58 KiB |
After Width: | Height: | Size: 58 KiB |
After Width: | Height: | Size: 58 KiB |
After Width: | Height: | Size: 58 KiB |
After Width: | Height: | Size: 58 KiB |
@ -1,8 +0,0 @@
|
||||
#!/bin/bash
|
||||
# product-emm qsg sample setup script for copying the required files
|
||||
|
||||
echo "Copying the required files for wso2iots-3.0.0 QSG setup ..."
|
||||
cp dropings/* ../../repository/components/dropins/
|
||||
cp webapps/* ../../repository/deployment/server/webapps/
|
||||
|
||||
|