Merge branch 'cloud-3.1.0' of https://github.com/wso2/carbon-device-mgt into cloud-3.1.0

revert-70aa11f8
geethkokila 8 years ago
commit 5c659484e6

@ -286,6 +286,11 @@
<artifactId>org.wso2.carbon.application.mgt.stub</artifactId> <artifactId>org.wso2.carbon.application.mgt.stub</artifactId>
<scope>provided</scope> <scope>provided</scope>
</dependency> </dependency>
<dependency>
<groupId>org.wso2.carbon.devicemgt</groupId>
<artifactId>org.wso2.carbon.identity.jwt.client.extension</artifactId>
<scope>provided</scope>
</dependency>
</dependencies> </dependencies>
</project> </project>

@ -18,8 +18,6 @@
*/ */
package org.wso2.carbon.device.mgt.jaxrs.service.impl.admin; package org.wso2.carbon.device.mgt.jaxrs.service.impl.admin;
import org.apache.axiom.om.OMElement;
import org.apache.axiom.om.OMXMLBuilderFactory;
import org.apache.axis2.client.Options; import org.apache.axis2.client.Options;
import org.apache.axis2.java.security.SSLProtocolSocketFactory; import org.apache.axis2.java.security.SSLProtocolSocketFactory;
import org.apache.axis2.transport.http.HTTPConstants; import org.apache.axis2.transport.http.HTTPConstants;
@ -36,6 +34,7 @@ import org.wso2.carbon.context.PrivilegedCarbonContext;
import org.wso2.carbon.core.util.Utils; import org.wso2.carbon.core.util.Utils;
import org.wso2.carbon.device.mgt.jaxrs.service.api.admin.DeviceTypePublisherAdminService; import org.wso2.carbon.device.mgt.jaxrs.service.api.admin.DeviceTypePublisherAdminService;
import org.wso2.carbon.device.mgt.jaxrs.util.DeviceMgtAPIUtils; import org.wso2.carbon.device.mgt.jaxrs.util.DeviceMgtAPIUtils;
import org.wso2.carbon.identity.jwt.client.extension.JWTClient;
import org.wso2.carbon.registry.core.Registry; import org.wso2.carbon.registry.core.Registry;
import org.wso2.carbon.registry.core.Resource; import org.wso2.carbon.registry.core.Resource;
import org.wso2.carbon.registry.core.ResourceImpl; import org.wso2.carbon.registry.core.ResourceImpl;
@ -65,9 +64,14 @@ import java.util.List;
public class DeviceTypePublisherAdminServiceImpl implements DeviceTypePublisherAdminService { public class DeviceTypePublisherAdminServiceImpl implements DeviceTypePublisherAdminService {
/** /**
* required soap header for mutualSSL * required soap header for authorization
*/ */
private static final String USER_NAME_HEADER = "UserName"; private static final String AUTHORIZATION_HEADER = "Authorization";
/**
* required soap header value for mutualSSL
*/
private static final String AUTHORIZATION_HEADER_VALUE = "Bearer";
private static final String KEY_STORE_TYPE = "JKS"; private static final String KEY_STORE_TYPE = "JKS";
/** /**
@ -129,22 +133,16 @@ public class DeviceTypePublisherAdminServiceImpl implements DeviceTypePublisherA
//Call to load the TrustStore. //Call to load the TrustStore.
loadTrustStore(trustStoreLocation, trustStorePassword); loadTrustStore(trustStoreLocation, trustStorePassword);
//Create the SSL context with the loaded TrustStore/keystore. //Create the SSL context with the loaded TrustStore/keystore.
initMutualSSLConnection(); initSSLConnection();
JWTClient jwtClient = DeviceMgtAPIUtils.getJWTClientManagerService().getJWTClient();
//Constructing the soap header that required for mutual SSL
String strHeader =
"<m:UserName soapenv:mustUnderstand=\"0\" xmlns:m=\"http://mutualssl.carbon.wso2.org\" " +
"xmlns:soapenv=\"http://www.w3.org/2001/12/soap-envelope\" >'" + tenantAdminUser +
"'</m:UserName>";
InputStream is = new ByteArrayInputStream(strHeader.getBytes()); String authValue = AUTHORIZATION_HEADER_VALUE + " " + new String(Base64.encodeBase64(
OMElement header = OMXMLBuilderFactory.createOMBuilder(is).getDocumentElement(); jwtClient.getJwtToken(tenantAdminUser).getBytes()));
List<Header> list = new ArrayList<Header>(); List<Header> list = new ArrayList<Header>();
Header httpHeader = new Header(); Header httpHeader = new Header();
httpHeader.setName(USER_NAME_HEADER); httpHeader.setName(AUTHORIZATION_HEADER);
byte[] encodedBytes = Base64.encodeBase64(tenantAdminUser.getBytes()); httpHeader.setValue(authValue);
httpHeader.setValue(new String(encodedBytes));
list.add(httpHeader);//"https" list.add(httpHeader);//"https"
File directory = new File(CAR_FILE_LOCATION + File.separator + type); File directory = new File(CAR_FILE_LOCATION + File.separator + type);
@ -153,7 +151,6 @@ public class DeviceTypePublisherAdminServiceImpl implements DeviceTypePublisherA
if (uploadedFileItems.length > 0) { if (uploadedFileItems.length > 0) {
CarbonAppUploaderStub carbonAppUploaderStub = new CarbonAppUploaderStub(Utils.replaceSystemProperty( CarbonAppUploaderStub carbonAppUploaderStub = new CarbonAppUploaderStub(Utils.replaceSystemProperty(
IOT_MGT_URL)); IOT_MGT_URL));
carbonAppUploaderStub._getServiceClient().addHeader(header);
Options appUploaderOptions = carbonAppUploaderStub._getServiceClient().getOptions(); Options appUploaderOptions = carbonAppUploaderStub._getServiceClient().getOptions();
if (appUploaderOptions == null) { if (appUploaderOptions == null) {
appUploaderOptions = new Options(); appUploaderOptions = new Options();
@ -168,7 +165,6 @@ public class DeviceTypePublisherAdminServiceImpl implements DeviceTypePublisherA
if (!DEVICE_MANAGEMENT_TYPE.equals(type.toLowerCase())) { if (!DEVICE_MANAGEMENT_TYPE.equals(type.toLowerCase())) {
carbonAppUploaderStub = new CarbonAppUploaderStub(Utils.replaceSystemProperty(DAS_URL)); carbonAppUploaderStub = new CarbonAppUploaderStub(Utils.replaceSystemProperty(DAS_URL));
carbonAppUploaderStub._getServiceClient().addHeader(header);
appUploaderOptions = carbonAppUploaderStub._getServiceClient().getOptions(); appUploaderOptions = carbonAppUploaderStub._getServiceClient().getOptions();
if (appUploaderOptions == null) { if (appUploaderOptions == null) {
appUploaderOptions = new Options(); appUploaderOptions = new Options();
@ -297,7 +293,7 @@ public class DeviceTypePublisherAdminServiceImpl implements DeviceTypePublisherA
/** /**
* Initializes the SSL Context * Initializes the SSL Context
*/ */
private void initMutualSSLConnection() throws NoSuchAlgorithmException, UnrecoverableKeyException, private void initSSLConnection() throws NoSuchAlgorithmException, UnrecoverableKeyException,
KeyStoreException, KeyManagementException { KeyStoreException, KeyManagementException {
KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(KEY_MANAGER_TYPE); KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(KEY_MANAGER_TYPE);
keyManagerFactory.init(keyStore, keyStorePassword); keyManagerFactory.init(keyStore, keyStorePassword);

@ -36,6 +36,7 @@ import org.wso2.carbon.device.mgt.core.service.DeviceManagementProviderService;
import org.wso2.carbon.device.mgt.core.service.GroupManagementProviderService; import org.wso2.carbon.device.mgt.core.service.GroupManagementProviderService;
import org.wso2.carbon.device.mgt.jaxrs.beans.ErrorResponse; import org.wso2.carbon.device.mgt.jaxrs.beans.ErrorResponse;
import org.wso2.carbon.device.mgt.jaxrs.service.impl.util.InputValidationException; import org.wso2.carbon.device.mgt.jaxrs.service.impl.util.InputValidationException;
import org.wso2.carbon.identity.jwt.client.extension.service.JWTClientManagerService;
import org.wso2.carbon.policy.mgt.common.PolicyMonitoringTaskException; import org.wso2.carbon.policy.mgt.common.PolicyMonitoringTaskException;
import org.wso2.carbon.policy.mgt.core.PolicyManagerService; import org.wso2.carbon.policy.mgt.core.PolicyManagerService;
import org.wso2.carbon.policy.mgt.core.task.TaskScheduleService; import org.wso2.carbon.policy.mgt.core.task.TaskScheduleService;
@ -168,6 +169,18 @@ public class DeviceMgtAPIUtils {
return registryService; return registryService;
} }
public static JWTClientManagerService getJWTClientManagerService() {
JWTClientManagerService jwtClientManagerService;
PrivilegedCarbonContext ctx = PrivilegedCarbonContext.getThreadLocalCarbonContext();
jwtClientManagerService = (JWTClientManagerService) ctx.getOSGiService(JWTClientManagerService.class, null);
if (jwtClientManagerService == null) {
String msg = "jwtClientManagerServicehas not initialized.";
log.error(msg);
throw new IllegalStateException(msg);
}
return jwtClientManagerService;
}
/** /**
* Getting the current tenant's user realm * Getting the current tenant's user realm
*/ */

@ -0,0 +1,29 @@
/*
* Copyright (c) 2017, 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.
*/
$(document).ready(function () {
$('#cloud-menu-popover i.fw-tiles').popover({
html: true,
trigger:'click',
title: function() {
return $("#popover-head").html();
},
content: function() {
return $("#popover-content").html();
}
});
});

@ -18,10 +18,10 @@
<ul class="nav navbar-right float-remove-xs text-center-xs"> <ul class="nav navbar-right float-remove-xs text-center-xs">
<li class="visible-inline-block"> <li class="visible-inline-block">
<a href="#" target="_self" title="kachiex"> <a href="#" target="_self" title="{{@user.domain}}">
<span class="icon fw-stack fw-lg"> <span class="icon fw-stack fw-lg">
<i class="fw fw-organization fw-stack-1x" title=" {{@user.domain}}"></i> <i class="fw fw-organization fw-stack-1x" title=" {{@user.domain}}"></i>
</span> </span>
<span class="hidden-xs"> <span class="hidden-xs">
{{@user.domain}} {{@user.domain}}
</span> </span>
@ -75,25 +75,38 @@
<li class="visible-inline-block"> <li class="visible-inline-block">
<a href="#" target="null" class="dropdown" data-toggle="dropdown" title="Configure"> <a href="#" target="null" class="dropdown" data-toggle="dropdown" title="App Management">
<span class="icon fw-stack fw-lg"> <span class="icon fw-stack fw-lg">
<i class="fw fw-settings fw-stack-1x" title="Configure"></i> <i class="fw fw-settings fw-stack-1x" title="App Management"></i>
</span> </span>
<span class="hidden-xs"> <span class="hidden-xs">
Configure App Management
</span> </span>
<span class="caret"></span> <!--<span class="caret"></span>-->
</a> </a>
<ul class="dropdown-menu dropdown-menu-right float-remove-xs position-static-xs text-center-xs remove-margin-xs slideInDown" <ul class="dropdown-menu dropdown-menu-right float-remove-xs position-static-xs text-center-xs remove-margin-xs slideInDown"
role="menu"> role="menu">
<li class="visible-inline-block">
<a title="Mobile App Publisher" href="https://devicemgt.clouddev.wso2.com/publisher"
target="_self">
<i class="fw fw-user" title="Mobilr App Publisher"></i> App Publisher
</a>
</li>
<li class="visible-inline-block">
<a title="App Store " href="https://devicemgt.clouddev.wso2.com/store"
target="_self">
<i class="fw fw-store" title="App Store"></i> App Store
</a>
</li>
</ul> </ul>
</li> </li>
<li class="visible-inline-block"> <li class="visible-inline-block">
<a href="https://cloudmgt.clouddev.wso2.com/cloudmgt/site/pages/contact-us.jag" target="_self" title="Support"> <a href="https://cloudmgt.clouddev.wso2.com/cloudmgt/site/pages/contact-us.jag" target="_self"
title="Support">
<span class="icon fw-stack fw-lg" style="color: #ff8c27;"> <span class="icon fw-stack fw-lg" style="color: #ff8c27;">
@ -122,28 +135,32 @@
role="menu"> role="menu">
<li> <li>
<a title="API Cloud" href="https://docs.wso2.com/display/APICloud/WSO2+API+Cloud+Documentation" <a title="API Cloud"
href="https://docs.wso2.com/display/APICloud/WSO2+API+Cloud+Documentation"
target="_blank"> target="_blank">
<i class="fw fw-api" title="API Cloud"></i> API Cloud <i class="fw fw-api" title="API Cloud"></i> API Cloud
</a> </a>
</li> </li>
<li> <li>
<a title="App Cloud" href="https://docs.wso2.com/display/AppCloud/WSO2+App+Cloud+Documentation" <a title="App Cloud"
href="https://docs.wso2.com/display/AppCloud/WSO2+App+Cloud+Documentation"
target="_blank"> target="_blank">
<i class="fw fw-application" title="App Cloud"></i> App Cloud <i class="fw fw-application" title="App Cloud"></i> App Cloud
</a> </a>
</li> </li>
<li> <li>
<a title="App Cloud" href="https://docs.wso2.com/display/AppCloud/WSO2+Device+Cloud+Documentation" <a title="App Cloud"
href="https://docs.wso2.com/display/AppCloud/WSO2+Device+Cloud+Documentation"
target="_blank"> target="_blank">
<i class="fw fw-application" title="App Cloud"></i> Device Cloud <i class="fw fw-application" title="App Cloud"></i> Device Cloud
</a> </a>
</li> </li>
<li> <li>
<a title="API Cloud Walkthrough" href="https://api.clouddev.wso2.com/publisher?interactiveTutorial=true" <a title="API Cloud Walkthrough"
href="https://api.clouddev.wso2.com/publisher?interactiveTutorial=true"
target="_self"> target="_self">
<i class="fw fw-document" title="API Cloud Walkthrough"></i> API Cloud Walkthrough <i class="fw fw-document" title="API Cloud Walkthrough"></i> API Cloud Walkthrough
</a> </a>
@ -152,21 +169,6 @@
</ul> </ul>
</li> </li>
<li class="visible-inline-block">
<a title="Mobile App Publisher" href="https://devicemgt.clouddev.wso2.com/publisher" target="_self">
<i class="fw fw-user" title="Mobilr App Publisher"></i> App Publisher
</a>
</li>
<li class="visible-inline-block">
<a title="App Store " href="https://devicemgt.clouddev.wso2.com/store"
target="_self">
<i class="fw fw-store" title="App Store"></i> App Store
</a>
</li>
<li class="visible-inline-block"> <li class="visible-inline-block">
<a href="#" class="dropdown" data-toggle="dropdown" title="user"> <a href="#" class="dropdown" data-toggle="dropdown" title="user">
<span class="icon fw-stack fw-lg"> <span class="icon fw-stack fw-lg">
@ -184,7 +186,8 @@
role="menu"> role="menu">
<li> <li>
<a title="Profile" href="https://cloudmgt.clouddev.wso2.com/cloudmgt/site/pages/user-profile.jag" <a title="Profile"
href="https://cloudmgt.clouddev.wso2.com/cloudmgt/site/pages/user-profile.jag"
target="_self"> target="_self">
<i class="fw fw-user" title="Profile"></i> Profile <i class="fw fw-user" title="Profile"></i> Profile
</a> </a>
@ -192,13 +195,15 @@
<li> <li>
<a title="Change Password" <a title="Change Password"
href="https://cloudmgt.clouddev.wso2.com/cloudmgt/site/pages/change-password.jag" target="_self"> href="https://cloudmgt.clouddev.wso2.com/cloudmgt/site/pages/change-password.jag"
target="_self">
<i class="fw fw-lock" title="Change Password"></i> Change Password <i class="fw fw-lock" title="Change Password"></i> Change Password
</a> </a>
</li> </li>
<li> <li>
<a title="Logout" href="https://api.clouddev.wso2.com/publisher/site/pages/logout.jag" target="_self"> <a title="Logout" href="https://api.clouddev.wso2.com/publisher/site/pages/logout.jag"
target="_self">
<i class="fw fw-sign-out" title="Logout"></i> Logout <i class="fw fw-sign-out" title="Logout"></i> Logout
</a> </a>
</li> </li>
@ -217,3 +222,48 @@
</a> </a>
</li> </li>
</ul> </ul>
<div class="cloud-menu-content hide">
<div id="popover-head" class="hide">Navigate to Cloud</div>
<div id="popover-content" class="hide">
<div class="cloud-apps">
<a href="https://api.cloud.wso2.com/publisher" target="_self" class="cloud-block add-padding-top-3x">
<i class="fw fw-api fw-3x"></i>
<div class="cloud-name">API Cloud</div>
</a>
<a href="https://apps.cloud.wso2.com/appmgt" target="_self" class="cloud-block add-padding-top-3x">
<i class="fw fw-application fw-3x"></i>
<div class="cloud-name">App Cloud</div>
</a>
<a href="https://devicemgt.cloud.wso2.com/devicemgt" target="_self" class="cloud-block add-padding-top-3x">
<i class="fw fw-mobile fw-3x"></i>
<div class="cloud-name">Device Cloud</div>
</a>
<div class="clearfix"></div><!-- to make seperate -->
</div>
<div class="cloud-actions">
<h3>Manage your cloud</h3>
<a href="https://cloudmgt.cloud.wso2.com/cloudmgt/site/pages/organization.jag" target="_self" class="cloud-block-invert add-padding-top-3x">
<i class="fw fw-organization fw-3x"></i>
<div class="cloud-name">Organization</div>
</a>
<a href="https://cloudmgt.cloud.wso2.com/cloudmgt/site/pages/user.jag" target="_self" class="cloud-block-invert add-padding-top-3x">
<i class="fa fa-users fa-3x"></i>
<div class="cloud-name">Members</div>
</a>
</div>
</div>
</div>
{{#zone "bottomJs"}}
{{js "/js/user-menu.js"}}
{{/zone}}

@ -15,5 +15,11 @@
specific language governing permissions and limitations specific language governing permissions and limitations
under the License. under the License.
}} }}
{{#zone "productName"}}WSO2 IoT Server{{/zone}}
{{#zone "productNameResponsive"}}WSO2 IoT Server{{/zone}} {{#if isCloud}}
{{#zone "productName"}}WSO2 Cloud{{/zone}}
{{#zone "productNameResponsive"}}WSO2 Cloud{{/zone}}
{{else}}
{{#zone "productName"}}WSO2 IoT Server{{/zone}}
{{#zone "productNameResponsive"}}WSO2 IoT Server{{/zone}}
{{/if}}

@ -0,0 +1,24 @@
/*
* 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.
*/
function onRequest(context) {
var mdmProps = require("/app/modules/conf-reader/main.js")["conf"];
var viewModal = {};
viewModal.isCloud = mdmProps["isCloud"];
return viewModal;
}

@ -109,3 +109,126 @@
header .brand h1 { header .brand h1 {
text-transform: none !important; text-transform: none !important;
} }
.visible-inline-block {
display: inline-block !important;
}
.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;
}

@ -72,6 +72,10 @@ public class JWTClientUtil {
private static final String JWT_CONFIG_FILE_NAME = "jwt.properties"; private static final String JWT_CONFIG_FILE_NAME = "jwt.properties";
private static final String SUPERTENANT_JWT_CONFIG_LOCATION = private static final String SUPERTENANT_JWT_CONFIG_LOCATION =
CarbonUtils.getEtcCarbonConfigDirPath() + File.separator + JWT_CONFIG_FILE_NAME; CarbonUtils.getEtcCarbonConfigDirPath() + File.separator + JWT_CONFIG_FILE_NAME;
/**
* This is added for the carbon authenticator.
*/
public static final String SIGNED_JWT_AUTH_USERNAME = "Username";
/** /**
* Return a http client instance * Return a http client instance
@ -226,10 +230,11 @@ public class JWTClientUtil {
claimsSet.setIssueTime(new Date(iat)); claimsSet.setIssueTime(new Date(iat));
claimsSet.setExpirationTime(new Date(exp)); claimsSet.setExpirationTime(new Date(exp));
claimsSet.setIssuer(iss); claimsSet.setIssuer(iss);
claimsSet.setSubject(username); claimsSet.setSubject(username);
claimsSet.setNotBeforeTime(new Date(nbf)); claimsSet.setNotBeforeTime(new Date(nbf));
claimsSet.setJWTID(jti); claimsSet.setJWTID(jti);
claimsSet.setAudience(aud); claimsSet.setAudience(aud);
claimsSet.setClaim(SIGNED_JWT_AUTH_USERNAME, username);
if (customClaims != null && !customClaims.isEmpty()) { if (customClaims != null && !customClaims.isEmpty()) {
for (String key : customClaims.keySet()) { for (String key : customClaims.keySet()) {
claimsSet.setClaim(key, customClaims.get(key)); claimsSet.setClaim(key, customClaims.get(key));

Loading…
Cancel
Save