Compare commits
21 Commits
Author | SHA1 | Date |
---|---|---|
Alfredo Oliviero | a20fc7db3b | |
Alfredo Oliviero | c56f8ec9c2 | |
Alfredo Oliviero | 910397f3d1 | |
Alfredo Oliviero | c70331e6a6 | |
Alfredo Oliviero | f08edf6985 | |
Alfredo Oliviero | 99358c1f62 | |
Alfredo Oliviero | c0f90cc895 | |
Alfredo Oliviero | 05f8c088a9 | |
Alfredo Oliviero | 1ad5038583 | |
Massimiliano Assante | 048d59ac21 | |
Massimiliano Assante | 3c2294a0f4 | |
Massimiliano Assante | 0c300190c8 | |
Massimiliano Assante | 94cfc6739a | |
Alfredo Oliviero | a4e7537791 | |
Alfredo Oliviero | 6b1f9b0570 | |
Alfredo Oliviero | 64b04a8c28 | |
Alfredo Oliviero | 7252491fd5 | |
Alfredo Oliviero | 2ac68f0690 | |
Alfredo Oliviero | 7a57ca9a95 | |
Alfredo Oliviero | 1a956b4e25 | |
Alfredo Oliviero | b77c02b171 |
33
.classpath
33
.classpath
|
@ -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>
|
|
@ -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
|
37
.project
37
.project
|
@ -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>
|
|
@ -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>
|
|
@ -1,4 +0,0 @@
|
|||
eclipse.preferences.version=1
|
||||
encoding//src/main/java=UTF-8
|
||||
encoding//src/main/resources=UTF-8
|
||||
encoding/<project>=UTF-8
|
|
@ -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
|
|
@ -1,3 +0,0 @@
|
|||
eclipse.preferences.version=1
|
||||
validateFragments=false
|
||||
validation.use-project-settings=true
|
|
@ -1,4 +0,0 @@
|
|||
activeProfiles=
|
||||
eclipse.preferences.version=1
|
||||
resolveWorkspaceProjects=true
|
||||
version=1
|
|
@ -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>
|
|
@ -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>
|
|
@ -1 +0,0 @@
|
|||
org.eclipse.wst.jsdt.launching.baseBrowserLibrary
|
|
@ -1 +0,0 @@
|
|||
Window
|
|
@ -1,2 +0,0 @@
|
|||
disabled=06target
|
||||
eclipse.preferences.version=1
|
11
CHANGELOG.md
11
CHANGELOG.md
|
@ -1,8 +1,15 @@
|
|||
# Changelog
|
||||
|
||||
## [v1.1.0] - 2023-03-20
|
||||
## [v1.3.0] = 2024-04-10
|
||||
Client-exchange configuration for a dedicated client (#27204)
|
||||
|
||||
- Feature #24755 - generate a fresh token anytime the button is clicked.
|
||||
## [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
|
||||
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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
|
4
pom.xml
4
pom.xml
|
@ -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.1.0</version>
|
||||
<version>1.3.0</version>
|
||||
<description>
|
||||
Requesting Party Token Portlet
|
||||
</description>
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
|
@ -18,17 +18,20 @@ 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.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 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;
|
||||
|
@ -40,49 +43,70 @@ 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));
|
||||
JWTToken umaToken = null;
|
||||
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 sessionId = httpReq.getSession().getId();
|
||||
String urlEncodedContext = null;
|
||||
try {
|
||||
urlEncodedContext = URLEncoder.encode(context, "UTF-8");
|
||||
|
@ -90,23 +114,65 @@ 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());
|
||||
} catch (Exception e) {
|
||||
|
||||
// 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 jsonObject = JSONFactoryUtil.createJSONObject();
|
||||
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);
|
||||
super.serveResource(resourceRequest, resourceResponse);
|
||||
return;
|
||||
}
|
||||
String toReturn = umaToken.getAccessTokenString();
|
||||
resourceResponse.setContentType("application/json");
|
||||
JSONObject jsonObject = JSONFactoryUtil.createJSONObject();
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
|
@ -121,11 +187,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();
|
||||
}
|
||||
|
|
|
@ -17,8 +17,8 @@
|
|||
<portlet-mode>view</portlet-mode>
|
||||
</supports>
|
||||
<portlet-info>
|
||||
<title>Personal UMA Token</title>
|
||||
<short-title>Personal UMA Token</short-title>
|
||||
<title>Personal Token</title>
|
||||
<short-title>Personal Token</short-title>
|
||||
<keywords></keywords>
|
||||
</portlet-info>
|
||||
<security-role-ref>
|
||||
|
|
|
@ -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;
|
||||
}
|
|
@ -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,32 +284,242 @@ pageContext.setAttribute("userContexts", userContexts);
|
|||
/* Copy the text inside the text field */
|
||||
document.execCommand("copy");
|
||||
}
|
||||
|
||||
</script>
|
||||
<c:if test = "${userContexts.size() > 1}">
|
||||
<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> 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>
|
|
@ -0,0 +1 @@
|
|||
ssh 10.1.30.156 ./tail-tomcatlog.sh
|
Loading…
Reference in New Issue