Compare commits

...

28 Commits

Author SHA1 Message Date
Alfredo Oliviero a20fc7db3b authors 2024-05-08 14:26:32 +02:00
Alfredo Oliviero c56f8ec9c2 v1.3.0 2024-04-17 11:08:28 +02:00
Alfredo Oliviero 910397f3d1 removed logs 2024-04-17 11:08:18 +02:00
Alfredo Oliviero c70331e6a6 credentials for exchange client from specific parameters in config 2024-04-10 15:16:31 +02:00
Alfredo Oliviero f08edf6985 renamed methods of extended Helper 2024-04-04 18:01:59 +02:00
Alfredo Oliviero 99358c1f62 exchange uses custom context header instead of audience parameter 2024-04-04 17:03:00 +02:00
Alfredo Oliviero c0f90cc895 tail-tomcatlog.sh 2024-03-25 17:02:57 +01:00
Alfredo Oliviero 05f8c088a9 v 1.3.0, token exchange (#27099) 2024-03-25 17:02:57 +01:00
Alfredo Oliviero 1ad5038583 gitignore for java projects, removed files excluded by gitignore 2024-03-25 17:02:57 +01:00
Massimiliano Assante 048d59ac21 updated README 2024-03-19 09:00:22 +01:00
Massimiliano Assante 3c2294a0f4 updated wrong docs, REFRESH instead of Access token 2024-03-12 14:51:34 +01:00
Massimiliano Assante 0c300190c8 added note for long lasting refresh tokens 2024-03-12 14:04:59 +01:00
Massimiliano Assante 94cfc6739a updated portlet name, removed UMA from display name 2024-03-12 13:40:42 +01:00
Alfredo Oliviero a4e7537791 changed version to 1.2.0 2024-03-07 16:58:15 +01:00
Alfredo Oliviero 6b1f9b0570 changed version to 1.2.0-SNAPSHOT 2024-03-07 16:47:44 +01:00
Alfredo Oliviero 64b04a8c28 script to fast deploy in dev 2024-03-07 16:38:19 +01:00
Alfredo Oliviero 7252491fd5 changed vre name 2024-03-07 16:37:35 +01:00
Alfredo Oliviero 2ac68f0690 modified layout, added curl examples 2024-03-07 15:24:43 +01:00
Alfredo Oliviero 7a57ca9a95 curl code, detailed instructions 2024-03-06 17:59:59 +01:00
Alfredo Oliviero 1a956b4e25 decode button 2024-03-05 09:49:14 +01:00
Alfredo Oliviero b77c02b171 v1.2.0 2024-03-04 18:01:43 +01:00
Massimiliano Assante 713f4c1bb3 - Feature #24755 verified 2023-04-27 16:29:17 +02:00
Massimiliano Assante 8d899c3015 ready to release 2023-03-20 17:03:47 +01:00
Massimiliano Assante dfa6fcf4c9 removed goal build css as not useful for this 2023-03-20 17:02:53 +01:00
Massimiliano Assante 3c4e677ca9 merged feature 2023-03-20 17:00:53 +01:00
Massimiliano Assante 2c47f5e01e Feature #24755 asks for a fresh token anytime the button is clicked 2023-03-20 16:59:44 +01:00
Massimiliano Assante 4d90f27835 ready for release 2022-05-25 18:09:40 +02:00
Massimiliano Assante bc1cb9dc3e Bug #23411 fix 2022-05-25 18:05:24 +02:00
24 changed files with 1180 additions and 259 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,9 +1,23 @@
# Changelog
## [v1.3.0] = 2024-04-10
Client-exchange configuration for a dedicated client (#27204)
## [v1.2.0] - 2024-03-20
- Decode Button
- Updatet layout
- Added refresh token
- Added expiration
- Button for decode on https://jwt.io/
## [v1.0.1] - 2022-05-25
- Bug #23411 fix to the context list when deployed at VRE level
## [v1.0.0] - 2021-05-14
First release
- First release
This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

View File

@ -1,4 +1,4 @@
# gCube System - RPT Token Portlet
# gCube System - UMA Token Portlet
## Structure of the project
@ -16,16 +16,19 @@
## Change log
See [Releases](https://code-repo.d4science.org/gCubeSystem/my-vres/releases).
See [Releases](https://code-repo.d4science.org/gCubeSystem/rpt-token-portlet/releases).
## Authors
* **Massimiliano Assante** - [ISTI-CNR Infrascience Group](http://nemis.isti.cnr.it/groups/infrascience)
* **Massimiliano Assante** ([ORCID](https://orcid.org/0000-0002-3761-1492)) - [ISTI-CNR Infrascience Group](https://www.isti.cnr.it/People/M.Assante)
* **Alfredo Oliviero** ([ORCID]( https://orcid.org/0009-0007-3191-1025)) - [ISTI-CNR Infrascience Group](https://www.isti.cnr.it/People/A.Oliviero)
## Maintainers
* **Massimiliano Assante** - [ISTI-CNR Infrascience Group](http://nemis.isti.cnr.it/groups/infrascience)
* **Massimiliano Assante** ([ORCID](https://orcid.org/0000-0002-3761-1492)) - [ISTI-CNR Infrascience Group](https://www.isti.cnr.it/People/M.Assante)
* **Alfredo Oliviero** ([ORCID]( https://orcid.org/0009-0007-3191-1025)) - [ISTI-CNR Infrascience Group](https://www.isti.cnr.it/People/A.Oliviero)
## License
This project is licensed under the EUPL V.1.1 License - see the [LICENSE.md](LICENSE.md) file for details.
@ -37,12 +40,4 @@ open-source software toolkit used for building and operating Hybrid Data
Infrastructures enabling the dynamic deployment of Virtual Research Environments
by favouring the realisation of reuse oriented policies.
The projects leading to this software have received funding from a series of European Union programmes including:
- the Sixth Framework Programme for Research and Technological Development
- DILIGENT (grant no. 004260);
- the Seventh Framework Programme for research, technological development and demonstration
- D4Science (grant no. 212488), D4Science-II (grant no.239019), ENVRI (grant no. 283465), EUBrazilOpenBio (grant no. 288754), iMarine(grant no. 283644);
- the H2020 research and innovation programme
- BlueBRIDGE (grant no. 675680), EGIEngage (grant no. 654142), ENVRIplus (grant no. 654182), Parthenos (grant no. 654119), SoBigData (grant no. 654024),DESIRA (grant no. 818194), ARIADNEplus (grant no. 823914), RISIS2 (grant no. 824091), PerformFish (grant no. 727610), AGINFRAplus (grant no. 731001);
The projects leading to this software have received funding from a series of European Union programmes see [FUNDING.md](FUNDING.md)

3
deploy.sh Executable file
View File

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

14
pom.xml
View File

@ -6,14 +6,14 @@
<parent>
<artifactId>maven-parent</artifactId>
<groupId>org.gcube.tools</groupId>
<version>1.1.0</version>
<version>1.2.0</version>
<relativePath />
</parent>
<groupId>org.gcube.portlets.admin</groupId>
<artifactId>rpt-token-portlet</artifactId>
<packaging>war</packaging>
<name>RPT UMA Token Portlet</name>
<version>1.0.0</version>
<version>1.3.0</version>
<description>
Requesting Party Token Portlet
</description>
@ -38,13 +38,18 @@
<dependency>
<groupId>org.gcube.distribution</groupId>
<artifactId>maven-portal-bom</artifactId>
<version>3.6.3</version>
<version>3.6.4</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.gcube.core</groupId>
<artifactId>common-scope</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.gcube.dvos</groupId>
<artifactId>usermanagement-core</artifactId>
@ -133,9 +138,6 @@
<executions>
<execution>
<phase>generate-sources</phase>
<goals>
<goal>build-css</goal>
</goals>
</execution>
</executions>
<configuration>

View File

@ -0,0 +1,173 @@
package org.gcube.portlets.admin;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.ProtocolException;
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 ExtendedQueryExchangeToken(URL tokenUrl, String authorization, String audience, String client_id,
String client_secret,
List<String> permissions) throws OpenIdConnectRESTHelperException {
// logger.info("Queried exchangeToken for context " + audience);
// logger.info("token url " + tokenUrl);
// logger.info("exchangedToken credentials " + client_id + " " + client_secret) ;
Map<String, List<String>> params = new HashMap<>();
Map<String, String> extraHeaders = 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);
}
}
extraHeaders.put("X-D4Science-Context", audience);
// 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()));
}
// logger.info("Query exchangeToken, url " + tokenUrl);
// logger.info("Query exchangeToken, params " + params);
// logger.info("Query exchangeToken, extraHeaders " + extraHeaders);
return ExtenedPerformQueryTokenWithPOST(tokenUrl, null, params, extraHeaders);
}
protected static JWTToken ExtenedPerformQueryTokenWithPOST(URL tokenURL, String authorization,
Map<String, List<String>> params, Map<String, String> headers) throws OpenIdConnectRESTHelperException {
// logger.debug("Querying access token from OIDC server with URL: {}", tokenURL);
StringBuilder sb;
try {
HttpURLConnection httpURLConnection = ExtendedPerformURLEncodedPOSTSendData(tokenURL, params, authorization,
headers);
sb = new StringBuilder();
int httpResultCode = httpURLConnection.getResponseCode();
logger.trace("HTTP Response code: {}", httpResultCode);
String responseContentType = httpURLConnection.getContentType();
if (responseContentType != null) {
// logger.debug("Response content type is: {}", responseContentType);
} else {
responseContentType = "";
}
if (httpResultCode != HttpURLConnection.HTTP_OK) {
BufferedReader br = new BufferedReader(
new InputStreamReader(httpURLConnection.getErrorStream(), "UTF-8"));
String line = null;
while ((line = br.readLine()) != null) {
sb.append(line + "\n");
}
br.close();
throw OpenIdConnectRESTHelperException.create("Unable to get token", httpResultCode,
responseContentType, sb.toString());
} else {
BufferedReader br = new BufferedReader(
new InputStreamReader(httpURLConnection.getInputStream(), "UTF-8"));
String line = null;
while ((line = br.readLine()) != null) {
sb.append(line + "\n");
}
br.close();
}
} catch (IOException e) {
throw new OpenIdConnectRESTHelperException("Unable to get the token", e);
}
return JWTToken.fromString(sb.toString());
}
protected static HttpURLConnection ExtendedPerformURLEncodedPOSTSendData(URL url, Map<String, List<String>> params,
String authorization, Map<String, String> headers)
throws IOException, ProtocolException, UnsupportedEncodingException {
HttpURLConnection con = (HttpURLConnection) url.openConnection();
con.setRequestMethod("POST");
con.setDoOutput(true);
con.setDoInput(true);
con.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
con.setRequestProperty("Accept", "application/json");
if (authorization != null) {
// logger.debug("Adding authorization header as: {}", authorization);
con.setRequestProperty("Authorization", authorization);
}
if (headers != null) {
for (String key : headers.keySet()) {
con.setRequestProperty(key, headers.get(key));
// logger.info("setting header " + key + " : " + headers.get(key));
}
}
OutputStream os = con.getOutputStream();
String queryString = mapToQueryString(params);
// logger.debug("Parameters query string is: {}", queryString);
os.write(queryString.getBytes("UTF-8"));
os.close();
return con;
}
}

View File

@ -1,6 +1,8 @@
package org.gcube.portlets.admin;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.List;
@ -12,14 +14,24 @@ import javax.portlet.ResourceResponse;
import javax.servlet.http.HttpServletRequest;
import org.gcube.common.portal.PortalContext;
import org.gcube.portal.oidc.lr62.OIDCUmaUtil;
import org.gcube.common.scope.impl.ScopeBean;
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.OpenIdConnectRESTHelperException;
import org.gcube.portal.oidc.lr62.JWTCacheProxy;
import org.gcube.portal.oidc.lr62.LiferayOpenIdConnectConfiguration;
import org.gcube.vomanagement.usermanagement.GroupManager;
import org.gcube.vomanagement.usermanagement.impl.LiferayGroupManager;
import org.gcube.vomanagement.usermanagement.model.GCubeGroup;
import org.gcube.oidc.rest.JWTToken;
import com.liferay.portal.kernel.json.JSONArray;
import com.liferay.portal.kernel.json.JSONFactoryUtil;
import com.liferay.portal.kernel.json.JSONObject;
import com.liferay.portal.kernel.log.LogFactoryUtil;
import com.liferay.portal.kernel.util.ParamUtil;
import com.liferay.portal.kernel.util.PrefsPropsUtil;
import com.liferay.portal.model.User;
import com.liferay.portal.util.PortalUtil;
import com.liferay.util.bridges.mvc.MVCPortlet;
@ -28,54 +40,160 @@ import com.liferay.util.bridges.mvc.MVCPortlet;
* Portlet implementation class RPTTokenReader
*/
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);
List<GCubeGroup> userGroups = gm.listGroupsByUser(theUser.getUserId());
String currentContext = getCurrentContext(renderRequest);
ScopeBean bean = new ScopeBean(currentContext);
List<String> userContexts = new ArrayList<String>();
for (GCubeGroup g : userGroups) {
if (g.getGroupName().equals(PortalContext.getConfiguration().getInfrastructureName())) {
String context = gm.getInfrastructureScope(g.getGroupId());
userContexts.add(context);
}
if (g.getParentGroupId() > 0) {
String context = gm.getInfrastructureScope(g.getGroupId());
userContexts.add(context);
List<String> vreContexts = new ArrayList<String>();
List<GCubeGroup> userGroups = gm.listGroupsByUser(theUser.getUserId());
if (bean.is(Type.VRE)) {
userContexts.add(currentContext);
vreContexts.add(currentContext);
} else {
for (GCubeGroup g : userGroups) {
// 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));
JWTToken umaToken = null;
try {
String username = PortalUtil.getUser(resourceRequest).getScreenName();
umaToken = OIDCUmaUtil.getUMAToken(httpReq, username, context);
} 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);
}
String toReturn = umaToken.getAccessTokenString();
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");
JSONObject jsonObject = JSONFactoryUtil.createJSONObject();
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 urlEncodedContext = null;
try {
urlEncodedContext = URLEncoder.encode(context, "UTF-8");
} catch (UnsupportedEncodingException e) {
// Almost impossible
log.error("Cannot URL encode context", e);
}
JWTToken authToken = jwtCacheProxy.getOIDCToken(theUser, sessionId);
// umaToken = OpenIdConnectRESTHelper.queryUMAToken(configuration.getTokenURL(),
// authToken.getAccessTokenAsBearer(), urlEncodedContext, null);
Long companyId = PortalUtil.getCompanyId(httpReq);
String exchangeClientId = PrefsPropsUtil.getString(companyId,
"d4science.oidc-token-exchange-dedicated-client-id");
String exchangeClientSecret = PrefsPropsUtil.getString(companyId,
"d4science.oidc-token-exchange-dedicated-client-secret");
exchangedToken = OpenIdConnectRESTHelperExtended.ExtendedQueryExchangeToken(
configuration.getTokenURL(),
authToken.getAccessTokenString(),
urlEncodedContext,
exchangeClientId,
exchangeClientSecret,
null);
// 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);
super.serveResource(resourceRequest, resourceResponse);
return;
} catch (Exception e) {
e.printStackTrace();
jsonObject.put("success", false);
jsonObject.put("comment", e.getMessage());
resourceResponse.getWriter().println(jsonObject);
super.serveResource(resourceRequest, resourceResponse);
return;
}
jsonObject.put("success", true);
jsonObject.put("comment", toReturn);
resourceResponse.getWriter().println(jsonObject);
jsonObject.put("access_token", exchangedToken.getAccessTokenString());
jsonObject.put("refresh_token", exchangedToken.getRefreshTokenString());
jsonObject.put("raw_token", exchangedToken.getRaw());
jsonObject.put("access_token_exp", exchangedToken.getExp());
jsonObject.put("essential", exchangedToken.getTokenEssentials());
jsonObject.put("client_id", exchangedToken.getAzp());
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);
super.serveResource(resourceRequest, resourceResponse);
}
private String getCurrentContext(RenderRequest request) {
long groupId = -1;
try {
groupId = PortalUtil.getScopeGroupId(request);
return getCurrentContext(groupId);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
private String getCurrentContext(long groupId) {
try {
PortalContext pContext = PortalContext.getConfiguration();
return pContext.getCurrentScope("" + groupId);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}

View File

@ -17,8 +17,8 @@
<portlet-mode>view</portlet-mode>
</supports>
<portlet-info>
<title>RPT/UMA Token Reader</title>
<short-title>RPT Token Reader</short-title>
<title>Personal Token</title>
<short-title>Personal Token</short-title>
<keywords></keywords>
</portlet-info>
<security-role-ref>

View File

@ -0,0 +1,11 @@
code.wraptext {
white-space: pre-wrap;
white-space: -moz-pre-wrap;
white-space: -pre-wrap;
white-space: -o-pre-wrap;
word-wrap: break-word;
}
.bg_white {
background-color: white !important;
}

View File

@ -1,47 +1,281 @@
<%@ taglib uri="http://java.sun.com/portlet_2_0" prefix="portlet"%>
<%@include file="../init.jsp"%>
<%@ page import="org.gcube.vomanagement.usermanagement.model.GCubeGroup"%>
<%@ taglib uri="http://java.sun.com/portlet_2_0" prefix="portlet" %>
<%@include file="../init.jsp" %>
<%@ page import="org.gcube.vomanagement.usermanagement.model.GCubeGroup" %>
<portlet:defineObjects />
<portlet:resourceURL var="resourceURL">
</portlet:resourceURL>
<%
List<GCubeGroup> userGroups = (List<GCubeGroup>) request.getAttribute("userGroups");
<% 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 (user_contexts != null && user_contexts.size()>0){
sub = user_contexts.get(0).substring(user_contexts.get(0).lastIndexOf("/") + 1);
}
pageContext.setAttribute("firstContextName", sub);
%>
<script type="text/javascript">
var global_token_response = {};
function formatDuration(seconds) {
console.log("seconds", seconds);
if (!seconds) {
return "";
}
if (seconds < 0) seconds *= seconds;
var intervals = {
day: Math.floor(seconds / (60 * 60 * 24)),
hour: Math.floor(seconds / (60 * 60)) % 24,
minute: Math.floor(seconds / 60) % 60,
second: Math.floor(seconds / 1) % 60
};
return Object.entries(intervals)
.filter(val => val[1] !== 0)
.map(([key, val]) => "" + val + " " + key + (val != 1 ? 's' : ''))
.join(', ');
}
function initForm() {
$('#response_group').hide();
$('#error_msg').hide();
$('#rawTokenResult').hide();
openInfo('intro_info')
closeInfo('token_info')
closeInfo('refresh_token_info')
closeInfo('refresh')
console.log("hided response_group")
}
function resetResults() {
// $('#buttonCopy').hide();
// $('#buttonDecode').hide();
$('#tokenResult').text('');
$('#tokenResultDetails').text('');
$('#refreshTokenResult').text('');
$('#refreshTokenResultDetails').text('');
$('#rawTokenResult').text('');
$('#error_msg').html("")
$('#refresh_token_url').html('');
$('#client_id').html('');
}
function setResults(resultObject) {
global_token_response = resultObject;
$('#tokenResult').text(resultObject.access_token);
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();
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();
}
$('#rawTokenResult').html(JSON.stringify(raw, undefined, 4));
$('#response_group').show();
console.log("resultObject", resultObject)
//closeInfo('intro_info', false);
// closeInfo('token_info', true);
// closeInfo('refresh_token_info', true);
}
function setError(error_comment) {
$('#response_group').hide();
$('#intro_container').hide();
$('#error_msg').show();
$('#error_msg').html(error_comment);
}
function getUMAToken(endpoint) {
console.log("getUMAToken:" + endpoint);
$('#umaButton').attr("disabled", true);
$('#buttonCopy').hide();
resetResults();
var selectedContext = $("#myselect").val();
$('#tokenResult').text('');
console.log("selected context: ", selectedContext);
$.ajax({
url : endpoint,
type : 'POST',
datatype : 'json',
data : {
context : selectedContext
url: endpoint,
type: 'POST',
datatype: 'json',
data: {
context: selectedContext
},
success : function(data) {
var resultObject = JSON.parse(JSON.stringify(data));
success: function (data) {
$("#intro").hide();
var raw = JSON.stringify(data)
var resultObject = JSON.parse(raw);
if (resultObject.success) {
$('#tokenResult').text(resultObject.comment);
$('#buttonCopy').show();
setResults(resultObject);
} else {
$('#tokenResult').text(resultObject.comment);
$('#tokenResult').css('color', 'red');
setError(resultObject.comment)
}
$('#umaButton').attr("disabled", false);
},
error: function (xhr, status, error) {
console.error("error", xhr, status, error);
setError("Server error, cannot obtain the token");
$('#umaButton').attr("disabled", false);
}
});
}
function copyFunction() {
function openInfo(destination_id) {
toggleInfo(destination_id, true)
}
function closeInfo(destination_id, do_switch) {
toggleInfo(destination_id, false)
}
function toggleInfo(destination_id, do_switch) {
$("#" + destination_id).toggle(do_switch);
do_switch = $("#" + destination_id).css('display') != 'none';
$("#" + destination_id + "_icon").toggleClass("icon-chevron-up", do_switch);
$("#" + destination_id + "_icon").toggleClass("icon-chevron-down", !do_switch);
}
function decodeFunction(text_id) {
var decode_text = $("#" + text_id).val();
window.open(
"https://jwt.io/#id_token=" + encodeURIComponent(decode_text),
'_blank'
);
}
function generateAccessCurl(token, 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" +
"\t--data-urlencode 'grant_type=refresh_token' \\\n" +
"\t--data-urlencode 'client_id=" + client_id + "' \\\n" +
"\t--data-urlencode 'refresh_token=" + refresh_token + "' "
// return "curl --request POST " +
// "--data " +
// "'refresh_token=eyJhbGciOiJIUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJjOTk5YmVjNC1iNDc4LTQ4Y2YtYmI5OS0wMWMxODY5NzcwNGIifQ.eyJleHAiOjE3MTA5NDMyNzcsImlhdCI6MTcwOTczMzY3NywianRpIjoiYTEyNWNkNjUtYTJlYi00OTM3LWEwODAtNzZkYjMxNThlZGU0IiwiaXNzIjoiaHR0cHM6Ly9hY2NvdW50cy5kZXYuZDRzY2llbmNlLm9yZy9hdXRoL3JlYWxtcy9kNHNjaWVuY2UiLCJhdWQiOiJodHRwczovL2FjY291bnRzLmRldi5kNHNjaWVuY2Uub3JnL2F1dGgvcmVhbG1zL2Q0c2NpZW5jZSIsInN1YiI6ImI5OTY5YjUxLTU3OGYtNGI2OS1hNTNmLTJjOGFkZjllZmNjNyIsInR5cCI6IlJlZnJlc2giLCJhenAiOiJuZXh0LmRldi5kNHNjaWVuY2Uub3JnIiwic2Vzc2lvbl9zdGF0ZSI6IjczMzVjZGY5LTFlMjUtNGU5OC1iNjg2LWM1ZTg1NGU2MmQ4OCIsImF1dGhvcml6YXRpb24iOnsicGVybWlzc2lvbnMiOlt7InJzaWQiOiI1NzI4NTUxMC0zOTM5LTRkZTctOGZjMS1lM2E5ZDNjY2UyODEiLCJyc25hbWUiOiJEZWZhdWx0IFJlc291cmNlIn1dfSwic2NvcGUiOiJlbWFpbCBwcm9maWxlIiwic2lkIjoiNzMzNWNkZjktMWUyNS00ZTk4LWI2ODYtYzVlODU0ZTYyZDg4In0.q6T2tVSvMXJzxaxRGavGaghRB9myk4CSjhO_-mvOXxY" +
// "&client_id=next.dev.d4science.org" +
// "&grant_type=refresh_token' " +
// "https://accounts.dev.d4science.org/auth/realms/d4science/protocol/openid-connect/token"
}
function copyText(text) {
var listener = function (ev) {
ev.clipboardData.setData("text/plain", text);
ev.preventDefault();
};
document.addEventListener("copy", listener);
document.execCommand("copy");
document.removeEventListener("copy", listener);
navigator.clipboard.writeText(text).then(function () {
/* clipboard successfully set */
}, function () {
/* clipboard write failed */
});
}
function defaultServicePathUrl() {
// ***.dev.d4science.org => api.dev.d4science.org
// ***.pre.d4science.org => api.pre.d4science.org
// xxx.d4science.org => api.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")) {
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,
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(
global_token_response.client_id,
global_token_response.refresh_token,
global_token_response.token_url);
copyText(curl);
}
function copyFromTextField(text_id) {
/* Get the text field */
var copyText = document.getElementById("tokenResult");
var copyText = document.getElementById(text_id);
/* Select the text field */
copyText.select();
@ -50,30 +284,242 @@ pageContext.setAttribute("userContexts", userContexts);
/* Copy the text inside the text field */
document.execCommand("copy");
}
</script>
<p>Select the context:</p>
<c:if test="${user_contexts.size() == 0}">
<div class="alert alert-error">
Configuration error, no context available
</div>
</c:if>
<div>
<select style="width: 100%;" name="contexts" id="myselect">
<c:forEach var="context" items="${userContexts}">
<option value="${context}">${context}</option>
</c:forEach>
</select>
<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="${user_contexts.size() > 1}">
<p>Select the context:</p>
<div>
<select style="width: 100%;" name="contexts" id="myselect">
<c:forEach var="context" items="${user_contexts}">
<option value="${context}">${context}</option>
</c:forEach>
</select>
</div>
</c:if>
<div class="row">
<div>
<c:if test="${user_contexts.size() >= 1}">
<button name="umaButton" id="umaButton" type="button"
class="btn btn-primary" onClick="getUMAToken('${resourceURL}')">Get
Token</button>
</c:if>
</div>
</div>
</div>
<div style="margin-bottom: 15px;">
<button name="umaButton" id="umaButton" type="button"
class="btn btn-primary" onClick="getUMAToken('${resourceURL}')">Get
Token</button>
<br>
<div id="response_group">
<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 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>
</div>
<textarea rows=" 2" id="tokenResult" class="disabled span12" readonly></textarea>
<div class="row">
<span class="help-block span9" id='tokenResultDetails'></span>
<div class="btn-group btn-group span2">
<button id="buttonDecode" data-toggle="tooltip" class="btn btn-small"
onclick="decodeFunction('tokenResult')" title="Decode" alt="Decode">
<i class="icon-eye-open"></i>
</button>
<button id="buttonCopy" data-toggle="tooltip" class="btn btn-small"
onclick="copyFromTextField('tokenResult')" title="Copy" alt="Copy">
<i class="icon-copy"></i>
</button>
</div>
</div>
<div id="token_info" style="display: none;" class="well well-small bg_white">
<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>
<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>
</div>
<div id="response_group_refreshToken" class="well well-small">
<div class="row">
<span span9><b>Oauth2 Refresh Token</b></span>
<button id="buttonInfo" data-toggle="tooltip" class="btn btn-small pull-right"
onclick="toggleInfo('refresh_token_info')" title="Toggle infos"
alt="Toggle infos">
<i class="icon-info"></i>
<i id="refresh_token_info_icon" class="icon-chevron-down"></i>
</button>
</div>
<textarea rows=" 2" id="refreshTokenResult" class="disabled span12"
readonly></textarea>
<div class="row">
<span class="help-block span9" id='refreshTokenResultDetails'></span>
<div class="btn-group btn-group span2">
<button id="buttonDecodeRefresh" data-toggle="tooltip" class="btn btn-small"
onclick="decodeFunction('refreshTokenResult')" title="Decode"
alt="Decode">
<i class="icon-eye-open"></i>
</button>
<button id="buttonCopy" data-toggle="tooltip" class="btn btn-small"
onclick="copyFromTextField('refreshTokenResult')" title="Copy"
alt="Copy">
<i class="icon-copy"></i>
</button>
</div>
</div>
<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>
<code class="wraptext" id="usage_refresh"></code>
</p>
ref: <a href="https: //oauth.net/2/refresh-tokens/">
https://oauth.net/2/refresh-tokens/</a>
<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 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">
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>
</div>
</div>
</div>
<div>
<button id="buttonCopy" class="btn btn-mini" onclick="copyFunction()">
<i class="icon-copy"></i> Copy
</button>
<textarea style="width: 90%;" 300px; margin: 10px;" id="tokenResult"></textarea>
<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, to be used for
programmatic interaction with the Resources</p>
<p> Do not use this token to authenticate services but only for personal
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>
</ul>
</p>
<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>
<div>
You can use <a href="https://jwt.io/" target="blank">https://jwt.io/</a>
to decode.
<div id="error_msg" class="alert alert-error">
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>
$('#buttonCopy').hide();
</script>
initForm();
</script>

1
tail-tomcatlog.sh Executable file
View File

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