Compare commits

...

3 Commits

21 changed files with 623 additions and 315 deletions

BIN
.DS_Store vendored

Binary file not shown.

View File

@ -1,33 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" output="target/classes" path="src/main/java">
<attributes>
<attribute name="optional" value="true"/>
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry excluding="**" kind="src" output="target/classes" path="src/main/resources">
<attributes>
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="src" output="target/test-classes" path="src/test/java">
<attributes>
<attribute name="optional" value="true"/>
<attribute name="maven.pomderived" value="true"/>
<attribute name="test" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="con" path="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER">
<attributes>
<attribute name="maven.pomderived" value="true"/>
<attribute name="org.eclipse.jst.component.dependency" value="/WEB-INF/lib"/>
</attributes>
</classpathentry>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8">
<attributes>
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="output" path="target/classes"/>
</classpath>

322
.gitignore vendored
View File

@ -1 +1,321 @@
/target/
# Created by https://www.toptal.com/developers/gitignore/api/java,linux,macos,maven,eclipse,windows,intellij,visualstudiocode
# Edit at https://www.toptal.com/developers/gitignore?templates=java,linux,macos,maven,eclipse,windows,intellij,visualstudiocode
### Eclipse ###
.metadata
bin/
tmp/
*.tmp
*.bak
*.swp
*~.nib
local.properties
.settings/
.loadpath
.recommenders
# External tool builders
.externalToolBuilders/
# Locally stored "Eclipse launch configurations"
*.launch
# PyDev specific (Python IDE for Eclipse)
*.pydevproject
# CDT-specific (C/C++ Development Tooling)
.cproject
# CDT- autotools
.autotools
# Java annotation processor (APT)
.factorypath
# PDT-specific (PHP Development Tools)
.buildpath
# sbteclipse plugin
.target
# Tern plugin
.tern-project
# TeXlipse plugin
.texlipse
# STS (Spring Tool Suite)
.springBeans
# Code Recommenders
.recommenders/
# Annotation Processing
.apt_generated/
.apt_generated_test/
# Scala IDE specific (Scala & Java development for Eclipse)
.cache-main
.scala_dependencies
.worksheet
# Uncomment this line if you wish to ignore the project description file.
# Typically, this file would be tracked if it contains build/dependency configurations:
#.project
### Eclipse Patch ###
# Spring Boot Tooling
.sts4-cache/
### Intellij ###
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio, WebStorm and Rider
# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
# User-specific stuff
.idea/**/workspace.xml
.idea/**/tasks.xml
.idea/**/usage.statistics.xml
.idea/**/dictionaries
.idea/**/shelf
# AWS User-specific
.idea/**/aws.xml
# Generated files
.idea/**/contentModel.xml
# Sensitive or high-churn files
.idea/**/dataSources/
.idea/**/dataSources.ids
.idea/**/dataSources.local.xml
.idea/**/sqlDataSources.xml
.idea/**/dynamic.xml
.idea/**/uiDesigner.xml
.idea/**/dbnavigator.xml
# Gradle
.idea/**/gradle.xml
.idea/**/libraries
# Gradle and Maven with auto-import
# When using Gradle or Maven with auto-import, you should exclude module files,
# since they will be recreated, and may cause churn. Uncomment if using
# auto-import.
# .idea/artifacts
# .idea/compiler.xml
# .idea/jarRepositories.xml
# .idea/modules.xml
# .idea/*.iml
# .idea/modules
# *.iml
# *.ipr
# CMake
cmake-build-*/
# Mongo Explorer plugin
.idea/**/mongoSettings.xml
# File-based project format
*.iws
# IntelliJ
out/
# mpeltonen/sbt-idea plugin
.idea_modules/
# JIRA plugin
atlassian-ide-plugin.xml
# Cursive Clojure plugin
.idea/replstate.xml
# SonarLint plugin
.idea/sonarlint/
# Crashlytics plugin (for Android Studio and IntelliJ)
com_crashlytics_export_strings.xml
crashlytics.properties
crashlytics-build.properties
fabric.properties
# Editor-based Rest Client
.idea/httpRequests
# Android studio 3.1+ serialized cache file
.idea/caches/build_file_checksums.ser
### Intellij Patch ###
# Comment Reason: https://github.com/joeblau/gitignore.io/issues/186#issuecomment-215987721
# *.iml
# modules.xml
# .idea/misc.xml
# *.ipr
# Sonarlint plugin
# https://plugins.jetbrains.com/plugin/7973-sonarlint
.idea/**/sonarlint/
# SonarQube Plugin
# https://plugins.jetbrains.com/plugin/7238-sonarqube-community-plugin
.idea/**/sonarIssues.xml
# Markdown Navigator plugin
# https://plugins.jetbrains.com/plugin/7896-markdown-navigator-enhanced
.idea/**/markdown-navigator.xml
.idea/**/markdown-navigator-enh.xml
.idea/**/markdown-navigator/
# Cache file creation bug
# See https://youtrack.jetbrains.com/issue/JBR-2257
.idea/$CACHE_FILE$
# CodeStream plugin
# https://plugins.jetbrains.com/plugin/12206-codestream
.idea/codestream.xml
# Azure Toolkit for IntelliJ plugin
# https://plugins.jetbrains.com/plugin/8053-azure-toolkit-for-intellij
.idea/**/azureSettings.xml
### Java ###
# Compiled class file
*.class
# Log file
*.log
# BlueJ files
*.ctxt
# Mobile Tools for Java (J2ME)
.mtj.tmp/
# Package Files #
*.jar
*.war
*.nar
*.ear
*.zip
*.tar.gz
*.rar
# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
hs_err_pid*
replay_pid*
### Linux ###
*~
# temporary files which can be created if a process still has a handle open of a deleted file
.fuse_hidden*
# KDE directory preferences
.directory
# Linux trash folder which might appear on any partition or disk
.Trash-*
# .nfs files are created when an open file is removed but is still being accessed
.nfs*
### macOS ###
# General
.DS_Store
.AppleDouble
.LSOverride
# Icon must end with two \r
Icon
# Thumbnails
._*
# Files that might appear in the root of a volume
.DocumentRevisions-V100
.fseventsd
.Spotlight-V100
.TemporaryItems
.Trashes
.VolumeIcon.icns
.com.apple.timemachine.donotpresent
# Directories potentially created on remote AFP share
.AppleDB
.AppleDesktop
Network Trash Folder
Temporary Items
.apdisk
### macOS Patch ###
# iCloud generated files
*.icloud
### Maven ###
target/
pom.xml.tag
pom.xml.releaseBackup
pom.xml.versionsBackup
pom.xml.next
release.properties
dependency-reduced-pom.xml
buildNumber.properties
.mvn/timing.properties
# https://github.com/takari/maven-wrapper#usage-without-binary-jar
.mvn/wrapper/maven-wrapper.jar
# Eclipse m2e generated files
# Eclipse Core
.project
# JDT-specific (Eclipse Java Development Tools)
.classpath
### VisualStudioCode ###
.vscode/*
!.vscode/settings.json
!.vscode/tasks.json
!.vscode/launch.json
!.vscode/extensions.json
!.vscode/*.code-snippets
# Local History for Visual Studio Code
.history/
# Built Visual Studio Code Extensions
*.vsix
### VisualStudioCode Patch ###
# Ignore all local history of files
.history
.ionide
### Windows ###
# Windows thumbnail cache files
Thumbs.db
Thumbs.db:encryptable
ehthumbs.db
ehthumbs_vista.db
# Dump file
*.stackdump
# Folder config file
[Dd]esktop.ini
# Recycle Bin used on file shares
$RECYCLE.BIN/
# Windows Installer files
*.cab
*.msi
*.msix
*.msm
*.msp
# Windows shortcuts
*.lnk
# End of https://www.toptal.com/developers/gitignore/api/java,linux,macos,maven,eclipse,windows,intellij,visualstudiocode

View File

@ -1,37 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>RPT-Token</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.wst.common.project.facet.core.builder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.wst.validation.validationbuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.m2e.core.maven2Builder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.jem.workbench.JavaEMFNature</nature>
<nature>org.eclipse.wst.common.modulecore.ModuleCoreNature</nature>
<nature>org.eclipse.jdt.core.javanature</nature>
<nature>org.eclipse.m2e.core.maven2Nature</nature>
<nature>org.eclipse.wst.common.project.facet.core.nature</nature>
<nature>org.eclipse.wst.jsdt.core.jsNature</nature>
</natures>
</projectDescription>

View File

@ -1,13 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" path="src/main/webapp"/>
<classpathentry excluding="**/bower_components/*|**/node_modules/*|**/*.min.js" kind="src" path="target/m2e-wtp/web-resources"/>
<classpathentry kind="con" path="org.eclipse.wst.jsdt.launching.JRE_CONTAINER"/>
<classpathentry kind="con" path="org.eclipse.wst.jsdt.launching.WebProject">
<attributes>
<attribute name="hide" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="con" path="org.eclipse.wst.jsdt.launching.baseBrowserLibrary"/>
<classpathentry kind="output" path=""/>
</classpath>

View File

@ -1,4 +0,0 @@
eclipse.preferences.version=1
encoding//src/main/java=UTF-8
encoding//src/main/resources=UTF-8
encoding/<project>=UTF-8

View File

@ -1,11 +0,0 @@
eclipse.preferences.version=1
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8
org.eclipse.jdt.core.compiler.compliance=1.8
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=ignore
org.eclipse.jdt.core.compiler.release=disabled
org.eclipse.jdt.core.compiler.source=1.8

View File

@ -1,3 +0,0 @@
eclipse.preferences.version=1
validateFragments=false
validation.use-project-settings=true

View File

@ -1,4 +0,0 @@
activeProfiles=
eclipse.preferences.version=1
resolveWorkspaceProjects=true
version=1

View File

@ -1,45 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?><project-modules id="moduleCoreId" project-version="1.5.0">
<wb-module deploy-name="rpt-token-portlet">
<wb-resource deploy-path="/" source-path="/target/m2e-wtp/web-resources"/>
<wb-resource deploy-path="/" source-path="/src/main/webapp" tag="defaultRootSource"/>
<wb-resource deploy-path="/WEB-INF/classes" source-path="/src/main/java"/>
<wb-resource deploy-path="/WEB-INF/classes" source-path="/src/main/resources"/>
<property name="java-output-path" value="/RPT-Token/target/classes"/>
<property name="context-root" value="rpt-token-portlet"/>
</wb-module>
</project-modules>

View File

@ -1,8 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<faceted-project>
<fixed facet="wst.jsdt.web"/>
<installed facet="jst.web" version="2.4"/>
<installed facet="liferay.portlet" version="6.0"/>
<installed facet="wst.jsdt.web" version="1.0"/>
<installed facet="java" version="1.8"/>
</faceted-project>

View File

@ -1 +0,0 @@
org.eclipse.wst.jsdt.launching.baseBrowserLibrary

View File

@ -1 +0,0 @@
Window

View File

@ -1,2 +0,0 @@
disabled=06target
eclipse.preferences.version=1

View File

@ -1,6 +1,9 @@
# Changelog
## [v1.2.0] - 2023-03-20
## [v1.3.0-SNAPSHOT] - 20240-03-22
Token exchange (#27099)
## [v1..0] - 2023-03-20
- Decode Button
- Updatet layout

View File

@ -1,2 +1,3 @@
VERSION=1.3.0-SNAPSHOT
mvn package
scp target/rpt-token-portlet-1.2.0.war life@10.1.30.156:/home/life/Portal-Bundle/deploy/rpt-token-portlet.war
scp target/rpt-token-portlet-$VERSION.war life@10.1.30.156:/home/life/Portal-Bundle/deploy/rpt-token-portlet.war

View File

@ -13,7 +13,7 @@
<artifactId>rpt-token-portlet</artifactId>
<packaging>war</packaging>
<name>RPT UMA Token Portlet</name>
<version>1.2.0</version>
<version>1.3.0-SNAPSHOT</version>
<description>
Requesting Party Token Portlet
</description>

View File

@ -0,0 +1,73 @@
package org.gcube.portlets.admin;
import java.io.UnsupportedEncodingException;
import java.net.URL;
import java.net.URLEncoder;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import org.gcube.oidc.rest.JWTToken;
import org.gcube.oidc.rest.OpenIdConnectRESTHelper;
import org.gcube.oidc.rest.OpenIdConnectRESTHelperException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class OpenIdConnectRESTHelperExtended extends OpenIdConnectRESTHelper {
protected static final Logger logger = LoggerFactory.getLogger(OpenIdConnectRESTHelperExtended.class);
/**
* Queries from the OIDC server an exchanged token by using provided access token, for the given audience (context),
* in URLEncoded form or not, and optionally a list of permissions.
*
* @param tokenUrl the token endpoint {@link URL} of the OIDC server
* @param authorization the auth token (the access token URLEncoded by the "Bearer " string)
* @param audience the audience (context) where to request the issuing of the ticket (URLEncoded)
* @param permissions a list of permissions, can be <code>null</code>
* @return the issued token
* @throws OpenIdConnectRESTHelperException if an error occurs (also an unauthorized call), inspect the exception for details
*/
public static JWTToken queryExchangeToken(URL tokenUrl, String authorization, String audience, String client_id, String client_secret,
List<String> permissions) throws OpenIdConnectRESTHelperException {
logger.info("Queried exchangeToken for context " + audience);
Map<String, List<String>> params = new HashMap<>();
params.put("subject_token", Arrays.asList(authorization));
params.put("client_id", Arrays.asList(client_id));
params.put("client_secret", Arrays.asList(client_secret));
params.put("grant_type", Arrays.asList("urn:ietf:params:oauth:grant-type:token-exchange"));
params.put("subject_token_type", Arrays.asList("urn:ietf:params:oauth:token-type:access_token"));
params.put("requested_token_type", Arrays.asList("urn:ietf:params:oauth:token-type:access_token"));
if (audience.startsWith("/")) {
try {
logger.trace("Audience was provided in non URL encoded form, encoding it");
audience = URLEncoder.encode(audience, "UTF-8");
} catch (UnsupportedEncodingException e) {
logger.error("Cannot URL encode 'audience'", e);
}
}
try {
params.put("audience", Arrays.asList(URLEncoder.encode(audience, "UTF-8")));
} catch (UnsupportedEncodingException e) {
logger.error("Cannot URL encode 'audience'", e);
}
if (permissions != null && !permissions.isEmpty()) {
params.put(
"permission", permissions.stream().map(s -> {
try {
return URLEncoder.encode(s, "UTF-8");
} catch (UnsupportedEncodingException e) {
return "";
}
}).collect(Collectors.toList()));
}
return performQueryTokenWithPOST(tokenUrl, null, params);
}
}

View File

@ -2,6 +2,7 @@ package org.gcube.portlets.admin;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URL;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.List;
@ -21,6 +22,7 @@ import org.gcube.common.scope.impl.ScopeBean.Type;
import org.gcube.oidc.rest.JWTToken;
import org.gcube.oidc.rest.OpenIdConnectConfiguration;
import org.gcube.oidc.rest.OpenIdConnectRESTHelper;
//import org.gcube.oidc.rest.OpenIdConnectRESTHelper;
import org.gcube.oidc.rest.OpenIdConnectRESTHelperException;
import org.gcube.portal.oidc.lr62.JWTCacheProxy;
import org.gcube.portal.oidc.lr62.LiferayOpenIdConnectConfiguration;
@ -44,44 +46,59 @@ public class RPTTokenReader extends MVCPortlet {
private static com.liferay.portal.kernel.log.Log log = LogFactoryUtil.getLog(RPTTokenReader.class);
@Override
public void render(RenderRequest renderRequest, RenderResponse renderResponse) throws PortletException, IOException {
public void render(RenderRequest renderRequest, RenderResponse renderResponse)
throws PortletException, IOException {
GroupManager gm = new LiferayGroupManager();
try {
try {
User theUser = PortalUtil.getUser(renderRequest);
String currentContext = getCurrentContext(renderRequest);
ScopeBean bean = new ScopeBean(currentContext);
List<String> userContexts = new ArrayList<String>();
List<String> vreContexts = new ArrayList<String>();
List<GCubeGroup> userGroups = gm.listGroupsByUser(theUser.getUserId());
if (bean.is(Type.VRE)) {
userContexts.add(currentContext);
}
else {
vreContexts.add(currentContext);
} else {
for (GCubeGroup g : userGroups) {
if(! (g.getFriendlyURL().equals("/guest") || g.getFriendlyURL().equals("/global") )) {// skipping these sites
// skipping these sites
if (!(g.getFriendlyURL().equals("/guest") || g.getFriendlyURL().equals("/global"))) {
if (g.getGroupName().equals(PortalContext.getConfiguration().getInfrastructureName())) {
String context = gm.getInfrastructureScope(g.getGroupId());
userContexts.add(context);
if (context.split("/").length == 4){
vreContexts.add(context);
}
}
if (g.getParentGroupId() > 0) {
String context = gm.getInfrastructureScope(g.getGroupId());
userContexts.add(context);
if (context.split("/").length == 4){
vreContexts.add(context);
}
}
}
}
}
renderRequest.setAttribute("userGroups", userGroups);
renderRequest.setAttribute("userContexts", userContexts);
renderRequest.setAttribute("vreContexts", vreContexts);
} catch (Exception e) {
e.printStackTrace();
}
super.render(renderRequest, renderResponse);
super.render(renderRequest, renderResponse);
}
public void serveResource(ResourceRequest resourceRequest, ResourceResponse resourceResponse) throws IOException, PortletException {
public void serveResource(ResourceRequest resourceRequest, ResourceResponse resourceResponse)
throws IOException, PortletException {
String context = ParamUtil.getString(resourceRequest, "context", null);
System.out.println("Selected context="+context);
HttpServletRequest httpReq = PortalUtil.getOriginalServletRequest(PortalUtil.getHttpServletRequest(resourceRequest));
System.out.println("Selected context=" + context);
HttpServletRequest httpReq = PortalUtil
.getOriginalServletRequest(PortalUtil.getHttpServletRequest(resourceRequest));
JWTToken umaToken = null;
JWTToken exchangedToken = null;
GroupManager gm = new LiferayGroupManager();
resourceResponse.setContentType("application/json");
@ -90,10 +107,10 @@ public class RPTTokenReader extends MVCPortlet {
try {
User theUser = PortalUtil.getUser(resourceRequest);
OpenIdConnectConfiguration configuration = LiferayOpenIdConnectConfiguration.getConfiguration(httpReq);
jsonObject.put("token_url", configuration.getTokenURL().toString());
JWTCacheProxy jwtCacheProxy = JWTCacheProxy.getInstance();
String sessionId = httpReq.getSession().getId();
String sessionId = httpReq.getSession().getId();
String urlEncodedContext = null;
try {
urlEncodedContext = URLEncoder.encode(context, "UTF-8");
@ -101,55 +118,78 @@ public class RPTTokenReader extends MVCPortlet {
// Almost impossible
log.error("Cannot URL encode context", e);
}
JWTToken authToken = jwtCacheProxy.getOIDCToken(theUser, sessionId);
umaToken = OpenIdConnectRESTHelper.queryUMAToken(configuration.getTokenURL(), authToken.getAccessTokenAsBearer(), urlEncodedContext, null);
log.debug("Got a new UMA token " + umaToken.getTokenEssentials());
umaToken = OpenIdConnectRESTHelper.queryUMAToken(configuration.getTokenURL(),
authToken.getAccessTokenAsBearer(), urlEncodedContext, null);
// URL auth_url = configuration.getTokenURL();
// log.info("auth_url " + auth_url);
// log.info("authToken " + authToken.getAccessTokenString());
// log.info("umaToken " + umaToken.getAccessTokenString());
// log.info("context " + context);
// log.info("encoded_context " + urlEncodedContext);
// log.info("client_id " + configuration.getPortalClientId());
// log.info("client_secret " + configuration.getPortalClientSecret());
exchangedToken = OpenIdConnectRESTHelperExtended.queryExchangeToken(
configuration.getTokenURL(),
umaToken.getAccessTokenString(),
urlEncodedContext,
configuration.getPortalClientId(),
configuration.getPortalClientSecret(),
null);
// log.info("exchangedToken " + exchangedToken.getAccessTokenString());
// log.debug("Got a new UMA token " + exchangedToken.getTokenEssentials());
} catch (OpenIdConnectRESTHelperException e) {
resourceResponse.setProperty(ResourceResponse.HTTP_STATUS_CODE, "" + e.getStatus());
e.printStackTrace();
jsonObject.put("success", false);
jsonObject.put("comment", e.getMessage());
resourceResponse.getWriter().println(jsonObject);
resourceResponse.getWriter().println(jsonObject);
super.serveResource(resourceRequest, resourceResponse);
return;
} catch (Exception e) {
e.printStackTrace();
jsonObject.put("success", false);
jsonObject.put("comment", e.getMessage());
resourceResponse.getWriter().println(jsonObject);
resourceResponse.getWriter().println(jsonObject);
super.serveResource(resourceRequest, resourceResponse);
return;
}
// } catch (Exception e) {
// e.printStackTrace();
// JSONObject jsonObject = JSONFactoryUtil.createJSONObject();
// jsonObject.put("success", false);
// jsonObject.put("comment", e.getMessage());
// resourceResponse.getWriter().println(jsonObject);
// super.serveResource(resourceRequest, resourceResponse);
// }
// e.printStackTrace();
// JSONObject jsonObject = JSONFactoryUtil.createJSONObject();
// jsonObject.put("success", false);
// jsonObject.put("comment", e.getMessage());
// resourceResponse.getWriter().println(jsonObject);
// super.serveResource(resourceRequest, resourceResponse);
// }
jsonObject.put("success", true);
jsonObject.put("access_token", umaToken.getAccessTokenString());
jsonObject.put("refresh_token", umaToken.getRefreshTokenString());
jsonObject.put("access_token", exchangedToken.getAccessTokenString());
jsonObject.put("refresh_token", exchangedToken.getRefreshTokenString());
jsonObject.put("raw_token", umaToken.getRaw());
jsonObject.put("access_token_exp", umaToken.getExp());
jsonObject.put("essential", umaToken.getTokenEssentials());
jsonObject.put("raw_token", exchangedToken.getRaw());
jsonObject.put("access_token_exp", exchangedToken.getExp());
jsonObject.put("essential", exchangedToken.getTokenEssentials());
jsonObject.put("client_id", umaToken.getAzp());
JSONArray audiences = JSONFactoryUtil.createJSONArray();
List<String> list_audiences = umaToken.getAud();
JSONArray audiences = JSONFactoryUtil.createJSONArray();
List<String> list_audiences = exchangedToken.getAud();
for (int i = 0; i < list_audiences.size(); i++) {
audiences.put((String) list_audiences.get(i));
}
jsonObject.put("audience", audiences);
resourceResponse.getWriter().println(jsonObject);
resourceResponse.getWriter().println(jsonObject);
super.serveResource(resourceRequest, resourceResponse);
}
@ -164,11 +204,10 @@ public class RPTTokenReader extends MVCPortlet {
return null;
}
private String getCurrentContext(long groupId) {
private String getCurrentContext(long groupId) {
try {
PortalContext pContext = PortalContext.getConfiguration();
return pContext.getCurrentScope(""+groupId);
PortalContext pContext = PortalContext.getConfiguration();
return pContext.getCurrentScope("" + groupId);
} catch (Exception e) {
e.printStackTrace();
}

View File

@ -7,15 +7,16 @@
<% List<GCubeGroup> userGroups = (List<GCubeGroup>) request.getAttribute("userGroups");
pageContext.setAttribute("userGroups", userGroups);
List<String> userContexts = (List<String>) request.getAttribute("userContexts");
pageContext.setAttribute("userContexts", userContexts);
List<String> user_contexts = (List<String>) request.getAttribute("vreContexts");
pageContext.setAttribute("user_contexts", user_contexts);
String sub = "-";
if (userContexts != null && userContexts.size()>0){
sub = userContexts.get(0).substring(userContexts.get(0).lastIndexOf("/") + 1);
if (user_contexts != null && user_contexts.size()>0){
sub = user_contexts.get(0).substring(user_contexts.get(0).lastIndexOf("/") + 1);
}
pageContext.setAttribute("firstContextName", sub);
%>
@ -76,33 +77,35 @@ pageContext.setAttribute("firstContextName", sub);
global_token_response = resultObject;
$('#tokenResult').text(resultObject.access_token);
$('#refreshTokenResult').text(resultObject.refresh_token);
$('#refresh_token_url').text(resultObject.token_url);
$('#client_id').text(resultObject.client_id);
$('#usage_token').html(generateAccessCurl("[ACCESS_TOKEN]", "[SERVICE_URL]"))
$('#usage_refresh').html(generateRefreshCurl("[CLIENT_ID]", "[REFRESH_TOKEN]", "[REFRESH_URL]"))
var raw = JSON.parse(resultObject.raw_token)
var expires_in = raw.expires_in;
if (expires_in) {
$('#tokenResultDetails').html('expires in <b>' + formatDuration(expires_in) + '</b>');
}
$('#usage_token').html(generateAccessCurl("[ACCESS_TOKEN]", "[SERVICE_URL]"));
resetAccessUrl();
var refresh_expires_in = raw.refresh_expires_in;
if (expires_in) {
$('#refreshTokenResultDetails').html('expires in <b>' + formatDuration(refresh_expires_in) + '</b>');
openInfo('token_info');
var refresh_token = resultObject.refresh_token;
if (refresh_token) {
$('#refreshTokenResult').text(resultObject.refresh_token);
$('#refresh_token_url').text(resultObject.token_url);
$('#client_id').text(resultObject.client_id);
$('#usage_refresh').html(generateRefreshCurl("[CLIENT_ID]", "[REFRESH_TOKEN]", "[REFRESH_URL]"))
var refresh_expires_in = raw.refresh_expires_in;
if (refresh_expires_in) {
$('#refreshTokenResultDetails').html('expires in <b>' + formatDuration(refresh_expires_in) + '</b>');
}
$('#response_group_refreshToken').show();
$('#refresh_parameters').show();
} else {
$('#response_group_refreshToken').hide();
$('#refresh_parameters').hide();
}
var not_before_policy = raw["not-before-policy"];
console.log("expires_in", expires_in);
console.log("refresh_expires_in", refresh_expires_in);
console.log("not-before-policy", not_before_policy);
$('#rawTokenResult').html(JSON.stringify(raw, undefined, 4));
$('#response_group').show();
@ -114,7 +117,9 @@ pageContext.setAttribute("firstContextName", sub);
}
function setError(error_comment) {
$('response_group').hide();
$('#response_group').hide();
$('#intro_container').hide();
$('#error_msg').show();
$('#error_msg').html(error_comment);
@ -179,16 +184,11 @@ pageContext.setAttribute("firstContextName", sub);
'_blank'
);
}
function generateAccessCurl(token, service_url) {
return "curl -X GET -H 'Authorization: Bearer " + token + "' \\\n"
+ "\t " + service_url
return "curl -X GET -H 'Authorization: Bearer " + token + "' " + service_url
}
function generateRefreshCurl(client_id, refresh_token, refresh_url) {
return "curl -X POST --location '" + refresh_url + "' \\\n" +
// "\t--header 'Content-Type: application/x-www-form-urlencoded' \\\n" +
@ -221,28 +221,48 @@ pageContext.setAttribute("firstContextName", sub);
});
}
function copyAccessCurl() {
function defaultServicePathUrl() {
// ***.dev.d4science.org => api.dev.d4science.org
// ***.pre.d4science.org => api.pre.d4science.org
// xxx.d4science.org => api.d4science.org
var client_id = global_token_response.client_id;
var service_path = "api.d4science.org";
if (client_id.endsWith("dev.d4science.org")){
var service_path = "api.d4science.org";
var client_id = global_token_response.client_id;
if (client_id.endsWith("dev.d4science.org")) {
service_path = "api.dev.d4science.org";
} else if (client_id.endsWith("pre.d4science.org")){
} else if (client_id.endsWith("pre.d4science.org")) {
service_path = "api.pre.d4science.org";
}
console.log(defaultServicePathUrl, client_id, service_path);
return service_path;
}
function defaultServiceAccessUrl() {
var service_path = defaultServicePathUrl();
//return "https://" + service_path + "/catalogue/items";
return "https://" + service_path + "/rest/2/people/profile";
}
function copyAccessCurl() {
var service_access_url = $("#input_access_url").val();
var curl = generateAccessCurl(
global_token_response.access_token,
"https://" + service_path + "/catalogue/items");
service_access_url);
console.info("curl", curl);
copyText(curl);
}
function resetAccessUrl() {
var accessUrl = defaultServiceAccessUrl();
console.log("accessUrl", accessUrl)
$("#input_access_url").val(accessUrl);
}
function copyRefreshCurl() {
var curl = generateRefreshCurl(
@ -267,24 +287,24 @@ pageContext.setAttribute("firstContextName", sub);
</script>
<c:if test="${userContexts.size() == 0}">
<c:if test="${user_contexts.size() == 0}">
<div class="alert alert-error">
Configuration error, no context available
</div>
</c:if>
<div>
<c:if test="${userContexts.size() == 1}">
<p>Current context: ${firstContextName}</p>
<input type="hidden" name="contexts" id="myselect" value="${userContexts[0]}">
<c:if test="${user_contexts.size() == 1}">
<p>Current context: ${firstContextName} </p>
<input type="hidden" name="contexts" id="myselect" value="${user_contexts[0]}">
</c:if>
<c:if test="${userContexts.size() > 1}">
<c:if test="${user_contexts.size() > 1}">
<p>Select the context:</p>
<div>
<select style="width: 100%;" name="contexts" id="myselect">
<c:forEach var="context" items="${userContexts}">
<c:forEach var="context" items="${user_contexts}">
<option value="${context}">${context}</option>
</c:forEach>
</select>
@ -293,7 +313,7 @@ pageContext.setAttribute("firstContextName", sub);
<div class="row">
<div>
<c:if test="${userContexts.size() >= 1}">
<c:if test="${user_contexts.size() >= 1}">
<button name="umaButton" id="umaButton" type="button"
class="btn btn-primary" onClick="getUMAToken('${resourceURL}')">Get
Token</button>
@ -311,9 +331,9 @@ pageContext.setAttribute("firstContextName", sub);
<div id="response_group_token" class="well well-small">
<div class="row">
<span class="span9"><b>OAuth Access Token <br> (Bearer Authorization)</b></span>
<button id="buttonInfo" data-toggle="tooltip" class="btn btn-small pull-right span2"
onclick="toggleInfo('token_info')" title="Toggle infos"
alt="Toggle infos">
<button id="buttonInfo" data-toggle="tooltip"
class="btn btn-small pull-right span3" onclick="toggleInfo('token_info')"
title="Toggle infos" alt="Toggle infos">
<i class="icon-info"></i>
<i id="token_info_icon" class="icon-chevron-down"></i>
</button>
@ -333,27 +353,40 @@ pageContext.setAttribute("firstContextName", sub);
</div>
</div>
<div id="token_info" style="display: none;" class="well well-small bg_white">
<p>Personal Token used to access protected resources</p>
<p>The token has a limited lifespan and must be included as a Bearer
token
in the Authorization header of the http request"</p>
<p>usage:<br>
<code id="usage_token" class="wraptext">curl -H "Authorization: Bearer [ACCESS_TOKEN] " \<br>&emsp;https://api.example.com/userinfo</code>
</p>
in the Authorization header of the http request</p>
<p>
ref: <a
href="https://oauth.net/2/access-tokens">https://oauth.net/2/access-tokens/
</a>
</p>
<i>The HTTP Request below is an example given in curl syntax, the equivalent HTTP can be coded in any language:</i><br>
<code id="usage_token"
class="wraptext">curl -H "Authorization: Bearer [ACCESS_TOKEN] " \<br>&emsp;https://api.example.com/userinfo</code>
</p>
<div id="curl_example" style="display: none;">
generate curl access request for url:
<textarea rows=" 2" id="input_access_url" class="span12"></textarea>
<div class="row">
<button id="buttonResetAccessCurl" data-toggle="tooltip"
class="btn btn-small pull-right" onclick="resetAccessUrl()"
title="reset" alt="reset">
<i class="icon-refresh"></i>
</button>
<button id="buttonGeneratAccessCurl" data-toggle="tooltip"
class="btn btn-small pull-right" onclick="copyAccessCurl()"
title="Copy to clipboard" alt="Copy to clipboard">
<i class="icon-copy"></i>
</button>
</div>
</div>
<p>
ref: <a
href="https://oauth.net/2/access-tokens">https://oauth.net/2/access-tokens/
</a>
</p>
<div class="row">
generate curl access request example: <button id="buttonGeneratAccessCurl"
data-toggle="tooltip" class="btn btn-small pull-right"
onclick="copyAccessCurl()" title="Copy to clipboard"
alt="Copy to clipboard">
<i class="icon-copy"></i>
</button>
</div>
</div>
@ -388,7 +421,8 @@ pageContext.setAttribute("firstContextName", sub);
</div>
</div>
<div id="refresh_token_info" style="display: none;" class="well well-small bg_white">
<div id="refresh_token_info" style="display: none;"
class="well well-small bg_white">
<p>Use this token to programmaticaly refresh the Access token.
</p>
<p>usage:<br>
@ -408,75 +442,71 @@ pageContext.setAttribute("firstContextName", sub);
</div>
<div id="parameters" class="well well-small">
<div id="refresh_parameters" class="well well-small">
<div class="row" onclick="toggleInfo('refresh')">
<span><b>Refresh parameters</b></span>
<i id="refresh_icon" class="icon-chevron-down pull-right"></i>
</div>
<div id="refresh">
<div class="row">
<br>
refresh token url: <code class="wraptext" id="refresh_token_url"></code>
<button id="refresh_token_url_copy" data-toggle="tooltip"
class="btn btn-small pull-right"
onclick="copyText(global_token_response.token_url)"
title="copy refresh token url" alt="copy refresh token url">
<i class="icon-copy"></i>
</button>
</div>
<div class="row">
<br>
refresh token url: <code class="wraptext" id="refresh_token_url"></code>
<button id="refresh_token_url_copy" data-toggle="tooltip"
class="btn btn-small pull-right"
onclick="copyText(global_token_response.token_url)"
title="copy refresh token url" alt="copy refresh token url">
<i class="icon-copy"></i>
</button>
</div>
<div class="row">
client_id: <code class="wraptext" id="client_id"></code> <button
id="client_id_copy" data-toggle="tooltip" class="btn btn-small pull-right"
onclick="copyText(global_token_response.client_id)"
title="copy refresh token url" alt="copy refresh token url">
<i class="icon-copy"></i>
</button><br>
</div>
<div class="row">
client_id: <code class="wraptext" id="client_id"></code> <button
id="client_id_copy" data-toggle="tooltip"
class="btn btn-small pull-right"
onclick="copyText(global_token_response.client_id)"
title="copy refresh token url" alt="copy refresh token url">
<i class="icon-copy"></i>
</button><br>
</div>
<div class="row">
generate curl refresh request: <button id="buttonGenerateRefreshCurl"
data-toggle="tooltip" class="btn btn-small pull-right"
onclick="copyRefreshCurl()" title="Copy to clipboard"
alt="Copy to clipboard">
<i class="icon-copy"></i>
</button>
<div class="row">
generate curl refresh request: <button id="buttonGenerateRefreshCurl"
data-toggle="tooltip" class="btn btn-small pull-right"
onclick="copyRefreshCurl()" title="Copy to clipboard"
alt="Copy to clipboard">
<i class="icon-copy"></i>
</button>
</div>
</div>
</div>
</div>
<div id="div_decode">
You can decode the tokens using <a href="https://jwt.io/#debugger-io"
target="blank">https://jwt.io/</a>
</div>
</div>
<div class="well well-small" id="intro_container">
<div class="row" onclick="toggleInfo('intro_info')">
<span><b>Instructions</b></span>
<i id="intro_info_icon" class="icon-chevron-down pull-right"></i>
</div>
<div id="intro_info" class="well well-small bg_white">
<p>Obtain your personal OAuth2 Access and Refresh Tokens, to be used for
programmatic interaction with the Resources</p>
<p>Obtain your personal OAuth2 Access, to be used for
programmatic interaction with the Resources</p>
<p> Do not use this token to authenticate services but only for personal
access
access
</p>
<p>
ref:
<ul>
<li><a href="https://dev.d4science.org/how-to-access-resources">
Accessing Resources - how to</a></li>
<li><a
href="https://www.oauth.com/oauth2-servers/making-authenticated-requests">OAuth2:
Making Authenticated Requests</a></li>
<li><a
href="https://www.oauth.com/oauth2-servers/making-authenticated-requests/refreshing-an-access-token/">OAuth2:
Refresh Tokens</a></li>
</ul>
<ul>
<li><a href="https://dev.d4science.org/how-to-access-resources">
Accessing Resources - how to</a></li>
<li><a
href="https://www.oauth.com/oauth2-servers/making-authenticated-requests">OAuth2:
Making Authenticated Requests</a></li>
</ul>
</p>
<p>Please Note: if you need long lasting refresh tokens (14 days) tick 'remember me' option during Sign In. For service to service interaction you may obtain a service account by opening a <a href="https://support.d4science.org" target="_blank">support request</a>.
<p>
Please note: if you need long lasting access tokens you may obtain a service account by opening a
<a href="https://support.d4science.org/projects/services-support/issues/new" target="_blank">request</a>
</p>
</div>
</div>
@ -485,7 +515,10 @@ pageContext.setAttribute("firstContextName", sub);
Configuration error, no context available
</div>
<div id="div_decode">
You can decode the tokens using <a href="https://jwt.io/#debugger-io"
target="blank">https://jwt.io/</a>
</div>
<script>
initForm();

1
tail-tomcatlog.sh Executable file
View File

@ -0,0 +1 @@
ssh 10.1.30.156 ./tail-tomcatlog.sh