first commit. smartgear service, keycloack client prototipe
This commit is contained in:
commit
493961ad0b
|
@ -0,0 +1,171 @@
|
||||||
|
# originale
|
||||||
|
target
|
||||||
|
.classpath
|
||||||
|
.visual
|
||||||
|
.project
|
||||||
|
.settings
|
||||||
|
/**/.DS_Store
|
||||||
|
|
||||||
|
# Created by https://www.toptal.com/developers/gitignore/api/java,macos,linux,visualstudiocode,eclipse
|
||||||
|
# Edit at https://www.toptal.com/developers/gitignore?templates=java,macos,linux,visualstudiocode,eclipse
|
||||||
|
|
||||||
|
### 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/
|
||||||
|
|
||||||
|
### 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
|
||||||
|
|
||||||
|
### 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
|
||||||
|
|
||||||
|
# End of https://www.toptal.com/developers/gitignore/api/java,macos,linux,visualstudiocode,eclipse
|
|
@ -0,0 +1,4 @@
|
||||||
|
{
|
||||||
|
"java.compile.nullAnalysis.mode": "automatic",
|
||||||
|
"java.configuration.updateBuildConfiguration": "automatic"
|
||||||
|
}
|
|
@ -0,0 +1,9 @@
|
||||||
|
This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||||
|
|
||||||
|
# Changelog for Identity Manager Service
|
||||||
|
|
||||||
|
|
||||||
|
## [v1.0.0-SNAPSHOT]
|
||||||
|
|
||||||
|
- First Version
|
||||||
|
|
|
@ -0,0 +1,11 @@
|
||||||
|
FROM smartgears-distribution:4.0.0-java11-tomcat9
|
||||||
|
ARG REPOUSER=admin
|
||||||
|
ARG REPOPWD=admin
|
||||||
|
COPY ./target/identity-manager.war /tomcat/webapps/
|
||||||
|
# COPY ./docker/storagehub.xml /tomcat/conf/Catalina/localhost/
|
||||||
|
COPY ./docker/logback.xml /etc/
|
||||||
|
COPY ./docker/container.ini /etc/
|
||||||
|
RUN unzip /tomcat/webapps/identity-manager.war -d /tomcat/webapps/identity-manager
|
||||||
|
RUN rm /tomcat/webapps/identity-manager.war
|
||||||
|
# COPY ./docker/storage-settings.properties /tomcat/webapps/identity-manager/WEB-INF/classes/
|
||||||
|
RUN sed -i "s/{{adminId}}/$REPOUSER/g; s/{{adminPwd}}/$REPOPWD/g" /tomcat/webapps/storagehub/WEB-INF/web.xml
|
|
@ -0,0 +1,26 @@
|
||||||
|
# Acknowledgments
|
||||||
|
|
||||||
|
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](https://cordis.europa.eu/project/id/004260) (grant no. 004260).
|
||||||
|
- the Seventh Framework Programme for research, technological development and demonstration
|
||||||
|
- [D4Science](https://cordis.europa.eu/project/id/212488) (grant no. 212488);
|
||||||
|
- [D4Science-II](https://cordis.europa.eu/project/id/239019) (grant no.239019);
|
||||||
|
- [ENVRI](https://cordis.europa.eu/project/id/283465) (grant no. 283465);
|
||||||
|
- [iMarine](https://cordis.europa.eu/project/id/283644) (grant no. 283644);
|
||||||
|
- [EUBrazilOpenBio](https://cordis.europa.eu/project/id/288754) (grant no. 288754).
|
||||||
|
- the H2020 research and innovation programme
|
||||||
|
- [SoBigData](https://cordis.europa.eu/project/id/654024) (grant no. 654024);
|
||||||
|
- [PARTHENOS](https://cordis.europa.eu/project/id/654119) (grant no. 654119);
|
||||||
|
- [EGI-Engage](https://cordis.europa.eu/project/id/654142) (grant no. 654142);
|
||||||
|
- [ENVRI PLUS](https://cordis.europa.eu/project/id/654182) (grant no. 654182);
|
||||||
|
- [BlueBRIDGE](https://cordis.europa.eu/project/id/675680) (grant no. 675680);
|
||||||
|
- [PerformFISH](https://cordis.europa.eu/project/id/727610) (grant no. 727610);
|
||||||
|
- [AGINFRA PLUS](https://cordis.europa.eu/project/id/731001) (grant no. 731001);
|
||||||
|
- [DESIRA](https://cordis.europa.eu/project/id/818194) (grant no. 818194);
|
||||||
|
- [ARIADNEplus](https://cordis.europa.eu/project/id/823914) (grant no. 823914);
|
||||||
|
- [RISIS 2](https://cordis.europa.eu/project/id/824091) (grant no. 824091);
|
||||||
|
- [EOSC-Pillar](https://cordis.europa.eu/project/id/857650) (grant no. 857650);
|
||||||
|
- [Blue Cloud](https://cordis.europa.eu/project/id/862409) (grant no. 862409);
|
||||||
|
- [SoBigData-PlusPlus](https://cordis.europa.eu/project/id/871042) (grant no. 871042);
|
|
@ -0,0 +1,312 @@
|
||||||
|
# European Union Public Licence V. 1.1
|
||||||
|
|
||||||
|
|
||||||
|
EUPL © the European Community 2007
|
||||||
|
|
||||||
|
|
||||||
|
This European Union Public Licence (the “EUPL”) applies to the Work or Software
|
||||||
|
(as defined below) which is provided under the terms of this Licence. Any use of
|
||||||
|
the Work, other than as authorised under this Licence is prohibited (to the
|
||||||
|
extent such use is covered by a right of the copyright holder of the Work).
|
||||||
|
|
||||||
|
The Original Work is provided under the terms of this Licence when the Licensor
|
||||||
|
(as defined below) has placed the following notice immediately following the
|
||||||
|
copyright notice for the Original Work:
|
||||||
|
|
||||||
|
Licensed under the EUPL V.1.1
|
||||||
|
|
||||||
|
or has expressed by any other mean his willingness to license under the EUPL.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## 1. Definitions
|
||||||
|
|
||||||
|
In this Licence, the following terms have the following meaning:
|
||||||
|
|
||||||
|
- The Licence: this Licence.
|
||||||
|
|
||||||
|
- The Original Work or the Software: the software distributed and/or
|
||||||
|
communicated by the Licensor under this Licence, available as Source Code and
|
||||||
|
also as Executable Code as the case may be.
|
||||||
|
|
||||||
|
- Derivative Works: the works or software that could be created by the Licensee,
|
||||||
|
based upon the Original Work or modifications thereof. This Licence does not
|
||||||
|
define the extent of modification or dependence on the Original Work required
|
||||||
|
in order to classify a work as a Derivative Work; this extent is determined by
|
||||||
|
copyright law applicable in the country mentioned in Article 15.
|
||||||
|
|
||||||
|
- The Work: the Original Work and/or its Derivative Works.
|
||||||
|
|
||||||
|
- The Source Code: the human-readable form of the Work which is the most
|
||||||
|
convenient for people to study and modify.
|
||||||
|
|
||||||
|
- The Executable Code: any code which has generally been compiled and which is
|
||||||
|
meant to be interpreted by a computer as a program.
|
||||||
|
|
||||||
|
- The Licensor: the natural or legal person that distributes and/or communicates
|
||||||
|
the Work under the Licence.
|
||||||
|
|
||||||
|
- Contributor(s): any natural or legal person who modifies the Work under the
|
||||||
|
Licence, or otherwise contributes to the creation of a Derivative Work.
|
||||||
|
|
||||||
|
- The Licensee or “You”: any natural or legal person who makes any usage of the
|
||||||
|
Software under the terms of the Licence.
|
||||||
|
|
||||||
|
- Distribution and/or Communication: any act of selling, giving, lending,
|
||||||
|
renting, distributing, communicating, transmitting, or otherwise making
|
||||||
|
available, on-line or off-line, copies of the Work or providing access to its
|
||||||
|
essential functionalities at the disposal of any other natural or legal
|
||||||
|
person.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## 2. Scope of the rights granted by the Licence
|
||||||
|
|
||||||
|
The Licensor hereby grants You a world-wide, royalty-free, non-exclusive,
|
||||||
|
sub-licensable licence to do the following, for the duration of copyright vested
|
||||||
|
in the Original Work:
|
||||||
|
|
||||||
|
- use the Work in any circumstance and for all usage, reproduce the Work, modify
|
||||||
|
- the Original Work, and make Derivative Works based upon the Work, communicate
|
||||||
|
- to the public, including the right to make available or display the Work or
|
||||||
|
- copies thereof to the public and perform publicly, as the case may be, the
|
||||||
|
- Work, distribute the Work or copies thereof, lend and rent the Work or copies
|
||||||
|
- thereof, sub-license rights in the Work or copies thereof.
|
||||||
|
|
||||||
|
Those rights can be exercised on any media, supports and formats, whether now
|
||||||
|
known or later invented, as far as the applicable law permits so.
|
||||||
|
|
||||||
|
In the countries where moral rights apply, the Licensor waives his right to
|
||||||
|
exercise his moral right to the extent allowed by law in order to make effective
|
||||||
|
the licence of the economic rights here above listed.
|
||||||
|
|
||||||
|
The Licensor grants to the Licensee royalty-free, non exclusive usage rights to
|
||||||
|
any patents held by the Licensor, to the extent necessary to make use of the
|
||||||
|
rights granted on the Work under this Licence.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## 3. Communication of the Source Code
|
||||||
|
|
||||||
|
The Licensor may provide the Work either in its Source Code form, or as
|
||||||
|
Executable Code. If the Work is provided as Executable Code, the Licensor
|
||||||
|
provides in addition a machine-readable copy of the Source Code of the Work
|
||||||
|
along with each copy of the Work that the Licensor distributes or indicates, in
|
||||||
|
a notice following the copyright notice attached to the Work, a repository where
|
||||||
|
the Source Code is easily and freely accessible for as long as the Licensor
|
||||||
|
continues to distribute and/or communicate the Work.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## 4. Limitations on copyright
|
||||||
|
|
||||||
|
Nothing in this Licence is intended to deprive the Licensee of the benefits from
|
||||||
|
any exception or limitation to the exclusive rights of the rights owners in the
|
||||||
|
Original Work or Software, of the exhaustion of those rights or of other
|
||||||
|
applicable limitations thereto.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## 5. Obligations of the Licensee
|
||||||
|
|
||||||
|
The grant of the rights mentioned above is subject to some restrictions and
|
||||||
|
obligations imposed on the Licensee. Those obligations are the following:
|
||||||
|
|
||||||
|
Attribution right: the Licensee shall keep intact all copyright, patent or
|
||||||
|
trademarks notices and all notices that refer to the Licence and to the
|
||||||
|
disclaimer of warranties. The Licensee must include a copy of such notices and a
|
||||||
|
copy of the Licence with every copy of the Work he/she distributes and/or
|
||||||
|
communicates. The Licensee must cause any Derivative Work to carry prominent
|
||||||
|
notices stating that the Work has been modified and the date of modification.
|
||||||
|
|
||||||
|
Copyleft clause: If the Licensee distributes and/or communicates copies of the
|
||||||
|
Original Works or Derivative Works based upon the Original Work, this
|
||||||
|
Distribution and/or Communication will be done under the terms of this Licence
|
||||||
|
or of a later version of this Licence unless the Original Work is expressly
|
||||||
|
distributed only under this version of the Licence. The Licensee (becoming
|
||||||
|
Licensor) cannot offer or impose any additional terms or conditions on the Work
|
||||||
|
or Derivative Work that alter or restrict the terms of the Licence.
|
||||||
|
|
||||||
|
Compatibility clause: If the Licensee Distributes and/or Communicates Derivative
|
||||||
|
Works or copies thereof based upon both the Original Work and another work
|
||||||
|
licensed under a Compatible Licence, this Distribution and/or Communication can
|
||||||
|
be done under the terms of this Compatible Licence. For the sake of this clause,
|
||||||
|
“Compatible Licence” refers to the licences listed in the appendix attached to
|
||||||
|
this Licence. Should the Licensee’s obligations under the Compatible Licence
|
||||||
|
conflict with his/her obligations under this Licence, the obligations of the
|
||||||
|
Compatible Licence shall prevail.
|
||||||
|
|
||||||
|
Provision of Source Code: When distributing and/or communicating copies of the
|
||||||
|
Work, the Licensee will provide a machine-readable copy of the Source Code or
|
||||||
|
indicate a repository where this Source will be easily and freely available for
|
||||||
|
as long as the Licensee continues to distribute and/or communicate the Work.
|
||||||
|
|
||||||
|
Legal Protection: This Licence does not grant permission to use the trade names,
|
||||||
|
trademarks, service marks, or names of the Licensor, except as required for
|
||||||
|
reasonable and customary use in describing the origin of the Work and
|
||||||
|
reproducing the content of the copyright notice.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## 6. Chain of Authorship
|
||||||
|
|
||||||
|
The original Licensor warrants that the copyright in the Original Work granted
|
||||||
|
hereunder is owned by him/her or licensed to him/her and that he/she has the
|
||||||
|
power and authority to grant the Licence.
|
||||||
|
|
||||||
|
Each Contributor warrants that the copyright in the modifications he/she brings
|
||||||
|
to the Work are owned by him/her or licensed to him/her and that he/she has the
|
||||||
|
power and authority to grant the Licence.
|
||||||
|
|
||||||
|
Each time You accept the Licence, the original Licensor and subsequent
|
||||||
|
Contributors grant You a licence to their contributions to the Work, under the
|
||||||
|
terms of this Licence.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## 7. Disclaimer of Warranty
|
||||||
|
|
||||||
|
The Work is a work in progress, which is continuously improved by numerous
|
||||||
|
contributors. It is not a finished work and may therefore contain defects or
|
||||||
|
“bugs” inherent to this type of software development.
|
||||||
|
|
||||||
|
For the above reason, the Work is provided under the Licence on an “as is” basis
|
||||||
|
and without warranties of any kind concerning the Work, including without
|
||||||
|
limitation merchantability, fitness for a particular purpose, absence of defects
|
||||||
|
or errors, accuracy, non-infringement of intellectual property rights other than
|
||||||
|
copyright as stated in Article 6 of this Licence.
|
||||||
|
|
||||||
|
This disclaimer of warranty is an essential part of the Licence and a condition
|
||||||
|
for the grant of any rights to the Work.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## 8. Disclaimer of Liability
|
||||||
|
|
||||||
|
Except in the cases of wilful misconduct or damages directly caused to natural
|
||||||
|
persons, the Licensor will in no event be liable for any direct or indirect,
|
||||||
|
material or moral, damages of any kind, arising out of the Licence or of the use
|
||||||
|
of the Work, including without limitation, damages for loss of goodwill, work
|
||||||
|
stoppage, computer failure or malfunction, loss of data or any commercial
|
||||||
|
damage, even if the Licensor has been advised of the possibility of such
|
||||||
|
damage. However, the Licensor will be liable under statutory product liability
|
||||||
|
laws as far such laws apply to the Work.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## 9. Additional agreements
|
||||||
|
|
||||||
|
While distributing the Original Work or Derivative Works, You may choose to
|
||||||
|
conclude an additional agreement to offer, and charge a fee for, acceptance of
|
||||||
|
support, warranty, indemnity, or other liability obligations and/or services
|
||||||
|
consistent with this Licence. However, in accepting such obligations, You may
|
||||||
|
act only on your own behalf and on your sole responsibility, not on behalf of
|
||||||
|
the original Licensor or any other Contributor, and only if You agree to
|
||||||
|
indemnify, defend, and hold each Contributor harmless for any liability incurred
|
||||||
|
by, or claims asserted against such Contributor by the fact You have accepted
|
||||||
|
any such warranty or additional liability.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## 10. Acceptance of the Licence
|
||||||
|
|
||||||
|
The provisions of this Licence can be accepted by clicking on an icon “I agree”
|
||||||
|
placed under the bottom of a window displaying the text of this Licence or by
|
||||||
|
affirming consent in any other similar way, in accordance with the rules of
|
||||||
|
applicable law. Clicking on that icon indicates your clear and irrevocable
|
||||||
|
acceptance of this Licence and all of its terms and conditions.
|
||||||
|
|
||||||
|
Similarly, you irrevocably accept this Licence and all of its terms and
|
||||||
|
conditions by exercising any rights granted to You by Article 2 of this Licence,
|
||||||
|
such as the use of the Work, the creation by You of a Derivative Work or the
|
||||||
|
Distribution and/or Communication by You of the Work or copies thereof.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## 11. Information to the public
|
||||||
|
|
||||||
|
In case of any Distribution and/or Communication of the Work by means of
|
||||||
|
electronic communication by You (for example, by offering to download the Work
|
||||||
|
from a remote location) the distribution channel or media (for example, a
|
||||||
|
website) must at least provide to the public the information requested by the
|
||||||
|
applicable law regarding the Licensor, the Licence and the way it may be
|
||||||
|
accessible, concluded, stored and reproduced by the Licensee.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## 12. Termination of the Licence
|
||||||
|
|
||||||
|
The Licence and the rights granted hereunder will terminate automatically upon
|
||||||
|
any breach by the Licensee of the terms of the Licence.
|
||||||
|
|
||||||
|
Such a termination will not terminate the licences of any person who has
|
||||||
|
received the Work from the Licensee under the Licence, provided such persons
|
||||||
|
remain in full compliance with the Licence.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## 13. Miscellaneous
|
||||||
|
|
||||||
|
Without prejudice of Article 9 above, the Licence represents the complete
|
||||||
|
agreement between the Parties as to the Work licensed hereunder.
|
||||||
|
|
||||||
|
If any provision of the Licence is invalid or unenforceable under applicable
|
||||||
|
law, this will not affect the validity or enforceability of the Licence as a
|
||||||
|
whole. Such provision will be construed and/or reformed so as necessary to make
|
||||||
|
it valid and enforceable.
|
||||||
|
|
||||||
|
The European Commission may publish other linguistic versions and/or new
|
||||||
|
versions of this Licence, so far this is required and reasonable, without
|
||||||
|
reducing the scope of the rights granted by the Licence. New versions of the
|
||||||
|
Licence will be published with a unique version number.
|
||||||
|
|
||||||
|
All linguistic versions of this Licence, approved by the European Commission,
|
||||||
|
have identical value. Parties can take advantage of the linguistic version of
|
||||||
|
their choice.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## 14. Jurisdiction
|
||||||
|
|
||||||
|
Any litigation resulting from the interpretation of this License, arising
|
||||||
|
between the European Commission, as a Licensor, and any Licensee, will be
|
||||||
|
subject to the jurisdiction of the Court of Justice of the European Communities,
|
||||||
|
as laid down in article 238 of the Treaty establishing the European Community.
|
||||||
|
|
||||||
|
Any litigation arising between Parties, other than the European Commission, and
|
||||||
|
resulting from the interpretation of this License, will be subject to the
|
||||||
|
exclusive jurisdiction of the competent court where the Licensor resides or
|
||||||
|
conducts its primary business.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## 15. Applicable Law
|
||||||
|
|
||||||
|
This Licence shall be governed by the law of the European Union country where
|
||||||
|
the Licensor resides or has his registered office.
|
||||||
|
|
||||||
|
This licence shall be governed by the Belgian law if:
|
||||||
|
|
||||||
|
- a litigation arises between the European Commission, as a Licensor, and any
|
||||||
|
- Licensee; the Licensor, other than the European Commission, has no residence
|
||||||
|
- or registered office inside a European Union country.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## Appendix
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
“Compatible Licences” according to article 5 EUPL are:
|
||||||
|
|
||||||
|
|
||||||
|
- GNU General Public License (GNU GPL) v. 2
|
||||||
|
|
||||||
|
- Open Software License (OSL) v. 2.1, v. 3.0
|
||||||
|
|
||||||
|
- Common Public License v. 1.0
|
||||||
|
|
||||||
|
- Eclipse Public License v. 1.0
|
||||||
|
|
||||||
|
- Cecill v. 2.0
|
||||||
|
|
|
@ -0,0 +1,49 @@
|
||||||
|
# Identity Manager Service
|
||||||
|
|
||||||
|
This service allows any client to publish on the gCube Catalogue.
|
||||||
|
|
||||||
|
## Built With
|
||||||
|
|
||||||
|
* [OpenJDK](https://openjdk.java.net/) - The JDK used
|
||||||
|
* [Maven](https://maven.apache.org/) - Dependency Management
|
||||||
|
|
||||||
|
## Documentation
|
||||||
|
|
||||||
|
[Identity Manager Service](https://wiki.gcube-system.org/gcube/SmartGears)
|
||||||
|
|
||||||
|
## Change log
|
||||||
|
|
||||||
|
See [CHANGELOG.md](CHANGELOG.md).
|
||||||
|
|
||||||
|
## Authors
|
||||||
|
|
||||||
|
* **Alfredo Oliviero** [ISTI-CNR Infrascience Group](http://nemis.isti.cnr.it/groups/infrascience)
|
||||||
|
* **Luca Frosini** ([ORCID](https://orcid.org/0000-0003-3183-2291)) - [ISTI-CNR Infrascience Group](http://nemis.isti.cnr.it/groups/infrascience)
|
||||||
|
|
||||||
|
## How to Cite this Software
|
||||||
|
|
||||||
|
Tell people how to cite this software.
|
||||||
|
* Cite an associated paper?
|
||||||
|
* Use a specific BibTeX entry for the software?
|
||||||
|
|
||||||
|
@software{gcat,
|
||||||
|
author = {{Alfredo Oliviero}},
|
||||||
|
title = {Identity Manager Service},
|
||||||
|
abstract = {This is an Identity Manager smargears service},
|
||||||
|
url = {doi Zenodo URL}
|
||||||
|
keywords = {D4Science, gCube}
|
||||||
|
}
|
||||||
|
|
||||||
|
## License
|
||||||
|
|
||||||
|
This project is licensed under the EUPL V.1.1 License - see the [LICENSE.md](LICENSE.md) file for details.
|
||||||
|
|
||||||
|
|
||||||
|
## About the gCube Framework
|
||||||
|
This software is part of the [gCubeFramework](https://www.gcube-system.org/ "gCubeFramework"): an
|
||||||
|
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 see [FUNDING.md](FUNDING.md)
|
||||||
|
|
|
@ -0,0 +1,21 @@
|
||||||
|
<!-- // da implementare rispetto al contesto -->
|
||||||
|
|
||||||
|
/2/users/get-profile // profilo utente corrente
|
||||||
|
/2/users/get-email // utente corrente
|
||||||
|
/2/users/get-fullname // utente corrente
|
||||||
|
|
||||||
|
/2/users/get-all-usernames
|
||||||
|
/2/users/get-all-fullnames-and-usernames
|
||||||
|
/2/users/get-usernames-by-role
|
||||||
|
/2/users/user-exists
|
||||||
|
|
||||||
|
// attenzione al risultato. vedere in seguito
|
||||||
|
/2/users/get-oauth-profile
|
||||||
|
|
||||||
|
// eventualemente in seguito. da approfondire
|
||||||
|
/2/users/get-custom-attribute
|
||||||
|
/2/users/get-usernames-by-global-role
|
||||||
|
|
||||||
|
rif. https://api.dev.d4science.org/social-networking-library-ws/api-docs/index.html
|
||||||
|
|
||||||
|
implementazione social: https://code-repo.d4science.org/gCubeSystem/social-networking-library-ws/src/branch/master/src/main/java/org/gcube/portal/social/networking/ws/methods/v2/Users.java
|
|
@ -0,0 +1,23 @@
|
||||||
|
eseguendo ```mvn install``` su gcat, ricevo questo errore
|
||||||
|
|
||||||
|
[ERROR] Failed to execute goal org.codehaus.gmaven:groovy-maven-plugin:2.1.1:execute (default) on project gcat: Execution default of goal org.codehaus.gmaven:groovy-maven-plugin:2.1.1:execute failed: startup failed:
|
||||||
|
[ERROR] script1.groovy: 1: expecting EOF, found 'matcher' @ line 1, column 100.
|
||||||
|
[ERROR] ANGELOG.md").getText('UTF-8') matcher =
|
||||||
|
[ERROR] ^
|
||||||
|
[ERROR]
|
||||||
|
[ERROR] 1 error
|
||||||
|
[ERROR]
|
||||||
|
|
||||||
|
|
||||||
|
https://maven.d4science.org/nexus/content/repositories/gcube-externals/org/gcube/tools/maven-parent/1.1.0/maven-parent-1.1.0.pom
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
cd ~/.m2/repository
|
||||||
|
grep -R "getText('UTF-8') matcher" .
|
||||||
|
|
||||||
|
|
||||||
|
<source> def fileContents = new File("${project.basedir}/CHANGELOG.md").getText('UTF-8') matcher = (fileContents =~ /(?s).\[v$project.version\].*?/) if (!matcher.find()) { throw new IllegalArgumentException("Tag [v$project.version] not found in ${project.basedir}/CHANGELOG.md") } assert matcher[0][1]: "Tag [v$project.version] not found in ${project.basedir}/CHANGELOG.md" </source>
|
||||||
|
</configuration>
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,25 @@
|
||||||
|
[node]
|
||||||
|
mode = online
|
||||||
|
hostname = alfredo-idm-service-dev
|
||||||
|
protocol= http
|
||||||
|
port = 8080
|
||||||
|
infrastructure = gcube
|
||||||
|
authorizeChildrenContext = true
|
||||||
|
publicationFrequencyInSeconds = 60
|
||||||
|
|
||||||
|
[properties]
|
||||||
|
SmartGearsDistribution = 4.0.0-SNAPSHOT
|
||||||
|
SmartGearsDistributionBundle = UnBundled
|
||||||
|
|
||||||
|
[site]
|
||||||
|
country = it
|
||||||
|
location = pisa
|
||||||
|
|
||||||
|
[authorization]
|
||||||
|
factory = org.gcube.smartgears.security.defaults.DefaultAuthorizationProviderFactory
|
||||||
|
factory.endpoint = https://accounts.dev.d4science.org/auth/realms/d4science/protocol/openid-connect/token
|
||||||
|
credentials.class = org.gcube.smartgears.security.SimpleCredentials
|
||||||
|
; credentials.clientID = node-whn-test-uno-d-d4s.d4science.org
|
||||||
|
; credentials.secret = 979bd3bc-5cc4-11ec-bf63-0242ac130002
|
||||||
|
credentials.clientID = alfredo-idm-service-dev
|
||||||
|
credentials.secret = 979bd3bc-5cc4-11ec-bf63-0242ac130002
|
|
@ -0,0 +1,25 @@
|
||||||
|
<configuration scan="true" debug="true">
|
||||||
|
|
||||||
|
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
|
||||||
|
<encoder>Ï
|
||||||
|
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
|
||||||
|
</encoder>
|
||||||
|
</appender>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<logger name="org.gcube" level="DEBUG" />
|
||||||
|
<logger name="org.gcube.smartgears" level="TRACE" />
|
||||||
|
<logger name="org.gcube.smartgears.handlers" level="TRACE"/>
|
||||||
|
<logger name="org.gcube.common.events" level="WARN" />
|
||||||
|
<logger name="org.gcube.data.publishing" level="ERROR" />
|
||||||
|
<logger name="org.gcube.documentstore" level="ERROR" />
|
||||||
|
<logger name="org.gcube.common.core.publisher.is.legacy" level="TRACE" />
|
||||||
|
<logger name="org.gcube.data.access" level="TRACE" />
|
||||||
|
<logger name="org.gcube.data.access.storagehub.handlers" level="DEBUG"/>
|
||||||
|
|
||||||
|
<root level="WARN">
|
||||||
|
<appender-ref ref="STDOUT" />
|
||||||
|
</root>
|
||||||
|
|
||||||
|
</configuration>
|
|
@ -0,0 +1 @@
|
||||||
|
/_build/
|
|
@ -0,0 +1,20 @@
|
||||||
|
# Minimal makefile for Sphinx documentation
|
||||||
|
#
|
||||||
|
|
||||||
|
# You can set these variables from the command line, and also
|
||||||
|
# from the environment for the first two.
|
||||||
|
SPHINXOPTS ?=
|
||||||
|
SPHINXBUILD ?= sphinx-build
|
||||||
|
SOURCEDIR = .
|
||||||
|
BUILDDIR = _build
|
||||||
|
|
||||||
|
# Put it first so that "make" without argument is like "make help".
|
||||||
|
help:
|
||||||
|
@$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
|
||||||
|
|
||||||
|
.PHONY: help Makefile
|
||||||
|
|
||||||
|
# Catch-all target: route all unknown targets to Sphinx using the new
|
||||||
|
# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS).
|
||||||
|
%: Makefile
|
||||||
|
@$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
|
|
@ -0,0 +1,54 @@
|
||||||
|
# Configuration file for the Sphinx documentation builder.
|
||||||
|
#
|
||||||
|
# This file only contains a selection of the most common options. For a full
|
||||||
|
# list see the documentation:
|
||||||
|
# https://www.sphinx-doc.org/en/master/usage/configuration.html
|
||||||
|
|
||||||
|
# -- Path setup --------------------------------------------------------------
|
||||||
|
|
||||||
|
# If extensions (or modules to document with autodoc) are in another directory,
|
||||||
|
# add these directories to sys.path here. If the directory is relative to the
|
||||||
|
# documentation root, use os.path.abspath to make it absolute, like shown here.
|
||||||
|
#
|
||||||
|
# import os
|
||||||
|
# import sys
|
||||||
|
# sys.path.insert(0, os.path.abspath('.'))
|
||||||
|
|
||||||
|
|
||||||
|
# -- Project information -----------------------------------------------------
|
||||||
|
|
||||||
|
project = 'gCube Catalogue (gCat) Service'
|
||||||
|
copyright = '2022, Luca Frosini (ISTI-CNR)'
|
||||||
|
author = 'Luca Frosini (ISTI-CNR)'
|
||||||
|
|
||||||
|
# The full version, including alpha/beta/rc tags
|
||||||
|
release = '2.5.1'
|
||||||
|
|
||||||
|
|
||||||
|
# -- General configuration ---------------------------------------------------
|
||||||
|
|
||||||
|
# Add any Sphinx extension module names here, as strings. They can be
|
||||||
|
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
|
||||||
|
# ones.
|
||||||
|
extensions = []
|
||||||
|
|
||||||
|
# Add any paths that contain templates here, relative to this directory.
|
||||||
|
templates_path = ['_templates']
|
||||||
|
|
||||||
|
# List of patterns, relative to source directory, that match files and
|
||||||
|
# directories to ignore when looking for source files.
|
||||||
|
# This pattern also affects html_static_path and html_extra_path.
|
||||||
|
exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store']
|
||||||
|
|
||||||
|
|
||||||
|
# -- Options for HTML output -------------------------------------------------
|
||||||
|
|
||||||
|
# The theme to use for HTML and HTML Help pages. See the documentation for
|
||||||
|
# a list of builtin themes.
|
||||||
|
#
|
||||||
|
html_theme = 'sphinxdoc'
|
||||||
|
|
||||||
|
# Add any paths that contain custom static files (such as style sheets) here,
|
||||||
|
# relative to this directory. They are copied after the builtin static files,
|
||||||
|
# so a file named "default.css" will overwrite the builtin "default.css".
|
||||||
|
html_static_path = ['_static']
|
|
@ -0,0 +1,484 @@
|
||||||
|
---
|
||||||
|
title: Welcome to gCube Catalogue Service (aka gCat) documentation
|
||||||
|
---
|
||||||
|
|
||||||
|
gCat is a RESTful application which exposes operations via REST-API.
|
||||||
|
|
||||||
|
See the available [REST-API docs](../api-docs/index.html).
|
||||||
|
|
||||||
|
Base URL
|
||||||
|
========
|
||||||
|
|
||||||
|
In the production environment, its current value is
|
||||||
|
<https://api.d4science.org/gcat>
|
||||||
|
|
||||||
|
Authorization
|
||||||
|
=============
|
||||||
|
|
||||||
|
D4Science adopts state-of-the-art industry standards for authentication
|
||||||
|
and authorization. Specifically, the implementation fully adopts [OIDC
|
||||||
|
(OpenID Connect)](https://openid.net/connect) for authentication and UMA
|
||||||
|
2 (User-Managed Authorization) for authorization flows. [JSON Web Token
|
||||||
|
(JWT) Access token](https://jwt.io/) are used for both authentication
|
||||||
|
and authorization.
|
||||||
|
|
||||||
|
Obtain your Bearer token here:
|
||||||
|
<https://dev.d4science.org/how-to-access-resources>
|
||||||
|
|
||||||
|
Service
|
||||||
|
=======
|
||||||
|
|
||||||
|
You can call the methods of the Web Service by writing your own REST
|
||||||
|
client application or using existing REST client plugins.
|
||||||
|
|
||||||
|
HTTP Statuses
|
||||||
|
-------------
|
||||||
|
|
||||||
|
Any successful operation returns *200 OK* HTTP status code. The create
|
||||||
|
operation returns *201 Created*. Any Background operation returns *202
|
||||||
|
Accepted*. Any operation which does not provide any content return *204
|
||||||
|
No Content*.
|
||||||
|
|
||||||
|
The most common error status a client can obtain are:
|
||||||
|
|
||||||
|
- **400 Bad Request** used to indicate a clients error
|
||||||
|
<https://tools.ietf.org/html/rfc7231#section-6.5.1>;
|
||||||
|
- **401 Unauthorized** used to indicate that the client does not
|
||||||
|
provide the authorization token in the HTTP Header or the client has
|
||||||
|
not enough right to perform such request
|
||||||
|
<https://tools.ietf.org/html/rfc7235#section-3.1>;
|
||||||
|
- **404 Not Found** used to indicate that the requested instance does
|
||||||
|
not exist <https://tools.ietf.org/html/rfc7231#section-6.5.4>;
|
||||||
|
- **405 Method Not Allowed** the used HTTP method is not supported for
|
||||||
|
the requested URL
|
||||||
|
<https://tools.ietf.org/html/rfc7231#section-6.5.5>. The response
|
||||||
|
contains the *Allow* HTTP Header indicating the supported HTTP
|
||||||
|
method for such URL
|
||||||
|
<https://tools.ietf.org/html/rfc7231#section-7.4.1>;
|
||||||
|
- **409 Conflict** the request could not be completed due to a
|
||||||
|
conflict with the current state of the target resource (e.g. the
|
||||||
|
name of the resource already exists)
|
||||||
|
<https://tools.ietf.org/html/rfc7231#section-6.5.8>;
|
||||||
|
- **500 Internal Server Error** indicate a server failure
|
||||||
|
<https://tools.ietf.org/html/rfc7231#section-6.6.1>.
|
||||||
|
|
||||||
|
You can find a complete list of HTTP Status at
|
||||||
|
<https://httpstatuses.com/>
|
||||||
|
|
||||||
|
If you get a *500 Internal Server Error*, please report it in the [gCube
|
||||||
|
ticketing system](https://support.d4science.org).
|
||||||
|
|
||||||
|
Please use this checklist before reporting an error:
|
||||||
|
|
||||||
|
- Replicate the request;
|
||||||
|
- The failure could be temporal due to network error, server issue and
|
||||||
|
many other temporal issues. For this reason, please retry the
|
||||||
|
request after a certain amount of time before reporting the issue;
|
||||||
|
- indicate how to replicate the error;
|
||||||
|
- indicate the time when the error occurred (this simplifies
|
||||||
|
identifying the issue).
|
||||||
|
|
||||||
|
HTTP Methods
|
||||||
|
------------
|
||||||
|
|
||||||
|
gCat is a pure RESTful service. It uses standard HTTP Methods to perform
|
||||||
|
listing of collections and CRUD (Create Read Update Delete) operations
|
||||||
|
on instances.
|
||||||
|
|
||||||
|
:::{table} Supported operations
|
||||||
|
:align: center
|
||||||
|
:widths: grid
|
||||||
|
|
||||||
|
|
||||||
|
| Operation | HTTP Method | URL | Success HTTP Status | Safe | Idempotent |
|
||||||
|
|-----------|-------------|-----|---------------------|------|------------|
|
||||||
|
| **Supported<br/>HTTP Methods** | OPTIONS | /{COLLECTION} | 204 No Content | Y | Y |
|
||||||
|
| **List** | GET | /{COLLECTION} | 200 OK | Y | Y |
|
||||||
|
| **Count** | GET | /{COLLECTION}?count=true | 200 OK | Y | Y |
|
||||||
|
| **Exists** | HEAD | /{COLLECTION} | 204 No Content | Y | Y |
|
||||||
|
| **Create** | POST | /{COLLECTION} | 201 Created | N | N |
|
||||||
|
| **Supported<br/>HTTP Methods** | OPTIONS | /{COLLECTION}/{INSTANCE_ID} | 204 No Content | Y | Y |
|
||||||
|
| **Exist** | HEAD | /{COLLECTION}/{INSTANCE_ID} | 204 No Content | Y | Y |
|
||||||
|
| **Read** | GET | /{COLLECTION}/{INSTANCE_ID} | 200 OK | Y | Y |
|
||||||
|
| **Update** | PUT | /{COLLECTION}/{INSTANCE_ID} | 200 OK | N | Y |
|
||||||
|
| **Patch** | PATCH | /{COLLECTION}/{INSTANCE_ID} | 200 OK | N | Y |
|
||||||
|
| **Delete** | DELETE | /{COLLECTION}/{INSTANCE_ID} | 204 No Content | N | N |
|
||||||
|
| **Purge** | PURGE | /{COLLECTION}/{INSTANCE_ID} | 204 No Content | N | N |
|
||||||
|
| **Purge** | DELETE | /{COLLECTION}/{INSTANCE_ID}?purge=true | 204 No Content | N | N |
|
||||||
|
|
||||||
|
|
||||||
|
### About URL
|
||||||
|
|
||||||
|
The presented URL uses the following convention:
|
||||||
|
|
||||||
|
- **{COLLECTION}** is the plural name of the entity type;
|
||||||
|
- **{INSTANCE\_ID}** is an identification that enables univocally
|
||||||
|
identifying the instance in the collection.
|
||||||
|
|
||||||
|
### About Safety and Idempotency properties
|
||||||
|
|
||||||
|
- A method is *Safe* if it does not produce any side effects. \"This
|
||||||
|
does not prevent an implementation from including behaviour that is
|
||||||
|
potentially harmful, that is not entirely read-only, or that causes
|
||||||
|
side effects while invoking a safe method\"
|
||||||
|
<https://tools.ietf.org/html/rfc7231#section-4.2.1>;
|
||||||
|
- A method is *Idempotent* if the same operation repeated multiple
|
||||||
|
times has the same side effect than using it one time. \"repeating
|
||||||
|
the request will have the same intended effect, even if the original
|
||||||
|
request succeeded, though the response might differ\"
|
||||||
|
<https://tools.ietf.org/html/rfc7231#section-4.2.2>.
|
||||||
|
|
||||||
|
You can find more information about HTTP Methods at
|
||||||
|
<https://restfulapi.net/http-methods/>
|
||||||
|
|
||||||
|
### Uncommon HTTP Methods
|
||||||
|
|
||||||
|
- PATCH method allows to perform a differential update (i.e. an update
|
||||||
|
which provides only the differences and not the whole new
|
||||||
|
representation);
|
||||||
|
- PURGE method is not a standard but is widely used in service which
|
||||||
|
requires this action (e.g.
|
||||||
|
[Varnish](https://varnish-cache.org/docs/3.0/tutorial/purging.html),
|
||||||
|
[Squid](https://wiki.squid-cache.org/SquidFaq/OperatingSquid#How_can_I_purge_an_object_from_my_cache.3F)).
|
||||||
|
gCat provides support for this method, but to support a wider range
|
||||||
|
of clients, it also provides the Purge action via *DELETE* with the
|
||||||
|
additional get parameter `purge=true`.
|
||||||
|
|
||||||
|
Content-Type
|
||||||
|
------------
|
||||||
|
|
||||||
|
Any request must contain an indication of the interesting content type.
|
||||||
|
|
||||||
|
The client must specify the **Accept** HTTP Header for any operation
|
||||||
|
returning a result.
|
||||||
|
|
||||||
|
``` {.rest}
|
||||||
|
Accept: application/json
|
||||||
|
```
|
||||||
|
|
||||||
|
For any operation sending content to the service, it is necessary to
|
||||||
|
specify the **Content-Type** HTTP Header.
|
||||||
|
|
||||||
|
``` {.rest}
|
||||||
|
Content-Type: application/json
|
||||||
|
```
|
||||||
|
|
||||||
|
The service accepts and returns only JSON objects.
|
||||||
|
|
||||||
|
[Profile Collection](../api-docs/resource\_Profile.html) instead can be
|
||||||
|
manipulated in XML only.
|
||||||
|
|
||||||
|
Collections
|
||||||
|
-----------
|
||||||
|
|
||||||
|
The following collections are available to any user. Catalogue-Editor or
|
||||||
|
above can invoke Non-safe methods only.
|
||||||
|
|
||||||
|
- [Item Collection](../api-docs/resource_Item.html);
|
||||||
|
- [Resource Collection](../api-docs/resource_Resource.html);
|
||||||
|
- [Profile Collection](../api-docs/resource_Profile.html);
|
||||||
|
- [Namespace Collection](../api-docs/resource_Namespace.html);
|
||||||
|
- [License Collection](../api-docs/resource_License.html);
|
||||||
|
- [Trash Collection](../api-docs/resource_Trash.html);
|
||||||
|
|
||||||
|
The following collections are available for Catalogue-Admins or above
|
||||||
|
only:
|
||||||
|
|
||||||
|
- [Group Collection](../api-docs/resource_Group.html);
|
||||||
|
- [Organization Collection](../api-docs/resource_Organization.html);
|
||||||
|
- [User Collection](../api-docs/resource_User.html);
|
||||||
|
- [Configuration Collection](../api-docs/resource_Configuration.html).
|
||||||
|
|
||||||
|
An overview of the available collections is available at
|
||||||
|
[../api-docs/index.html](../api-docs/index.html);
|
||||||
|
|
||||||
|
Roles
|
||||||
|
-----
|
||||||
|
|
||||||
|
Any user has one or more roles in the catalogue. Only the VRE Manager
|
||||||
|
can assign roles to VRE users.
|
||||||
|
|
||||||
|
The catalogue uses the following hierarchic roles:
|
||||||
|
|
||||||
|
**Catalogue-Member**:
|
||||||
|
|
||||||
|
: A user with such a role is mainly capable of listing and reading
|
||||||
|
items;
|
||||||
|
|
||||||
|
**Catalogue-Editor**:
|
||||||
|
|
||||||
|
: A user with such a role is capable of managing the items he/she
|
||||||
|
creates and capable of using other safe APIs;
|
||||||
|
|
||||||
|
**Catalogue-Admin**:
|
||||||
|
|
||||||
|
: A user with such a role is capable of administrating many aspects of
|
||||||
|
the catalogue;
|
||||||
|
|
||||||
|
**Catalogue-Manager**:
|
||||||
|
|
||||||
|
: A user with such a role can use all the APIs exposed by the service
|
||||||
|
except item moderation APIs (e.g. approve, reject, \...).
|
||||||
|
|
||||||
|
Another role that is not in the role hierarchy:
|
||||||
|
|
||||||
|
**Catalogue-Moderator**:
|
||||||
|
|
||||||
|
: A user with such a role is capable of invoking the item moderation
|
||||||
|
APIs.
|
||||||
|
|
||||||
|
::: {.tip}
|
||||||
|
::: {.title}
|
||||||
|
Tip
|
||||||
|
:::
|
||||||
|
:::
|
||||||
|
|
||||||
|
Please note that not all catalogues are moderated.
|
||||||
|
|
||||||
|
Moderated Catalogues
|
||||||
|
====================
|
||||||
|
|
||||||
|
Any catalogues can be declared as moderated. This means that, a
|
||||||
|
**Catalogue-Moderator** must approve any submitted items to make them
|
||||||
|
available to the other users of the catalogue.
|
||||||
|
|
||||||
|
In a moderated catalogue, an item can be in the following states:
|
||||||
|
|
||||||
|
**pending**:
|
||||||
|
|
||||||
|
: The item published by any allowed author (a Catalogue-Editor or
|
||||||
|
above) but not available to the other users of the catalogue. A
|
||||||
|
Catalogue-Moderator has to approve or reject it;
|
||||||
|
|
||||||
|
**approved**:
|
||||||
|
|
||||||
|
: A Catalogue-Moderator has approved the item published by any allowed
|
||||||
|
users;
|
||||||
|
|
||||||
|
**rejected**:
|
||||||
|
|
||||||
|
: A Catalogue-Moderator has rejected the item published by any allowed
|
||||||
|
users.
|
||||||
|
|
||||||
|
The following are the moderation operations that an allowed user can
|
||||||
|
perform on an item. To present the moderation operations, we use the
|
||||||
|
following convention:
|
||||||
|
|
||||||
|
> `initial_state` \-\--**operation** (*User/Role performing the
|
||||||
|
> operation*)\-\--\> `final_state`
|
||||||
|
|
||||||
|
`initial_state` can be `none`, meaning the item does not exist.
|
||||||
|
|
||||||
|
The following are the allowed moderation operation on an item
|
||||||
|
|
||||||
|
> `none` \-\--**create** (*Author*)\-\--\> `pending`
|
||||||
|
>
|
||||||
|
> `pending` \-\--**reject** (*Catalogue-Moderator*)\-\--\> `rejected`
|
||||||
|
>
|
||||||
|
> `pending` \-\--**approve** (*Catalogue-Moderator*)\-\--\> `approved`
|
||||||
|
>
|
||||||
|
> `rejected` \-\--**update** (*Author*)\-\--\> `pending`
|
||||||
|
>
|
||||||
|
> `approved` \-\--**update** (*Author*)\-\--\> `pending`
|
||||||
|
|
||||||
|
Please check the table below whcih summarise the item collection
|
||||||
|
operation and the allowed users/roles.
|
||||||
|
|
||||||
|
In a moderated catalogue, both the Catalogue-Moderators and the item
|
||||||
|
author can send messages to discuss the approval process of the item.
|
||||||
|
The messages are related to a specific item. Any Catalogue-Moderators
|
||||||
|
receive a message sent by an Author. The author receives a message sent
|
||||||
|
by a Catalogue-Moderator as well as the other Catalogue-Moderators (if
|
||||||
|
any).
|
||||||
|
|
||||||
|
Messages can be sent both with an action which changes the status of the
|
||||||
|
item or as explicit action which does not change the status of the item:
|
||||||
|
|
||||||
|
> `pending` \-\--**message** (*Author OR Catalogue-Moderator*)\-\--\>
|
||||||
|
> `pending`
|
||||||
|
>
|
||||||
|
> `rejected` \-\--**message** (*Author OR Catalogue-Moderator*)\-\--\>
|
||||||
|
> `rejected`
|
||||||
|
>
|
||||||
|
> `approved` \-\--**message** (*Author OR Catalogue-Moderator*)\-\--\>
|
||||||
|
> `approved`
|
||||||
|
|
||||||
|
The following table summarize the allowed/forbidden operations depending
|
||||||
|
on: the role of the user and the state of the item.
|
||||||
|
|
||||||
|
The Moderation process has associated notification to authors and
|
||||||
|
Catalogue-Moderators. Please note that the user who has acted is not
|
||||||
|
self-notified, e.g. approve operation made by a Catalogue-Moderator
|
||||||
|
notifies the item author and the other Catalogue-Moderators of the VRE.
|
||||||
|
|
||||||
|
The following table summarises the addressee of the notification for any
|
||||||
|
action.
|
||||||
|
|
||||||
|
Java Client
|
||||||
|
===========
|
||||||
|
|
||||||
|
We provide the following Java Client out-of-the-box.
|
||||||
|
|
||||||
|
> ::: {.tip}
|
||||||
|
> ::: {.title}
|
||||||
|
> Tip
|
||||||
|
> :::
|
||||||
|
>
|
||||||
|
> If you\'re coding in Java, it is recommended that you use this Java
|
||||||
|
> Client.
|
||||||
|
> :::
|
||||||
|
|
||||||
|
**Maven Coordinates**
|
||||||
|
|
||||||
|
``` {.xml}
|
||||||
|
<groupId>org.gcube.data-catalogue</groupId>
|
||||||
|
<artifactId>gcat-client</artifactId>
|
||||||
|
<version>[2.2.0, 3.0.0-SNAPSHOT)</version>
|
||||||
|
```
|
||||||
|
|
||||||
|
**Methods Result**
|
||||||
|
|
||||||
|
The service exposes [its methods](../api-docs/index.html) using a
|
||||||
|
standard naming approach. Moreover, they accept (in the case of HTTP
|
||||||
|
POST/PUT methods) JSON objects.
|
||||||
|
|
||||||
|
> ::: {.important}
|
||||||
|
> ::: {.title}
|
||||||
|
> Important
|
||||||
|
> :::
|
||||||
|
>
|
||||||
|
> The result of all methods is always a JSON object as per below:
|
||||||
|
> :::
|
||||||
|
|
||||||
|
``` {.javascript}
|
||||||
|
{
|
||||||
|
"rating": 0.0,
|
||||||
|
"license_title": "Creative Commons Attribution Share-Alike 4.0",
|
||||||
|
"maintainer": "Frosini Luca",
|
||||||
|
"relationships_as_object": [],
|
||||||
|
"private": false,
|
||||||
|
"maintainer_email": "luca.frosini@isti.cnr.it",
|
||||||
|
"num_tags": 1,
|
||||||
|
"id": "17051d86-c127-4928-9296-d3d7590161fe",
|
||||||
|
"metadata_created": "2022-10-17T12:45:53.118318",
|
||||||
|
"metadata_modified": "2022-10-18T10:30:03.362756",
|
||||||
|
"author": "Frosini Luca",
|
||||||
|
"author_email": "luca.frosini@isti.cnr.it",
|
||||||
|
"state": "active",
|
||||||
|
"version": null,
|
||||||
|
"creator_user_id": "f1b0265c-9983-4f97-a7b6-be3cc0544b27",
|
||||||
|
"type": "dataset",
|
||||||
|
"resources": [],
|
||||||
|
"num_resources": 0,
|
||||||
|
"tags": [
|
||||||
|
{
|
||||||
|
"vocabulary_id": null,
|
||||||
|
"state": "active",
|
||||||
|
"display_name": "Test",
|
||||||
|
"id": "fec9de86-51a2-41b0-aef4-ba06eb39e16d",
|
||||||
|
"name": "Test"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"groups": [],
|
||||||
|
"license_id": "CC-BY-SA-4.0",
|
||||||
|
"relationships_as_subject": [],
|
||||||
|
"organization": {
|
||||||
|
"description": "",
|
||||||
|
"created": "2016-05-30T11:30:41.710079",
|
||||||
|
"title": "devVRE",
|
||||||
|
"name": "devvre",
|
||||||
|
"is_organization": true,
|
||||||
|
"state": "active",
|
||||||
|
"image_url": "",
|
||||||
|
"revision_id": "a7eee485-a6d5-4a7b-8f73-b0ed999d5b03",
|
||||||
|
"type": "organization",
|
||||||
|
"id": "3571cca5-b0ae-4dc6-b791-434a8e062ce5",
|
||||||
|
"approval_status": "approved"
|
||||||
|
},
|
||||||
|
"name": "my_test_item_devvre",
|
||||||
|
"isopen": true,
|
||||||
|
"url": "http://www.d4science.org",
|
||||||
|
"notes": "A test item of Luca Frosini",
|
||||||
|
"extras": [
|
||||||
|
{
|
||||||
|
"key": "Item URL",
|
||||||
|
"value": "https://data.dev.d4science.org/ctlg/devVRE/my_test_item_devvre"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "Language",
|
||||||
|
"value": "EN"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "system:cm_item_status",
|
||||||
|
"value": "approved"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "system:cm_item_visibility",
|
||||||
|
"value": "public"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "system:type",
|
||||||
|
"value": "EmptyProfile"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"license_url": "https://creativecommons.org/licenses/by-sa/4.0/",
|
||||||
|
"ratings_count": 0,
|
||||||
|
"title": "My Test Item",
|
||||||
|
"revision_id": "bc0d1f2a-4e97-4810-b951-8b72e8279719"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
*Inputs are automatically validated before the request is served.*
|
||||||
|
|
||||||
|
**Usage examples**
|
||||||
|
|
||||||
|
- Example 1
|
||||||
|
|
||||||
|
``` {.java}
|
||||||
|
import org.gcube.gcat.client.Item;
|
||||||
|
|
||||||
|
// count item number
|
||||||
|
Item item = new Item();
|
||||||
|
int count = item.count();
|
||||||
|
...
|
||||||
|
```
|
||||||
|
|
||||||
|
Service Discovery on IS
|
||||||
|
=======================
|
||||||
|
|
||||||
|
The service can be discovered in the gCore IS as gCore Endpoint with the
|
||||||
|
following parameter:
|
||||||
|
|
||||||
|
``` {.xml}
|
||||||
|
<ServiceClass>org.gcube.data-catalogue</ServiceClass>
|
||||||
|
<ServiceName>gcat</ServiceName>
|
||||||
|
```
|
||||||
|
|
||||||
|
The service can be discovered in the Facet Based IS as EService with the
|
||||||
|
following json query:
|
||||||
|
|
||||||
|
``` {.json}
|
||||||
|
{
|
||||||
|
"@class": "EService",
|
||||||
|
"consistsOf": [
|
||||||
|
{
|
||||||
|
"@class": "IsIdentifiedBy",
|
||||||
|
"target": {
|
||||||
|
"@class": "SoftwareFacet",
|
||||||
|
"group": "org.gcube.data-catalogue",
|
||||||
|
"name": "gcat"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Service Maven Coordinates
|
||||||
|
=========================
|
||||||
|
|
||||||
|
The maven coordinates of gCat service are:
|
||||||
|
|
||||||
|
``` {.xml}
|
||||||
|
<groupId>org.gcube.data-catalogue</groupId>
|
||||||
|
<artifactId>gcat</artifactId>
|
||||||
|
```
|
|
@ -0,0 +1,510 @@
|
||||||
|
|
||||||
|
***********************************************************
|
||||||
|
Welcome to gCube Catalogue Service (aka gCat) documentation
|
||||||
|
***********************************************************
|
||||||
|
|
||||||
|
gCat is a RESTful application which exposes operations via REST-API.
|
||||||
|
|
||||||
|
See the available `REST-API docs <../api-docs/index.html>`_.
|
||||||
|
|
||||||
|
Base URL
|
||||||
|
========
|
||||||
|
|
||||||
|
In the production environment, its current value is https://api.d4science.org/gcat
|
||||||
|
|
||||||
|
|
||||||
|
Authorization
|
||||||
|
=============
|
||||||
|
|
||||||
|
D4Science adopts state-of-the-art industry standards for authentication and authorization.
|
||||||
|
Specifically, the implementation fully adopts `OIDC (OpenID Connect) <https://openid.net/connect>`_ for authentication and UMA 2 (User-Managed Authorization) for authorization flows.
|
||||||
|
`JSON Web Token (JWT) Access token <https://jwt.io/>`_ are used for both authentication and authorization.
|
||||||
|
|
||||||
|
Obtain your Bearer token here: https://dev.d4science.org/how-to-access-resources
|
||||||
|
|
||||||
|
Service
|
||||||
|
=======
|
||||||
|
|
||||||
|
You can call the methods of the Web Service by writing your own REST client application or using existing REST client plugins.
|
||||||
|
|
||||||
|
|
||||||
|
HTTP Statuses
|
||||||
|
-------------
|
||||||
|
|
||||||
|
Any successful operation returns *200 OK* HTTP status code.
|
||||||
|
The create operation returns *201 Created*.
|
||||||
|
Any Background operation returns *202 Accepted*.
|
||||||
|
Any operation which does not provide any content return *204 No Content*.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
The most common error status a client can obtain are:
|
||||||
|
|
||||||
|
* **400 Bad Request** used to indicate a clients error `<https://tools.ietf.org/html/rfc7231#section-6.5.1>`_;
|
||||||
|
* **401 Unauthorized** used to indicate that the client does not provide the authorization token in the HTTP Header or the client has not enough right to perform such request `<https://tools.ietf.org/html/rfc7235#section-3.1>`_;
|
||||||
|
* **404 Not Found** used to indicate that the requested instance does not exist `<https://tools.ietf.org/html/rfc7231#section-6.5.4>`_;
|
||||||
|
* **405 Method Not Allowed** the used HTTP method is not supported for the requested URL `<https://tools.ietf.org/html/rfc7231#section-6.5.5>`_.
|
||||||
|
The response contains the *Allow* HTTP Header indicating the supported HTTP method for such URL `<https://tools.ietf.org/html/rfc7231#section-7.4.1>`_;
|
||||||
|
* **409 Conflict** the request could not be completed due to a conflict with the current state of the target resource (e.g. the name of the resource already exists) `<https://tools.ietf.org/html/rfc7231#section-6.5.8>`_;
|
||||||
|
* **500 Internal Server Error** indicate a server failure `<https://tools.ietf.org/html/rfc7231#section-6.6.1>`_.
|
||||||
|
|
||||||
|
You can find a complete list of HTTP Status at `<https://httpstatuses.com/>`_
|
||||||
|
|
||||||
|
If you get a *500 Internal Server Error*, please report it in the `gCube ticketing system <https://support.d4science.org>`_.
|
||||||
|
|
||||||
|
Please use this checklist before reporting an error:
|
||||||
|
|
||||||
|
* Replicate the request;
|
||||||
|
* The failure could be temporal due to network error, server issue and many other temporal issues. For this reason, please retry the request after a certain amount of time before reporting the issue;
|
||||||
|
* indicate how to replicate the error;
|
||||||
|
* indicate the time when the error occurred (this simplifies identifying the issue).
|
||||||
|
|
||||||
|
HTTP Methods
|
||||||
|
------------
|
||||||
|
|
||||||
|
gCat is a pure RESTful service. It uses standard HTTP Methods to perform a listing of collections and CRUD (Create Read Update Delete) operations on instances.
|
||||||
|
|
||||||
|
|
||||||
|
.. table::
|
||||||
|
|
||||||
|
+--------------+-------------+----------------------------------------+---------------------+--------+------------+
|
||||||
|
| Operation | HTTP Method | URL | Success HTTP Status | Safe | Idempotent |
|
||||||
|
+==============+=============+========================================+=====================+========+============+
|
||||||
|
| Supported | OPTIONS | /{COLLECTION} | 204 No Content | Y | Y |
|
||||||
|
| HTTP Methods | | | [#allow]_ | | |
|
||||||
|
+--------------+-------------+----------------------------------------+---------------------+--------+------------+
|
||||||
|
| List | GET | /{COLLECTION} | 200 OK | Y | Y |
|
||||||
|
+--------------+-------------+----------------------------------------+---------------------+--------+------------+
|
||||||
|
| Count | GET | /{COLLECTION}?count=true | 200 OK | Y | Y |
|
||||||
|
+--------------+-------------+----------------------------------------+---------------------+--------+------------+
|
||||||
|
| Exists | HEAD | /{COLLECTION} | 204 No Content | Y | Y |
|
||||||
|
+--------------+-------------+----------------------------------------+---------------------+--------+------------+
|
||||||
|
| Create | POST | /{COLLECTION} | 201 Created | N | N |
|
||||||
|
+--------------+-------------+----------------------------------------+---------------------+--------+------------+
|
||||||
|
| Supported | OPTIONS | /{COLLECTION}/{INSTANCE_ID} | 204 No Content | Y | Y |
|
||||||
|
| HTTP Methods | | | [#allow]_ | | |
|
||||||
|
+--------------+-------------+----------------------------------------+---------------------+--------+------------+
|
||||||
|
| Exist | HEAD | /{COLLECTION}/{INSTANCE_ID} | 204 No Content | Y | Y |
|
||||||
|
+--------------+-------------+----------------------------------------+---------------------+--------+------------+
|
||||||
|
| Read | GET | /{COLLECTION}/{INSTANCE_ID} | 200 OK | Y | Y |
|
||||||
|
+--------------+-------------+----------------------------------------+---------------------+--------+------------+
|
||||||
|
| Update | PUT | /{COLLECTION}/{INSTANCE_ID} | 200 OK | N | Y |
|
||||||
|
+--------------+-------------+----------------------------------------+---------------------+--------+------------+
|
||||||
|
| Patch | PATCH | /{COLLECTION}/{INSTANCE_ID} | 200 OK | N | Y |
|
||||||
|
+--------------+-------------+----------------------------------------+---------------------+--------+------------+
|
||||||
|
| Delete | DELETE | /{COLLECTION}/{INSTANCE_ID} | 204 No Content | N | N [#del]_ |
|
||||||
|
+--------------+-------------+----------------------------------------+---------------------+--------+------------+
|
||||||
|
| Purge | DELETE | /{COLLECTION}/{INSTANCE_ID}?purge=true | 204 No Content | N | N [#del]_ |
|
||||||
|
+ +-------------+----------------------------------------+---------------------+--------+------------+
|
||||||
|
| | PURGE | /{COLLECTION}/{INSTANCE_ID} | 204 No Content | N | N [#del]_ |
|
||||||
|
+--------------+-------------+----------------------------------------+---------------------+--------+------------+
|
||||||
|
|
||||||
|
.. [#allow] Supported HTTP Methods in **Allow** HTTP Header
|
||||||
|
|
||||||
|
.. [#del] DELETE has been defined as idempotent.
|
||||||
|
|
||||||
|
*Allamaraju* [#Allamaraju]_ argues that DELETE idempotency should be accomplished client-side.
|
||||||
|
The server should inform the client if the delete operation succeeded because the resource was really deleted or it was not found, i.e., **404 Not Found** error is suggested instead of **204 No Content**.
|
||||||
|
The latter situation should be treated as idempotent by the client.
|
||||||
|
|
||||||
|
We share the same vision. For this reason, gCat does not provide server-side idempotency for DELETE and PURGE operations.
|
||||||
|
|
||||||
|
.. [#Allamaraju] Allamaraju S. RESTful Web Services Cookbook: Solutions for Improving Scalability and Simplicity . O’Reilly. first ed. 2010
|
||||||
|
|
||||||
|
|
||||||
|
About URL
|
||||||
|
^^^^^^^^^
|
||||||
|
|
||||||
|
The presented URL uses the following convention:
|
||||||
|
|
||||||
|
* **{COLLECTION}** is the plural name of the entity type;
|
||||||
|
* **{INSTANCE_ID}** is an identification that enables univocally identifying the instance in the collection.
|
||||||
|
|
||||||
|
|
||||||
|
About Safety and Idempotency properties
|
||||||
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
|
||||||
|
* A method is *Safe* if it does not produce any side effects.
|
||||||
|
"This does not prevent an implementation from including behaviour that is potentially harmful, that is not entirely read-only, or that causes side effects while invoking a safe method"
|
||||||
|
`<https://tools.ietf.org/html/rfc7231#section-4.2.1>`_;
|
||||||
|
* A method is *Idempotent* if the same operation repeated multiple times has the same side effect than using it one time.
|
||||||
|
"repeating the request will have the same intended effect, even if the original request succeeded, though the response might differ"
|
||||||
|
`<https://tools.ietf.org/html/rfc7231#section-4.2.2>`_.
|
||||||
|
|
||||||
|
You can find more information about HTTP Methods at `<https://restfulapi.net/http-methods/>`_
|
||||||
|
|
||||||
|
Uncommon HTTP Methods
|
||||||
|
^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
* PATCH method allows to perform a differential update (i.e. an update which provides only the differences and not the whole new representation);
|
||||||
|
* PURGE method is not a standard but is widely used in service which requires this action
|
||||||
|
(e.g. `Varnish <https://varnish-cache.org/docs/3.0/tutorial/purging.html>`_, `Squid <https://wiki.squid-cache.org/SquidFaq/OperatingSquid#How_can_I_purge_an_object_from_my_cache.3F>`_).
|
||||||
|
gCat provides support for this method, but to support a wider range of clients, it also provides the Purge action via *DELETE* with the additional get parameter ``purge=true``.
|
||||||
|
|
||||||
|
|
||||||
|
Content-Type
|
||||||
|
------------
|
||||||
|
|
||||||
|
Any request must contain an indication of the interesting content type.
|
||||||
|
|
||||||
|
The client must specify the **Accept** HTTP Header for any operation returning a result.
|
||||||
|
|
||||||
|
.. code-block:: rest
|
||||||
|
|
||||||
|
Accept: application/json
|
||||||
|
|
||||||
|
For any operation sending content to the service, it is necessary to specify the **Content-Type** HTTP Header.
|
||||||
|
|
||||||
|
.. code-block:: rest
|
||||||
|
|
||||||
|
Content-Type: application/json
|
||||||
|
|
||||||
|
The service accepts and returns only JSON objects.
|
||||||
|
|
||||||
|
`Profile Collection <../api-docs/resource\_Profile.html>`_ instead can be manipulated in XML only.
|
||||||
|
|
||||||
|
Collections
|
||||||
|
-----------
|
||||||
|
|
||||||
|
The following collections are available to any user.
|
||||||
|
Catalogue-Editor or above can invoke Non-safe methods only.
|
||||||
|
|
||||||
|
* `Item Collection <../api-docs/resource_Item.html>`_;
|
||||||
|
|
||||||
|
* `Resource Collection <../api-docs/resource_Resource.html>`_;
|
||||||
|
|
||||||
|
* `Profile Collection <../api-docs/resource_Profile.html>`_;
|
||||||
|
* `Namespace Collection <../api-docs/resource_Namespace.html>`_;
|
||||||
|
* `License Collection <../api-docs/resource_License.html>`_;
|
||||||
|
* `Trash Collection <../api-docs/resource_Trash.html>`_;
|
||||||
|
|
||||||
|
The following collections are available for Catalogue-Admins or above only:
|
||||||
|
|
||||||
|
* `Group Collection <../api-docs/resource_Group.html>`_;
|
||||||
|
* `Organization Collection <../api-docs/resource_Organization.html>`_;
|
||||||
|
* `User Collection <../api-docs/resource_User.html>`_;
|
||||||
|
* `Configuration Collection <../api-docs/resource_Configuration.html>`_.
|
||||||
|
|
||||||
|
An overview of the available collections is available at `<../api-docs/index.html>`_;
|
||||||
|
|
||||||
|
|
||||||
|
Roles
|
||||||
|
-----
|
||||||
|
|
||||||
|
Any user has one or more roles in the catalogue.
|
||||||
|
Only the VRE Manager can assign roles to VRE users.
|
||||||
|
|
||||||
|
|
||||||
|
The catalogue uses the following hierarchic roles:
|
||||||
|
|
||||||
|
**Catalogue-Member**:
|
||||||
|
A user with such a role is mainly capable of listing and reading items;
|
||||||
|
|
||||||
|
**Catalogue-Editor**:
|
||||||
|
A user with such a role is capable of managing the items he/she creates and capable of using other safe APIs;
|
||||||
|
|
||||||
|
**Catalogue-Admin**:
|
||||||
|
A user with such a role is capable of administrating many aspects of the catalogue;
|
||||||
|
|
||||||
|
**Catalogue-Manager**:
|
||||||
|
A user with such a role can use all the APIs exposed by the service except item moderation APIs (e.g. approve, reject, ...).
|
||||||
|
|
||||||
|
|
||||||
|
Another role that is not in the role hierarchy:
|
||||||
|
|
||||||
|
**Catalogue-Moderator**:
|
||||||
|
A user with such a role is capable of invoking the item moderation APIs.
|
||||||
|
|
||||||
|
|
||||||
|
.. TIP::
|
||||||
|
Please note that not all catalogues are moderated.
|
||||||
|
|
||||||
|
Moderated Catalogues
|
||||||
|
====================
|
||||||
|
|
||||||
|
|
||||||
|
Any catalogues can be declared as moderated.
|
||||||
|
This means that, a **Catalogue-Moderator** must approve any submitted items to make them available to the other users of the catalogue.
|
||||||
|
|
||||||
|
In a moderated catalogue, an item can be in the following states:
|
||||||
|
|
||||||
|
**pending**:
|
||||||
|
The item published by any allowed author (a Catalogue-Editor or above) but not available to the other users of the catalogue.
|
||||||
|
A Catalogue-Moderator has to approve or reject it;
|
||||||
|
|
||||||
|
**approved**:
|
||||||
|
A Catalogue-Moderator has approved the item published by any allowed users;
|
||||||
|
|
||||||
|
**rejected**:
|
||||||
|
A Catalogue-Moderator has rejected the item published by any allowed users.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
The following are the moderation operations that an allowed user can perform on an item.
|
||||||
|
To present the moderation operations, we use the following convention:
|
||||||
|
|
||||||
|
``initial_state`` ---**operation** (*User/Role performing the operation*)---> ``final_state``
|
||||||
|
|
||||||
|
|
||||||
|
``initial_state`` can be ``none``, meaning the item does not exist.
|
||||||
|
|
||||||
|
|
||||||
|
The following are the allowed moderation operation on an item
|
||||||
|
|
||||||
|
``none`` ---**create** (*Author*)---> ``pending``
|
||||||
|
|
||||||
|
``pending`` ---**reject** (*Catalogue-Moderator*)---> ``rejected``
|
||||||
|
|
||||||
|
``pending`` ---**approve** (*Catalogue-Moderator*)---> ``approved``
|
||||||
|
|
||||||
|
``rejected`` ---**update** (*Author*)---> ``pending``
|
||||||
|
|
||||||
|
``approved`` ---**update** (*Author*)---> ``pending``
|
||||||
|
|
||||||
|
|
||||||
|
Please check the table below whcih summarise the item collection operation and the allowed users/roles.
|
||||||
|
|
||||||
|
In a moderated catalogue, both the Catalogue-Moderators and the item author can send messages to
|
||||||
|
discuss the approval process of the item. The messages are related to a specific item.
|
||||||
|
Any Catalogue-Moderators receive a message sent by an Author.
|
||||||
|
The author receives a message sent by a Catalogue-Moderator as well as the other Catalogue-Moderators (if any).
|
||||||
|
|
||||||
|
Messages can be sent both with an action which changes the status of the item or as explicit action which does not change the status of the item:
|
||||||
|
|
||||||
|
``pending`` ---**message** (*Author OR Catalogue-Moderator*)---> ``pending``
|
||||||
|
|
||||||
|
``rejected`` ---**message** (*Author OR Catalogue-Moderator*)---> ``rejected``
|
||||||
|
|
||||||
|
``approved`` ---**message** (*Author OR Catalogue-Moderator*)---> ``approved``
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
The following table summarize the allowed/forbidden operations depending on: the role of the user and the state of the item.
|
||||||
|
|
||||||
|
.. table::
|
||||||
|
|
||||||
|
+-------------------------------------+-------------+----------------------+--------------------------+------------------------------------------+-------------------+
|
||||||
|
| Operation | Item State | Roles |
|
||||||
|
+ + +----------------------+--------------------------+------------------------------------------+-------------------+
|
||||||
|
| | | Catalogue Moderator | Catalogue Admin/Manager | Catalogue Editor | Catalogue Member |
|
||||||
|
+=====================================+=============+======================+==========================+==========================================+===================+
|
||||||
|
| List | Yes all states | Yes all states | Yes only approved - All states if Author | Yes only approved |
|
||||||
|
+-------------------------------------+-------------+----------------------+--------------------------+------------------------------------------+-------------------+
|
||||||
|
| Count | Yes all states | Yes all states | Yes only approved - All states if Author | Yes only approved |
|
||||||
|
+-------------------------------------+-------------+----------------------+--------------------------+------------------------------------------+-------------------+
|
||||||
|
| Create | 403 Forbidden | Yes -> Pending | Yes -> Pending | 403 Forbidden |
|
||||||
|
+-------------------------------------+-------------+----------------------+--------------------------+------------------------------------------+-------------------+
|
||||||
|
| Read | Yes all states | Yes all states | Yes only approved - All states if Author | Yes only approved |
|
||||||
|
+-------------------------------------+-------------+----------------------+--------------------------+------------------------------------------+-------------------+
|
||||||
|
| Update | Pending | Yes -> Pending | Yes if Author -> Pending | Yes if Author -> Pending | 403 Forbidden |
|
||||||
|
+ +-------------+----------------------+--------------------------+------------------------------------------+-------------------+
|
||||||
|
| | Rejected | Yes -> Pending | Yes if Author -> Pending | Yes if Author -> Pending | 403 Forbidden |
|
||||||
|
+ +-------------+----------------------+--------------------------+------------------------------------------+-------------------+
|
||||||
|
| | Approved | 403 Forbidden | Yes -> Approved | Yes if Author -> Pending | 403 Forbidden |
|
||||||
|
+-------------------------------------+-------------+----------------------+--------------------------+------------------------------------------+-------------------+
|
||||||
|
| Delete/Purge | Pending | Yes | Yes | Yes if Author | 403 Forbidden |
|
||||||
|
+ +-------------+----------------------+--------------------------+------------------------------------------+-------------------+
|
||||||
|
| | Rejected | Yes | Yes | Yes if Author | 403 Forbidden |
|
||||||
|
+ +-------------+----------------------+--------------------------+------------------------------------------+-------------------+
|
||||||
|
| | Approved | 403 Forbidden | Yes | Yes if Author | 403 Forbidden |
|
||||||
|
+-------------------------------------+-------------+----------------------+--------------------------+------------------------------------------+-------------------+
|
||||||
|
| Approve a pending item | Yes | 403 Forbidden | 403 Forbidden | 403 Forbidden |
|
||||||
|
+-------------------------------------+-------------+----------------------+--------------------------+------------------------------------------+-------------------+
|
||||||
|
| Reject a pending item | Yes | 403 Forbidden | 403 Forbidden | 403 Forbidden |
|
||||||
|
+-------------------------------------+-------------+----------------------+--------------------------+------------------------------------------+-------------------+
|
||||||
|
| Message about an item | Yes | Yes if Author | Yes if Author | 403 Forbidden |
|
||||||
|
+-------------------------------------+-------------+----------------------+--------------------------+------------------------------------------+-------------------+
|
||||||
|
|
||||||
|
|
||||||
|
The Moderation process has associated notification to authors and Catalogue-Moderators.
|
||||||
|
Please note that the user who has acted is not self-notified, e.g.
|
||||||
|
approve operation made by a Catalogue-Moderator notifies the item author and the other Catalogue-Moderators of the VRE.
|
||||||
|
|
||||||
|
The following table summarises the addressee of the notification for any action.
|
||||||
|
|
||||||
|
|
||||||
|
.. table::
|
||||||
|
|
||||||
|
+--------------+----------------------+--------+----------------------+
|
||||||
|
| Operation | Notified user/role |
|
||||||
|
+ +----------------------+--------+----------------------+
|
||||||
|
| | Catalogue-Moderators | Author | User made the action |
|
||||||
|
+==============+======================+========+======================+
|
||||||
|
| Create | Yes | Yes | Yes (custom message) |
|
||||||
|
+--------------+----------------------+--------+----------------------+
|
||||||
|
| Update | Yes | Yes | Yes (custom message) |
|
||||||
|
+--------------+----------------------+--------+----------------------+
|
||||||
|
| Approve | Yes + Social Post if | No |
|
||||||
|
| | requested (social_post=true) | |
|
||||||
|
| | and enabled for the VRE | |
|
||||||
|
+--------------+----------------------+--------+----------------------+
|
||||||
|
| Reject | Yes | Yes | No |
|
||||||
|
+--------------+----------------------+--------+----------------------+
|
||||||
|
| Delete/Purge | Yes | Yes | No |
|
||||||
|
+--------------+----------------------+--------+----------------------+
|
||||||
|
| Message | Yes | Yes | No |
|
||||||
|
+--------------+----------------------+--------+----------------------+
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Java Client
|
||||||
|
===========
|
||||||
|
|
||||||
|
We provide the following Java Client out-of-the-box.
|
||||||
|
|
||||||
|
.. TIP::
|
||||||
|
If you're coding in Java, it is recommended that you use this Java Client.
|
||||||
|
|
||||||
|
**Maven Coordinates**
|
||||||
|
|
||||||
|
.. code:: xml
|
||||||
|
|
||||||
|
<groupId>org.gcube.data-catalogue</groupId>
|
||||||
|
<artifactId>gcat-client</artifactId>
|
||||||
|
<version>[2.2.0, 3.0.0-SNAPSHOT)</version>
|
||||||
|
|
||||||
|
**Methods Result**
|
||||||
|
|
||||||
|
The service exposes `its methods <../api-docs/index.html>`_ using a standard naming approach. Moreover, they accept (in the case of HTTP POST/PUT methods) JSON objects.
|
||||||
|
|
||||||
|
.. IMPORTANT::
|
||||||
|
The result of all methods is always a JSON object as per below:
|
||||||
|
|
||||||
|
.. code:: javascript
|
||||||
|
|
||||||
|
{
|
||||||
|
"rating": 0.0,
|
||||||
|
"license_title": "Creative Commons Attribution Share-Alike 4.0",
|
||||||
|
"maintainer": "Frosini Luca",
|
||||||
|
"relationships_as_object": [],
|
||||||
|
"private": false,
|
||||||
|
"maintainer_email": "luca.frosini@isti.cnr.it",
|
||||||
|
"num_tags": 1,
|
||||||
|
"id": "17051d86-c127-4928-9296-d3d7590161fe",
|
||||||
|
"metadata_created": "2022-10-17T12:45:53.118318",
|
||||||
|
"metadata_modified": "2022-10-18T10:30:03.362756",
|
||||||
|
"author": "Frosini Luca",
|
||||||
|
"author_email": "luca.frosini@isti.cnr.it",
|
||||||
|
"state": "active",
|
||||||
|
"version": null,
|
||||||
|
"creator_user_id": "f1b0265c-9983-4f97-a7b6-be3cc0544b27",
|
||||||
|
"type": "dataset",
|
||||||
|
"resources": [],
|
||||||
|
"num_resources": 0,
|
||||||
|
"tags": [
|
||||||
|
{
|
||||||
|
"vocabulary_id": null,
|
||||||
|
"state": "active",
|
||||||
|
"display_name": "Test",
|
||||||
|
"id": "fec9de86-51a2-41b0-aef4-ba06eb39e16d",
|
||||||
|
"name": "Test"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"groups": [],
|
||||||
|
"license_id": "CC-BY-SA-4.0",
|
||||||
|
"relationships_as_subject": [],
|
||||||
|
"organization": {
|
||||||
|
"description": "",
|
||||||
|
"created": "2016-05-30T11:30:41.710079",
|
||||||
|
"title": "devVRE",
|
||||||
|
"name": "devvre",
|
||||||
|
"is_organization": true,
|
||||||
|
"state": "active",
|
||||||
|
"image_url": "",
|
||||||
|
"revision_id": "a7eee485-a6d5-4a7b-8f73-b0ed999d5b03",
|
||||||
|
"type": "organization",
|
||||||
|
"id": "3571cca5-b0ae-4dc6-b791-434a8e062ce5",
|
||||||
|
"approval_status": "approved"
|
||||||
|
},
|
||||||
|
"name": "my_test_item_devvre",
|
||||||
|
"isopen": true,
|
||||||
|
"url": "http://www.d4science.org",
|
||||||
|
"notes": "A test item of Luca Frosini",
|
||||||
|
"extras": [
|
||||||
|
{
|
||||||
|
"key": "Item URL",
|
||||||
|
"value": "https://data.dev.d4science.org/ctlg/devVRE/my_test_item_devvre"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "Language",
|
||||||
|
"value": "EN"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "system:cm_item_status",
|
||||||
|
"value": "approved"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "system:cm_item_visibility",
|
||||||
|
"value": "public"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "system:type",
|
||||||
|
"value": "EmptyProfile"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"license_url": "https://creativecommons.org/licenses/by-sa/4.0/",
|
||||||
|
"ratings_count": 0,
|
||||||
|
"title": "My Test Item",
|
||||||
|
"revision_id": "bc0d1f2a-4e97-4810-b951-8b72e8279719"
|
||||||
|
}
|
||||||
|
|
||||||
|
*Inputs are automatically validated before the request is served.*
|
||||||
|
|
||||||
|
|
||||||
|
**Usage examples**
|
||||||
|
|
||||||
|
- Example 1
|
||||||
|
|
||||||
|
.. code:: java
|
||||||
|
|
||||||
|
import org.gcube.gcat.client.Item;
|
||||||
|
|
||||||
|
// count item number
|
||||||
|
Item item = new Item();
|
||||||
|
int count = item.count();
|
||||||
|
...
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Service Discovery on IS
|
||||||
|
=======================
|
||||||
|
|
||||||
|
The service can be discovered in the gCore IS as gCore Endpoint with the following parameter:
|
||||||
|
|
||||||
|
.. code:: xml
|
||||||
|
|
||||||
|
<ServiceClass>org.gcube.data-catalogue</ServiceClass>
|
||||||
|
<ServiceName>gcat</ServiceName>
|
||||||
|
|
||||||
|
|
||||||
|
The service can be discovered in the Facet Based IS as EService with the following json query:
|
||||||
|
|
||||||
|
.. code:: json
|
||||||
|
|
||||||
|
{
|
||||||
|
"@class": "EService",
|
||||||
|
"consistsOf": [
|
||||||
|
{
|
||||||
|
"@class": "IsIdentifiedBy",
|
||||||
|
"target": {
|
||||||
|
"@class": "SoftwareFacet",
|
||||||
|
"group": "org.gcube.data-catalogue",
|
||||||
|
"name": "gcat"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Service Maven Coordinates
|
||||||
|
=========================
|
||||||
|
|
||||||
|
The maven coordinates of gCat service are:
|
||||||
|
|
||||||
|
.. code:: xml
|
||||||
|
|
||||||
|
<groupId>org.gcube.data-catalogue</groupId>
|
||||||
|
<artifactId>gcat</artifactId>
|
||||||
|
|
|
@ -0,0 +1,35 @@
|
||||||
|
@ECHO OFF
|
||||||
|
|
||||||
|
pushd %~dp0
|
||||||
|
|
||||||
|
REM Command file for Sphinx documentation
|
||||||
|
|
||||||
|
if "%SPHINXBUILD%" == "" (
|
||||||
|
set SPHINXBUILD=sphinx-build
|
||||||
|
)
|
||||||
|
set SOURCEDIR=.
|
||||||
|
set BUILDDIR=_build
|
||||||
|
|
||||||
|
if "%1" == "" goto help
|
||||||
|
|
||||||
|
%SPHINXBUILD% >NUL 2>NUL
|
||||||
|
if errorlevel 9009 (
|
||||||
|
echo.
|
||||||
|
echo.The 'sphinx-build' command was not found. Make sure you have Sphinx
|
||||||
|
echo.installed, then set the SPHINXBUILD environment variable to point
|
||||||
|
echo.to the full path of the 'sphinx-build' executable. Alternatively you
|
||||||
|
echo.may add the Sphinx directory to PATH.
|
||||||
|
echo.
|
||||||
|
echo.If you don't have Sphinx installed, grab it from
|
||||||
|
echo.https://www.sphinx-doc.org/
|
||||||
|
exit /b 1
|
||||||
|
)
|
||||||
|
|
||||||
|
%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O%
|
||||||
|
goto end
|
||||||
|
|
||||||
|
:help
|
||||||
|
%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O%
|
||||||
|
|
||||||
|
:end
|
||||||
|
popd
|
|
@ -0,0 +1,23 @@
|
||||||
|
Dev and Pre Users used for moderation tests
|
||||||
|
========
|
||||||
|
|
||||||
|
To perform moderation tests in dev and preproduction infrastructure we use different users with the indicated roles.
|
||||||
|
|
||||||
|
.. table::
|
||||||
|
|
||||||
|
+---------------+---------------+----------------------------------------+
|
||||||
|
| User | Username | Role |
|
||||||
|
+===============+===============+========================================+
|
||||||
|
| Mister Blonde | mister.blonde | Catalogue-Admin + Catalogue-Moderator |
|
||||||
|
+---------------+---------------+----------------------------------------+
|
||||||
|
| Mister Blue | mister.blue | Catalogue-Admin |
|
||||||
|
+---------------+---------------+----------------------------------------+
|
||||||
|
| Mister Brown | mister.brown | Catalogue-Moderator |
|
||||||
|
+---------------+---------------+----------------------------------------+
|
||||||
|
| Mister Orange | mister.orange | Catalogue-Editor |
|
||||||
|
+---------------+---------------+----------------------------------------+
|
||||||
|
| Mister Pink | mister.pink | NO ROLE (means Catalogue-Member) |
|
||||||
|
+---------------+---------------+----------------------------------------+
|
||||||
|
| Mister White | mister.white | Catalogue-Manager |
|
||||||
|
+---------------+---------------+----------------------------------------+
|
||||||
|
|
|
@ -0,0 +1,23 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<enunciate
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:noNamespaceSchemaLocation="http://enunciate.webcohesion.com/schemas/enunciate-2.14.0.xsd">
|
||||||
|
<description package="org.gcube.acme.rest"/>
|
||||||
|
<api-classes>
|
||||||
|
<include pattern="org.gcube.acme.rest.*" />
|
||||||
|
<exclude pattern="org.gcube.acme.*" />
|
||||||
|
</api-classes>
|
||||||
|
<modules>
|
||||||
|
<gwt-json-overlay disabled="true " />
|
||||||
|
<php-json-client disabled="true" />
|
||||||
|
<ruby-json-client disabled="true" />
|
||||||
|
<java-json-client disabled="true" />
|
||||||
|
<javascript-client disabled="true" />
|
||||||
|
<docs docsDir="${project.build.directory}" docsSubdir="api-docs" />
|
||||||
|
<swagger basePath="/${project.artifactId}" />
|
||||||
|
<docs freemarkerTemplate="${project.basedir}/src/main/resources/META-INF/enunciate/d4science_docs.fmt">
|
||||||
|
<additional-css
|
||||||
|
file="css/d4science_enunciate_custom.css" />
|
||||||
|
</docs>
|
||||||
|
</modules>
|
||||||
|
</enunciate>
|
|
@ -0,0 +1,10 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE xml>
|
||||||
|
<application mode='online'>
|
||||||
|
<name>${project.artifactId}</name>
|
||||||
|
<group>${project.groupId}</group>
|
||||||
|
<version>${project.version}</version>
|
||||||
|
<description>${project.description}</description>
|
||||||
|
<exclude>/api-docs.*</exclude>
|
||||||
|
<exclude>/docs.*</exclude>
|
||||||
|
</application>
|
|
@ -0,0 +1,16 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<web-app>
|
||||||
|
<!-- <context-param>
|
||||||
|
<param-name>resolver-basepath</param-name>
|
||||||
|
<param-value>https://data-d.d4science.org/shub</param-value>
|
||||||
|
</context-param> -->
|
||||||
|
<servlet>
|
||||||
|
<servlet-name>org.gcube.data.access.storagehub.StorageHub</servlet-name>
|
||||||
|
|
||||||
|
</servlet>
|
||||||
|
<servlet-mapping>
|
||||||
|
<servlet-name>org.gcube.data.access.storagehub.StorageHub</servlet-name>
|
||||||
|
<url-pattern>/workspace/*</url-pattern>
|
||||||
|
</servlet-mapping>
|
||||||
|
|
||||||
|
</web-app>
|
|
@ -0,0 +1,6 @@
|
||||||
|
name: IdentityManagerService
|
||||||
|
group: IAM
|
||||||
|
version: ${version}
|
||||||
|
description: ${description}
|
||||||
|
excludes:
|
||||||
|
- path: /workspace/api-docs/*
|
|
@ -0,0 +1,209 @@
|
||||||
|
<project xmlns="https://maven.apache.org/POM/4.0.0"
|
||||||
|
xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="https://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
<parent>
|
||||||
|
<groupId>org.gcube.tools</groupId>
|
||||||
|
<artifactId>maven-parent</artifactId>
|
||||||
|
<version>1.2.0</version>
|
||||||
|
</parent>
|
||||||
|
<groupId>org.gcube.idm</groupId>
|
||||||
|
<artifactId>identity-manager</artifactId>
|
||||||
|
<version>1.0.0-SNAPSHOT</version>
|
||||||
|
<packaging>war</packaging>
|
||||||
|
<name>Identity Manager Service</name>
|
||||||
|
<description>Identity Manager Smargears Service</description>
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
|
<maven.compiler.source>11</maven.compiler.source>
|
||||||
|
<maven.compiler.target>11</maven.compiler.target>
|
||||||
|
<webappDirectory>
|
||||||
|
${project.basedir}${file.separator}src${file.separator}main${file.separator}webapp${file.separator}WEB-INF</webappDirectory>
|
||||||
|
<enunciate.version>2.14.0</enunciate.version>
|
||||||
|
</properties>
|
||||||
|
|
||||||
|
<scm>
|
||||||
|
<connection>
|
||||||
|
scm:git:https://code-repo.d4science.org/gCubeSystem/${project.artifactId}.git</connection>
|
||||||
|
<developerConnection>
|
||||||
|
scm:git:https://code-repo.d4science.org/gCubeSystem/${project.artifactId}.git</developerConnection>
|
||||||
|
<url>https://code-repo.d4science.org/gCubeSystem/${project.artifactId}</url>
|
||||||
|
</scm>
|
||||||
|
|
||||||
|
<dependencyManagement>
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.gcube.distribution</groupId>
|
||||||
|
<artifactId>gcube-smartgears-bom</artifactId>
|
||||||
|
<version>3.0.1-SNAPSHOT</version>
|
||||||
|
<type>pom</type>
|
||||||
|
<scope>import</scope>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
</dependencyManagement>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.slf4j</groupId>
|
||||||
|
<artifactId>slf4j-api</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.gcube.common</groupId>
|
||||||
|
<artifactId>common-security</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.gcube.common</groupId>
|
||||||
|
<artifactId>keycloak-client</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.keycloak</groupId>
|
||||||
|
<artifactId>keycloak-admin-client</artifactId>
|
||||||
|
<version>21.0.1</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.glassfish.jersey.media</groupId>
|
||||||
|
<artifactId>jersey-media-multipart</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.glassfish.jersey.containers</groupId>
|
||||||
|
<artifactId>jersey-container-servlet</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>javax.ws.rs</groupId>
|
||||||
|
<artifactId>javax.ws.rs-api</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.gcube.core</groupId>
|
||||||
|
<artifactId>common-smartgears-app</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.gcube.core</groupId>
|
||||||
|
<artifactId>common-smartgears</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- Required for Enunciate plugin -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.webcohesion.enunciate</groupId>
|
||||||
|
<artifactId>enunciate-core-annotations</artifactId>
|
||||||
|
<version>${enunciate.version}</version>
|
||||||
|
<scope>provided</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.webcohesion.enunciate</groupId>
|
||||||
|
<artifactId>enunciate-rt-util</artifactId>
|
||||||
|
<version>${enunciate.version}</version>
|
||||||
|
<scope>provided</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>javax.servlet</groupId>
|
||||||
|
<artifactId>javax.servlet-api</artifactId>
|
||||||
|
<version>3.1.0</version>
|
||||||
|
<scope>provided</scope>
|
||||||
|
</dependency>
|
||||||
|
<!-- END Required for Enunciate plugin -->
|
||||||
|
|
||||||
|
<!-- Test libraries -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>junit</groupId>
|
||||||
|
<artifactId>junit</artifactId>
|
||||||
|
<version>4.11</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>ch.qos.logback</groupId>
|
||||||
|
<artifactId>logback-classic</artifactId>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.gcube.portlets.user</groupId>
|
||||||
|
<artifactId>uri-resolver-manager</artifactId>
|
||||||
|
<version>[1.0.0, 2.0.0-SNAPSHOT)</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
<build>
|
||||||
|
<finalName>${project.artifactId}</finalName>
|
||||||
|
<plugins>
|
||||||
|
<!-- Sphinx plugin' -->
|
||||||
|
<plugin>
|
||||||
|
<groupId>kr.motd.maven</groupId>
|
||||||
|
<artifactId>sphinx-maven-plugin</artifactId>
|
||||||
|
<version>2.10.0</version>
|
||||||
|
<configuration>
|
||||||
|
<outputDirectory>
|
||||||
|
${project.build.directory}/${project.artifactId}-${project.version}/docs</outputDirectory>
|
||||||
|
<builder>html</builder>
|
||||||
|
<configDirectory>${basedir}/docs</configDirectory>
|
||||||
|
<sourceDirectory>${basedir}/docs</sourceDirectory>
|
||||||
|
</configuration>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<phase>process-resources</phase>
|
||||||
|
<goals>
|
||||||
|
<goal>generate</goal>
|
||||||
|
</goals>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- Enunciate Maven plugin -->
|
||||||
|
<plugin>
|
||||||
|
<groupId>com.webcohesion.enunciate</groupId>
|
||||||
|
<artifactId>enunciate-maven-plugin</artifactId>
|
||||||
|
<version>${enunciate.version}</version>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<id>assemble</id>
|
||||||
|
<goals>
|
||||||
|
<goal>assemble</goal>
|
||||||
|
</goals>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
|
<!-- Copy Enunciate Documentation from your-application/api-docs
|
||||||
|
into your war -->
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-resources-plugin</artifactId>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<id>copy-enunciate-docs</id>
|
||||||
|
<phase>process-resources</phase>
|
||||||
|
<goals>
|
||||||
|
<goal>copy-resources</goal>
|
||||||
|
</goals>
|
||||||
|
<configuration>
|
||||||
|
<outputDirectory>target</outputDirectory>
|
||||||
|
<resources>
|
||||||
|
<resource>
|
||||||
|
<targetPath>
|
||||||
|
${project.build.directory}/${project.artifactId}-${project.version}/api-docs</targetPath>
|
||||||
|
<directory>
|
||||||
|
${project.build.directory}/api-docs</directory>
|
||||||
|
<filtering>true</filtering>
|
||||||
|
</resource>
|
||||||
|
</resources>
|
||||||
|
</configuration>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
|
|
||||||
|
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-war-plugin</artifactId>
|
||||||
|
<configuration>
|
||||||
|
<attachClasses>true</attachClasses>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
|
||||||
|
</project>
|
|
@ -0,0 +1,38 @@
|
||||||
|
package org.gcube.idm;
|
||||||
|
|
||||||
|
import javax.ws.rs.WebApplicationException;
|
||||||
|
import javax.ws.rs.core.MediaType;
|
||||||
|
import javax.ws.rs.core.Response;
|
||||||
|
import javax.ws.rs.core.Response.Status;
|
||||||
|
import javax.ws.rs.ext.ExceptionMapper;
|
||||||
|
import javax.ws.rs.ext.Provider;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Alfredo Oliviero (ISTI - CNR)
|
||||||
|
*/
|
||||||
|
@Provider
|
||||||
|
public class IdentityManagerExceptionMapper implements ExceptionMapper<Exception> {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Response toResponse(Exception exception) {
|
||||||
|
|
||||||
|
Status status = Status.INTERNAL_SERVER_ERROR;
|
||||||
|
String exceptionMessage = exception.getMessage();
|
||||||
|
try {
|
||||||
|
if(exception.getCause() != null) {
|
||||||
|
exceptionMessage = exception.getCause().getMessage();
|
||||||
|
}
|
||||||
|
} catch(Exception e) {
|
||||||
|
exceptionMessage = exception.getMessage();
|
||||||
|
}
|
||||||
|
MediaType mediaType = MediaType.TEXT_PLAIN_TYPE;
|
||||||
|
|
||||||
|
if(WebApplicationException.class.isAssignableFrom(exception.getClass())) {
|
||||||
|
Response gotResponse = ((WebApplicationException) exception).getResponse();
|
||||||
|
status = Status.fromStatusCode(gotResponse.getStatusInfo().getStatusCode());
|
||||||
|
}
|
||||||
|
|
||||||
|
return Response.status(status).entity(exceptionMessage).type(mediaType).build();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,25 @@
|
||||||
|
package org.gcube.idm;
|
||||||
|
|
||||||
|
import javax.ws.rs.ApplicationPath;
|
||||||
|
|
||||||
|
import org.gcube.idm.rest.GreetingsRest;
|
||||||
|
import org.gcube.smartgears.annotations.ManagedBy;
|
||||||
|
import org.glassfish.jersey.server.ResourceConfig;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Alfredo Oliviero (ISTI - CNR)
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
// SMARTGEARS
|
||||||
|
// legge i parametri del service da application.yaml
|
||||||
|
|
||||||
|
@ApplicationPath("/")
|
||||||
|
@ManagedBy(IdentityManagerdInitializator.class)
|
||||||
|
public class IdentityManagerResourceInitializer extends ResourceConfig {
|
||||||
|
|
||||||
|
public IdentityManagerResourceInitializer() {
|
||||||
|
packages(GreetingsRest.class.getPackage().toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,68 @@
|
||||||
|
package org.gcube.idm;
|
||||||
|
|
||||||
|
import org.gcube.common.security.providers.SecretManagerProvider;
|
||||||
|
import org.gcube.smartgears.ApplicationManager;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Alfredo Oliviero (ISTI - CNR)
|
||||||
|
*/
|
||||||
|
public class IdentityManagerdInitializator implements ApplicationManager {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Logger
|
||||||
|
*/
|
||||||
|
private static Logger logger = LoggerFactory.getLogger(IdentityManagerdInitializator.class);
|
||||||
|
|
||||||
|
public static boolean initialised;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public synchronized void onInit() {
|
||||||
|
|
||||||
|
String context = SecretManagerProvider.instance.get().getContext();
|
||||||
|
|
||||||
|
logger.trace(
|
||||||
|
"\n-------------------------------------------------------\n"
|
||||||
|
+ "Identity Manager Service is Starting on context {}\n"
|
||||||
|
+ "-------------------------------------------------------",
|
||||||
|
context);
|
||||||
|
|
||||||
|
// ApplicationContext applicationContext = ContextProvider.get();
|
||||||
|
// String helloWorldEServiceID = applicationContext.id();
|
||||||
|
|
||||||
|
logger.trace(
|
||||||
|
"\n-------------------------------------------------------\n"
|
||||||
|
+ "Identity Manager Service Started Successfully on context {}\n"
|
||||||
|
+ "-------------------------------------------------------",
|
||||||
|
context);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public synchronized void onShutdown(){
|
||||||
|
|
||||||
|
String context = SecretManagerProvider.instance.get().getContext();
|
||||||
|
|
||||||
|
logger.trace(
|
||||||
|
"\n-------------------------------------------------------\n"
|
||||||
|
+ "Identity Manager Service is Stopping on context {}\n"
|
||||||
|
+ "-------------------------------------------------------",
|
||||||
|
context);
|
||||||
|
|
||||||
|
|
||||||
|
logger.trace(
|
||||||
|
"\n-------------------------------------------------------\n"
|
||||||
|
+ "Identity Manager Service Stopped Successfully on context {}\n"
|
||||||
|
+ "-------------------------------------------------------",
|
||||||
|
context);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,69 @@
|
||||||
|
package org.gcube.idm.rest;
|
||||||
|
|
||||||
|
import javax.ws.rs.Consumes;
|
||||||
|
import javax.ws.rs.DELETE;
|
||||||
|
import javax.ws.rs.DefaultValue;
|
||||||
|
import javax.ws.rs.GET;
|
||||||
|
import javax.ws.rs.POST;
|
||||||
|
import javax.ws.rs.PUT;
|
||||||
|
import javax.ws.rs.Path;
|
||||||
|
import javax.ws.rs.PathParam;
|
||||||
|
import javax.ws.rs.Produces;
|
||||||
|
import javax.ws.rs.QueryParam;
|
||||||
|
|
||||||
|
import com.webcohesion.enunciate.metadata.rs.RequestHeader;
|
||||||
|
import com.webcohesion.enunciate.metadata.rs.RequestHeaders;
|
||||||
|
import com.webcohesion.enunciate.metadata.rs.ResourceGroup;
|
||||||
|
import com.webcohesion.enunciate.metadata.rs.ResourceLabel;
|
||||||
|
import com.webcohesion.enunciate.metadata.rs.ResponseCode;
|
||||||
|
import com.webcohesion.enunciate.metadata.rs.StatusCodes;
|
||||||
|
|
||||||
|
@Path("greetings")
|
||||||
|
@ResourceGroup("Greetings APIs")
|
||||||
|
@ResourceLabel("Greetings APIs")
|
||||||
|
@RequestHeaders ({
|
||||||
|
@RequestHeader( name = "Authorization", description = "Bearer token, see <a href=\"https://dev.d4science.org/how-to-access-resources\">https://dev.d4science.org/how-to-access-resources</a>")
|
||||||
|
})
|
||||||
|
public class GreetingsRest {
|
||||||
|
|
||||||
|
@GET
|
||||||
|
@Produces({"application/json;charset=UTF-8", "application/vnd.api+json"})
|
||||||
|
public String list(@QueryParam("limit") @DefaultValue("10") int limit,
|
||||||
|
@QueryParam("offset") @DefaultValue("0") int offset) {
|
||||||
|
|
||||||
|
return "[\"saluti\",\"saluti_volgari\"]";
|
||||||
|
}
|
||||||
|
|
||||||
|
@POST
|
||||||
|
@Produces("application/json;charset=UTF-8")
|
||||||
|
@Consumes("application/json;charset=UTF-8")
|
||||||
|
public String create(String json) {
|
||||||
|
//Greeting g = new Greeting();
|
||||||
|
//return g.create(json);
|
||||||
|
return "{\"text\":\"hi\"}";
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@PUT
|
||||||
|
@Path("/{greeting_name}")
|
||||||
|
@Consumes("application/json;charset=UTF-8")
|
||||||
|
@Produces("application/json;charset=UTF-8")
|
||||||
|
@StatusCodes ({
|
||||||
|
@ResponseCode ( code = 200, condition = "The greeting has been updated successfully.")
|
||||||
|
})
|
||||||
|
// @AuthorizationControl(allowedRoles={"boss"}, exception=NotAuthorizedException.class)
|
||||||
|
public String update(@PathParam("greeting_name") String name, String json) {
|
||||||
|
return "{}";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@DELETE
|
||||||
|
@Path("/{greeting_name}")
|
||||||
|
@StatusCodes ({
|
||||||
|
@ResponseCode ( code = 204, condition = "The item has been deleted successfully."),
|
||||||
|
@ResponseCode ( code = 404, condition = "The item was not found.")
|
||||||
|
})
|
||||||
|
public String delete(@PathParam("greeting_name") String name) {
|
||||||
|
return "{}";
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,153 @@
|
||||||
|
package org.gcube.idm.rest;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import javax.ws.rs.GET;
|
||||||
|
import javax.ws.rs.Path;
|
||||||
|
import javax.ws.rs.Produces;
|
||||||
|
import javax.ws.rs.QueryParam;
|
||||||
|
import javax.ws.rs.core.Response;
|
||||||
|
import javax.ws.rs.core.Response.Status;
|
||||||
|
|
||||||
|
import org.gcube.common.authorization.library.policies.Users;
|
||||||
|
import org.gcube.common.security.Owner;
|
||||||
|
import org.gcube.common.security.providers.SecretManagerProvider;
|
||||||
|
import org.gcube.keycloack.KeycloackApiClient;
|
||||||
|
import org.gcube.keycloack.KeycloakAPIFactory;
|
||||||
|
import org.gcube.rest.ResponseBean;
|
||||||
|
import org.gcube.smartgears.ContextProvider;
|
||||||
|
import org.gcube.smartgears.context.application.ApplicationContext;
|
||||||
|
import org.gcube.smartgears.security.SimpleCredentials;
|
||||||
|
import org.gcube.smartgears.security.defaults.DefaultAuthorizationProvider;
|
||||||
|
import org.gcube.smartgears.utils.InnerMethodName;
|
||||||
|
import org.jboss.resteasy.spi.NotImplementedYetException;
|
||||||
|
import org.keycloak.representations.idm.ClientRepresentation;
|
||||||
|
import org.keycloak.representations.idm.UserRepresentation;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import com.webcohesion.enunciate.metadata.rs.RequestHeader;
|
||||||
|
import com.webcohesion.enunciate.metadata.rs.RequestHeaders;
|
||||||
|
import com.webcohesion.enunciate.metadata.rs.ResourceGroup;
|
||||||
|
import com.webcohesion.enunciate.metadata.rs.ResourceLabel;
|
||||||
|
|
||||||
|
@Path("2/users")
|
||||||
|
@ResourceGroup("Users APIs")
|
||||||
|
@ResourceLabel("Greetings APIs")
|
||||||
|
@RequestHeaders({
|
||||||
|
@RequestHeader(name = "Authorization", description = "Bearer token, see <a href=\"https://dev.d4science.org/how-to-access-resources\">https://dev.d4science.org/how-to-access-resources</a>")
|
||||||
|
})
|
||||||
|
public class UsersRest {
|
||||||
|
private static final org.slf4j.Logger logger = LoggerFactory.getLogger(Users.class);
|
||||||
|
|
||||||
|
@GET
|
||||||
|
@Path("/{get-usernames-by-role}")
|
||||||
|
@Produces({ "application/json;charset=UTF-8", "application/vnd.api+json" })
|
||||||
|
public Response getUsernamesByRole(
|
||||||
|
@QueryParam("role-name") String roleName) {
|
||||||
|
Status status = Status.OK;
|
||||||
|
ResponseBean responseBean = new ResponseBean();
|
||||||
|
|
||||||
|
List<String> usernames = new ArrayList<String>();
|
||||||
|
try {
|
||||||
|
String ctx = SecretManagerProvider.instance.get().getContext();
|
||||||
|
KeycloackApiClient keycloackApiClient = KeycloakAPIFactory.getSingleton().createtKeycloakInstance(ctx);
|
||||||
|
|
||||||
|
List<UserRepresentation> users = searchByRole(keycloackApiClient, roleName);
|
||||||
|
if (users != null) {
|
||||||
|
for (UserRepresentation user : users) {
|
||||||
|
usernames.add(user.getUsername());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
responseBean.setResult(usernames);
|
||||||
|
responseBean.setSuccess(true);
|
||||||
|
} catch (Exception e) {
|
||||||
|
logger.error("Unable to retrieve user with the requested role", e);
|
||||||
|
responseBean.setMessage(e.getMessage());
|
||||||
|
status = Status.INTERNAL_SERVER_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Response.status(status).entity(responseBean).build();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private static List<UserRepresentation> searchByRole(KeycloackApiClient keycloackApiClient, String roleName) {
|
||||||
|
logger.info("Searching by role: {}", roleName);
|
||||||
|
|
||||||
|
List<ClientRepresentation> clients = keycloackApiClient.kclient.realm(keycloackApiClient.realmName)
|
||||||
|
.clients().findByClientId(keycloackApiClient.clientIdContext);
|
||||||
|
|
||||||
|
String id = "";
|
||||||
|
for (ClientRepresentation client : clients) {
|
||||||
|
logger.info("found client =" + client.getClientId());
|
||||||
|
logger.info("found client id=" + client.getId());
|
||||||
|
id = client.getId();
|
||||||
|
}
|
||||||
|
|
||||||
|
List<UserRepresentation> users = keycloackApiClient.kclient.realm(keycloackApiClient.realmName)
|
||||||
|
.clients()
|
||||||
|
.get(id).roles().get(roleName)
|
||||||
|
.getUserMembers(0, 100000);
|
||||||
|
return users;
|
||||||
|
}
|
||||||
|
|
||||||
|
@GET
|
||||||
|
@Path("/{get-profile}")
|
||||||
|
@Produces({ "application/json;charset=UTF-8", "application/vnd.api+json" })
|
||||||
|
public String getCurrentProfile() {
|
||||||
|
// SMARTGEARS Specializza il tracciamento della chiamata su Accounting
|
||||||
|
InnerMethodName.instance.set("getCurrentProfile");
|
||||||
|
Owner owner = SecretManagerProvider.instance.get().getOwner();
|
||||||
|
|
||||||
|
ApplicationContext appContext = ContextProvider.get();
|
||||||
|
SimpleCredentials credentials = ((DefaultAuthorizationProvider) appContext.container().authorizationProvider())
|
||||||
|
.getCredentials();
|
||||||
|
|
||||||
|
String ctx = SecretManagerProvider.instance.get().getContext();
|
||||||
|
KeycloackApiClient keycloackApiClient = KeycloakAPIFactory.getSingleton().createtKeycloakInstance(ctx);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@GET
|
||||||
|
@Path("/{get-email}")
|
||||||
|
@Produces({ "application/json;charset=UTF-8", "application/vnd.api+json" })
|
||||||
|
public String getCurrentEmail() {
|
||||||
|
throw new NotImplementedYetException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@GET
|
||||||
|
@Path("/{get-fullname}")
|
||||||
|
@Produces({ "application/json;charset=UTF-8", "application/vnd.api+json" })
|
||||||
|
public String getCurrentFullname() {
|
||||||
|
throw new NotImplementedYetException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@GET
|
||||||
|
@Path("/{get-all-usernames}")
|
||||||
|
@Produces({ "application/json;charset=UTF-8", "application/vnd.api+json" })
|
||||||
|
public String getAllUsernames() {
|
||||||
|
throw new NotImplementedYetException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@GET
|
||||||
|
@Path("/{get-all-fullnames-and-usernames}")
|
||||||
|
@Produces({ "application/json;charset=UTF-8", "application/vnd.api+json" })
|
||||||
|
public String getAllUsernamesFullnames() {
|
||||||
|
throw new NotImplementedYetException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@GET
|
||||||
|
@Path("/{user-exists}")
|
||||||
|
@Produces({ "application/json;charset=UTF-8", "application/vnd.api+json" })
|
||||||
|
public boolean checkUserExists() {
|
||||||
|
throw new NotImplementedYetException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@GET
|
||||||
|
@Path("/{get-oauth-profile}")
|
||||||
|
@Produces({ "application/json;charset=UTF-8", "application/vnd.api+json" })
|
||||||
|
public boolean getCurrentOAuthProfile() {
|
||||||
|
throw new NotImplementedYetException();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,34 @@
|
||||||
|
package org.gcube.keycloack;
|
||||||
|
|
||||||
|
public class ErrorMessages {
|
||||||
|
|
||||||
|
protected static final String NOT_USER_TOKEN_CONTEXT_USED = "User's information can only be retrieved through a user token (not qualified)";
|
||||||
|
protected static final String CANNOT_RETRIEVE_SERVICE_ENDPOINT_INFORMATION = "Unable to retrieve such service endpoint information";
|
||||||
|
|
||||||
|
private static final String NO_RUNTIME_RESOURCE_TEMPLATE_NAME_CATEGORY = "There is no Runtime Resource having name %s and Category %s in this scope";
|
||||||
|
|
||||||
|
protected static final String no_runtime_category(String runtime, String category) {
|
||||||
|
return String.format(NO_RUNTIME_RESOURCE_TEMPLATE_NAME_CATEGORY, runtime, category);
|
||||||
|
}
|
||||||
|
|
||||||
|
// public static final String MISSING_TOKEN = "Missing token.";
|
||||||
|
// public static final String MISSING_PARAMETERS = "Missing request
|
||||||
|
// parameters.";
|
||||||
|
// public static final String INVALID_TOKEN = "Invalid token.";
|
||||||
|
// public static final String TOKEN_GENERATION_APP_FAILED = "Token generation
|
||||||
|
// failed.";
|
||||||
|
// public static final String NOT_APP_TOKEN = "Invalid token: not belonging to
|
||||||
|
// an application.";
|
||||||
|
// public static final String NOT_APP_ID = "Invalid application id: it doesn't
|
||||||
|
// belong to an application.";
|
||||||
|
// public static final String NO_APP_PROFILE_FOUND = "There is no application
|
||||||
|
// profile for this app id/scope.";
|
||||||
|
// public static final String BAD_REQUEST = "Please check the parameter you
|
||||||
|
// passed, it seems a bad request";
|
||||||
|
// public static final String ERROR_IN_API_RESULT = "The error is reported into
|
||||||
|
// the 'message' field of the returned object";
|
||||||
|
// public static final String POST_OUTSIDE_VRE = "A post cannot be written into
|
||||||
|
// a context that is not a VRE";
|
||||||
|
// public static final String DEPRECATED_METHOD = "This method is deprecated,
|
||||||
|
// must use version 2";
|
||||||
|
}
|
|
@ -0,0 +1,23 @@
|
||||||
|
package org.gcube.keycloack;
|
||||||
|
|
||||||
|
import org.keycloak.admin.client.Keycloak;
|
||||||
|
|
||||||
|
public class KeycloackApiClient {
|
||||||
|
public Keycloak kclient;
|
||||||
|
public String realmName;
|
||||||
|
public String clientIdContext;
|
||||||
|
public String context;
|
||||||
|
|
||||||
|
public static String getClientIdContext(String context){
|
||||||
|
return context.replace("/", "%2F");
|
||||||
|
}
|
||||||
|
|
||||||
|
public KeycloackApiClient(Keycloak kclient, String realmName, String context) {
|
||||||
|
this.clientIdContext = getClientIdContext(context);
|
||||||
|
this.context = context;
|
||||||
|
this.kclient = kclient;
|
||||||
|
this.realmName = realmName;
|
||||||
|
// ClientsResource clients = kclient.realm(realmName).clients();
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,102 @@
|
||||||
|
package org.gcube.keycloack;
|
||||||
|
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.net.URL;
|
||||||
|
import java.util.AbstractMap.SimpleEntry;
|
||||||
|
import java.util.Map.Entry;
|
||||||
|
import java.util.Properties;
|
||||||
|
|
||||||
|
import javax.ws.rs.InternalServerErrorException;
|
||||||
|
|
||||||
|
import org.gcube.common.security.providers.SecretManagerProvider;
|
||||||
|
import org.gcube.common.keycloak.DefaultKeycloakClient;
|
||||||
|
import org.gcube.common.keycloak.KeycloakClientException;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
public class KeycloackClientParams_UNUSED {
|
||||||
|
|
||||||
|
private static final Logger logger = LoggerFactory.getLogger(KeycloackClientParams_UNUSED.class);
|
||||||
|
|
||||||
|
public static final String CATALOGUE_NAME = "IDM";
|
||||||
|
|
||||||
|
protected static final String CLIENT_ID_SECRET_FILENAME = "config.properties";
|
||||||
|
protected static final String CLIENT_ID_PROPERTY_NAME = "clientId";
|
||||||
|
|
||||||
|
public String context;
|
||||||
|
public String clientId;
|
||||||
|
public String clientSecret;
|
||||||
|
public DefaultKeycloakClient gcubeKeycloakClient;
|
||||||
|
|
||||||
|
// Reads the property file and extracts the keycloack configuration params
|
||||||
|
protected static Entry<String, String> getClientIdAndClientSecret(String context) {
|
||||||
|
try {
|
||||||
|
Properties properties = new Properties();
|
||||||
|
ClassLoader classLoader = KeycloackClientParams_UNUSED.class.getClassLoader();
|
||||||
|
URL url = classLoader.getResource(CLIENT_ID_SECRET_FILENAME);
|
||||||
|
logger.trace("Going to read {} at {}", CLIENT_ID_SECRET_FILENAME, url.toString());
|
||||||
|
InputStream input = classLoader.getResourceAsStream(CLIENT_ID_SECRET_FILENAME);
|
||||||
|
properties.load(input);
|
||||||
|
|
||||||
|
String clientId = "IDM";
|
||||||
|
if (properties.containsKey(CLIENT_ID_PROPERTY_NAME)) {
|
||||||
|
clientId = properties.getProperty(CLIENT_ID_PROPERTY_NAME);
|
||||||
|
}
|
||||||
|
|
||||||
|
int index = context.indexOf('/', 1);
|
||||||
|
String root = context.substring(0, index == -1 ? context.length() : index);
|
||||||
|
String clientSecret = properties.getProperty(root);
|
||||||
|
|
||||||
|
SimpleEntry<String, String> entry = new SimpleEntry<String, String>(clientId, clientSecret);
|
||||||
|
return entry;
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new InternalServerErrorException(
|
||||||
|
"Unable to retrieve Application Token for context "
|
||||||
|
+ SecretManagerProvider.instance.get().getContext(),
|
||||||
|
e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: VERIFICARE
|
||||||
|
public URL getRealmBaseURL() throws KeycloakClientException {
|
||||||
|
return this.gcubeKeycloakClient.getRealmBaseURL(this.context);
|
||||||
|
}
|
||||||
|
|
||||||
|
public URL getRealmBaseURL(String realm) throws KeycloakClientException {
|
||||||
|
return this.gcubeKeycloakClient.getRealmBaseURL(this.context, realm);
|
||||||
|
}
|
||||||
|
|
||||||
|
public URL getServerURL() {
|
||||||
|
try {
|
||||||
|
return this.getRealmBaseURL();
|
||||||
|
} catch (KeycloakClientException e) {
|
||||||
|
// That should be almost impossible
|
||||||
|
logger.warn("Cannot create base URL", e);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getClientid() {
|
||||||
|
return clientId;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: serve? implementare
|
||||||
|
public String getPassword() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: VERIFICARE
|
||||||
|
public String getRealm() {
|
||||||
|
return this.context;
|
||||||
|
}
|
||||||
|
|
||||||
|
public KeycloackClientParams_UNUSED(String context) {
|
||||||
|
this.context = context;
|
||||||
|
Entry<String, String> params = getClientIdAndClientSecret(context);
|
||||||
|
this.clientId = params.getKey();
|
||||||
|
this.clientSecret = params.getKey();
|
||||||
|
|
||||||
|
this.gcubeKeycloakClient = new DefaultKeycloakClient();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,147 @@
|
||||||
|
package org.gcube.keycloack;
|
||||||
|
|
||||||
|
import static org.gcube.resources.discovery.icclient.ICFactory.clientFor;
|
||||||
|
import static org.gcube.resources.discovery.icclient.ICFactory.queryFor;
|
||||||
|
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.gcube.common.encryption.encrypter.StringEncrypter;
|
||||||
|
import org.gcube.common.resources.gcore.ServiceEndpoint;
|
||||||
|
import org.gcube.common.resources.gcore.ServiceEndpoint.AccessPoint;
|
||||||
|
import org.gcube.resources.discovery.client.api.DiscoveryClient;
|
||||||
|
import org.gcube.resources.discovery.client.queries.api.SimpleQuery;
|
||||||
|
import org.gcube.smartgears.ContextProvider;
|
||||||
|
import org.gcube.smartgears.context.application.ApplicationContext;
|
||||||
|
import org.keycloak.OAuth2Constants;
|
||||||
|
import org.keycloak.admin.client.Keycloak;
|
||||||
|
import org.keycloak.admin.client.KeycloakBuilder;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
public class KeycloakAPIFactory {
|
||||||
|
private static final Logger logger = LoggerFactory.getLogger(KeycloakAPIFactory.class);
|
||||||
|
|
||||||
|
private final static String RUNTIME_RESOURCE_NAME = "IAM";
|
||||||
|
private final static String CATEGORY = "Service";
|
||||||
|
|
||||||
|
// the singleton obj
|
||||||
|
|
||||||
|
private static KeycloakAPIFactory singleton = new KeycloakAPIFactory();
|
||||||
|
|
||||||
|
// properties that it contains
|
||||||
|
private String keycloakURL;
|
||||||
|
private String realm;
|
||||||
|
private String clientid;
|
||||||
|
private String password;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Private constructor
|
||||||
|
*/
|
||||||
|
private KeycloakAPIFactory() {
|
||||||
|
logger.info("Building KeycloakAPICredentials object");
|
||||||
|
|
||||||
|
lookupPropertiesFromIs();
|
||||||
|
logger.info("KeycloakAPICredentials object built");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Read the properties from the infrastructure
|
||||||
|
*/
|
||||||
|
private void lookupPropertiesFromIs() {
|
||||||
|
|
||||||
|
logger.info("Starting creating KeycloakAPICredentials");
|
||||||
|
|
||||||
|
// String ctx = SecretManagerProvider.instance.get().getContext();
|
||||||
|
// TODO: verificare che sia contesto corretto
|
||||||
|
ApplicationContext ctx = ContextProvider.get(); // get this info from SmartGears
|
||||||
|
|
||||||
|
logger.info("Discovering liferay user's credentials in context "
|
||||||
|
+ ctx.container().configuration().infrastructure());
|
||||||
|
|
||||||
|
try {
|
||||||
|
List<ServiceEndpoint> resources = getConfigurationFromIS();
|
||||||
|
if (resources.size() == 0) {
|
||||||
|
logger.error("There is no Runtime Resource having name " + RUNTIME_RESOURCE_NAME + " and Category "
|
||||||
|
+ CATEGORY + " in this scope.");
|
||||||
|
throw new Exception("There is no Runtime Resource having name " + RUNTIME_RESOURCE_NAME
|
||||||
|
+ " and Category " + CATEGORY + " in this scope.");
|
||||||
|
} else {
|
||||||
|
for (ServiceEndpoint res : resources) {
|
||||||
|
Iterator<AccessPoint> accessPointIterator = res.profile().accessPoints().iterator();
|
||||||
|
while (accessPointIterator.hasNext()) {
|
||||||
|
ServiceEndpoint.AccessPoint accessPoint = (ServiceEndpoint.AccessPoint) accessPointIterator
|
||||||
|
.next();
|
||||||
|
|
||||||
|
if (accessPoint.name().equals("d4science")) {
|
||||||
|
keycloakURL = accessPoint.address();
|
||||||
|
realm = accessPoint.name();
|
||||||
|
clientid = accessPoint.username();
|
||||||
|
password = StringEncrypter.getEncrypter().decrypt(accessPoint.password());
|
||||||
|
logger.info("Found accesspoint URL = " + keycloakURL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
logger.error("Unable to retrieve such service endpoint information!", e);
|
||||||
|
return;
|
||||||
|
// }finally{
|
||||||
|
// if(oldContext != null)
|
||||||
|
// ScopeProvider.instance.set(oldContext);
|
||||||
|
}
|
||||||
|
|
||||||
|
logger.info("Bean built " + toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve endpoints information from IS for DB
|
||||||
|
*
|
||||||
|
* @return list of endpoints for ckan database
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
private List<ServiceEndpoint> getConfigurationFromIS() throws Exception {
|
||||||
|
SimpleQuery query = queryFor(ServiceEndpoint.class);
|
||||||
|
query.addCondition("$resource/Profile/Name/text() eq '" + RUNTIME_RESOURCE_NAME + "'");
|
||||||
|
query.addCondition("$resource/Profile/Category/text() eq '" + CATEGORY + "'");
|
||||||
|
DiscoveryClient<ServiceEndpoint> client = clientFor(ServiceEndpoint.class);
|
||||||
|
List<ServiceEndpoint> toReturn = client.submit(query);
|
||||||
|
return toReturn;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static KeycloakAPIFactory getSingleton() {
|
||||||
|
if (singleton == null)
|
||||||
|
singleton = new KeycloakAPIFactory();
|
||||||
|
return singleton;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getServerURL() {
|
||||||
|
return keycloakURL;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getClientid() {
|
||||||
|
return clientid;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getPassword() {
|
||||||
|
return password;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getRealm() {
|
||||||
|
return realm;
|
||||||
|
}
|
||||||
|
|
||||||
|
public KeycloackApiClient createtKeycloakInstance(String context) {
|
||||||
|
// String clientIdContext = KeycloackUtils.getClientIdContext(context);
|
||||||
|
String realm = this.getRealm();
|
||||||
|
Keycloak keycloak = KeycloakBuilder.builder()
|
||||||
|
.serverUrl(this.getServerURL())
|
||||||
|
.realm(realm)
|
||||||
|
.grantType(OAuth2Constants.CLIENT_CREDENTIALS)
|
||||||
|
.clientId(this.getClientid()) //
|
||||||
|
.clientSecret(this.getPassword()).build();
|
||||||
|
return new KeycloackApiClient(keycloak, realm, context);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,71 @@
|
||||||
|
package org.gcube.rest;
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Response bean
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class ResponseBean implements Serializable {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = -2725238162673879658L;
|
||||||
|
/**
|
||||||
|
* The result of the request: true if it succeeded, false otherwise
|
||||||
|
*/
|
||||||
|
private boolean success;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An error message if something wrong happened, null/empty otherwise
|
||||||
|
*/
|
||||||
|
private String message;
|
||||||
|
/**
|
||||||
|
* The result object of the request
|
||||||
|
*/
|
||||||
|
private Object result;
|
||||||
|
|
||||||
|
public ResponseBean() {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param success
|
||||||
|
* @param message
|
||||||
|
* @param result
|
||||||
|
*/
|
||||||
|
public ResponseBean(boolean success, String message, Object result) {
|
||||||
|
super();
|
||||||
|
this.success = success;
|
||||||
|
this.message = message;
|
||||||
|
this.result = result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isSuccess() {
|
||||||
|
return success;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSuccess(boolean success) {
|
||||||
|
this.success = success;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getMessage() {
|
||||||
|
return message;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMessage(String message) {
|
||||||
|
this.message = message;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Object getResult() {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setResult(Object result) {
|
||||||
|
this.result = result;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "ResponseBean [success=" + success
|
||||||
|
+ ", message=" + message + ", result=" + result + "]";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,17 @@
|
||||||
|
package org.gcube.rest.annotation;
|
||||||
|
|
||||||
|
import java.lang.annotation.ElementType;
|
||||||
|
import java.lang.annotation.Retention;
|
||||||
|
import java.lang.annotation.RetentionPolicy;
|
||||||
|
import java.lang.annotation.Target;
|
||||||
|
|
||||||
|
import javax.ws.rs.HttpMethod;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Luca Frosini (ISTI - CNR)
|
||||||
|
*/
|
||||||
|
@Target({ElementType.METHOD})
|
||||||
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
|
@HttpMethod("PATCH")
|
||||||
|
public @interface PATCH {
|
||||||
|
}
|
|
@ -0,0 +1,17 @@
|
||||||
|
package org.gcube.rest.annotation;
|
||||||
|
|
||||||
|
import java.lang.annotation.ElementType;
|
||||||
|
import java.lang.annotation.Retention;
|
||||||
|
import java.lang.annotation.RetentionPolicy;
|
||||||
|
import java.lang.annotation.Target;
|
||||||
|
|
||||||
|
import javax.ws.rs.HttpMethod;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Luca Frosini (ISTI - CNR)
|
||||||
|
*/
|
||||||
|
@Target({ElementType.METHOD})
|
||||||
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
|
@HttpMethod("PURGE")
|
||||||
|
public @interface PURGE {
|
||||||
|
}
|
|
@ -0,0 +1,66 @@
|
||||||
|
package org.gcube.rest.utils;
|
||||||
|
|
||||||
|
import java.io.BufferedReader;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.io.InputStreamReader;
|
||||||
|
import java.io.UnsupportedEncodingException;
|
||||||
|
import java.net.HttpURLConnection;
|
||||||
|
|
||||||
|
import javax.ws.rs.WebApplicationException;
|
||||||
|
import javax.ws.rs.core.HttpHeaders;
|
||||||
|
import javax.ws.rs.core.MediaType;
|
||||||
|
import javax.ws.rs.core.Response.Status;
|
||||||
|
|
||||||
|
import org.gcube.common.gxhttp.request.GXHTTPStringRequest;
|
||||||
|
import org.gcube.keycloack.KeycloackClientParams_UNUSED;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Luca Frosini (ISTI - CNR)
|
||||||
|
*/
|
||||||
|
public class HTTPUtility {
|
||||||
|
|
||||||
|
private static final Logger logger = LoggerFactory.getLogger(HTTPUtility.class);
|
||||||
|
|
||||||
|
public static StringBuilder getStringBuilder(InputStream inputStream) throws IOException {
|
||||||
|
StringBuilder result = new StringBuilder();
|
||||||
|
try(BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream))) {
|
||||||
|
String line;
|
||||||
|
while((line = reader.readLine()) != null) {
|
||||||
|
result.append(line);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static GXHTTPStringRequest createGXHTTPStringRequest(String url, String path, boolean post)
|
||||||
|
throws UnsupportedEncodingException {
|
||||||
|
GXHTTPStringRequest gxhttpStringRequest = GXHTTPStringRequest.newRequest(url);
|
||||||
|
gxhttpStringRequest.from(KeycloackClientParams_UNUSED.CATALOGUE_NAME);
|
||||||
|
if(post) {
|
||||||
|
gxhttpStringRequest.header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON);
|
||||||
|
}
|
||||||
|
gxhttpStringRequest.header(HttpHeaders.ACCEPT, MediaType.APPLICATION_JSON);
|
||||||
|
gxhttpStringRequest.path(path);
|
||||||
|
return gxhttpStringRequest;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getResultAsString(HttpURLConnection httpURLConnection) throws IOException {
|
||||||
|
int responseCode = httpURLConnection.getResponseCode();
|
||||||
|
if(responseCode >= Status.BAD_REQUEST.getStatusCode()) {
|
||||||
|
Status status = Status.fromStatusCode(responseCode);
|
||||||
|
InputStream inputStream = httpURLConnection.getErrorStream();
|
||||||
|
StringBuilder result = getStringBuilder(inputStream);
|
||||||
|
logger.trace(result.toString());
|
||||||
|
throw new WebApplicationException(result.toString(), status);
|
||||||
|
}
|
||||||
|
InputStream inputStream = httpURLConnection.getInputStream();
|
||||||
|
String ret = getStringBuilder(inputStream).toString();
|
||||||
|
logger.trace("Got Respose is {}", ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,12 @@
|
||||||
|
package org.gcube.utils.IdmConstantsaa;
|
||||||
|
|
||||||
|
public class IdmConstants {
|
||||||
|
|
||||||
|
public static final String SERVICE_CLASS = "org.gcube.data-catalogue";
|
||||||
|
public static final String SERVICE_NAME = "gcat";
|
||||||
|
|
||||||
|
public final static String CONFIGURATION_CATEGORY = IdmConstants.SERVICE_CLASS;
|
||||||
|
public final static String CONFIGURATION_NAME = IdmConstants.SERVICE_NAME + "-configuration";
|
||||||
|
|
||||||
|
public static final String SERVICE_ENTRY_NAME = "org.gcube.gcat.ResourceInitializer";
|
||||||
|
}
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,5 @@
|
||||||
|
/LICENSE.md
|
||||||
|
/README.md
|
||||||
|
/changelog.xml
|
||||||
|
/gcube-app.xml
|
||||||
|
/CHANGELOG.md
|
|
@ -0,0 +1,19 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE xml>
|
||||||
|
<web-app>
|
||||||
|
<servlet>
|
||||||
|
<servlet-name>org.gcube.acme.ResourceInitializer</servlet-name>
|
||||||
|
</servlet>
|
||||||
|
<servlet-mapping>
|
||||||
|
<servlet-name>default</servlet-name>
|
||||||
|
<url-pattern>/docs/*</url-pattern>
|
||||||
|
</servlet-mapping>
|
||||||
|
<servlet-mapping>
|
||||||
|
<servlet-name>default</servlet-name>
|
||||||
|
<url-pattern>/api-docs/*</url-pattern>
|
||||||
|
</servlet-mapping>
|
||||||
|
<servlet-mapping>
|
||||||
|
<servlet-name>org.gcube.acme.ResourceInitializer</servlet-name>
|
||||||
|
<url-pattern>/*</url-pattern>
|
||||||
|
</servlet-mapping>
|
||||||
|
</web-app>
|
|
@ -0,0 +1,25 @@
|
||||||
|
.d4science_intro {
|
||||||
|
top: 0;
|
||||||
|
z-index: 2000;
|
||||||
|
position: fixed;
|
||||||
|
display: block ruby;
|
||||||
|
padding: 10px;
|
||||||
|
background: white;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.navbar-fixed-top {
|
||||||
|
top: 100px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sidebar {
|
||||||
|
top: 160px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.navbar {
|
||||||
|
margin-bottom: 40px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.main {
|
||||||
|
top: 90px;
|
||||||
|
}
|
Loading…
Reference in New Issue