Compare commits
5 Commits
Author | SHA1 | Date |
---|---|---|
Alfredo Oliviero | c81ef827aa | |
Alfredo Oliviero | 74b53ae193 | |
Alfredo Oliviero | 74a9f60d77 | |
Alfredo Oliviero | fd2739690d | |
Alfredo Oliviero | 711af67199 |
|
@ -4,6 +4,7 @@ FROM d4science/smartgears-distribution:4.0.0-SNAPSHOT-java$JAVA_VERSION-tomcat10
|
|||
|
||||
COPY ./docker/logback.xml /etc/
|
||||
COPY ./docker/container.ini /etc/
|
||||
COPY ./docker/*.gcubekey /tomcat/lib
|
||||
COPY ./target/helloworld.war /tomcat/webapps/
|
||||
|
||||
EXPOSE 8080
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
|
||||
# optional, for local develop in docker containers
|
||||
├── docker/
|
||||
│ ├── ontainer.ini
|
||||
│ ├── container.ini
|
||||
│ └── logback.xml
|
||||
├── docker-compose.yaml
|
||||
└── Dockerfile
|
||||
|
@ -33,7 +33,6 @@
|
|||
* mode: [online/offline]: register the service on IS. use offline for local docker instances
|
||||
|
||||
|
||||
|
||||
# EXCECUTION
|
||||
|
||||
start the docker container
|
||||
|
|
|
@ -1,26 +1,36 @@
|
|||
#!/bin/bash
|
||||
|
||||
|
||||
accepted_java_versions=(11 17)
|
||||
|
||||
NAME=smartgears-helloworld
|
||||
PORT=8081
|
||||
DEBUG_PORT=5005
|
||||
DEBUG=false
|
||||
COMPILE=true
|
||||
java_version=11
|
||||
|
||||
|
||||
CONTAINERFILE=docker/container.ini
|
||||
|
||||
|
||||
################################################################################
|
||||
# Help #
|
||||
################################################################################
|
||||
Help()
|
||||
{
|
||||
# Display Help
|
||||
echo "build, create and run in docker the helloworld service"
|
||||
echo
|
||||
echo "Syntax: buildDistribution [-n arg] [-p arg] [-j arg] [-d arg?] [-h]"
|
||||
echo "options:"
|
||||
echo "-n arg specifies the docker image name (default is smartgears-helloworld)."
|
||||
echo "-p arg specifies the port to be exposed for the docker container to access the service (default 8081)"
|
||||
echo "-j arg specify java version (default is 11)"
|
||||
echo " accepted version are: ${accepted_java_versions[@]}"
|
||||
echo "-d arg? enable java debug mode"
|
||||
echo " arg is the debug port (default is 5005)"
|
||||
echo "-h Print this Help."
|
||||
echo
|
||||
Help() {
|
||||
# Display Help
|
||||
echo "build, create and run in docker the helloworld service"
|
||||
echo
|
||||
echo "Syntax: buildDistribution [-n arg] [-p arg] [-j arg] [-d arg?] [-h]"
|
||||
echo "options:"
|
||||
echo "-s skip maven package"
|
||||
echo "-n arg specifies the docker image name (default is smartgears-helloworld)."
|
||||
echo "-p arg specifies the port to be exposed for the docker container to access the service (default $PORT)"
|
||||
echo "-j arg specify java version (default is $java_version)"
|
||||
echo " accepted version are: ${accepted_java_versions[@]}"
|
||||
echo "-d arg? enable java debug mode"
|
||||
echo " arg is the debug port (default is $DEBUG_PORT)"
|
||||
echo "-h Print this Help."
|
||||
echo
|
||||
}
|
||||
|
||||
################################################################################
|
||||
|
@ -31,38 +41,63 @@ Help()
|
|||
|
||||
set -e
|
||||
|
||||
OPTSTRING=":sn:p:d:j:?h"
|
||||
|
||||
NAME=smartgears-helloworld
|
||||
PORT=8081
|
||||
DEBUG_PORT=5005
|
||||
debug=false
|
||||
compile=false
|
||||
java_version=11
|
||||
|
||||
while getopts n:p:j:d?h flag
|
||||
do
|
||||
echo ${flag};
|
||||
case "${flag}" in
|
||||
n) NAME=${OPTARG};;
|
||||
p) PORT=${OPTARG};;
|
||||
d) debug=true && DEBUG_PORT=${OPTARG:-5005};;
|
||||
j) if [[ ${accepted_java_versions[@]} =~ ${OPTARG} ]]
|
||||
then java_version=${OPTARG};
|
||||
else echo "Invalid java version" && echo "accepted version are: ${accepted_java_versions[@]}" && exit 1;
|
||||
fi;;
|
||||
h) Help && exit 0 ;;
|
||||
*) echo "Invalid option" && exit 1 ;;
|
||||
while getopts $OPTSTRING opt; do
|
||||
# echo "Option -${opt} was triggered, Argument: ${OPTARG}"
|
||||
case "${opt}" in
|
||||
s) COMPILE=false && echo "compile $COMPILE" ;;
|
||||
n) NAME=${OPTARG} ;;
|
||||
p) PORT=${OPTARG} ;;
|
||||
d) DEBUG=true
|
||||
DEBUG_PORT=${OPTARG}
|
||||
echo "debug enabled, port $DEBUG_PORT"
|
||||
;;
|
||||
j) if [[ ${accepted_java_versions[@]} =~ ${OPTARG} ]]; then
|
||||
java_version=${OPTARG}
|
||||
else
|
||||
echo "Invalid java version" && echo "accepted version are: ${accepted_java_versions[@]}" && exit 1
|
||||
fi
|
||||
;;
|
||||
h) Help && exit 0 ;;
|
||||
:) # matched when an option that is expected to have an argument is passed without one
|
||||
if [ ${OPTARG} = "d" ]; then
|
||||
DEBUG=true
|
||||
echo "debug enabled, port $DEBUG_PORT"
|
||||
else
|
||||
# matched when an option that is expected to have an argument is passed without one
|
||||
echo "Option -${OPTARG} requires an argument."
|
||||
exit 1
|
||||
fi
|
||||
;;
|
||||
?) # match any invalid option that is passed
|
||||
echo "Invalid option: -${OPTARG}."
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
mvn clean package
|
||||
if ! test -e "$CONTAINERFILE"; then
|
||||
echo "missing docker/container.ini file.
|
||||
|
||||
Create and configurate your container.config.ini file from container.default.ini,
|
||||
then create a symbolic link to container.ini
|
||||
|
||||
cp docker/container.default.ini docker/container.configuration.ini
|
||||
ln -s docker/container.configuration.ini docker/container.ini"
|
||||
exit 1;
|
||||
fi
|
||||
|
||||
if [ $COMPILE = true ]; then
|
||||
mvn clean package
|
||||
else
|
||||
echo "skipping mvn package"
|
||||
fi
|
||||
|
||||
docker build -t $NAME --build-arg JAVA_VERSION=${java_version} .
|
||||
|
||||
if [ $debug = false ] ; then
|
||||
docker run -p $PORT:8080 $NAME
|
||||
if [ $DEBUG = false ]; then
|
||||
docker run -p $PORT:8080 $NAME
|
||||
else
|
||||
docker run -p $PORT:8080 -p $DEBUG_PORT:5005 -e JAVA_TOOL_OPTIONS="-agentlib:jdwp=transport=dt_socket,address=*:5005,server=y,suspend=y" $NAME
|
||||
docker run -p $PORT:8080 -p $DEBUG_PORT:5005 -e JAVA_TOOL_OPTIONS="-agentlib:jdwp=transport=dt_socket,address=*:5005,server=y,suspend=y" $NAME
|
||||
fi
|
||||
|
||||
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
container*.ini
|
||||
!container.default.ini
|
||||
*.gcubekey
|
|
@ -1,23 +0,0 @@
|
|||
[node]
|
||||
mode = offline
|
||||
hostname = mb-lelii.isti.cnr.it
|
||||
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
|
|
@ -0,0 +1 @@
|
|||
container.alf.ini
|
|
@ -8,51 +8,170 @@
|
|||
},
|
||||
"item": [
|
||||
{
|
||||
"name": "hello TOKEN PARAM",
|
||||
"name": "[UAT] Obtain CONTEXT id token for a user",
|
||||
"event": [
|
||||
{
|
||||
"listen": "test",
|
||||
"script": {
|
||||
"exec": [
|
||||
"var jsonData = JSON.parse(responseBody);",
|
||||
"pm.collectionVariables.set(\"access_token\", jsonData.access_token);",
|
||||
"pm.collectionVariables.set(\"refresh_token\", jsonData.refresh_token);",
|
||||
""
|
||||
],
|
||||
"type": "text/javascript",
|
||||
"packages": {}
|
||||
}
|
||||
},
|
||||
{
|
||||
"listen": "prerequest",
|
||||
"script": {
|
||||
"exec": [
|
||||
""
|
||||
],
|
||||
"type": "text/javascript",
|
||||
"packages": {}
|
||||
}
|
||||
}
|
||||
],
|
||||
"request": {
|
||||
"auth": {
|
||||
"type": "noauth"
|
||||
},
|
||||
"method": "GET",
|
||||
"method": "POST",
|
||||
"header": [
|
||||
{
|
||||
"key": "Content-Type",
|
||||
"name": "Content-Type",
|
||||
"value": "application/x-www-form-urlencoded",
|
||||
"type": "text"
|
||||
},
|
||||
{
|
||||
"key": "X-D4Science-Context",
|
||||
"value": "{{url-encoded-context}}",
|
||||
"type": "text"
|
||||
},
|
||||
{
|
||||
"key": "",
|
||||
"value": "{{token}}",
|
||||
"value": "",
|
||||
"type": "text",
|
||||
"disabled": true
|
||||
}
|
||||
],
|
||||
"body": {
|
||||
"mode": "urlencoded",
|
||||
"urlencoded": [
|
||||
{
|
||||
"key": "client_id",
|
||||
"value": "{{client-id-user}}",
|
||||
"type": "text"
|
||||
},
|
||||
{
|
||||
"key": "username",
|
||||
"value": "{{username}}",
|
||||
"type": "text"
|
||||
},
|
||||
{
|
||||
"key": "password",
|
||||
"value": "{{password}}",
|
||||
"type": "text"
|
||||
},
|
||||
{
|
||||
"key": "grant_type",
|
||||
"value": "password",
|
||||
"type": "text"
|
||||
}
|
||||
]
|
||||
},
|
||||
"url": {
|
||||
"raw": "{{keycloak_url}}/realms/{{realm}}/protocol/openid-connect/token",
|
||||
"host": [
|
||||
"{{keycloak_url}}"
|
||||
],
|
||||
"path": [
|
||||
"realms",
|
||||
"{{realm}}",
|
||||
"protocol",
|
||||
"openid-connect",
|
||||
"token"
|
||||
]
|
||||
},
|
||||
"description": "Obtain UAT = user access token from a user in realm"
|
||||
},
|
||||
"response": []
|
||||
},
|
||||
{
|
||||
"name": "[UAT] refresh CONTEXT token",
|
||||
"event": [
|
||||
{
|
||||
"listen": "test",
|
||||
"script": {
|
||||
"exec": [
|
||||
"var jsonData = JSON.parse(responseBody);",
|
||||
"",
|
||||
"pm.collectionVariables.set(\"access_token\", jsonData.access_token);",
|
||||
"pm.collectionVariables.set(\"refresh_token\", jsonData.refresh_token);",
|
||||
""
|
||||
],
|
||||
"type": "text/javascript",
|
||||
"packages": {}
|
||||
}
|
||||
}
|
||||
],
|
||||
"request": {
|
||||
"method": "POST",
|
||||
"header": [
|
||||
{
|
||||
"key": "X-D4Science-Context",
|
||||
"value": "{{url-encoded-context}}",
|
||||
"type": "text"
|
||||
}
|
||||
],
|
||||
"body": {
|
||||
"mode": "urlencoded",
|
||||
"urlencoded": [
|
||||
{
|
||||
"key": "grant_type",
|
||||
"value": "refresh_token",
|
||||
"type": "text"
|
||||
},
|
||||
{
|
||||
"key": "client_id",
|
||||
"value": "{{client-id-user}}",
|
||||
"type": "text"
|
||||
},
|
||||
{
|
||||
"key": "refresh_token",
|
||||
"value": "{{refresh_token}}",
|
||||
"type": "text"
|
||||
},
|
||||
{
|
||||
"key": "client_secret",
|
||||
"value": "{{service_client_secret}}",
|
||||
"type": "text",
|
||||
"disabled": true
|
||||
}
|
||||
]
|
||||
},
|
||||
"url": {
|
||||
"raw": "{{base_url}}/{{application}}/hello?gcube-token={{gcube_token}}",
|
||||
"raw": "{{keycloak_url}}/realms/{{realm}}/protocol/openid-connect/token",
|
||||
"host": [
|
||||
"{{base_url}}"
|
||||
"{{keycloak_url}}"
|
||||
],
|
||||
"path": [
|
||||
"{{application}}",
|
||||
"hello"
|
||||
],
|
||||
"query": [
|
||||
{
|
||||
"key": "gcube-token",
|
||||
"value": "{{gcube_token}}"
|
||||
}
|
||||
"realms",
|
||||
"{{realm}}",
|
||||
"protocol",
|
||||
"openid-connect",
|
||||
"token"
|
||||
]
|
||||
}
|
||||
},
|
||||
"response": []
|
||||
},
|
||||
{
|
||||
"name": "hello BEARER",
|
||||
"name": "hello",
|
||||
"request": {
|
||||
"auth": {
|
||||
"type": "bearer",
|
||||
"bearer": [
|
||||
{
|
||||
"key": "token",
|
||||
"value": "{{uma_token}}",
|
||||
"type": "string"
|
||||
}
|
||||
]
|
||||
},
|
||||
"method": "GET",
|
||||
"header": [],
|
||||
"url": {
|
||||
|
@ -69,45 +188,8 @@
|
|||
"response": []
|
||||
},
|
||||
{
|
||||
"name": "details TOKEN PARAM",
|
||||
"name": "details",
|
||||
"request": {
|
||||
"auth": {
|
||||
"type": "noauth"
|
||||
},
|
||||
"method": "GET",
|
||||
"header": [],
|
||||
"url": {
|
||||
"raw": "{{base_url}}/{{application}}/details?gcube-token={{gcube_token}}",
|
||||
"host": [
|
||||
"{{base_url}}"
|
||||
],
|
||||
"path": [
|
||||
"{{application}}",
|
||||
"details"
|
||||
],
|
||||
"query": [
|
||||
{
|
||||
"key": "gcube-token",
|
||||
"value": "{{gcube_token}}"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"response": []
|
||||
},
|
||||
{
|
||||
"name": "details BEARER",
|
||||
"request": {
|
||||
"auth": {
|
||||
"type": "bearer",
|
||||
"bearer": [
|
||||
{
|
||||
"key": "token",
|
||||
"value": "{{uma_token}}",
|
||||
"type": "string"
|
||||
}
|
||||
]
|
||||
},
|
||||
"method": "GET",
|
||||
"header": [],
|
||||
"url": {
|
||||
|
@ -123,6 +205,25 @@
|
|||
},
|
||||
"response": []
|
||||
},
|
||||
{
|
||||
"name": "auth org member",
|
||||
"request": {
|
||||
"method": "GET",
|
||||
"header": [],
|
||||
"url": {
|
||||
"raw": "{{base_url}}/{{application}}/auth/org_member",
|
||||
"host": [
|
||||
"{{base_url}}"
|
||||
],
|
||||
"path": [
|
||||
"{{application}}",
|
||||
"auth",
|
||||
"org_member"
|
||||
]
|
||||
}
|
||||
},
|
||||
"response": []
|
||||
},
|
||||
{
|
||||
"name": "guest",
|
||||
"request": {
|
||||
|
@ -145,75 +246,8 @@
|
|||
"response": []
|
||||
},
|
||||
{
|
||||
"name": "auth org member BEARER",
|
||||
"name": "auth member",
|
||||
"request": {
|
||||
"auth": {
|
||||
"type": "bearer",
|
||||
"bearer": [
|
||||
{
|
||||
"key": "token",
|
||||
"value": "{{uma_token}}",
|
||||
"type": "string"
|
||||
}
|
||||
]
|
||||
},
|
||||
"method": "GET",
|
||||
"header": [],
|
||||
"url": {
|
||||
"raw": "{{base_url}}/{{application}}/auth/org_member",
|
||||
"host": [
|
||||
"{{base_url}}"
|
||||
],
|
||||
"path": [
|
||||
"{{application}}",
|
||||
"auth",
|
||||
"org_member"
|
||||
]
|
||||
}
|
||||
},
|
||||
"response": []
|
||||
},
|
||||
{
|
||||
"name": "auth org member TOKEN PARAM",
|
||||
"request": {
|
||||
"auth": {
|
||||
"type": "noauth"
|
||||
},
|
||||
"method": "GET",
|
||||
"header": [],
|
||||
"url": {
|
||||
"raw": "{{base_url}}/{{application}}/auth/org_member?gcube-token={{gcube_token}}",
|
||||
"host": [
|
||||
"{{base_url}}"
|
||||
],
|
||||
"path": [
|
||||
"{{application}}",
|
||||
"auth",
|
||||
"org_member"
|
||||
],
|
||||
"query": [
|
||||
{
|
||||
"key": "gcube-token",
|
||||
"value": "{{gcube_token}}"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"response": []
|
||||
},
|
||||
{
|
||||
"name": "auth member BEARER",
|
||||
"request": {
|
||||
"auth": {
|
||||
"type": "bearer",
|
||||
"bearer": [
|
||||
{
|
||||
"key": "token",
|
||||
"value": "{{uma_token}}",
|
||||
"type": "string"
|
||||
}
|
||||
]
|
||||
},
|
||||
"method": "GET",
|
||||
"header": [],
|
||||
"url": {
|
||||
|
@ -231,27 +265,31 @@
|
|||
"response": []
|
||||
},
|
||||
{
|
||||
"name": "auth member TOKEN PARAM",
|
||||
"name": "test keycloak",
|
||||
"request": {
|
||||
"auth": {
|
||||
"type": "noauth"
|
||||
},
|
||||
"method": "GET",
|
||||
"header": [],
|
||||
"header": [
|
||||
{
|
||||
"key": "gcube-token",
|
||||
"value": "{{gcube_token}}",
|
||||
"type": "text",
|
||||
"disabled": true
|
||||
}
|
||||
],
|
||||
"url": {
|
||||
"raw": "{{base_url}}/{{application}}/auth/member?gcube-token={{gcube_token}}",
|
||||
"raw": "{{base_url}}/{{application}}/keycloak",
|
||||
"host": [
|
||||
"{{base_url}}"
|
||||
],
|
||||
"path": [
|
||||
"{{application}}",
|
||||
"auth",
|
||||
"member"
|
||||
"keycloak"
|
||||
],
|
||||
"query": [
|
||||
{
|
||||
"key": "gcube-token",
|
||||
"value": "{{gcube_token}}"
|
||||
"key": "client_id",
|
||||
"value": "{{current_client-id}}",
|
||||
"disabled": true
|
||||
}
|
||||
]
|
||||
}
|
||||
|
@ -259,6 +297,16 @@
|
|||
"response": []
|
||||
}
|
||||
],
|
||||
"auth": {
|
||||
"type": "bearer",
|
||||
"bearer": [
|
||||
{
|
||||
"key": "token",
|
||||
"value": "{{access_token}}",
|
||||
"type": "string"
|
||||
}
|
||||
]
|
||||
},
|
||||
"event": [
|
||||
{
|
||||
"listen": "prerequest",
|
||||
|
@ -285,20 +333,48 @@
|
|||
"value": "http://localhost:8081",
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"key": "keycloak_url",
|
||||
"value": "https://accounts.dev.d4science.org/auth",
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"key": "url-encoded-context",
|
||||
"value": "%2Fgcube%2Fdevsec%2FdevVRE",
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"key": "realm",
|
||||
"value": "d4science",
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"key": "client-id-user",
|
||||
"value": "next.d4science.org",
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"key": "application",
|
||||
"value": "helloworld",
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"key": "gcube_token",
|
||||
"key": "username",
|
||||
"value": "",
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"key": "uma_token",
|
||||
"key": "password",
|
||||
"value": "",
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"key": "access_token",
|
||||
"value": ""
|
||||
},
|
||||
{
|
||||
"key": "refresh_token",
|
||||
"value": ""
|
||||
}
|
||||
]
|
||||
}
|
66
pom.xml
66
pom.xml
|
@ -24,6 +24,10 @@
|
|||
|
||||
<!-- OPTIONAL. for authorization-control-library -->
|
||||
<aspectj-plugin.version>1.14.0</aspectj-plugin.version>
|
||||
|
||||
<!-- bind jackson version to avoid inconsistences with keycloak dependencies -->
|
||||
<jackson.version>2.15.3</jackson.version>
|
||||
|
||||
</properties>
|
||||
|
||||
<scm>
|
||||
|
@ -48,13 +52,56 @@
|
|||
</dependencyManagement>
|
||||
|
||||
<dependencies>
|
||||
|
||||
<!-- <dependency>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<artifactId>keycloak-admin-client-jakarta</artifactId>
|
||||
<version>21.1.2</version>
|
||||
</dependency>
|
||||
|
||||
<!--
|
||||
Keycloak use a older version of jackson (2.12.3).
|
||||
some jackson libraries are imported only by keyclock,
|
||||
not by smartgears so it mixed different versions.
|
||||
We explicity import its jackson dependency to ovverride the version
|
||||
-->
|
||||
<dependency>
|
||||
<groupId>com.fasterxml.jackson.core</groupId>
|
||||
<artifactId>jackson-core</artifactId>
|
||||
<version>${jackson.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.fasterxml.jackson.jaxrs</groupId>
|
||||
<artifactId>jackson-jaxrs-base</artifactId>
|
||||
<version>${jackson.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.fasterxml.jackson.jaxrs</groupId>
|
||||
<artifactId>jackson-jaxrs-json-provider</artifactId>
|
||||
<version>${jackson.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.fasterxml.jackson.module</groupId>
|
||||
<artifactId>jackson-module-jaxb-annotations</artifactId>
|
||||
<version>${jackson.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>jakarta.activation</groupId>
|
||||
<artifactId>jakarta.activation-api</artifactId>
|
||||
<version>2.1.2</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<artifactId>keycloak-admin-client</artifactId>
|
||||
<version>21.1.2</version>
|
||||
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>org.jboss.spec.javax.ws.rs</groupId>
|
||||
<artifactId>jboss-jaxrs-api_3.0_spec</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.aspectj</groupId>
|
||||
<artifactId>aspectjrt</artifactId>
|
||||
|
@ -91,7 +138,6 @@
|
|||
<artifactId>jersey-cdi2-se</artifactId>
|
||||
</dependency>
|
||||
|
||||
|
||||
<!-- add jackson as json provider -->
|
||||
<dependency>
|
||||
<groupId>org.glassfish.jersey.media</groupId>
|
||||
|
@ -110,7 +156,8 @@
|
|||
<!-- OPTIONAL generate the war in a different folder, that will be
|
||||
mounted on docker
|
||||
container -->
|
||||
<!-- <plugin>
|
||||
<!--
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-war-plugin</artifactId>
|
||||
<version>2.3</version>
|
||||
|
@ -118,7 +165,8 @@
|
|||
<warName>identity-manager</warName>
|
||||
<outputDirectory>tomcat/webapps</outputDirectory>
|
||||
</configuration>
|
||||
</plugin> -->
|
||||
</plugin>
|
||||
-->
|
||||
|
||||
<!-- OPTIONAL. authorization-control-library: add this plugin if you
|
||||
want to use gcube
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
package org.gcube.service.helloworld.serializers;
|
||||
|
||||
import org.gcube.common.resources.gcore.ServiceEndpoint;
|
||||
import org.gcube.common.security.Owner;
|
||||
import org.gcube.smartgears.configuration.container.ContainerConfiguration;
|
||||
import org.gcube.smartgears.context.container.ContainerContext;
|
||||
import org.gcube.smartgears.security.SimpleCredentials;
|
||||
|
@ -14,7 +16,7 @@ import com.fasterxml.jackson.databind.module.SimpleModule;
|
|||
*
|
||||
*/
|
||||
|
||||
public class ContextSerializator {
|
||||
public class CustomSerializator {
|
||||
private static ObjectMapper serializer = null;
|
||||
|
||||
public static ObjectMapper getSerializer() {
|
||||
|
@ -24,7 +26,9 @@ public class ContextSerializator {
|
|||
// module.addSerializer(Owner.class, new OwnerSerializer());
|
||||
|
||||
module.addSerializer(ContainerConfiguration.class, new ContainerConfigurationSerializer());
|
||||
module.addSerializer(Owner.class, new OwnerSerializer());
|
||||
module.addSerializer(ContainerContext.class, new ContainerContextSerializer());
|
||||
module.addSerializer(ServiceEndpoint.AccessPoint.class, new ServiceEndpointAccessPointSerializer());
|
||||
module.addSerializer(SimpleCredentials.class, new SimpleCredentialsSerializer());
|
||||
|
||||
om.registerModule(module);
|
|
@ -0,0 +1,64 @@
|
|||
package org.gcube.service.helloworld.serializers;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import org.gcube.common.encryption.encrypter.StringEncrypter;
|
||||
import org.gcube.common.resources.gcore.ServiceEndpoint;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonGenerator;
|
||||
import com.fasterxml.jackson.databind.SerializerProvider;
|
||||
import com.fasterxml.jackson.databind.ser.std.StdSerializer;
|
||||
|
||||
/**
|
||||
* Jackson serializer for ServiceEndpoint.AccessPoint
|
||||
*
|
||||
* @author Alfredo Oliviero (ISTI-CNR)
|
||||
*
|
||||
*/
|
||||
|
||||
public class ServiceEndpointAccessPointSerializer extends StdSerializer<ServiceEndpoint.AccessPoint> {
|
||||
|
||||
protected ServiceEndpointAccessPointSerializer(Class<ServiceEndpoint.AccessPoint> t) {
|
||||
super(t);
|
||||
}
|
||||
|
||||
public ServiceEndpointAccessPointSerializer() {
|
||||
super(ServiceEndpoint.AccessPoint.class, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void serialize(ServiceEndpoint.AccessPoint accessPoint, JsonGenerator jgen, SerializerProvider provider)
|
||||
throws IOException {
|
||||
jgen.writeStartObject();
|
||||
|
||||
String error = null;
|
||||
String clientSecret = null;
|
||||
try {
|
||||
clientSecret = StringEncrypter.getEncrypter().decrypt(accessPoint.password());
|
||||
} catch (Exception e) {
|
||||
error = e.getMessage();
|
||||
}
|
||||
|
||||
jgen.writeStringField("address", accessPoint.address());
|
||||
jgen.writeStringField("name", accessPoint.name());
|
||||
jgen.writeStringField("description", accessPoint.description());
|
||||
|
||||
try {
|
||||
jgen.writeStringField("username", accessPoint.username());
|
||||
} catch (Exception e) {
|
||||
jgen.writeStringField("username", null);
|
||||
}
|
||||
try {
|
||||
jgen.writeStringField("tostring", accessPoint.toString());
|
||||
} catch (Exception e) {
|
||||
jgen.writeStringField("tostring", null);
|
||||
}
|
||||
if (error != null) {
|
||||
jgen.writeStringField("key_error", error);
|
||||
jgen.writeBooleanField("key_decoded", false);
|
||||
} else {
|
||||
jgen.writeBooleanField("key_decoded", true);
|
||||
}
|
||||
jgen.writeEndObject();
|
||||
}
|
||||
}
|
|
@ -13,7 +13,7 @@ import org.gcube.common.security.Owner;
|
|||
import org.gcube.common.security.providers.SecretManagerProvider;
|
||||
import org.gcube.common.security.secrets.Secret;
|
||||
import org.gcube.service.helloworld.HelloWorldManager;
|
||||
import org.gcube.service.helloworld.serializers.ContextSerializator;
|
||||
import org.gcube.service.helloworld.serializers.CustomSerializator;
|
||||
import org.gcube.smartgears.ContextProvider;
|
||||
import org.gcube.smartgears.annotations.ManagedBy;
|
||||
import org.gcube.smartgears.context.container.ContainerContext;
|
||||
|
@ -70,7 +70,7 @@ public class HelloService {
|
|||
ContainerContext container = ContextProvider.get().container();
|
||||
data.put("container", container);
|
||||
|
||||
ObjectMapper objectMapper = ContextSerializator.getSerializer();
|
||||
ObjectMapper objectMapper = CustomSerializator.getSerializer();
|
||||
|
||||
try {
|
||||
String jsonData = objectMapper.writeValueAsString(data);
|
||||
|
|
|
@ -0,0 +1,95 @@
|
|||
package org.gcube.service.helloworld.services;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.gcube.common.resources.gcore.ServiceEndpoint.AccessPoint;
|
||||
import org.gcube.service.helloworld.HelloWorldManager;
|
||||
import org.gcube.service.helloworld.serializers.CustomSerializator;
|
||||
import org.gcube.service.helloworld.utils.InfrastrctureServiceClient;
|
||||
import org.gcube.smartgears.annotations.ManagedBy;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
|
||||
import jakarta.ws.rs.DefaultValue;
|
||||
import jakarta.ws.rs.GET;
|
||||
import jakarta.ws.rs.NotFoundException;
|
||||
import jakarta.ws.rs.Path;
|
||||
import jakarta.ws.rs.Produces;
|
||||
import jakarta.ws.rs.QueryParam;
|
||||
import jakarta.ws.rs.core.Response;
|
||||
|
||||
/**
|
||||
* service example that shows how to query IS and how to access Keycloak
|
||||
*
|
||||
* @author Alfredo Oliviero (ISTI - CNR)
|
||||
*/
|
||||
|
||||
@ManagedBy(HelloWorldManager.class)
|
||||
@Path("is")
|
||||
public class IsService {
|
||||
|
||||
private final static Logger logger = LoggerFactory.getLogger(IsService.class);
|
||||
|
||||
private final static String RUNTIME_RESOURCE_NAME = "IAM";
|
||||
private final static String CATEGORY = "Service";
|
||||
private final static String REALM_D4S = "d4science";
|
||||
private final static boolean IS_ROOT_SERVICE = true;
|
||||
|
||||
public static String getClientIdContext(String context) {
|
||||
return context.replace("/", "%2F");
|
||||
}
|
||||
|
||||
@GET
|
||||
@Path("/test")
|
||||
@Produces({ "application/json;charset=UTF-8", "application/vnd.api+json" })
|
||||
public Response test(
|
||||
|
||||
@QueryParam("resource") @DefaultValue(RUNTIME_RESOURCE_NAME) String resourceName,
|
||||
@QueryParam("category") @DefaultValue(CATEGORY) String categoryName,
|
||||
@QueryParam("realm") @DefaultValue(REALM_D4S) String realm,
|
||||
@QueryParam("is_root") @DefaultValue("" + IS_ROOT_SERVICE) boolean is_root) {
|
||||
|
||||
return this.queryIS(resourceName, categoryName, realm, is_root);
|
||||
}
|
||||
|
||||
@GET
|
||||
@Path("/query")
|
||||
@Produces({ "application/json;charset=UTF-8", "application/vnd.api+json" })
|
||||
public Response queryIS(
|
||||
|
||||
@QueryParam("resource") String resourceName,
|
||||
@QueryParam("category") String categoryName,
|
||||
@QueryParam("realm") @DefaultValue(REALM_D4S) String realm,
|
||||
@QueryParam("is_root") @DefaultValue("false") boolean is_root) {
|
||||
try {
|
||||
|
||||
List<AccessPoint> accessPoints = InfrastrctureServiceClient.getAccessPointsFromIS(
|
||||
resourceName,
|
||||
categoryName,
|
||||
realm,
|
||||
is_root);
|
||||
|
||||
if (accessPoints.size() == 0) {
|
||||
String error_log = "Unable to retrieve service endpoint " + REALM_D4S;
|
||||
|
||||
logger.error(error_log);
|
||||
throw new NotFoundException(error_log);
|
||||
}
|
||||
|
||||
ObjectMapper objectMapper = CustomSerializator.getSerializer();
|
||||
|
||||
String jsonData = objectMapper.writeValueAsString(accessPoints);
|
||||
return Response.ok(jsonData).build();
|
||||
|
||||
} catch (JsonProcessingException e) {
|
||||
e.printStackTrace();
|
||||
return Response.serverError().build();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return Response.serverError().build();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,166 @@
|
|||
package org.gcube.service.helloworld.services;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.gcube.common.encryption.encrypter.StringEncrypter;
|
||||
import org.gcube.common.resources.gcore.ServiceEndpoint;
|
||||
import org.gcube.service.helloworld.HelloWorldManager;
|
||||
import org.gcube.service.helloworld.serializers.CustomSerializator;
|
||||
import org.gcube.service.helloworld.utils.InfrastrctureServiceClient;
|
||||
import org.gcube.smartgears.annotations.ManagedBy;
|
||||
import org.keycloak.OAuth2Constants;
|
||||
import org.keycloak.admin.client.Keycloak;
|
||||
import org.keycloak.admin.client.KeycloakBuilder;
|
||||
import org.keycloak.admin.client.resource.ClientResource;
|
||||
import org.keycloak.admin.client.resource.ClientsResource;
|
||||
import org.keycloak.admin.client.resource.RealmResource;
|
||||
import org.keycloak.admin.client.resource.RoleResource;
|
||||
import org.keycloak.admin.client.resource.RolesResource;
|
||||
import org.keycloak.representations.idm.ClientRepresentation;
|
||||
import org.keycloak.representations.idm.RoleRepresentation;
|
||||
import org.keycloak.representations.idm.UserRepresentation;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
|
||||
import jakarta.ws.rs.GET;
|
||||
import jakarta.ws.rs.NotFoundException;
|
||||
import jakarta.ws.rs.Path;
|
||||
import jakarta.ws.rs.Produces;
|
||||
import jakarta.ws.rs.QueryParam;
|
||||
import jakarta.ws.rs.DefaultValue;
|
||||
import jakarta.ws.rs.core.Response;
|
||||
|
||||
/**
|
||||
* service example that shows how to query IS and how to access Keycloak
|
||||
* @author Alfredo Oliviero (ISTI - CNR)
|
||||
*/
|
||||
|
||||
@ManagedBy(HelloWorldManager.class)
|
||||
@Path("")
|
||||
public class KeycloakTestService {
|
||||
|
||||
private final static Logger logger = LoggerFactory.getLogger(KeycloakTestService.class);
|
||||
|
||||
private final static String RUNTIME_RESOURCE_NAME = "IAM";
|
||||
private final static String CATEGORY = "Service";
|
||||
private final static String REALM_D4S = "d4science";
|
||||
private final static boolean IS_ROOT_SERVICE = true;
|
||||
|
||||
public static String getClientIdContext(String context) {
|
||||
return context.replace("/", "%2F");
|
||||
}
|
||||
|
||||
@GET
|
||||
@Path("/keycloak")
|
||||
@Produces({ "application/json;charset=UTF-8", "application/vnd.api+json" })
|
||||
public Response testKeycloak(
|
||||
@QueryParam("role-name") @DefaultValue("Member") String roleName) {
|
||||
|
||||
String client_contenxt = "/gcube";
|
||||
|
||||
List<String> usernames = new ArrayList<String>();
|
||||
try {
|
||||
|
||||
ServiceEndpoint.AccessPoint accessPoint = InfrastrctureServiceClient.getAccessPointFromIS(
|
||||
RUNTIME_RESOURCE_NAME,
|
||||
CATEGORY,
|
||||
REALM_D4S,
|
||||
IS_ROOT_SERVICE);
|
||||
|
||||
if (accessPoint == null) {
|
||||
String error_log = "Unable to retrieve service endpoint " + REALM_D4S;
|
||||
|
||||
logger.error(error_log);
|
||||
throw new NotFoundException(error_log);
|
||||
}
|
||||
|
||||
String keycloakURL = accessPoint.address();
|
||||
String realm = accessPoint.name();
|
||||
String clientId = accessPoint.username();
|
||||
String clientSecret = StringEncrypter.getEncrypter().decrypt(accessPoint.password());
|
||||
|
||||
Keycloak kclient = KeycloakBuilder.builder()
|
||||
.serverUrl(keycloakURL)
|
||||
.realm(realm)
|
||||
.grantType(OAuth2Constants.CLIENT_CREDENTIALS)
|
||||
.clientId(clientId) //
|
||||
.clientSecret(clientSecret).build();
|
||||
|
||||
List<UserRepresentation> users = searchByRole(kclient, realm, client_contenxt, roleName);
|
||||
if (users != null) {
|
||||
for (UserRepresentation user : users) {
|
||||
usernames.add(user.getUsername());
|
||||
}
|
||||
}
|
||||
|
||||
// responseBean.setResult(usernames);
|
||||
// responseBean.setSuccess(true);
|
||||
|
||||
ObjectMapper objectMapper = CustomSerializator.getSerializer();
|
||||
|
||||
String jsonData = objectMapper.writeValueAsString(usernames);
|
||||
return Response.ok(jsonData).build();
|
||||
|
||||
} catch (JsonProcessingException e) {
|
||||
e.printStackTrace();
|
||||
return Response.serverError().build();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return Response.serverError().build();
|
||||
}
|
||||
|
||||
// return Response.status(status).entity(responseBean).build();
|
||||
|
||||
}
|
||||
|
||||
private static List<UserRepresentation> searchByRole(Keycloak kclient, String krealm, String clientIdContext,
|
||||
String roleName) {
|
||||
|
||||
clientIdContext = getClientIdContext(clientIdContext);
|
||||
|
||||
logger.info("Searching by role: {}", roleName);
|
||||
|
||||
RealmResource realm_resource = kclient.realm(krealm);
|
||||
logger.info("{} realm_resource: {}", krealm, realm_resource);
|
||||
|
||||
ClientsResource clients_resource = realm_resource.clients();
|
||||
logger.info("clients_resource {}", clients_resource);
|
||||
|
||||
for (ClientRepresentation c : clients_resource.findAll()) {
|
||||
logger.info("listing all clients, found {} - {}", c.getClientId(), c.getId());
|
||||
}
|
||||
|
||||
List<ClientRepresentation> clients_repr = clients_resource.findByClientId(clientIdContext);
|
||||
logger.info("{} clients_repr: {}", clientIdContext, clients_repr);
|
||||
|
||||
String client_id = "";
|
||||
for (ClientRepresentation c_repr : clients_repr) {
|
||||
logger.info("searching {}, found client {} - {}", clientIdContext, c_repr.getClientId(), c_repr.getId());
|
||||
client_id = c_repr.getId();
|
||||
}
|
||||
|
||||
ClientResource client_resource = clients_resource.get(client_id);
|
||||
logger.info("client_resource {}", client_resource);
|
||||
|
||||
RolesResource roles_resource = client_resource.roles();
|
||||
for (RoleRepresentation r : roles_resource.list()) {
|
||||
logger.info("found role {}", r);
|
||||
}
|
||||
|
||||
logger.info("roles_resource {}", roles_resource);
|
||||
|
||||
RoleResource role_resource = roles_resource.get(roleName);
|
||||
logger.info("{} role_resource: {}", roleName, roles_resource);
|
||||
|
||||
List<UserRepresentation> users_repr = role_resource.getUserMembers(0, 100000);
|
||||
for (UserRepresentation u : users_repr) {
|
||||
logger.info("found user {}", u);
|
||||
}
|
||||
|
||||
return users_repr;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,126 @@
|
|||
package org.gcube.service.helloworld.utils;
|
||||
|
||||
import static org.gcube.resources.discovery.icclient.ICFactory.clientFor;
|
||||
import static org.gcube.resources.discovery.icclient.ICFactory.queryFor;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import org.gcube.common.resources.gcore.ServiceEndpoint;
|
||||
// import org.gcube.common.scope.api.ScopeProvider;
|
||||
import org.gcube.common.security.AuthorizedTasks;
|
||||
import org.gcube.common.security.secrets.Secret;
|
||||
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.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* Utility class to query EndPoints and search for AccessPoints from IS
|
||||
* @author Alfredo Oliviero (ISTI - CNR)
|
||||
*/
|
||||
|
||||
public class InfrastrctureServiceClient {
|
||||
private static final Logger logger = LoggerFactory.getLogger(InfrastrctureServiceClient.class);
|
||||
|
||||
/**
|
||||
* Retrieve endpoints information from IS for DB
|
||||
*
|
||||
* @return list of endpoints for ckan database
|
||||
* @throws Throwable
|
||||
*/
|
||||
public static List<ServiceEndpoint> getEndopintsFromIS(String resource_name, String category,
|
||||
boolean root_service) {
|
||||
SimpleQuery query = queryFor(ServiceEndpoint.class);
|
||||
|
||||
if (resource_name != null) {
|
||||
query.addCondition("$resource/Profile/Name/text() eq '" + resource_name + "'");
|
||||
}
|
||||
if (category != null){
|
||||
query.addCondition("$resource/Profile/Category/text() eq '" + category + "'");
|
||||
}
|
||||
DiscoveryClient<ServiceEndpoint> client = clientFor(ServiceEndpoint.class);
|
||||
|
||||
ApplicationContext ctx = ContextProvider.get();
|
||||
|
||||
String infra_context = "/" + ctx.container().configuration().infrastructure();
|
||||
Secret secret = ctx.container().authorizationProvider().getSecretForContext(infra_context);
|
||||
|
||||
List<ServiceEndpoint> endpoints = null;
|
||||
|
||||
try {
|
||||
if (root_service) {
|
||||
|
||||
endpoints = AuthorizedTasks.executeSafely(() -> {
|
||||
// esegui la query
|
||||
List<ServiceEndpoint> toReturn = client.submit(query);
|
||||
return toReturn;
|
||||
}, secret);
|
||||
} else {
|
||||
endpoints = client.submit(query);
|
||||
}
|
||||
} catch (Throwable e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
return endpoints;
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param resource_name
|
||||
* @param category
|
||||
* @param accessPointName
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
public static List<ServiceEndpoint.AccessPoint> getAccessPointsFromIS(String resource_name, String category,
|
||||
String accessPointName, boolean root_service) throws Exception {
|
||||
|
||||
List<ServiceEndpoint> resources = getEndopintsFromIS(resource_name, category, root_service);
|
||||
|
||||
if (resources.size() == 0) {
|
||||
logger.error("There is no Runtime Resource having name " + resource_name + " and Category "
|
||||
+ category + " in this scope.");
|
||||
return null;
|
||||
}
|
||||
|
||||
List<ServiceEndpoint.AccessPoint> response = new ArrayList<ServiceEndpoint.AccessPoint>();
|
||||
resources.forEach(res -> {
|
||||
Stream<ServiceEndpoint.AccessPoint> access_points_res = res.profile().accessPoints().stream();
|
||||
|
||||
if (accessPointName == null) {
|
||||
access_points_res = access_points_res.filter(ap -> ap.name().equals(accessPointName));
|
||||
}
|
||||
|
||||
access_points_res.forEach(a -> response.add(a));
|
||||
});
|
||||
return response;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param resource_name
|
||||
* @param category
|
||||
* @param accessPointName
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
public static ServiceEndpoint.AccessPoint getAccessPointFromIS(String resource_name, String category,
|
||||
String accessPointName, boolean root_service) throws Exception {
|
||||
|
||||
List<ServiceEndpoint.AccessPoint> access_points = getAccessPointsFromIS(resource_name, category, accessPointName, root_service);
|
||||
|
||||
if (access_points.size() == 0) {
|
||||
logger.error("Unable to retrieve service endpoint " + accessPointName);
|
||||
return null;
|
||||
}
|
||||
|
||||
return access_points.get(0);
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -8,8 +8,7 @@ import org.gcube.common.security.Owner;
|
|||
import org.gcube.smartgears.context.container.ContainerContext;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Lucio Lelii (ISTI-CNR)
|
||||
* @author Alfredo Oliviero (ISTI - CNR)
|
||||
*/
|
||||
|
||||
public class RestUtils {
|
||||
|
|
Loading…
Reference in New Issue