First Commit

This commit is contained in:
Giancarlo Panichi 2023-06-29 16:03:38 +02:00
commit 09b028d42a
385 changed files with 68166 additions and 0 deletions

18
.browserslistrc Normal file
View File

@ -0,0 +1,18 @@
# This file is used by the build system to adjust CSS and JS output to support the specified browsers below.
# For additional information regarding the format and rule options, please see:
# https://github.com/browserslist/browserslist#queries
# For the full list of supported browsers by the Angular framework, please see:
# https://angular.io/guide/browser-support
# You can see what browsers were selected by your queries by running:
# npx browserslist
last 1 Chrome version
last 1 Firefox version
last 2 Edge major versions
last 2 Safari major versions
last 2 iOS major versions
Firefox ESR
not IE 9-10 # Angular support for IE 9-10 has been deprecated and will be removed as of Angular v11. To opt-in, remove the 'not' prefix on this line.
not IE 11 # Angular supports IE 11 only as an opt-in. To opt-in, remove the 'not' prefix on this line.

51
.classpath Normal file
View File

@ -0,0 +1,51 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" output="target/classes" path="src/main/java">
<attributes>
<attribute name="optional" value="true"/>
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry excluding="**" kind="src" output="target/classes" path="src/main/resources"/>
<classpathentry kind="src" output="target/test-classes" path="src/test/java">
<attributes>
<attribute name="test" value="true"/>
<attribute name="optional" value="true"/>
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry excluding="**" kind="src" output="target/test-classes" path="src/test/resources">
<attributes>
<attribute name="test" value="true"/>
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-11">
<attributes>
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="con" path="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER">
<attributes>
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="src" path="target/generated-sources/annotations">
<attributes>
<attribute name="ignore_optional_problems" value="true"/>
<attribute name="optional" value="true"/>
<attribute name="maven.pomderived" value="true"/>
<attribute name="m2e-apt" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="src" output="target/test-classes" path="target/generated-test-sources/test-annotations">
<attributes>
<attribute name="optional" value="true"/>
<attribute name="maven.pomderived" value="true"/>
<attribute name="ignore_optional_problems" value="true"/>
<attribute name="m2e-apt" value="true"/>
<attribute name="test" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="output" path="target/classes"/>
</classpath>

25
.devcontainer/Dockerfile Normal file
View File

@ -0,0 +1,25 @@
# See here for image contents: https://github.com/microsoft/vscode-dev-containers/tree/v0.209.6/containers/java/.devcontainer/base.Dockerfile
# [Choice] Java version (use -bullseye variants on local arm64/Apple Silicon): 11, 17, 11-bullseye, 17-bullseye, 11-buster, 17-buster
ARG VARIANT="11"
FROM mcr.microsoft.com/vscode/devcontainers/java:0-${VARIANT}
# [Option] Install Maven
ARG INSTALL_MAVEN="false"
ARG MAVEN_VERSION=""
# [Option] Install Gradle
ARG INSTALL_GRADLE="false"
ARG GRADLE_VERSION=""
RUN if [ "${INSTALL_MAVEN}" = "true" ]; then su vscode -c "umask 0002 && . /usr/local/sdkman/bin/sdkman-init.sh && sdk install maven \"${MAVEN_VERSION}\""; fi \
&& if [ "${INSTALL_GRADLE}" = "true" ]; then su vscode -c "umask 0002 && . /usr/local/sdkman/bin/sdkman-init.sh && sdk install gradle \"${GRADLE_VERSION}\""; fi
# [Choice] Node.js version: none, lts/*, 16, 14, 12, 10
ARG NODE_VERSION="none"
RUN if [ "${NODE_VERSION}" != "none" ]; then su vscode -c "umask 0002 && . /usr/local/share/nvm/nvm.sh && nvm install ${NODE_VERSION} 2>&1"; fi
# [Optional] Uncomment this section to install additional OS packages.
# RUN apt-get update && export DEBIAN_FRONTEND=noninteractive \
# && apt-get -y install --no-install-recommends <your-package-list-here>
# [Optional] Uncomment this line to install global node packages.
# RUN su vscode -c "source /usr/local/share/nvm/nvm.sh && npm install -g <your-package-here>" 2>&1

View File

@ -0,0 +1,48 @@
// For format details, see https://aka.ms/devcontainer.json. For config options, see the README at:
// https://github.com/microsoft/vscode-dev-containers/tree/v0.209.6/containers/java
{
"name": "Informationsystemmonitor",
"build": {
"dockerfile": "Dockerfile",
"args": {
// Update the VARIANT arg to pick a Java version: 11, 17
// Append -bullseye or -buster to pin to an OS version.
// Use the -bullseye variants on local arm64/Apple Silicon.
"VARIANT": "11",
// Options
"INSTALL_MAVEN": "true",
"INSTALL_GRADLE": "false",
"NODE_VERSION": "lts/*"
}
},
// Set *default* container specific settings.json values on container create.
"settings": {
"java.home": "/docker-java-home"
},
// Add the IDs of extensions you want installed when the container is created.
"extensions": [
"angular.ng-template",
"christian-kohler.npm-intellisense",
"firsttris.vscode-jest-runner",
"ms-vscode.vscode-typescript-tslint-plugin",
"dbaeumer.vscode-eslint",
"vscjava.vscode-java-pack",
"pivotal.vscode-boot-dev-pack",
"esbenp.prettier-vscode"
],
// Use 'forwardPorts' to make a list of ports inside the container available locally.
"forwardPorts": [4200, 3001, 9000, 8080],
// Use 'postCreateCommand' to run commands after the container is created.
// "postCreateCommand": "java -version",
// Comment out connect as root instead. More info: https://aka.ms/vscode-remote/containers/non-root.
"remoteUser": "vscode",
"features": {
"docker-in-docker": "latest",
"docker-from-docker": "latest"
}
}

23
.editorconfig Normal file
View File

@ -0,0 +1,23 @@
# EditorConfig helps developers define and maintain consistent
# coding styles between different editors and IDEs
# editorconfig.org
root = true
[*]
# We recommend you to keep these unchanged
end_of_line = lf
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true
# Change these settings to your own preference
indent_style = space
indent_size = 4
[*.{ts,tsx,js,jsx,json,css,scss,yml,html,vue}]
indent_size = 2
[*.md]
trim_trailing_whitespace = false

8
.eslintignore Normal file
View File

@ -0,0 +1,8 @@
node_modules/
src/main/docker/
jest.conf.js
webpack/
target/
build/
node/
postcss.config.js

99
.eslintrc.json Normal file
View File

@ -0,0 +1,99 @@
{
"parser": "@typescript-eslint/parser",
"plugins": ["@angular-eslint/eslint-plugin", "@typescript-eslint"],
"extends": [
"eslint:recommended",
"plugin:@typescript-eslint/recommended",
"plugin:@typescript-eslint/recommended-requiring-type-checking",
"plugin:@angular-eslint/recommended",
"prettier",
"eslint-config-prettier"
],
"env": {
"browser": true,
"es6": true,
"commonjs": true
},
"parserOptions": {
"ecmaVersion": 2018,
"sourceType": "module",
"project": ["./tsconfig.app.json", "./tsconfig.spec.json"]
},
"rules": {
"@angular-eslint/component-selector": [
"error",
{
"type": "element",
"prefix": "jhi",
"style": "kebab-case"
}
],
"@angular-eslint/directive-selector": [
"error",
{
"type": "attribute",
"prefix": "jhi",
"style": "camelCase"
}
],
"@angular-eslint/relative-url-prefix": "error",
"@typescript-eslint/ban-types": [
"error",
{
"extendDefaults": true,
"types": {
"{}": false
}
}
],
"@typescript-eslint/explicit-function-return-type": ["error", { "allowExpressions": true }],
"@typescript-eslint/explicit-module-boundary-types": "off",
"@typescript-eslint/member-ordering": [
"error",
{
"default": [
"public-static-field",
"protected-static-field",
"private-static-field",
"public-instance-field",
"protected-instance-field",
"private-instance-field",
"constructor",
"public-static-method",
"protected-static-method",
"private-static-method",
"public-instance-method",
"protected-instance-method",
"private-instance-method"
]
}
],
"@typescript-eslint/no-explicit-any": "off",
"@typescript-eslint/no-floating-promises": "off",
"@typescript-eslint/no-non-null-assertion": "off",
"@typescript-eslint/no-parameter-properties": ["warn", { "allows": ["public", "private", "protected"] }],
"@typescript-eslint/no-shadow": ["error"],
"@typescript-eslint/no-unnecessary-condition": "error",
"@typescript-eslint/no-unsafe-argument": "off",
"@typescript-eslint/no-unsafe-assignment": "off",
"@typescript-eslint/no-unsafe-call": "off",
"@typescript-eslint/no-unsafe-member-access": "off",
"@typescript-eslint/prefer-nullish-coalescing": "error",
"@typescript-eslint/prefer-optional-chain": "error",
"@typescript-eslint/unbound-method": "off",
"arrow-body-style": "error",
"curly": "error",
"eqeqeq": ["error", "always", { "null": "ignore" }],
"guard-for-in": "error",
"no-bitwise": "error",
"no-caller": "error",
"no-console": ["error", { "allow": ["warn", "error"] }],
"no-eval": "error",
"no-labels": "error",
"no-new": "error",
"no-new-wrappers": "error",
"object-shorthand": ["error", "always", { "avoidExplicitReturnArrows": true }],
"radix": "error",
"spaced-comment": ["warn", "always"]
}
}

5
.factorypath Normal file
View File

@ -0,0 +1,5 @@
<factorypath>
<factorypathentry kind="VARJAR" id="M2_REPO/org/projectlombok/lombok/1.18.24/lombok-1.18.24.jar" enabled="true" runInBatchMode="false"/>
<factorypathentry kind="VARJAR" id="M2_REPO/org/springframework/boot/spring-boot-configuration-processor/2.7.3/spring-boot-configuration-processor-2.7.3.jar" enabled="true" runInBatchMode="false"/>
<factorypathentry kind="VARJAR" id="M2_REPO/org/mapstruct/mapstruct-processor/1.5.2.Final/mapstruct-processor-1.5.2.Final.jar" enabled="true" runInBatchMode="false"/>
</factorypath>

2
.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
/target/
/node_modules/

1
.mvn/jvm.config Normal file
View File

@ -0,0 +1 @@

BIN
.mvn/wrapper/maven-wrapper.jar vendored Normal file

Binary file not shown.

18
.mvn/wrapper/maven-wrapper.properties vendored Normal file
View File

@ -0,0 +1,18 @@
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.8.6/apache-maven-3.8.6-bin.zip
wrapperUrl=https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.1.1/maven-wrapper-3.1.1.jar

8
.prettierignore Normal file
View File

@ -0,0 +1,8 @@
node_modules
target
build
package-lock.json
.git
.mvn
gradle
.gradle

18
.prettierrc Normal file
View File

@ -0,0 +1,18 @@
# Prettier configuration
printWidth: 140
singleQuote: true
tabWidth: 2
useTabs: false
# js and ts rules:
arrowParens: avoid
# jsx and tsx rules:
bracketSameLine: false
# java rules:
overrides:
- files: "*.java"
options:
tabWidth: 4

28
.project Normal file
View File

@ -0,0 +1,28 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>informationsystemmonitor</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.springframework.ide.eclipse.boot.validation.springbootbuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.m2e.core.maven2Builder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.jdt.core.javanature</nature>
<nature>org.eclipse.m2e.core.maven2Nature</nature>
</natures>
</projectDescription>

View File

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

View File

@ -0,0 +1,4 @@
eclipse.preferences.version=1
org.eclipse.jdt.apt.aptEnabled=true
org.eclipse.jdt.apt.genSrcDir=target/generated-sources/annotations
org.eclipse.jdt.apt.genTestSrcDir=target/generated-test-sources/test-annotations

View File

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

View File

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

View File

@ -0,0 +1,2 @@
boot.validation.initialized=true
eclipse.preferences.version=1

8
.yo-rc-global.json Normal file
View File

@ -0,0 +1,8 @@
{
"generator-jhipster:7.9.3": {
"promptValues": {
"packageName": "org.gcube.fullstackapps.informationsystemmonitor",
"nativeLanguage": "en"
}
}
}

49
.yo-rc.json Normal file
View File

@ -0,0 +1,49 @@
{
"generator-jhipster": {
"applicationType": "monolith",
"authenticationType": "oauth2",
"baseName": "informationsystemmonitor",
"blueprints": [],
"buildTool": "maven",
"cacheProvider": "no",
"clientFramework": "angularX",
"clientPackageManager": "npm",
"clientTheme": "none",
"clientThemeVariant": "",
"creationTimestamp": 1687526025362,
"databaseType": "no",
"devDatabaseType": "no",
"devServerPort": 4200,
"dtoSuffix": "DTO",
"enableGradleEnterprise": false,
"enableHibernateCache": false,
"enableSwaggerCodegen": true,
"enableTranslation": true,
"entitySuffix": "",
"jhiPrefix": "jhi",
"jhipsterVersion": "7.9.3",
"languages": ["en"],
"messageBroker": false,
"microfrontend": false,
"microfrontends": [],
"monorepository": true,
"nativeLanguage": "en",
"otherModules": [],
"packageName": "org.gcube.fullstackapps.informationsystemmonitor",
"pages": [],
"prodDatabaseType": "no",
"reactive": false,
"searchEngine": false,
"serverPort": "8080",
"serverSideOptions": ["enableSwaggerCodegen:true"],
"serviceDiscoveryType": "no",
"skipCheckLengthOfIdentifier": false,
"skipClient": false,
"skipCommitHook": true,
"skipFakeData": false,
"skipUserManagement": true,
"testFrameworks": [],
"websocket": false,
"withAdminUi": true
}
}

8
CHANGELOG.md Normal file
View File

@ -0,0 +1,8 @@
This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
# Changelog for "informationsystemmonitor"
## [v1.0.0-SNAPSHOT]
- First Release

26
FUNDING.md Normal file
View File

@ -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);

311
LICENSE.md Normal file
View File

@ -0,0 +1,311 @@
# 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 Licensees 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

39
README.md Normal file
View File

@ -0,0 +1,39 @@
# Information System Monitor
Information System Monitor is a administration tool for monitoring and displaying resources data concerning the D4Science Infrastructure.
## Structure of the project
* The source code is present in the src folder.
## Built With
* [OpenJDK](https://openjdk.java.net/) - The JDK used
* [Maven](https://maven.apache.org/) - Dependency Management
## Documentation
* Use of this application is is described on [Wiki](https://wiki.gcube-system.org/gcube/InformationSytemMonitor).
## Change log
See [Releases](https://code-repo.d4science.org/gCubeSystem/informationsystemmonitor/releases).
## Authors
* **Maria Teresa Paratore** ([ORCID](http://orcid.org/0000-0001-8375-6644)) - [ISTI-CNR Infrascience Group](http://nemis.isti.cnr.it/groups/infrascience)
* **Giancarlo Panichi** ([ORCID](http://orcid.org/0000-0001-8375-6644)) - [ISTI-CNR Infrascience Group](http://nemis.isti.cnr.it/groups/infrascience)
## 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)

396
README_original.md Normal file
View File

@ -0,0 +1,396 @@
# informationsystemmonitor
This application was generated using JHipster 7.9.3, you can find documentation and help at [https://www.jhipster.tech/documentation-archive/v7.9.3](https://www.jhipster.tech/documentation-archive/v7.9.3).
## Project Structure
Node is required for generation and recommended for development. `package.json` is always generated for a better development experience with prettier, commit hooks, scripts and so on.
In the project root, JHipster generates configuration files for tools like git, prettier, eslint, husky, and others that are well known and you can find references in the web.
`/src/*` structure follows default Java structure.
- `.yo-rc.json` - Yeoman configuration file
JHipster configuration is stored in this file at `generator-jhipster` key. You may find `generator-jhipster-*` for specific blueprints configuration.
- `.yo-resolve` (optional) - Yeoman conflict resolver
Allows to use a specific action when conflicts are found skipping prompts for files that matches a pattern. Each line should match `[pattern] [action]` with pattern been a [Minimatch](https://github.com/isaacs/minimatch#minimatch) pattern and action been one of skip (default if ommited) or force. Lines starting with `#` are considered comments and are ignored.
- `.jhipster/*.json` - JHipster entity configuration files
- `npmw` - wrapper to use locally installed npm.
JHipster installs Node and npm locally using the build tool by default. This wrapper makes sure npm is installed locally and uses it avoiding some differences different versions can cause. By using `./npmw` instead of the traditional `npm` you can configure a Node-less environment to develop or test your application.
- `/src/main/docker` - Docker configurations for the application and services that the application depends on
## Development
Before you can build this project, you must install and configure the following dependencies on your machine:
1. [Node.js][]: We use Node to run a development web server and build the project.
Depending on your system, you can install Node either from source or as a pre-packaged bundle.
After installing Node, you should be able to run the following command to install development tools.
You will only need to run this command when dependencies change in [package.json](package.json).
```
npm install
```
We use npm scripts and [Angular CLI][] with [Webpack][] as our build system.
Run the following commands in two separate terminals to create a blissful development experience where your browser
auto-refreshes when files change on your hard drive.
```
./mvnw
npm start
```
Npm is also used to manage CSS and JavaScript dependencies used in this application. You can upgrade dependencies by
specifying a newer version in [package.json](package.json). You can also run `npm update` and `npm install` to manage dependencies.
Add the `help` flag on any command to see how you can use it. For example, `npm help update`.
The `npm run` command will list all of the scripts available to run for this project.
### PWA Support
JHipster ships with PWA (Progressive Web App) support, and it's turned off by default. One of the main components of a PWA is a service worker.
The service worker initialization code is disabled by default. To enable it, uncomment the following code in `src/main/webapp/app/app.module.ts`:
```typescript
ServiceWorkerModule.register('ngsw-worker.js', { enabled: false }),
```
### Managing dependencies
For example, to add [Leaflet][] library as a runtime dependency of your application, you would run following command:
```
npm install --save --save-exact leaflet
```
To benefit from TypeScript type definitions from [DefinitelyTyped][] repository in development, you would run following command:
```
npm install --save-dev --save-exact @types/leaflet
```
Then you would import the JS and CSS files specified in library's installation instructions so that [Webpack][] knows about them:
Edit [src/main/webapp/app/app.module.ts](src/main/webapp/app/app.module.ts) file:
```
import 'leaflet/dist/leaflet.js';
```
Edit [src/main/webapp/content/scss/vendor.scss](src/main/webapp/content/scss/vendor.scss) file:
```
@import '~leaflet/dist/leaflet.css';
```
Note: There are still a few other things remaining to do for Leaflet that we won't detail here.
For further instructions on how to develop with JHipster, have a look at [Using JHipster in development][].
### Using Angular CLI
You can also use [Angular CLI][] to generate some custom client code.
For example, the following command:
```
ng generate component my-component
```
will generate few files:
```
create src/main/webapp/app/my-component/my-component.component.html
create src/main/webapp/app/my-component/my-component.component.ts
update src/main/webapp/app/app.module.ts
```
### JHipster Control Center
JHipster Control Center can help you manage and control your application(s). You can start a local control center server (accessible on http://localhost:7419) with:
```
docker-compose -f src/main/docker/jhipster-control-center.yml up
```
### OAuth 2.0 / OpenID Connect
Congratulations! You've selected an excellent way to secure your JHipster application. If you're not sure what OAuth and OpenID Connect (OIDC) are, please see [What the Heck is OAuth?](https://developer.okta.com/blog/2017/06/21/what-the-heck-is-oauth)
To log in to your app, you'll need to have [Keycloak](https://keycloak.org) up and running. The JHipster Team has created a Docker container for you that has the default users and roles. Start Keycloak using the following command.
```
docker-compose -f src/main/docker/keycloak.yml up
```
The security settings in `src/main/resources/config/application.yml` are configured for this image.
```yaml
spring:
...
security:
oauth2:
client:
provider:
oidc:
issuer-uri: http://localhost:9080/realms/jhipster
registration:
oidc:
client-id: web_app
client-secret: web_app
scope: openid,profile,email
```
Some of Keycloak configuration is now done in build time and the other part before running the app, here is the [list](https://www.keycloak.org/server/all-config) of all build and configuration options.
Before moving to production, please make sure to follow this [guide](https://www.keycloak.org/server/configuration) for better security and performance.
Also, you should never use `start-dev` nor `KC_DB=dev-file` in production.
When using Kubernetes, importing should be done using init-containers (with a volume when using `db=dev-file`).
### Okta
If you'd like to use Okta instead of Keycloak, it's pretty quick using the [Okta CLI](https://cli.okta.com/). After you've installed it, run:
```shell
okta register
```
Then, in your JHipster app's directory, run `okta apps create` and select **JHipster**. This will set up an Okta app for you, create `ROLE_ADMIN` and `ROLE_USER` groups, create a `.okta.env` file with your Okta settings, and configure a `groups` claim in your ID token.
Run `source .okta.env` and start your app with Maven or Gradle. You should be able to sign in with the credentials you registered with.
If you're on Windows, you should install [WSL](https://docs.microsoft.com/en-us/windows/wsl/install-win10) so the `source` command will work.
If you'd like to configure things manually through the Okta developer console, see the instructions below.
First, you'll need to create a free developer account at <https://developer.okta.com/signup/>. After doing so, you'll get your own Okta domain, that has a name like `https://dev-123456.okta.com`.
Modify `src/main/resources/config/application.yml` to use your Okta settings.
```yaml
spring:
...
security:
oauth2:
client:
provider:
oidc:
issuer-uri: https://{yourOktaDomain}/oauth2/default
registration:
oidc:
client-id: {clientId}
client-secret: {clientSecret}
security:
```
Create an OIDC App in Okta to get a `{clientId}` and `{clientSecret}`. To do this, log in to your Okta Developer account and navigate to **Applications** > **Add Application**. Click **Web** and click the **Next** button. Give the app a name youll remember, specify `http://localhost:8080` as a Base URI, and `http://localhost:8080/login/oauth2/code/oidc` as a Login Redirect URI. Click **Done**, then Edit and add `http://localhost:8080` as a Logout redirect URI. Copy and paste the client ID and secret into your `application.yml` file.
Create a `ROLE_ADMIN` and `ROLE_USER` group and add users into them. Modify e2e tests to use this account when running integration tests. You'll need to change credentials in `src/test/javascript/e2e/account/account.spec.ts` and `src/test/javascript/e2e/admin/administration.spec.ts`.
Navigate to **API** > **Authorization Servers**, click the **Authorization Servers** tab and edit the default one. Click the **Claims** tab and **Add Claim**. Name it "groups", and include it in the ID Token. Set the value type to "Groups" and set the filter to be a Regex of `.*`.
After making these changes, you should be good to go! If you have any issues, please post them to [Stack Overflow](https://stackoverflow.com/questions/tagged/jhipster). Make sure to tag your question with "jhipster" and "okta".
### Auth0
If you'd like to use [Auth0](https://auth0.com/) instead of Keycloak, follow the configuration steps below:
- Create a free developer account at <https://auth0.com/signup>. After successful sign-up, your account will be associated with a unique domain like `dev-xxx.us.auth0.com`
- Create a new application of type `Regular Web Applications`. Switch to the `Settings` tab, and configure your application settings like:
- Allowed Callback URLs: `http://localhost:8080/login/oauth2/code/oidc`
- Allowed Logout URLs: `http://localhost:8080/`
- Navigate to **User Management** > **Roles** and create new roles named `ROLE_ADMIN`, and `ROLE_USER`.
- Navigate to **User Management** > **Users** and create a new user account. Click on the **Role** tab to assign roles to the newly created user account.
- Navigate to **Auth Pipeline** > **Rules** and create a new Rule. Choose `Empty rule` template. Provide a meaningful name like `JHipster claims` and replace `Script` content with the following and Save.
```javascript
function (user, context, callback) {
user.preferred_username = user.email;
const roles = (context.authorization || {}).roles;
function prepareCustomClaimKey(claim) {
return `https://www.jhipster.tech/${claim}`;
}
const rolesClaim = prepareCustomClaimKey('roles');
if (context.idToken) {
context.idToken[rolesClaim] = roles;
}
if (context.accessToken) {
context.accessToken[rolesClaim] = roles;
}
callback(null, user, context);
}
```
- In your `JHipster` application, modify `src/main/resources/config/application.yml` to use your Auth0 application settings:
```yaml
spring:
...
security:
oauth2:
client:
provider:
oidc:
# make sure to include the ending slash!
issuer-uri: https://{your-auth0-domain}/
registration:
oidc:
client-id: {clientId}
client-secret: {clientSecret}
scope: openid,profile,email
jhipster:
...
security:
oauth2:
audience:
- https://{your-auth0-domain}/api/v2/
```
### Doing API-First development using openapi-generator-cli
[OpenAPI-Generator]() is configured for this application. You can generate API code from the `src/main/resources/swagger/api.yml` definition file by running:
```bash
./mvnw generate-sources
```
Then implements the generated delegate classes with `@Service` classes.
To edit the `api.yml` definition file, you can use a tool such as [Swagger-Editor](). Start a local instance of the swagger-editor using docker by running: `docker-compose -f src/main/docker/swagger-editor.yml up -d`. The editor will then be reachable at [http://localhost:7742](http://localhost:7742).
Refer to [Doing API-First development][] for more details.
## Building for production
### Packaging as jar
To build the final jar and optimize the informationsystemmonitor application for production, run:
```
./mvnw -Pprod clean verify
```
This will concatenate and minify the client CSS and JavaScript files. It will also modify `index.html` so it references these new files.
To ensure everything worked, run:
```
java -jar target/*.jar
```
Then navigate to [http://localhost:8080](http://localhost:8080) in your browser.
Refer to [Using JHipster in production][] for more details.
### Packaging as war
To package your application as a war in order to deploy it to an application server, run:
```
./mvnw -Pprod,war clean verify
```
## Testing
To launch your application's tests, run:
```
./mvnw verify
```
### Client tests
Unit tests are run by [Jest][]. They're located in [src/test/javascript/](src/test/javascript/) and can be run with:
```
npm test
```
For more information, refer to the [Running tests page][].
### Code quality
Sonar is used to analyse code quality. You can start a local Sonar server (accessible on http://localhost:9001) with:
```
docker-compose -f src/main/docker/sonar.yml up -d
```
Note: we have turned off authentication in [src/main/docker/sonar.yml](src/main/docker/sonar.yml) for out of the box experience while trying out SonarQube, for real use cases turn it back on.
You can run a Sonar analysis with using the [sonar-scanner](https://docs.sonarqube.org/display/SCAN/Analyzing+with+SonarQube+Scanner) or by using the maven plugin.
Then, run a Sonar analysis:
```
./mvnw -Pprod clean verify sonar:sonar
```
If you need to re-run the Sonar phase, please be sure to specify at least the `initialize` phase since Sonar properties are loaded from the sonar-project.properties file.
```
./mvnw initialize sonar:sonar
```
For more information, refer to the [Code quality page][].
## Using Docker to simplify development (optional)
You can use Docker to improve your JHipster development experience. A number of docker-compose configuration are available in the [src/main/docker](src/main/docker) folder to launch required third party services.
You can also fully dockerize your application and all the services that it depends on.
To achieve this, first build a docker image of your app by running:
```
npm run java:docker
```
Or build a arm64 docker image when using an arm64 processor os like MacOS with M1 processor family running:
```
npm run java:docker:arm64
```
Then run:
```
docker-compose -f src/main/docker/app.yml up -d
```
When running Docker Desktop on MacOS Big Sur or later, consider enabling experimental `Use the new Virtualization framework` for better processing performance ([disk access performance is worse](https://github.com/docker/roadmap/issues/7)).
For more information refer to [Using Docker and Docker-Compose][], this page also contains information on the docker-compose sub-generator (`jhipster docker-compose`), which is able to generate docker configurations for one or several JHipster applications.
## Continuous Integration (optional)
To configure CI for your project, run the ci-cd sub-generator (`jhipster ci-cd`), this will let you generate configuration files for a number of Continuous Integration systems. Consult the [Setting up Continuous Integration][] page for more information.
[jhipster homepage and latest documentation]: https://www.jhipster.tech
[jhipster 7.9.3 archive]: https://www.jhipster.tech/documentation-archive/v7.9.3
[using jhipster in development]: https://www.jhipster.tech/documentation-archive/v7.9.3/development/
[using docker and docker-compose]: https://www.jhipster.tech/documentation-archive/v7.9.3/docker-compose
[using jhipster in production]: https://www.jhipster.tech/documentation-archive/v7.9.3/production/
[running tests page]: https://www.jhipster.tech/documentation-archive/v7.9.3/running-tests/
[code quality page]: https://www.jhipster.tech/documentation-archive/v7.9.3/code-quality/
[setting up continuous integration]: https://www.jhipster.tech/documentation-archive/v7.9.3/setting-up-ci/
[node.js]: https://nodejs.org/
[npm]: https://www.npmjs.com/
[webpack]: https://webpack.github.io/
[browsersync]: https://www.browsersync.io/
[jest]: https://facebook.github.io/jest/
[leaflet]: https://leafletjs.com/
[definitelytyped]: https://definitelytyped.org/
[angular cli]: https://cli.angular.io/
[openapi-generator]: https://openapi-generator.tech
[swagger-editor]: https://editor.swagger.io
[doing api-first development]: https://www.jhipster.tech/documentation-archive/v7.9.3/doing-api-first-development/

109
angular.json Normal file
View File

@ -0,0 +1,109 @@
{
"$schema": "./node_modules/@angular/cli/lib/config/schema.json",
"version": 1,
"newProjectRoot": "projects",
"projects": {
"informationsystemmonitor": {
"projectType": "application",
"schematics": {
"@schematics/angular:component": {
"style": "scss"
},
"@schematics/angular:application": {
"strict": true
}
},
"root": "",
"sourceRoot": "src/main/webapp",
"prefix": "jhi",
"architect": {
"build": {
"builder": "@angular-builders/custom-webpack:browser",
"options": {
"customWebpackConfig": {
"path": "./webpack/webpack.custom.js"
},
"outputPath": "target/classes/static/",
"index": "src/main/webapp/index.html",
"main": "src/main/webapp/main.ts",
"polyfills": "src/main/webapp/polyfills.ts",
"tsConfig": "tsconfig.app.json",
"inlineStyleLanguage": "scss",
"assets": [
"src/main/webapp/content",
"src/main/webapp/favicon.ico",
"src/main/webapp/manifest.webapp",
"src/main/webapp/robots.txt"
],
"styles": ["src/main/webapp/content/scss/vendor.scss", "src/main/webapp/content/scss/global.scss"],
"scripts": []
},
"configurations": {
"production": {
"optimization": true,
"outputHashing": "all",
"sourceMap": false,
"namedChunks": false,
"extractLicenses": true,
"vendorChunk": false,
"buildOptimizer": true,
"serviceWorker": true,
"ngswConfigPath": "ngsw-config.json",
"budgets": [
{
"type": "initial",
"maximumWarning": "500kb",
"maximumError": "1mb"
},
{
"type": "anyComponentStyle",
"maximumWarning": "2kb",
"maximumError": "4kb"
}
]
},
"development": {
"buildOptimizer": false,
"optimization": false,
"vendorChunk": true,
"extractLicenses": false,
"sourceMap": true,
"namedChunks": true
}
},
"defaultConfiguration": "production"
},
"serve": {
"builder": "@angular-builders/custom-webpack:dev-server",
"options": {
"browserTarget": "informationsystemmonitor:build:development",
"port": 4200
},
"configurations": {
"production": {
"browserTarget": "informationsystemmonitor:build:production"
},
"development": {
"browserTarget": "informationsystemmonitor:build:development"
}
},
"defaultConfiguration": "development"
},
"test": {
"builder": "@angular-builders/jest:run",
"options": {
"configPath": "jest.conf.js"
}
}
}
}
},
"cli": {
"cache": {
"enabled": true,
"path": "./target/angular/",
"environment": "all"
},
"packageManager": "npm"
}
}

20
checkstyle.xml Normal file
View File

@ -0,0 +1,20 @@
<?xml version="1.0"?>
<!DOCTYPE module PUBLIC "-//Puppy Crawl//DTD Check Configuration 1.3//EN"
"https://checkstyle.org/dtds/configuration_1_3.dtd">
<module name="Checker">
<!-- Configure checker to use UTF-8 encoding -->
<property name="charset" value="UTF-8"/>
<!-- Configure checker to run on files with these extensions -->
<property name="fileExtensions" value=""/>
<!-- For detailed checkstyle configuration, see https://github.com/spring-io/nohttp/tree/master/nohttp-checkstyle -->
<module name="io.spring.nohttp.checkstyle.check.NoHttpCheck">
<property name="allowlist" value="^\Qhttp://maven.apache.org/POM/4.0.0&#10;^\Qhttp://www.w3.org/2001/XMLSchema-instance"/>
</module>
<!-- Allow suppression with comments
// CHECKSTYLE:OFF
... ignored content ...
// CHECKSTYLE:ON
-->
<module name="SuppressWithPlainTextCommentFilter"/>
</module>

29
jest.conf.js Normal file
View File

@ -0,0 +1,29 @@
const { pathsToModuleNameMapper } = require('ts-jest');
const {
compilerOptions: { paths = {}, baseUrl = './' },
} = require('./tsconfig.json');
const environment = require('./webpack/environment');
module.exports = {
transformIgnorePatterns: ['node_modules/(?!.*\\.mjs$|dayjs/esm)'],
resolver: 'jest-preset-angular/build/resolvers/ng-jest-resolver.js',
globals: {
...environment,
},
roots: ['<rootDir>', `<rootDir>/${baseUrl}`],
modulePaths: [`<rootDir>/${baseUrl}`],
setupFiles: ['jest-date-mock'],
cacheDirectory: '<rootDir>/target/jest-cache',
coverageDirectory: '<rootDir>/target/test-results/',
moduleNameMapper: pathsToModuleNameMapper(paths, { prefix: `<rootDir>/${baseUrl}/` }),
reporters: [
'default',
['jest-junit', { outputDirectory: '<rootDir>/target/test-results/', outputName: 'TESTS-results-jest.xml' }],
['jest-sonar', { outputDirectory: './target/test-results/jest', outputName: 'TESTS-results-sonar.xml' }],
],
testMatch: ['<rootDir>/src/main/webapp/app/**/@(*.)@(spec.ts)'],
testEnvironmentOptions: {
url: 'https://jhipster.tech',
},
};

316
mvnw vendored Executable file
View File

@ -0,0 +1,316 @@
#!/bin/sh
# ----------------------------------------------------------------------------
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
# ----------------------------------------------------------------------------
# ----------------------------------------------------------------------------
# Maven Start Up Batch script
#
# Required ENV vars:
# ------------------
# JAVA_HOME - location of a JDK home dir
#
# Optional ENV vars
# -----------------
# M2_HOME - location of maven2's installed home dir
# MAVEN_OPTS - parameters passed to the Java VM when running Maven
# e.g. to debug Maven itself, use
# set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
# MAVEN_SKIP_RC - flag to disable loading of mavenrc files
# ----------------------------------------------------------------------------
if [ -z "$MAVEN_SKIP_RC" ] ; then
if [ -f /usr/local/etc/mavenrc ] ; then
. /usr/local/etc/mavenrc
fi
if [ -f /etc/mavenrc ] ; then
. /etc/mavenrc
fi
if [ -f "$HOME/.mavenrc" ] ; then
. "$HOME/.mavenrc"
fi
fi
# OS specific support. $var _must_ be set to either true or false.
cygwin=false;
darwin=false;
mingw=false
case "`uname`" in
CYGWIN*) cygwin=true ;;
MINGW*) mingw=true;;
Darwin*) darwin=true
# Use /usr/libexec/java_home if available, otherwise fall back to /Library/Java/Home
# See https://developer.apple.com/library/mac/qa/qa1170/_index.html
if [ -z "$JAVA_HOME" ]; then
if [ -x "/usr/libexec/java_home" ]; then
export JAVA_HOME="`/usr/libexec/java_home`"
else
export JAVA_HOME="/Library/Java/Home"
fi
fi
;;
esac
if [ -z "$JAVA_HOME" ] ; then
if [ -r /etc/gentoo-release ] ; then
JAVA_HOME=`java-config --jre-home`
fi
fi
if [ -z "$M2_HOME" ] ; then
## resolve links - $0 may be a link to maven's home
PRG="$0"
# need this for relative symlinks
while [ -h "$PRG" ] ; do
ls=`ls -ld "$PRG"`
link=`expr "$ls" : '.*-> \(.*\)$'`
if expr "$link" : '/.*' > /dev/null; then
PRG="$link"
else
PRG="`dirname "$PRG"`/$link"
fi
done
saveddir=`pwd`
M2_HOME=`dirname "$PRG"`/..
# make it fully qualified
M2_HOME=`cd "$M2_HOME" && pwd`
cd "$saveddir"
# echo Using m2 at $M2_HOME
fi
# For Cygwin, ensure paths are in UNIX format before anything is touched
if $cygwin ; then
[ -n "$M2_HOME" ] &&
M2_HOME=`cygpath --unix "$M2_HOME"`
[ -n "$JAVA_HOME" ] &&
JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
[ -n "$CLASSPATH" ] &&
CLASSPATH=`cygpath --path --unix "$CLASSPATH"`
fi
# For Mingw, ensure paths are in UNIX format before anything is touched
if $mingw ; then
[ -n "$M2_HOME" ] &&
M2_HOME="`(cd "$M2_HOME"; pwd)`"
[ -n "$JAVA_HOME" ] &&
JAVA_HOME="`(cd "$JAVA_HOME"; pwd)`"
fi
if [ -z "$JAVA_HOME" ]; then
javaExecutable="`which javac`"
if [ -n "$javaExecutable" ] && ! [ "`expr \"$javaExecutable\" : '\([^ ]*\)'`" = "no" ]; then
# readlink(1) is not available as standard on Solaris 10.
readLink=`which readlink`
if [ ! `expr "$readLink" : '\([^ ]*\)'` = "no" ]; then
if $darwin ; then
javaHome="`dirname \"$javaExecutable\"`"
javaExecutable="`cd \"$javaHome\" && pwd -P`/javac"
else
javaExecutable="`readlink -f \"$javaExecutable\"`"
fi
javaHome="`dirname \"$javaExecutable\"`"
javaHome=`expr "$javaHome" : '\(.*\)/bin'`
JAVA_HOME="$javaHome"
export JAVA_HOME
fi
fi
fi
if [ -z "$JAVACMD" ] ; then
if [ -n "$JAVA_HOME" ] ; then
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
# IBM's JDK on AIX uses strange locations for the executables
JAVACMD="$JAVA_HOME/jre/sh/java"
else
JAVACMD="$JAVA_HOME/bin/java"
fi
else
JAVACMD="`\\unset -f command; \\command -v java`"
fi
fi
if [ ! -x "$JAVACMD" ] ; then
echo "Error: JAVA_HOME is not defined correctly." >&2
echo " We cannot execute $JAVACMD" >&2
exit 1
fi
if [ -z "$JAVA_HOME" ] ; then
echo "Warning: JAVA_HOME environment variable is not set."
fi
CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher
# traverses directory structure from process work directory to filesystem root
# first directory with .mvn subdirectory is considered project base directory
find_maven_basedir() {
if [ -z "$1" ]
then
echo "Path not specified to find_maven_basedir"
return 1
fi
basedir="$1"
wdir="$1"
while [ "$wdir" != '/' ] ; do
if [ -d "$wdir"/.mvn ] ; then
basedir=$wdir
break
fi
# workaround for JBEAP-8937 (on Solaris 10/Sparc)
if [ -d "${wdir}" ]; then
wdir=`cd "$wdir/.."; pwd`
fi
# end of workaround
done
echo "${basedir}"
}
# concatenates all lines of a file
concat_lines() {
if [ -f "$1" ]; then
echo "$(tr -s '\n' ' ' < "$1")"
fi
}
BASE_DIR=`find_maven_basedir "$(pwd)"`
if [ -z "$BASE_DIR" ]; then
exit 1;
fi
##########################################################################################
# Extension to allow automatically downloading the maven-wrapper.jar from Maven-central
# This allows using the maven wrapper in projects that prohibit checking in binary data.
##########################################################################################
if [ -r "$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" ]; then
if [ "$MVNW_VERBOSE" = true ]; then
echo "Found .mvn/wrapper/maven-wrapper.jar"
fi
else
if [ "$MVNW_VERBOSE" = true ]; then
echo "Couldn't find .mvn/wrapper/maven-wrapper.jar, downloading it ..."
fi
if [ -n "$MVNW_REPOURL" ]; then
jarUrl="$MVNW_REPOURL/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar"
else
jarUrl="https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar"
fi
while IFS="=" read key value; do
case "$key" in (wrapperUrl) jarUrl="$value"; break ;;
esac
done < "$BASE_DIR/.mvn/wrapper/maven-wrapper.properties"
if [ "$MVNW_VERBOSE" = true ]; then
echo "Downloading from: $jarUrl"
fi
wrapperJarPath="$BASE_DIR/.mvn/wrapper/maven-wrapper.jar"
if $cygwin; then
wrapperJarPath=`cygpath --path --windows "$wrapperJarPath"`
fi
if command -v wget > /dev/null; then
if [ "$MVNW_VERBOSE" = true ]; then
echo "Found wget ... using wget"
fi
if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then
wget "$jarUrl" -O "$wrapperJarPath" || rm -f "$wrapperJarPath"
else
wget --http-user=$MVNW_USERNAME --http-password=$MVNW_PASSWORD "$jarUrl" -O "$wrapperJarPath" || rm -f "$wrapperJarPath"
fi
elif command -v curl > /dev/null; then
if [ "$MVNW_VERBOSE" = true ]; then
echo "Found curl ... using curl"
fi
if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then
curl -o "$wrapperJarPath" "$jarUrl" -f
else
curl --user $MVNW_USERNAME:$MVNW_PASSWORD -o "$wrapperJarPath" "$jarUrl" -f
fi
else
if [ "$MVNW_VERBOSE" = true ]; then
echo "Falling back to using Java to download"
fi
javaClass="$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.java"
# For Cygwin, switch paths to Windows format before running javac
if $cygwin; then
javaClass=`cygpath --path --windows "$javaClass"`
fi
if [ -e "$javaClass" ]; then
if [ ! -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then
if [ "$MVNW_VERBOSE" = true ]; then
echo " - Compiling MavenWrapperDownloader.java ..."
fi
# Compiling the Java class
("$JAVA_HOME/bin/javac" "$javaClass")
fi
if [ -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then
# Running the downloader
if [ "$MVNW_VERBOSE" = true ]; then
echo " - Running MavenWrapperDownloader.java ..."
fi
("$JAVA_HOME/bin/java" -cp .mvn/wrapper MavenWrapperDownloader "$MAVEN_PROJECTBASEDIR")
fi
fi
fi
fi
##########################################################################################
# End of extension
##########################################################################################
export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"}
if [ "$MVNW_VERBOSE" = true ]; then
echo $MAVEN_PROJECTBASEDIR
fi
MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS"
# For Cygwin, switch paths to Windows format before running java
if $cygwin; then
[ -n "$M2_HOME" ] &&
M2_HOME=`cygpath --path --windows "$M2_HOME"`
[ -n "$JAVA_HOME" ] &&
JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"`
[ -n "$CLASSPATH" ] &&
CLASSPATH=`cygpath --path --windows "$CLASSPATH"`
[ -n "$MAVEN_PROJECTBASEDIR" ] &&
MAVEN_PROJECTBASEDIR=`cygpath --path --windows "$MAVEN_PROJECTBASEDIR"`
fi
# Provide a "standardized" way to retrieve the CLI args that will
# work with both Windows and non-Windows executions.
MAVEN_CMD_LINE_ARGS="$MAVEN_CONFIG $@"
export MAVEN_CMD_LINE_ARGS
WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
exec "$JAVACMD" \
$MAVEN_OPTS \
$MAVEN_DEBUG_OPTS \
-classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \
"-Dmaven.home=${M2_HOME}" \
"-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \
${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@"

188
mvnw.cmd vendored Normal file
View File

@ -0,0 +1,188 @@
@REM ----------------------------------------------------------------------------
@REM Licensed to the Apache Software Foundation (ASF) under one
@REM or more contributor license agreements. See the NOTICE file
@REM distributed with this work for additional information
@REM regarding copyright ownership. The ASF licenses this file
@REM to you under the Apache License, Version 2.0 (the
@REM "License"); you may not use this file except in compliance
@REM with the License. You may obtain a copy of the License at
@REM
@REM http://www.apache.org/licenses/LICENSE-2.0
@REM
@REM Unless required by applicable law or agreed to in writing,
@REM software distributed under the License is distributed on an
@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
@REM KIND, either express or implied. See the License for the
@REM specific language governing permissions and limitations
@REM under the License.
@REM ----------------------------------------------------------------------------
@REM ----------------------------------------------------------------------------
@REM Maven Start Up Batch script
@REM
@REM Required ENV vars:
@REM JAVA_HOME - location of a JDK home dir
@REM
@REM Optional ENV vars
@REM M2_HOME - location of maven2's installed home dir
@REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands
@REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a keystroke before ending
@REM MAVEN_OPTS - parameters passed to the Java VM when running Maven
@REM e.g. to debug Maven itself, use
@REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
@REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files
@REM ----------------------------------------------------------------------------
@REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on'
@echo off
@REM set title of command window
title %0
@REM enable echoing by setting MAVEN_BATCH_ECHO to 'on'
@if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO%
@REM set %HOME% to equivalent of $HOME
if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%")
@REM Execute a user defined script before this one
if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre
@REM check for pre script, once with legacy .bat ending and once with .cmd ending
if exist "%USERPROFILE%\mavenrc_pre.bat" call "%USERPROFILE%\mavenrc_pre.bat" %*
if exist "%USERPROFILE%\mavenrc_pre.cmd" call "%USERPROFILE%\mavenrc_pre.cmd" %*
:skipRcPre
@setlocal
set ERROR_CODE=0
@REM To isolate internal variables from possible post scripts, we use another setlocal
@setlocal
@REM ==== START VALIDATION ====
if not "%JAVA_HOME%" == "" goto OkJHome
echo.
echo Error: JAVA_HOME not found in your environment. >&2
echo Please set the JAVA_HOME variable in your environment to match the >&2
echo location of your Java installation. >&2
echo.
goto error
:OkJHome
if exist "%JAVA_HOME%\bin\java.exe" goto init
echo.
echo Error: JAVA_HOME is set to an invalid directory. >&2
echo JAVA_HOME = "%JAVA_HOME%" >&2
echo Please set the JAVA_HOME variable in your environment to match the >&2
echo location of your Java installation. >&2
echo.
goto error
@REM ==== END VALIDATION ====
:init
@REM Find the project base dir, i.e. the directory that contains the folder ".mvn".
@REM Fallback to current working directory if not found.
set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR%
IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir
set EXEC_DIR=%CD%
set WDIR=%EXEC_DIR%
:findBaseDir
IF EXIST "%WDIR%"\.mvn goto baseDirFound
cd ..
IF "%WDIR%"=="%CD%" goto baseDirNotFound
set WDIR=%CD%
goto findBaseDir
:baseDirFound
set MAVEN_PROJECTBASEDIR=%WDIR%
cd "%EXEC_DIR%"
goto endDetectBaseDir
:baseDirNotFound
set MAVEN_PROJECTBASEDIR=%EXEC_DIR%
cd "%EXEC_DIR%"
:endDetectBaseDir
IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig
@setlocal EnableExtensions EnableDelayedExpansion
for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a
@endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS%
:endReadAdditionalConfig
SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe"
set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar"
set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
set DOWNLOAD_URL="https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar"
FOR /F "usebackq tokens=1,2 delims==" %%A IN ("%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties") DO (
IF "%%A"=="wrapperUrl" SET DOWNLOAD_URL=%%B
)
@REM Extension to allow automatically downloading the maven-wrapper.jar from Maven-central
@REM This allows using the maven wrapper in projects that prohibit checking in binary data.
if exist %WRAPPER_JAR% (
if "%MVNW_VERBOSE%" == "true" (
echo Found %WRAPPER_JAR%
)
) else (
if not "%MVNW_REPOURL%" == "" (
SET DOWNLOAD_URL="%MVNW_REPOURL%/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar"
)
if "%MVNW_VERBOSE%" == "true" (
echo Couldn't find %WRAPPER_JAR%, downloading it ...
echo Downloading from: %DOWNLOAD_URL%
)
powershell -Command "&{"^
"$webclient = new-object System.Net.WebClient;"^
"if (-not ([string]::IsNullOrEmpty('%MVNW_USERNAME%') -and [string]::IsNullOrEmpty('%MVNW_PASSWORD%'))) {"^
"$webclient.Credentials = new-object System.Net.NetworkCredential('%MVNW_USERNAME%', '%MVNW_PASSWORD%');"^
"}"^
"[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; $webclient.DownloadFile('%DOWNLOAD_URL%', '%WRAPPER_JAR%')"^
"}"
if "%MVNW_VERBOSE%" == "true" (
echo Finished downloading %WRAPPER_JAR%
)
)
@REM End of extension
@REM Provide a "standardized" way to retrieve the CLI args that will
@REM work with both Windows and non-Windows executions.
set MAVEN_CMD_LINE_ARGS=%*
%MAVEN_JAVA_EXE% ^
%JVM_CONFIG_MAVEN_PROPS% ^
%MAVEN_OPTS% ^
%MAVEN_DEBUG_OPTS% ^
-classpath %WRAPPER_JAR% ^
"-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" ^
%WRAPPER_LAUNCHER% %MAVEN_CONFIG% %*
if ERRORLEVEL 1 goto error
goto end
:error
set ERROR_CODE=1
:end
@endlocal & set ERROR_CODE=%ERROR_CODE%
if not "%MAVEN_SKIP_RC%"=="" goto skipRcPost
@REM check for post script, once with legacy .bat ending and once with .cmd ending
if exist "%USERPROFILE%\mavenrc_post.bat" call "%USERPROFILE%\mavenrc_post.bat"
if exist "%USERPROFILE%\mavenrc_post.cmd" call "%USERPROFILE%\mavenrc_post.cmd"
:skipRcPost
@REM pause the script if MAVEN_BATCH_PAUSE is set to 'on'
if "%MAVEN_BATCH_PAUSE%"=="on" pause
if "%MAVEN_TERMINATE_CMD%"=="on" exit %ERROR_CODE%
cmd /C exit /B %ERROR_CODE%

21
ngsw-config.json Normal file
View File

@ -0,0 +1,21 @@
{
"$schema": "./node_modules/@angular/service-worker/config/schema.json",
"index": "/index.html",
"assetGroups": [
{
"name": "app",
"installMode": "prefetch",
"resources": {
"files": ["/favicon.ico", "/index.html", "/manifest.webapp", "/*.css", "/*.js"]
}
},
{
"name": "assets",
"installMode": "lazy",
"updateMode": "prefetch",
"resources": {
"files": ["/content/**", "/*.(eot|svg|cur|jpg|png|webp|gif|otf|ttf|woff|woff2|ani)"]
}
}
]
}

42
npmw Executable file
View File

@ -0,0 +1,42 @@
#!/bin/sh
basedir=`dirname "$0"`
if [ -f "$basedir/mvnw" ]; then
bindir="$basedir/target/node"
repodir="$basedir/target/node/node_modules"
installCommand="$basedir/mvnw -Pwebapp frontend:install-node-and-npm@install-node-and-npm"
PATH="$basedir/$builddir/:$PATH"
NPM_EXE="$basedir/$builddir/node_modules/npm/bin/npm-cli.js"
NODE_EXE="$basedir/$builddir/node"
elif [ -f "$basedir/gradlew" ]; then
bindir="$basedir/build/node/bin"
repodir="$basedir/build/node/lib/node_modules"
installCommand="$basedir/gradlew npmSetup"
else
echo "Using npm installed globally"
exec npm "$@"
fi
NPM_EXE="$repodir/npm/bin/npm-cli.js"
NODE_EXE="$bindir/node"
if [ ! -x "$NPM_EXE" ] || [ ! -x "$NODE_EXE" ]; then
$installCommand || true
fi
if [ -x "$NODE_EXE" ]; then
echo "Using node installed locally $($NODE_EXE --version)"
PATH="$bindir:$PATH"
else
NODE_EXE='node'
fi
if [ ! -x "$NPM_EXE" ]; then
echo "Local npm not found, using npm installed globally"
npm "$@"
else
echo "Using npm installed locally $($NODE_EXE $NPM_EXE --version)"
$NODE_EXE $NPM_EXE "$@"
fi

31
npmw.cmd Normal file
View File

@ -0,0 +1,31 @@
@echo off
setlocal
set NPMW_DIR=%~dp0
if exist "%NPMW_DIR%mvnw.cmd" (
set NODE_EXE=^"^"
set NODE_PATH=%NPMW_DIR%target\node\
set NPM_EXE=^"%NPMW_DIR%target\node\npm.cmd^"
set INSTALL_NPM_COMMAND=^"%NPMW_DIR%mvnw.cmd^" -Pwebapp frontend:install-node-and-npm@install-node-and-npm
) else (
set NODE_EXE=^"%NPMW_DIR%build\node\bin\node.exe^"
set NODE_PATH=%NPMW_DIR%build\node\bin\
set NPM_EXE=^"%NPMW_DIR%build\node\lib\node_modules\npm\bin\npm-cli.js^"
set INSTALL_NPM_COMMAND=^"%NPMW_DIR%gradlew.bat^" npmSetup
)
if not exist %NPM_EXE% (
call %INSTALL_NPM_COMMAND%
)
if exist %NODE_EXE% (
Rem execute local npm with local node, whilst adding local node location to the PATH for this CMD session
endlocal & echo "%PATH%"|find /i "%NODE_PATH%;">nul || set "PATH=%NODE_PATH%;%PATH%" & call %NODE_EXE% %NPM_EXE% %*
) else if exist %NPM_EXE% (
Rem execute local npm, whilst adding local npm location to the PATH for this CMD session
endlocal & echo "%PATH%"|find /i "%NODE_PATH%;">nul || set "PATH=%NODE_PATH%;%PATH%" & call %NPM_EXE% %*
) else (
call npm %*
)

43823
package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

150
package.json Normal file
View File

@ -0,0 +1,150 @@
{
"name": "informationsystemmonitor",
"version": "0.0.1-SNAPSHOT",
"private": true,
"description": "Description for informationsystemmonitor",
"license": "UNLICENSED",
"scripts": {
"app:start": "./mvnw",
"backend:build-cache": "./mvnw dependency:go-offline",
"backend:debug": "./mvnw -Dspring-boot.run.jvmArguments=\"-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=*:8000\"",
"backend:doc:test": "./mvnw -ntp javadoc:javadoc --batch-mode",
"backend:info": "./mvnw -ntp enforcer:display-info --batch-mode",
"backend:nohttp:test": "./mvnw -ntp checkstyle:check --batch-mode",
"backend:start": "./mvnw -Dskip.installnodenpm -Dskip.npm",
"backend:unit:test": "./mvnw -ntp -Dskip.installnodenpm -Dskip.npm verify --batch-mode -Dlogging.level.ROOT=OFF -Dlogging.level.org.zalando=OFF -Dlogging.level.tech.jhipster=OFF -Dlogging.level.org.gcube.fullstackapps.informationsystemmonitor=OFF -Dlogging.level.org.springframework=OFF -Dlogging.level.org.springframework.web=OFF -Dlogging.level.org.springframework.security=OFF",
"build": "npm run webapp:prod --",
"build-watch": "concurrently 'npm run webapp:build:dev -- --watch' npm:backend:start",
"ci:backend:test": "npm run backend:info && npm run backend:doc:test && npm run backend:nohttp:test && npm run backend:unit:test -- -P$npm_package_config_default_environment",
"ci:e2e:package": "npm run java:$npm_package_config_packaging:$npm_package_config_default_environment -- -Pe2e -Denforcer.skip=true",
"ci:e2e:prepare": "npm run ci:e2e:prepare:docker",
"ci:e2e:prepare:docker": "npm run docker:db:up && npm run docker:others:up && docker ps -a",
"preci:e2e:server:start": "npm run docker:db:await --if-present && npm run docker:others:await --if-present",
"ci:e2e:server:start": "java -jar target/e2e.$npm_package_config_packaging --spring.profiles.active=e2e,$npm_package_config_default_environment -Dlogging.level.ROOT=OFF -Dlogging.level.org.zalando=OFF -Dlogging.level.tech.jhipster=OFF -Dlogging.level.org.gcube.fullstackapps.informationsystemmonitor=OFF -Dlogging.level.org.springframework=OFF -Dlogging.level.org.springframework.web=OFF -Dlogging.level.org.springframework.security=OFF --logging.level.org.springframework.web=ERROR",
"ci:e2e:teardown": "npm run ci:e2e:teardown:docker",
"ci:e2e:teardown:docker": "npm run docker:db:down --if-present && npm run docker:others:down && docker ps -a",
"ci:frontend:build": "npm run webapp:build:$npm_package_config_default_environment",
"ci:frontend:test": "npm run ci:frontend:build && npm test",
"clean-www": "rimraf target/classes/static/app/{src,target/}",
"cleanup": "rimraf target/classes/static/",
"docker:app:up": "docker-compose -f src/main/docker/app.yml up -d",
"docker:db:up": "echo \"Docker for db no not configured for application informationsystemmonitor\"",
"docker:keycloak:await": "echo \"Waiting for keycloak to start\" && wait-on -t 180000 http-get://localhost:9080/realms/jhipster && echo \"keycloak started\" || echo \"keycloak not running, make sure oauth2 server is running\"",
"docker:keycloak:down": "docker-compose -f src/main/docker/keycloak.yml down -v",
"docker:keycloak:up": "docker-compose -f src/main/docker/keycloak.yml up -d",
"docker:others:await": "npm run docker:keycloak:await",
"docker:others:down": "npm run docker:keycloak:down",
"predocker:others:up": "",
"docker:others:up": "npm run docker:keycloak:up",
"java:docker": "./mvnw -ntp verify -DskipTests -Pprod jib:dockerBuild",
"java:docker:arm64": "npm run java:docker -- -Djib-maven-plugin.architecture=arm64",
"java:docker:dev": "npm run java:docker -- -Pdev,webapp",
"java:docker:prod": "npm run java:docker -- -Pprod",
"java:jar": "./mvnw -ntp verify -DskipTests --batch-mode",
"java:jar:dev": "npm run java:jar -- -Pdev,webapp",
"java:jar:prod": "npm run java:jar -- -Pprod",
"java:war": "./mvnw -ntp verify -DskipTests --batch-mode -Pwar",
"java:war:dev": "npm run java:war -- -Pdev,webapp",
"java:war:prod": "npm run java:war -- -Pprod",
"jest": "jest --coverage --logHeapUsage --maxWorkers=2 --config jest.conf.js",
"lint": "eslint . --ext .js,.ts",
"lint:fix": "npm run lint -- --fix",
"prettier:check": "prettier --check \"{,src/**/,webpack/,.blueprint/**/}*.{md,json,yml,html,cjs,mjs,js,ts,tsx,css,scss,java}\"",
"prettier:format": "prettier --write \"{,src/**/,webpack/,.blueprint/**/}*.{md,json,yml,html,cjs,mjs,js,ts,tsx,css,scss,java}\"",
"serve": "npm run start --",
"start": "ng serve --hmr",
"start-tls": "npm run webapp:dev-ssl",
"pretest": "npm run lint",
"test": "ng test --coverage --log-heap-usage -w=2",
"test:watch": "npm run test -- --watch",
"watch": "concurrently npm:start npm:backend:start",
"webapp:build": "npm run clean-www && npm run webapp:build:dev",
"webapp:build:dev": "ng build --configuration development",
"webapp:build:prod": "ng build --configuration production",
"webapp:dev": "ng serve",
"webapp:dev-ssl": "ng serve --ssl",
"webapp:dev-verbose": "ng serve --verbose",
"webapp:prod": "npm run clean-www && npm run webapp:build:prod",
"webapp:test": "npm run test --"
},
"config": {
"backend_port": "8080",
"default_environment": "prod",
"packaging": "jar"
},
"dependencies": {
"@angular/common": "14.2.0",
"@angular/compiler": "14.2.0",
"@angular/core": "14.2.0",
"@angular/forms": "14.2.0",
"@angular/localize": "14.2.0",
"@angular/platform-browser": "14.2.0",
"@angular/platform-browser-dynamic": "14.2.0",
"@angular/router": "14.2.0",
"@fortawesome/angular-fontawesome": "0.11.1",
"@fortawesome/fontawesome-svg-core": "6.2.0",
"@fortawesome/free-solid-svg-icons": "6.2.0",
"@ng-bootstrap/ng-bootstrap": "13.0.0",
"@ngx-translate/core": "14.0.0",
"@ngx-translate/http-loader": "7.0.0",
"@popperjs/core": "2.11.6",
"bootstrap": "5.2.0",
"cytoscape": "3.25.0",
"dayjs": "1.11.5",
"ngx-infinite-scroll": "14.0.0",
"ngx-webstorage": "10.0.1",
"rxjs": "7.5.6",
"tslib": "2.4.0",
"zone.js": "0.11.6"
},
"devDependencies": {
"@angular-builders/custom-webpack": "14.0.1",
"@angular-builders/jest": "14.0.1",
"@angular-devkit/build-angular": "14.2.1",
"@angular-eslint/eslint-plugin": "14.0.3",
"@angular/cli": "14.2.1",
"@angular/compiler-cli": "14.2.0",
"@angular/service-worker": "14.2.0",
"@types/cytoscape": "3.19.10",
"@types/jest": "28.1.8",
"@types/node": "16.11.56",
"@typescript-eslint/eslint-plugin": "5.36.1",
"@typescript-eslint/parser": "5.36.1",
"browser-sync": "2.27.10",
"browser-sync-webpack-plugin": "2.3.0",
"concurrently": "7.3.0",
"copy-webpack-plugin": "11.0.0",
"eslint": "8.23.0",
"eslint-config-prettier": "8.5.0",
"eslint-webpack-plugin": "3.2.0",
"folder-hash": "4.0.2",
"generator-jhipster": "7.9.3",
"jest": "28.1.3",
"jest-date-mock": "1.0.8",
"jest-environment-jsdom": "28.1.3",
"jest-junit": "14.0.1",
"jest-preset-angular": "12.2.2",
"jest-sonar": "0.2.12",
"merge-jsons-webpack-plugin": "2.0.1",
"prettier": "2.7.1",
"prettier-plugin-java": "1.6.2",
"prettier-plugin-packagejson": "2.2.18",
"rimraf": "3.0.2",
"swagger-ui-dist": "4.14.0",
"ts-jest": "28.0.8",
"typescript": "4.8.2",
"wait-on": "6.0.1",
"webpack-bundle-analyzer": "4.6.1",
"webpack-merge": "5.8.0",
"webpack-notifier": "1.15.0"
},
"engines": {
"node": ">=16.17.0"
},
"cacheDirectories": [
"node_modules"
],
"overrides": {
"webpack": "5.74.0"
}
}

1212
pom.xml Normal file

File diff suppressed because it is too large Load Diff

31
sonar-project.properties Normal file
View File

@ -0,0 +1,31 @@
sonar.projectKey=informationsystemmonitor
sonar.projectName=informationsystemmonitor generated by jhipster
# Typescript tests files must be inside sources and tests, othewise `INFO: Test execution data ignored for 80 unknown files, including:` is shown.
sonar.sources=src
sonar.tests=src
sonar.host.url=http://localhost:9001
sonar.test.inclusions=src/test/**/*.*, src/main/webapp/app/**/*.spec.ts
sonar.coverage.jacoco.xmlReportPaths=target/site/**/jacoco*.xml
sonar.java.codeCoveragePlugin=jacoco
sonar.junit.reportPaths=target/surefire-reports,target/failsafe-reports
sonar.testExecutionReportPaths=target/test-results/jest/TESTS-results-sonar.xml
sonar.javascript.lcov.reportPaths=target/test-results/lcov.info
sonar.sourceEncoding=UTF-8
sonar.exclusions=src/main/webapp/content/**/*.*, src/main/webapp/i18n/*.js, target/classes/static/**/*.*
sonar.issue.ignore.multicriteria=S3437,S4684,S5145,UndocumentedApi
# Rule https://rules.sonarsource.com/java/RSPEC-3437 is ignored, as a JPA-managed field cannot be transient
sonar.issue.ignore.multicriteria.S3437.resourceKey=src/main/java/**/*
sonar.issue.ignore.multicriteria.S3437.ruleKey=squid:S3437
# Rule https://rules.sonarsource.com/java/RSPEC-4684
sonar.issue.ignore.multicriteria.S4684.resourceKey=src/main/java/**/*
sonar.issue.ignore.multicriteria.S4684.ruleKey=java:S4684
# Rule https://rules.sonarsource.com/java/RSPEC-5145 log filter is applied
sonar.issue.ignore.multicriteria.S5145.resourceKey=src/main/java/**/*
sonar.issue.ignore.multicriteria.S5145.ruleKey=javasecurity:S5145
# Rule https://rules.sonarsource.com/java/RSPEC-1176 is ignored, as we want to follow "clean code" guidelines and classes, methods and arguments names should be self-explanatory
sonar.issue.ignore.multicriteria.UndocumentedApi.resourceKey=src/main/java/**/*
sonar.issue.ignore.multicriteria.UndocumentedApi.ruleKey=squid:UndocumentedApi

34
src/main/docker/app.yml Normal file
View File

@ -0,0 +1,34 @@
# This configuration is intended for development purpose, it's **your** responsibility to harden it for production
version: '3.8'
services:
informationsystemmonitor-app:
image: informationsystemmonitor
environment:
- _JAVA_OPTIONS=-Xmx512m -Xms256m
- SPRING_PROFILES_ACTIVE=prod,api-docs
- MANAGEMENT_METRICS_EXPORT_PROMETHEUS_ENABLED=true
- SPRING_SECURITY_OAUTH2_CLIENT_PROVIDER_OIDC_ISSUER_URI=http://keycloak:9080/realms/jhipster
- SPRING_SECURITY_OAUTH2_CLIENT_REGISTRATION_OIDC_CLIENT_ID=web_app
- SPRING_SECURITY_OAUTH2_CLIENT_REGISTRATION_OIDC_CLIENT_SECRET=web_app
- JHIPSTER_SLEEP=30 # gives time for other services to boot before the application
# If you want to expose these ports outside your dev PC,
# remove the "127.0.0.1:" prefix
ports:
- 127.0.0.1:8080:8080
keycloak:
image: quay.io/keycloak/keycloak:19.0.1
command: ['start-dev --import-realm']
volumes:
- ./realm-config:/opt/keycloak/data/import
environment:
- KC_DB=dev-file
- KEYCLOAK_ADMIN=admin
- KEYCLOAK_ADMIN_PASSWORD=admin
- KC_FEATURES=scripts
- KC_HTTP_PORT=9080
- KC_HTTPS_PORT=9443
# If you want to expose these ports outside your dev PC,
# remove the "127.0.0.1:" prefix
ports:
- 127.0.0.1:9080:9080
- 127.0.0.1:9443:9443

View File

@ -0,0 +1 @@
# Central configuration sources details

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,11 @@
apiVersion: 1
providers:
- name: 'Prometheus'
orgId: 1
folder: ''
type: file
disableDeletion: false
editable: true
options:
path: /etc/grafana/provisioning/dashboards

View File

@ -0,0 +1,50 @@
apiVersion: 1
# list of datasources that should be deleted from the database
deleteDatasources:
- name: Prometheus
orgId: 1
# list of datasources to insert/update depending
# whats available in the database
datasources:
# <string, required> name of the datasource. Required
- name: Prometheus
# <string, required> datasource type. Required
type: prometheus
# <string, required> access mode. direct or proxy. Required
access: proxy
# <int> org id. will default to orgId 1 if not specified
orgId: 1
# <string> url
# On MacOS, replace localhost by host.docker.internal
url: http://localhost:9090
# <string> database password, if used
password:
# <string> database user, if used
user:
# <string> database name, if used
database:
# <bool> enable/disable basic auth
basicAuth: false
# <string> basic auth username
basicAuthUser: admin
# <string> basic auth password
basicAuthPassword: admin
# <bool> enable/disable with credentials headers
withCredentials:
# <bool> mark as default datasource. Max one per org
isDefault: true
# <map> fields that will be converted to json and stored in json_data
jsonData:
graphiteVersion: '1.1'
tlsAuth: false
tlsAuthWithCACert: false
# <string> json object of data that will be encrypted.
secureJsonData:
tlsCACert: '...'
tlsClientCert: '...'
tlsClientKey: '...'
version: 1
# <bool> allow users to edit datasources from the UI.
editable: true

View File

@ -0,0 +1,53 @@
## How to use JHCC docker compose
# To allow JHCC to reach JHipster application from a docker container note that we set the host as host.docker.internal
# To reach the application from a browser, you need to add '127.0.0.1 host.docker.internal' to your hosts file.
### Discovery mode
# JHCC support 3 kinds of discovery mode: Consul, Eureka and static
# In order to use one, please set SPRING_PROFILES_ACTIVE to one (and only one) of this values: consul,eureka,static
### Discovery properties
# According to the discovery mode choose as Spring profile, you have to set the right properties
# please note that current properties are set to run JHCC with default values, personalize them if needed
# and remove those from other modes. You can only have one mode active.
#### Eureka
# - EUREKA_CLIENT_SERVICE_URL_DEFAULTZONE=http://admin:admin@host.docker.internal:8761/eureka/
#### Consul
# - SPRING_CLOUD_CONSUL_HOST=host.docker.internal
# - SPRING_CLOUD_CONSUL_PORT=8500
#### Static
# Add instances to "MyApp"
# - SPRING_CLOUD_DISCOVERY_CLIENT_SIMPLE_INSTANCES_MYAPP_0_URI=http://host.docker.internal:8081
# - SPRING_CLOUD_DISCOVERY_CLIENT_SIMPLE_INSTANCES_MYAPP_1_URI=http://host.docker.internal:8082
# Or add a new application named MyNewApp
# - SPRING_CLOUD_DISCOVERY_CLIENT_SIMPLE_INSTANCES_MYNEWAPP_0_URI=http://host.docker.internal:8080
# This configuration is intended for development purpose, it's **your** responsibility to harden it for production
#### IMPORTANT
# If you choose Consul or Eureka mode:
# Do not forget to remove the prefix "127.0.0.1" in front of their port in order to expose them.
# This is required because JHCC need to communicate with Consul or Eureka.
# - In Consul mode, the ports are in the consul.yml file.
# - In Eureka mode, the ports are in the jhipster-registry.yml file.
version: '3.8'
services:
jhipster-control-center:
image: 'jhipster/jhipster-control-center:v0.5.0'
command:
- /bin/sh
- -c
# Patch /etc/hosts to support resolving host.docker.internal to the internal IP address used by the host in all OSes
- echo "`ip route | grep default | cut -d ' ' -f3` host.docker.internal" | tee -a /etc/hosts > /dev/null && java -jar /jhipster-control-center.jar
environment:
- _JAVA_OPTIONS=-Xmx512m -Xms256m
- SPRING_PROFILES_ACTIVE=prod,api-docs,static,oauth2
- JHIPSTER_SLEEP=30 # gives time for other services to boot before the application
# For keycloak to work, you need to add '127.0.0.1 keycloak' to your hosts file
- SPRING_SECURITY_OAUTH2_CLIENT_PROVIDER_OIDC_ISSUER_URI=http://keycloak:9080/realms/jhipster
- SPRING_SECURITY_OAUTH2_CLIENT_REGISTRATION_OIDC_CLIENT_ID=jhipster-control-center
- SPRING_SECURITY_OAUTH2_CLIENT_REGISTRATION_OIDC_CLIENT_SECRET=jhipster-control-center
- SPRING_CLOUD_DISCOVERY_CLIENT_SIMPLE_INSTANCES_INFORMATIONSYSTEMMONITOR_0_URI=http://host.docker.internal:8080
- LOGGING_FILE_NAME=/tmp/jhipster-control-center.log
# If you want to expose these ports outside your dev PC,
# remove the "127.0.0.1:" prefix
ports:
- 127.0.0.1:7419:7419

View File

@ -0,0 +1,39 @@
#!/bin/bash
echo "The application will start in ${JHIPSTER_SLEEP}s..." && sleep ${JHIPSTER_SLEEP}
# usage: file_env VAR [DEFAULT]
# ie: file_env 'XYZ_DB_PASSWORD' 'example'
# (will allow for "$XYZ_DB_PASSWORD_FILE" to fill in the value of
# "$XYZ_DB_PASSWORD" from a file, especially for Docker's secrets feature)
file_env() {
local var="$1"
local fileVar="${var}_FILE"
local def="${2:-}"
if [[ ${!var:-} && ${!fileVar:-} ]]; then
echo >&2 "error: both $var and $fileVar are set (but are exclusive)"
exit 1
fi
local val="$def"
if [[ ${!var:-} ]]; then
val="${!var}"
elif [[ ${!fileVar:-} ]]; then
val="$(< "${!fileVar}")"
fi
if [[ -n $val ]]; then
export "$var"="$val"
fi
unset "$fileVar"
}
file_env 'SPRING_DATASOURCE_URL'
file_env 'SPRING_DATASOURCE_USERNAME'
file_env 'SPRING_DATASOURCE_PASSWORD'
file_env 'SPRING_LIQUIBASE_URL'
file_env 'SPRING_LIQUIBASE_USER'
file_env 'SPRING_LIQUIBASE_PASSWORD'
file_env 'JHIPSTER_REGISTRY_PASSWORD'
exec java ${JAVA_OPTS} -noverify -XX:+AlwaysPreTouch -Djava.security.egd=file:/dev/./urandom -cp /app/resources/:/app/classes/:/app/libs/* "org.gcube.fullstackapps.informationsystemmonitor.InformationsystemmonitorApp" "$@"

View File

@ -0,0 +1,20 @@
# This configuration is intended for development purpose, it's **your** responsibility to harden it for production
version: '3.8'
services:
keycloak:
image: quay.io/keycloak/keycloak:19.0.1
command: ['start-dev --import-realm']
volumes:
- ./realm-config:/opt/keycloak/data/import
environment:
- KC_DB=dev-file
- KEYCLOAK_ADMIN=admin
- KEYCLOAK_ADMIN_PASSWORD=admin
- KC_FEATURES=scripts
- KC_HTTP_PORT=9080
- KC_HTTPS_PORT=9443
# If you want to expose these ports outside your dev PC,
# remove the "127.0.0.1:" prefix
ports:
- 127.0.0.1:9080:9080
- 127.0.0.1:9443:9443

View File

@ -0,0 +1,31 @@
# This configuration is intended for development purpose, it's **your** responsibility to harden it for production
version: '3.8'
services:
informationsystemmonitor-prometheus:
image: prom/prometheus:v2.38.0
volumes:
- ./prometheus/:/etc/prometheus/
command:
- '--config.file=/etc/prometheus/prometheus.yml'
# If you want to expose these ports outside your dev PC,
# remove the "127.0.0.1:" prefix
ports:
- 127.0.0.1:9090:9090
# On MacOS, remove next line and replace localhost by host.docker.internal in prometheus/prometheus.yml and
# grafana/provisioning/datasources/datasource.yml
network_mode: 'host' # to test locally running service
informationsystemmonitor-grafana:
image: grafana/grafana:9.1.0
volumes:
- ./grafana/provisioning/:/etc/grafana/provisioning/
environment:
- GF_SECURITY_ADMIN_PASSWORD=admin
- GF_USERS_ALLOW_SIGN_UP=false
- GF_INSTALL_PLUGINS=grafana-piechart-panel
# If you want to expose these ports outside your dev PC,
# remove the "127.0.0.1:" prefix
ports:
- 127.0.0.1:3000:3000
# On MacOS, remove next line and replace localhost by host.docker.internal in prometheus/prometheus.yml and
# grafana/provisioning/datasources/datasource.yml
network_mode: 'host' # to test locally running service

View File

@ -0,0 +1,31 @@
# Sample global config for monitoring JHipster applications
global:
scrape_interval: 15s # By default, scrape targets every 15 seconds.
evaluation_interval: 15s # By default, scrape targets every 15 seconds.
# scrape_timeout is set to the global default (10s).
# Attach these labels to any time series or alerts when communicating with
# external systems (federation, remote storage, Alertmanager).
external_labels:
monitor: 'jhipster'
# A scrape configuration containing exactly one endpoint to scrape:
# Here it's Prometheus itself.
scrape_configs:
# The job name is added as a label `job=<job_name>` to any timeseries scraped from this config.
- job_name: 'prometheus'
# Override the global default and scrape targets from this job every 5 seconds.
scrape_interval: 5s
# scheme defaults to 'http' enable https in case your application is server via https
#scheme: https
# basic auth is not needed by default. See https://www.jhipster.tech/monitoring/#configuring-metrics-forwarding for details
#basic_auth:
# username: admin
# password: admin
metrics_path: /management/prometheus
static_configs:
- targets:
# On MacOS, replace localhost by host.docker.internal
- localhost:8080

File diff suppressed because it is too large Load Diff

13
src/main/docker/sonar.yml Normal file
View File

@ -0,0 +1,13 @@
# This configuration is intended for development purpose, it's **your** responsibility to harden it for production
version: '3.8'
services:
informationsystemmonitor-sonar:
image: sonarqube:9.6.0-community
# Authentication is turned off for out of the box experience while trying out SonarQube
# For real use cases delete sonar.forceAuthentication variable or set sonar.forceAuthentication=true
environment:
- sonar.forceAuthentication=false
# If you want to expose these ports outside your dev PC,
# remove the "127.0.0.1:" prefix
ports:
- 127.0.0.1:9001:9000

View File

@ -0,0 +1,7 @@
# This configuration is intended for development purpose, it's **your** responsibility to harden it for production
version: '3.8'
services:
swagger-editor:
image: swaggerapi/swagger-editor:latest
ports:
- 127.0.0.1:7742:8080

View File

@ -0,0 +1,7 @@
# This configuration is intended for development purpose, it's **your** responsibility to harden it for production
version: '3.8'
services:
zipkin:
image: openzipkin/zipkin:2.23
ports:
- 127.0.0.1:9411:9411

View File

@ -0,0 +1,19 @@
package org.gcube.fullstackapps.informationsystemmonitor;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
import tech.jhipster.config.DefaultProfileUtil;
/**
* This is a helper Java class that provides an alternative to creating a {@code web.xml}.
* This will be invoked only when the application is deployed to a Servlet container like Tomcat, JBoss etc.
*/
public class ApplicationWebXml extends SpringBootServletInitializer {
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
// set a default to use when no profile is configured.
DefaultProfileUtil.addDefaultProfile(application.application());
return application.sources(InformationsystemmonitorApp.class);
}
}

View File

@ -0,0 +1,13 @@
package org.gcube.fullstackapps.informationsystemmonitor;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import javax.annotation.Generated;
@Generated(value = "JHipster", comments = "Generated by JHipster 7.9.3")
@Retention(RetentionPolicy.SOURCE)
@Target({ ElementType.TYPE })
public @interface GeneratedByJHipster {
}

View File

@ -0,0 +1,104 @@
package org.gcube.fullstackapps.informationsystemmonitor;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.Arrays;
import java.util.Collection;
import java.util.Optional;
import javax.annotation.PostConstruct;
import org.apache.commons.lang3.StringUtils;
import org.gcube.fullstackapps.informationsystemmonitor.config.ApplicationProperties;
import org.gcube.fullstackapps.informationsystemmonitor.config.CRLFLogConverter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.core.env.Environment;
import tech.jhipster.config.DefaultProfileUtil;
import tech.jhipster.config.JHipsterConstants;
@SpringBootApplication
@EnableConfigurationProperties({ ApplicationProperties.class })
public class InformationsystemmonitorApp {
private static final Logger log = LoggerFactory.getLogger(InformationsystemmonitorApp.class);
private final Environment env;
public InformationsystemmonitorApp(Environment env) {
this.env = env;
}
/**
* Initializes informationsystemmonitor.
* <p>
* Spring profiles can be configured with a program argument --spring.profiles.active=your-active-profile
* <p>
* You can find more information on how profiles work with JHipster on <a href="https://www.jhipster.tech/profiles/">https://www.jhipster.tech/profiles/</a>.
*/
@PostConstruct
public void initApplication() {
Collection<String> activeProfiles = Arrays.asList(env.getActiveProfiles());
if (
activeProfiles.contains(JHipsterConstants.SPRING_PROFILE_DEVELOPMENT) &&
activeProfiles.contains(JHipsterConstants.SPRING_PROFILE_PRODUCTION)
) {
log.error(
"You have misconfigured your application! It should not run " + "with both the 'dev' and 'prod' profiles at the same time."
);
}
if (
activeProfiles.contains(JHipsterConstants.SPRING_PROFILE_DEVELOPMENT) &&
activeProfiles.contains(JHipsterConstants.SPRING_PROFILE_CLOUD)
) {
log.error(
"You have misconfigured your application! It should not " + "run with both the 'dev' and 'cloud' profiles at the same time."
);
}
}
/**
* Main method, used to run the application.
*
* @param args the command line arguments.
*/
public static void main(String[] args) {
SpringApplication app = new SpringApplication(InformationsystemmonitorApp.class);
DefaultProfileUtil.addDefaultProfile(app);
Environment env = app.run(args).getEnvironment();
logApplicationStartup(env);
}
private static void logApplicationStartup(Environment env) {
String protocol = Optional.ofNullable(env.getProperty("server.ssl.key-store")).map(key -> "https").orElse("http");
String serverPort = env.getProperty("server.port");
String contextPath = Optional
.ofNullable(env.getProperty("server.servlet.context-path"))
.filter(StringUtils::isNotBlank)
.orElse("/");
String hostAddress = "localhost";
try {
hostAddress = InetAddress.getLocalHost().getHostAddress();
} catch (UnknownHostException e) {
log.warn("The host name could not be determined, using `localhost` as fallback");
}
log.info(
CRLFLogConverter.CRLF_SAFE_MARKER,
"\n----------------------------------------------------------\n\t" +
"Application '{}' is running! Access URLs:\n\t" +
"Local: \t\t{}://localhost:{}{}\n\t" +
"External: \t{}://{}:{}{}\n\t" +
"Profile(s): \t{}\n----------------------------------------------------------",
env.getProperty("spring.application.name"),
protocol,
serverPort,
contextPath,
protocol,
hostAddress,
serverPort,
contextPath,
env.getActiveProfiles().length == 0 ? env.getDefaultProfiles() : env.getActiveProfiles()
);
}
}

View File

@ -0,0 +1,115 @@
package org.gcube.fullstackapps.informationsystemmonitor.aop.logging;
import java.util.Arrays;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.env.Environment;
import org.springframework.core.env.Profiles;
import tech.jhipster.config.JHipsterConstants;
/**
* Aspect for logging execution of service and repository Spring components.
*
* By default, it only runs with the "dev" profile.
*/
@Aspect
public class LoggingAspect {
private final Environment env;
public LoggingAspect(Environment env) {
this.env = env;
}
/**
* Pointcut that matches all repositories, services and Web REST endpoints.
*/
@Pointcut(
"within(@org.springframework.stereotype.Repository *)" +
" || within(@org.springframework.stereotype.Service *)" +
" || within(@org.springframework.web.bind.annotation.RestController *)"
)
public void springBeanPointcut() {
// Method is empty as this is just a Pointcut, the implementations are in the advices.
}
/**
* Pointcut that matches all Spring beans in the application's main packages.
*/
@Pointcut(
"within(org.gcube.fullstackapps.informationsystemmonitor.repository..*)" +
" || within(org.gcube.fullstackapps.informationsystemmonitor.service..*)" +
" || within(org.gcube.fullstackapps.informationsystemmonitor.web.rest..*)"
)
public void applicationPackagePointcut() {
// Method is empty as this is just a Pointcut, the implementations are in the advices.
}
/**
* Retrieves the {@link Logger} associated to the given {@link JoinPoint}.
*
* @param joinPoint join point we want the logger for.
* @return {@link Logger} associated to the given {@link JoinPoint}.
*/
private Logger logger(JoinPoint joinPoint) {
return LoggerFactory.getLogger(joinPoint.getSignature().getDeclaringTypeName());
}
/**
* Advice that logs methods throwing exceptions.
*
* @param joinPoint join point for advice.
* @param e exception.
*/
@AfterThrowing(pointcut = "applicationPackagePointcut() && springBeanPointcut()", throwing = "e")
public void logAfterThrowing(JoinPoint joinPoint, Throwable e) {
if (env.acceptsProfiles(Profiles.of(JHipsterConstants.SPRING_PROFILE_DEVELOPMENT))) {
logger(joinPoint)
.error(
"Exception in {}() with cause = '{}' and exception = '{}'",
joinPoint.getSignature().getName(),
e.getCause() != null ? e.getCause() : "NULL",
e.getMessage(),
e
);
} else {
logger(joinPoint)
.error(
"Exception in {}() with cause = {}",
joinPoint.getSignature().getName(),
e.getCause() != null ? e.getCause() : "NULL"
);
}
}
/**
* Advice that logs when a method is entered and exited.
*
* @param joinPoint join point for advice.
* @return result.
* @throws Throwable throws {@link IllegalArgumentException}.
*/
@Around("applicationPackagePointcut() && springBeanPointcut()")
public Object logAround(ProceedingJoinPoint joinPoint) throws Throwable {
Logger log = logger(joinPoint);
if (log.isDebugEnabled()) {
log.debug("Enter: {}() with argument[s] = {}", joinPoint.getSignature().getName(), Arrays.toString(joinPoint.getArgs()));
}
try {
Object result = joinPoint.proceed();
if (log.isDebugEnabled()) {
log.debug("Exit: {}() with result = {}", joinPoint.getSignature().getName(), result);
}
return result;
} catch (IllegalArgumentException e) {
log.error("Illegal argument: {} in {}()", Arrays.toString(joinPoint.getArgs()), joinPoint.getSignature().getName());
throw e;
}
}
}

View File

@ -0,0 +1,16 @@
package org.gcube.fullstackapps.informationsystemmonitor.config;
import org.springframework.boot.context.properties.ConfigurationProperties;
/**
* Properties specific to Informationsystemmonitor.
* <p>
* Properties are configured in the {@code application.yml} file.
* See {@link tech.jhipster.config.JHipsterProperties} for a good example.
*/
@ConfigurationProperties(prefix = "application", ignoreUnknownFields = false)
public class ApplicationProperties {
// jhipster-needle-application-properties-property
// jhipster-needle-application-properties-property-getter
// jhipster-needle-application-properties-property-class
}

View File

@ -0,0 +1,48 @@
package org.gcube.fullstackapps.informationsystemmonitor.config;
import java.util.concurrent.Executor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.aop.interceptor.AsyncUncaughtExceptionHandler;
import org.springframework.aop.interceptor.SimpleAsyncUncaughtExceptionHandler;
import org.springframework.boot.autoconfigure.task.TaskExecutionProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;
import org.springframework.scheduling.annotation.AsyncConfigurer;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import tech.jhipster.async.ExceptionHandlingAsyncTaskExecutor;
@Configuration
@EnableAsync
@EnableScheduling
@Profile("!testdev & !testprod")
public class AsyncConfiguration implements AsyncConfigurer {
private final Logger log = LoggerFactory.getLogger(AsyncConfiguration.class);
private final TaskExecutionProperties taskExecutionProperties;
public AsyncConfiguration(TaskExecutionProperties taskExecutionProperties) {
this.taskExecutionProperties = taskExecutionProperties;
}
@Override
@Bean(name = "taskExecutor")
public Executor getAsyncExecutor() {
log.debug("Creating Async Task Executor");
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(taskExecutionProperties.getPool().getCoreSize());
executor.setMaxPoolSize(taskExecutionProperties.getPool().getMaxSize());
executor.setQueueCapacity(taskExecutionProperties.getPool().getQueueCapacity());
executor.setThreadNamePrefix(taskExecutionProperties.getThreadNamePrefix());
return new ExceptionHandlingAsyncTaskExecutor(executor);
}
@Override
public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
return new SimpleAsyncUncaughtExceptionHandler();
}
}

View File

@ -0,0 +1,56 @@
package org.gcube.fullstackapps.informationsystemmonitor.config;
import ch.qos.logback.classic.spi.ILoggingEvent;
import ch.qos.logback.core.pattern.CompositeConverter;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import org.slf4j.Marker;
import org.slf4j.MarkerFactory;
import org.springframework.boot.ansi.AnsiColor;
import org.springframework.boot.ansi.AnsiElement;
import org.springframework.boot.ansi.AnsiOutput;
import org.springframework.boot.ansi.AnsiStyle;
public class CRLFLogConverter extends CompositeConverter<ILoggingEvent> {
public static final Marker CRLF_SAFE_MARKER = MarkerFactory.getMarker("CRLF_SAFE");
private static final String[] SAFE_LOGGERS = { "org.hibernate" };
private static final Map<String, AnsiElement> ELEMENTS;
static {
Map<String, AnsiElement> ansiElements = new HashMap<>();
ansiElements.put("faint", AnsiStyle.FAINT);
ansiElements.put("red", AnsiColor.RED);
ansiElements.put("green", AnsiColor.GREEN);
ansiElements.put("yellow", AnsiColor.YELLOW);
ansiElements.put("blue", AnsiColor.BLUE);
ansiElements.put("magenta", AnsiColor.MAGENTA);
ansiElements.put("cyan", AnsiColor.CYAN);
ELEMENTS = Collections.unmodifiableMap(ansiElements);
}
@Override
protected String transform(ILoggingEvent event, String in) {
AnsiElement element = ELEMENTS.get(getFirstOption());
if ((event.getMarker() != null && event.getMarker().contains(CRLF_SAFE_MARKER)) || isLoggerSafe(event)) {
return in;
}
String replacement = element == null ? "_" : toAnsiString("_", element);
return in.replaceAll("[\n\r\t]", replacement);
}
protected boolean isLoggerSafe(ILoggingEvent event) {
for (String safeLogger : SAFE_LOGGERS) {
if (event.getLoggerName().startsWith(safeLogger)) {
return true;
}
}
return false;
}
protected String toAnsiString(String in, AnsiElement element) {
return AnsiOutput.toString(element, in);
}
}

View File

@ -0,0 +1,15 @@
package org.gcube.fullstackapps.informationsystemmonitor.config;
/**
* Application constants.
*/
public final class Constants {
// Regex for acceptable logins
public static final String LOGIN_REGEX = "^(?>[a-zA-Z0-9!$&*+=?^_`{|}~.-]+@[a-zA-Z0-9-]+(?:\\.[a-zA-Z0-9-]+)*)|(?>[_.@A-Za-z0-9-]+)$";
public static final String SYSTEM = "system";
public static final String DEFAULT_LANGUAGE = "en";
private Constants() {}
}

View File

@ -0,0 +1,20 @@
package org.gcube.fullstackapps.informationsystemmonitor.config;
import org.springframework.context.annotation.Configuration;
import org.springframework.format.FormatterRegistry;
import org.springframework.format.datetime.standard.DateTimeFormatterRegistrar;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
/**
* Configure the converters to use the ISO format for dates by default.
*/
@Configuration
public class DateTimeFormatConfiguration implements WebMvcConfigurer {
@Override
public void addFormatters(FormatterRegistry registry) {
DateTimeFormatterRegistrar registrar = new DateTimeFormatterRegistrar();
registrar.setUseIsoFormat(true);
registrar.registerFormatters(registry);
}
}

View File

@ -0,0 +1,42 @@
package org.gcube.fullstackapps.informationsystemmonitor.config;
import com.fasterxml.jackson.datatype.jdk8.Jdk8Module;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.zalando.problem.jackson.ProblemModule;
import org.zalando.problem.violations.ConstraintViolationProblemModule;
@Configuration
public class JacksonConfiguration {
/**
* Support for Java date and time API.
* @return the corresponding Jackson module.
*/
@Bean
public JavaTimeModule javaTimeModule() {
return new JavaTimeModule();
}
@Bean
public Jdk8Module jdk8TimeModule() {
return new Jdk8Module();
}
/*
* Module for serialization/deserialization of RFC7807 Problem.
*/
@Bean
public ProblemModule problemModule() {
return new ProblemModule();
}
/*
* Module for serialization/deserialization of ConstraintViolationProblem.
*/
@Bean
public ConstraintViolationProblemModule constraintViolationProblemModule() {
return new ConstraintViolationProblemModule();
}
}

View File

@ -0,0 +1,26 @@
package org.gcube.fullstackapps.informationsystemmonitor.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.LocaleResolver;
import org.springframework.web.servlet.config.annotation.*;
import org.springframework.web.servlet.i18n.LocaleChangeInterceptor;
import tech.jhipster.config.locale.AngularCookieLocaleResolver;
@Configuration
public class LocaleConfiguration implements WebMvcConfigurer {
@Bean
public LocaleResolver localeResolver() {
AngularCookieLocaleResolver cookieLocaleResolver = new AngularCookieLocaleResolver();
cookieLocaleResolver.setCookieName("NG_TRANSLATE_LANG_KEY");
return cookieLocaleResolver;
}
@Override
public void addInterceptors(InterceptorRegistry registry) {
LocaleChangeInterceptor localeChangeInterceptor = new LocaleChangeInterceptor();
localeChangeInterceptor.setParamName("language");
registry.addInterceptor(localeChangeInterceptor);
}
}

View File

@ -0,0 +1,17 @@
package org.gcube.fullstackapps.informationsystemmonitor.config;
import org.gcube.fullstackapps.informationsystemmonitor.aop.logging.LoggingAspect;
import org.springframework.context.annotation.*;
import org.springframework.core.env.Environment;
import tech.jhipster.config.JHipsterConstants;
@Configuration
@EnableAspectJAutoProxy
public class LoggingAspectConfiguration {
@Bean
@Profile(JHipsterConstants.SPRING_PROFILE_DEVELOPMENT)
public LoggingAspect loggingAspect(Environment env) {
return new LoggingAspect(env);
}
}

View File

@ -0,0 +1,47 @@
package org.gcube.fullstackapps.informationsystemmonitor.config;
import static tech.jhipster.config.logging.LoggingUtils.*;
import ch.qos.logback.classic.LoggerContext;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.util.HashMap;
import java.util.Map;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
import tech.jhipster.config.JHipsterProperties;
/*
* Configures the console and Logstash log appenders from the app properties
*/
@Configuration
public class LoggingConfiguration {
public LoggingConfiguration(
@Value("${spring.application.name}") String appName,
@Value("${server.port}") String serverPort,
JHipsterProperties jHipsterProperties,
ObjectMapper mapper
) throws JsonProcessingException {
LoggerContext context = (LoggerContext) LoggerFactory.getILoggerFactory();
Map<String, String> map = new HashMap<>();
map.put("app_name", appName);
map.put("app_port", serverPort);
String customFields = mapper.writeValueAsString(map);
JHipsterProperties.Logging loggingProperties = jHipsterProperties.getLogging();
JHipsterProperties.Logging.Logstash logstashProperties = loggingProperties.getLogstash();
if (loggingProperties.isUseJsonFormat()) {
addJsonConsoleAppender(context, customFields);
}
if (logstashProperties.isEnabled()) {
addLogstashTcpSocketAppender(context, customFields, logstashProperties);
}
if (loggingProperties.isUseJsonFormat() || logstashProperties.isEnabled()) {
addContextListener(context, customFields, loggingProperties);
}
}
}

View File

@ -0,0 +1,38 @@
package org.gcube.fullstackapps.informationsystemmonitor.config;
import java.time.Duration;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.oauth2.client.OAuth2AuthorizedClientManager;
import org.springframework.security.oauth2.client.OAuth2AuthorizedClientProviderBuilder;
import org.springframework.security.oauth2.client.registration.ClientRegistrationRepository;
import org.springframework.security.oauth2.client.web.DefaultOAuth2AuthorizedClientManager;
import org.springframework.security.oauth2.client.web.OAuth2AuthorizedClientRepository;
@Configuration
public class OAuth2Configuration {
@Bean
public OAuth2AuthorizedClientManager authorizedClientManager(
ClientRegistrationRepository clientRegistrationRepository,
OAuth2AuthorizedClientRepository authorizedClientRepository
) {
DefaultOAuth2AuthorizedClientManager authorizedClientManager = new DefaultOAuth2AuthorizedClientManager(
clientRegistrationRepository,
authorizedClientRepository
);
authorizedClientManager.setAuthorizedClientProvider(
OAuth2AuthorizedClientProviderBuilder
.builder()
.authorizationCode()
.refreshToken(builder -> builder.clockSkew(Duration.ofMinutes(3)))
.clientCredentials()
.password()
.build()
);
return authorizedClientManager;
}
}

View File

@ -0,0 +1,33 @@
package org.gcube.fullstackapps.informationsystemmonitor.config;
import org.springdoc.core.GroupedOpenApi;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;
import tech.jhipster.config.JHipsterConstants;
import tech.jhipster.config.JHipsterProperties;
import tech.jhipster.config.apidoc.customizer.JHipsterOpenApiCustomizer;
@Configuration
@Profile(JHipsterConstants.SPRING_PROFILE_API_DOCS)
public class OpenApiConfiguration {
public static final String API_FIRST_PACKAGE = "org.gcube.fullstackapps.informationsystemmonitor.web.api";
@Bean
@ConditionalOnMissingBean(name = "apiFirstGroupedOpenAPI")
public GroupedOpenApi apiFirstGroupedOpenAPI(
JHipsterOpenApiCustomizer jhipsterOpenApiCustomizer,
JHipsterProperties jHipsterProperties
) {
JHipsterProperties.ApiDocs properties = jHipsterProperties.getApiDocs();
return GroupedOpenApi
.builder()
.group("openapi")
.addOpenApiCustomiser(jhipsterOpenApiCustomizer)
.packagesToScan(API_FIRST_PACKAGE)
.pathsToMatch(properties.getDefaultIncludePattern())
.build();
}
}

View File

@ -0,0 +1,236 @@
package org.gcube.fullstackapps.informationsystemmonitor.config;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.gcube.fullstackapps.informationsystemmonitor.security.AuthoritiesConstants;
import org.gcube.fullstackapps.informationsystemmonitor.security.SecurityUtils;
import org.gcube.fullstackapps.informationsystemmonitor.security.oauth2.AudienceValidator;
import org.gcube.fullstackapps.informationsystemmonitor.security.oauth2.CustomClaimConverter;
import org.gcube.fullstackapps.informationsystemmonitor.security.oauth2.JwtGrantedAuthorityConverter;
import org.gcube.fullstackapps.informationsystemmonitor.web.filter.OAuth2RefreshTokensWebFilter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.web.client.RestTemplateBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Import;
import org.springframework.core.convert.converter.Converter;
import org.springframework.http.HttpMethod;
import org.springframework.http.RequestEntity;
import org.springframework.http.converter.FormHttpMessageConverter;
import org.springframework.security.authentication.AbstractAuthenticationToken;
import org.springframework.security.authorization.AuthorityAuthorizationManager;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.mapping.GrantedAuthoritiesMapper;
import org.springframework.security.oauth2.client.InMemoryOAuth2AuthorizedClientService;
import org.springframework.security.oauth2.client.OAuth2AuthorizedClientService;
import org.springframework.security.oauth2.client.endpoint.DefaultAuthorizationCodeTokenResponseClient;
import org.springframework.security.oauth2.client.endpoint.NimbusAuthorizationCodeTokenResponseClient;
import org.springframework.security.oauth2.client.endpoint.OAuth2AccessTokenResponseClient;
import org.springframework.security.oauth2.client.endpoint.OAuth2AuthorizationCodeGrantRequest;
import org.springframework.security.oauth2.client.http.OAuth2ErrorResponseErrorHandler;
import org.springframework.security.oauth2.client.oidc.userinfo.OidcUserRequest;
import org.springframework.security.oauth2.client.oidc.userinfo.OidcUserService;
import org.springframework.security.oauth2.client.registration.ClientRegistrationRepository;
import org.springframework.security.oauth2.client.userinfo.OAuth2UserService;
import org.springframework.security.oauth2.core.DelegatingOAuth2TokenValidator;
import org.springframework.security.oauth2.core.OAuth2AccessToken;
import org.springframework.security.oauth2.core.OAuth2TokenValidator;
import org.springframework.security.oauth2.core.endpoint.OAuth2AccessTokenResponse;
import org.springframework.security.oauth2.core.http.converter.OAuth2AccessTokenResponseHttpMessageConverter;
import org.springframework.security.oauth2.core.oidc.user.DefaultOidcUser;
import org.springframework.security.oauth2.core.oidc.user.OidcUser;
import org.springframework.security.oauth2.core.oidc.user.OidcUserAuthority;
import org.springframework.security.oauth2.jwt.Jwt;
import org.springframework.security.oauth2.jwt.JwtDecoder;
import org.springframework.security.oauth2.jwt.JwtDecoders;
import org.springframework.security.oauth2.jwt.JwtValidators;
import org.springframework.security.oauth2.jwt.NimbusJwtDecoder;
import org.springframework.security.oauth2.server.resource.authentication.JwtAuthenticationConverter;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.csrf.CookieCsrfTokenRepository;
import org.springframework.security.web.csrf.CsrfFilter;
import org.springframework.security.web.header.writers.ReferrerPolicyHeaderWriter;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.filter.CorsFilter;
import org.zalando.problem.spring.web.advice.security.SecurityProblemSupport;
import tech.jhipster.config.JHipsterProperties;
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true)
@Import(SecurityProblemSupport.class)
public class SecurityConfiguration {
private static final Logger logger = LoggerFactory.getLogger(SecurityConfiguration.class);
private final JHipsterProperties jHipsterProperties;
private final CorsFilter corsFilter;
@Value("${spring.security.oauth2.client.provider.oidc.issuer-uri}")
private String issuerUri;
private final SecurityProblemSupport problemSupport;
public SecurityConfiguration(CorsFilter corsFilter, JHipsterProperties jHipsterProperties,
SecurityProblemSupport problemSupport) {
this.corsFilter = corsFilter;
this.problemSupport = problemSupport;
this.jHipsterProperties = jHipsterProperties;
}
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
// @formatter:off
http
.csrf()
.csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse())
.and()
.addFilterBefore(corsFilter, CsrfFilter.class)
.exceptionHandling()
.authenticationEntryPoint(problemSupport)
.accessDeniedHandler(problemSupport)
.and()
.headers()
.contentSecurityPolicy(jHipsterProperties.getSecurity().getContentSecurityPolicy())
.and()
.referrerPolicy(ReferrerPolicyHeaderWriter.ReferrerPolicy.STRICT_ORIGIN_WHEN_CROSS_ORIGIN)
.and()
.permissionsPolicy().policy("camera=(), fullscreen=(self), geolocation=(), gyroscope=(), magnetometer=(), microphone=(), midi=(), payment=(), sync-xhr=()")
.and()
.frameOptions().sameOrigin()
.and()
.authorizeRequests()
.antMatchers(HttpMethod.OPTIONS, "/**").permitAll()
.antMatchers("/app/**/*.{js,html}").permitAll()
.antMatchers("/i18n/**").permitAll()
.antMatchers("/content/**").permitAll()
.antMatchers("/swagger-ui/**").permitAll()
.antMatchers("/test/**").permitAll()
.antMatchers("/login/oauth2/code/oidc").permitAll()
.antMatchers("/api/account").permitAll()
.antMatchers("/api/authenticate").permitAll()
.antMatchers("/api/auth-info").permitAll()
.antMatchers("/api/admin/**").hasAuthority(AuthoritiesConstants.ADMIN)
.antMatchers("/api/**").authenticated()
.antMatchers("/management/health").permitAll()
.antMatchers("/management/health/**").permitAll()
.antMatchers("/management/info").permitAll()
.antMatchers("/management/prometheus").permitAll()
.antMatchers("/management/**").hasAuthority(AuthoritiesConstants.ADMIN)
.and()
.oauth2Login()
//.defaultSuccessUrl("/api/scopes/discovery").userInfoEndpoint(userInfo -> userInfo
// .oidcUserService(this.oidcUserService()))
//.defaultSuccessUrl(issuerUri, false)
//.defaultSuccessUrl("/api/login/oauth2/code/oidc")
//.addFilterAfter(new CustomAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class)
//.logout(logout -> logout.logoutSuccessHandler(oidcLogoutSuccessHandler()))
//.tokenEndpoint()
//.accessTokenResponseClient(accessTokenResponseClient())
//.and()
//.oauth2ResourceServer()
//.jwt()
//.jwtAuthenticationConverter(authenticationConverter())
//.and()
.and()
.oauth2Client();
//.authorizationCodeGrant();
return http.build();
// @formatter:on
}
private OAuth2UserService<OidcUserRequest, OidcUser> oidcUserService() {
final OidcUserService delegate = new OidcUserService();
return (userRequest) -> {
// Delegate to the default implementation for loading a user
OidcUser oidcUser = delegate.loadUser(userRequest);
OAuth2AccessToken accessToken = userRequest.getAccessToken();
Set<GrantedAuthority> mappedAuthorities = new HashSet<>();
logger.debug("Fetch AccessToken: {}",accessToken.getTokenValue());
// TODO
// 1) Fetch the authority information from the protected resource using accessToken
// 2) Map the authority information to one or more GrantedAuthority's and add it to mappedAuthorities
// 3) Create a copy of oidcUser but use the mappedAuthorities instead
oidcUser = new DefaultOidcUser(mappedAuthorities, oidcUser.getIdToken(), oidcUser.getUserInfo());
logger.debug("OIDCUser: {}",oidcUser);
return oidcUser;
};
}
Converter<Jwt, AbstractAuthenticationToken> authenticationConverter() {
logger.debug("JWT AuthenticationConverter()");
JwtAuthenticationConverter jwtAuthenticationConverter = new JwtAuthenticationConverter();
jwtAuthenticationConverter.setJwtGrantedAuthoritiesConverter(new JwtGrantedAuthorityConverter());
return jwtAuthenticationConverter;
}
/**
* Map authorities from "groups" or "roles" claim in ID Token.
*
* @return a {@link GrantedAuthoritiesMapper} that maps groups from the IdP to
* Spring Security Authorities.
*/
@Bean
public GrantedAuthoritiesMapper userAuthoritiesMapper() {
return authorities -> {
logger.debug("Authorities: {}", authorities);
Set<GrantedAuthority> mappedAuthorities = new HashSet<>();
authorities.forEach(authority -> {
// Check for OidcUserAuthority because Spring Security 5.2 returns
// each scope as a GrantedAuthority, which we don't care about.
logger.debug("Authority: {}", authority);
if (authority instanceof OidcUserAuthority) {
OidcUserAuthority oidcUserAuthority = (OidcUserAuthority) authority;
logger.debug("TokenValue: {}", oidcUserAuthority.getIdToken().getTokenValue());
logger.debug("oidcUserAuthority: {}", oidcUserAuthority);
mappedAuthorities.addAll(
SecurityUtils.extractAuthorityFromClaims(oidcUserAuthority.getUserInfo().getClaims()));
}
});
return mappedAuthorities;
};
}
@Bean
JwtDecoder jwtDecoder(ClientRegistrationRepository clientRegistrationRepository,
RestTemplateBuilder restTemplateBuilder) {
logger.debug("JWTDecoder: {}", restTemplateBuilder);
NimbusJwtDecoder jwtDecoder = JwtDecoders.fromOidcIssuerLocation(issuerUri);
OAuth2TokenValidator<Jwt> audienceValidator = new AudienceValidator(
jHipsterProperties.getSecurity().getOauth2().getAudience());
OAuth2TokenValidator<Jwt> withIssuer = JwtValidators.createDefaultWithIssuer(issuerUri);
OAuth2TokenValidator<Jwt> withAudience = new DelegatingOAuth2TokenValidator<>(withIssuer, audienceValidator);
jwtDecoder.setJwtValidator(withAudience);
jwtDecoder.setClaimSetConverter(new CustomClaimConverter(
clientRegistrationRepository.findByRegistrationId("oidc"), restTemplateBuilder.build()));
return jwtDecoder;
}
}

View File

@ -0,0 +1,59 @@
package org.gcube.fullstackapps.informationsystemmonitor.config;
import java.util.concurrent.TimeUnit;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;
import org.springframework.http.CacheControl;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistration;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import tech.jhipster.config.JHipsterConstants;
import tech.jhipster.config.JHipsterProperties;
@Configuration
@Profile({ JHipsterConstants.SPRING_PROFILE_PRODUCTION })
public class StaticResourcesWebConfiguration implements WebMvcConfigurer {
protected static final String[] RESOURCE_LOCATIONS = new String[] {
"classpath:/static/",
"classpath:/static/content/",
"classpath:/static/i18n/",
};
protected static final String[] RESOURCE_PATHS = new String[] {
"/*.js",
"/*.css",
"/*.svg",
"/*.png",
"*.ico",
"/content/**",
"/i18n/*",
};
private final JHipsterProperties jhipsterProperties;
public StaticResourcesWebConfiguration(JHipsterProperties jHipsterProperties) {
this.jhipsterProperties = jHipsterProperties;
}
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
ResourceHandlerRegistration resourceHandlerRegistration = appendResourceHandler(registry);
initializeResourceHandler(resourceHandlerRegistration);
}
protected ResourceHandlerRegistration appendResourceHandler(ResourceHandlerRegistry registry) {
return registry.addResourceHandler(RESOURCE_PATHS);
}
protected void initializeResourceHandler(ResourceHandlerRegistration resourceHandlerRegistration) {
resourceHandlerRegistration.addResourceLocations(RESOURCE_LOCATIONS).setCacheControl(getCacheControl());
}
protected CacheControl getCacheControl() {
return CacheControl.maxAge(getJHipsterHttpCacheProperty(), TimeUnit.DAYS).cachePublic();
}
private int getJHipsterHttpCacheProperty() {
return jhipsterProperties.getHttp().getCache().getTimeToLiveInDays();
}
}

View File

@ -0,0 +1,83 @@
package org.gcube.fullstackapps.informationsystemmonitor.config;
import org.gcube.fullstackapps.informationsystemmonitor.service.dto.UmaResponseDTO;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.oauth2.client.OAuth2AuthorizedClient;
import org.springframework.security.oauth2.client.OAuth2AuthorizedClientService;
import org.springframework.security.oauth2.client.authentication.OAuth2AuthenticationToken;
import org.springframework.stereotype.Component;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;
@Component
public class TokenManager {
private static final Logger log = LoggerFactory.getLogger(TokenManager.class);
@Value("${spring.security.oauth2.client.provider.oidc.token-uri}")
private String tokenUri;
@Autowired
private OAuth2AuthorizedClientService authorizedClientService;
public String getUmaToken(String context) {
String accessToken=getAccessToken();
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
headers.set("Authorization", "Bearer " + accessToken);
log.debug("Headers: {}", headers);
MultiValueMap<String, String> params = new LinkedMultiValueMap<>();
params.add("grant_type", "urn:ietf:params:oauth:grant-type:uma-ticket");
params.add("audience", context);
log.debug("Params: {}", params);
HttpEntity<MultiValueMap<String, String>> entity = new HttpEntity<>(params, headers);
RestTemplate restTemplate = new RestTemplate();
ResponseEntity<UmaResponseDTO> response = restTemplate.exchange(tokenUri, HttpMethod.POST, entity, UmaResponseDTO.class);
UmaResponseDTO umaResponceDTO = response.getBody();
log.debug("UmaResponceDTO: {}", umaResponceDTO);
String umaToken=umaResponceDTO.getAccess_token();
log.debug("UmaToken: {}", umaToken);
return umaToken;
}
public String getAccessToken() {
OAuth2AuthenticationToken oAuth2AuthenticationToken = (OAuth2AuthenticationToken) SecurityContextHolder
.getContext().getAuthentication();
log.debug("OAuth2AuthenticationToken: {}", oAuth2AuthenticationToken);
OAuth2AuthorizedClient client = authorizedClientService.loadAuthorizedClient(
oAuth2AuthenticationToken.getAuthorizedClientRegistrationId(), oAuth2AuthenticationToken.getName());
/*if(client.getAccessToken().getExpiresAt().compareTo(Instant.now())>0) {
}*/
String accessToken = client.getAccessToken().getTokenValue();
log.debug("AccessToken: {}", accessToken);
return accessToken;
}
public String getRootContext() {
String rootContext = "/gcube";
return rootContext;
}
}

View File

@ -0,0 +1,105 @@
package org.gcube.fullstackapps.informationsystemmonitor.config;
import static java.net.URLDecoder.decode;
import java.io.File;
import java.nio.charset.StandardCharsets;
import java.nio.file.Paths;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.web.server.WebServerFactory;
import org.springframework.boot.web.server.WebServerFactoryCustomizer;
import org.springframework.boot.web.servlet.ServletContextInitializer;
import org.springframework.boot.web.servlet.server.ConfigurableServletWebServerFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.Environment;
import org.springframework.util.CollectionUtils;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;
import tech.jhipster.config.JHipsterProperties;
/**
* Configuration of web application with Servlet 3.0 APIs.
*/
@Configuration
public class WebConfigurer implements ServletContextInitializer, WebServerFactoryCustomizer<WebServerFactory> {
private final Logger log = LoggerFactory.getLogger(WebConfigurer.class);
private final Environment env;
private final JHipsterProperties jHipsterProperties;
public WebConfigurer(Environment env, JHipsterProperties jHipsterProperties) {
this.env = env;
this.jHipsterProperties = jHipsterProperties;
}
@Override
public void onStartup(ServletContext servletContext) throws ServletException {
if (env.getActiveProfiles().length != 0) {
log.info("Web application configuration, using profiles: {}", (Object[]) env.getActiveProfiles());
}
log.info("Web application fully configured");
}
/**
* Customize the Servlet engine: Mime types, the document root, the cache.
*/
@Override
public void customize(WebServerFactory server) {
// When running in an IDE or with ./mvnw spring-boot:run, set location of the static web assets.
setLocationForStaticAssets(server);
}
private void setLocationForStaticAssets(WebServerFactory server) {
if (server instanceof ConfigurableServletWebServerFactory) {
ConfigurableServletWebServerFactory servletWebServer = (ConfigurableServletWebServerFactory) server;
File root;
String prefixPath = resolvePathPrefix();
root = new File(prefixPath + "target/classes/static/");
if (root.exists() && root.isDirectory()) {
servletWebServer.setDocumentRoot(root);
}
}
}
/**
* Resolve path prefix to static resources.
*/
private String resolvePathPrefix() {
String fullExecutablePath = decode(this.getClass().getResource("").getPath(), StandardCharsets.UTF_8);
String rootPath = Paths.get(".").toUri().normalize().getPath();
String extractedPath = fullExecutablePath.replace(rootPath, "");
int extractionEndIndex = extractedPath.indexOf("target/");
if (extractionEndIndex <= 0) {
return "";
}
return extractedPath.substring(0, extractionEndIndex);
}
@Bean
public CorsFilter corsFilter() {
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
CorsConfiguration config = jHipsterProperties.getCors();
if (!CollectionUtils.isEmpty(config.getAllowedOrigins()) || !CollectionUtils.isEmpty(config.getAllowedOriginPatterns())) {
log.debug("Registering CORS filter");
source.registerCorsConfiguration("/login/**", config);
source.registerCorsConfiguration("/api/**", config);
source.registerCorsConfiguration("/management/**", config);
source.registerCorsConfiguration("/v3/api-docs", config);
source.registerCorsConfiguration("/swagger-ui/**", config);
}
return new CorsFilter(source);
}
}

View File

@ -0,0 +1,4 @@
/**
* Spring Framework configuration files.
*/
package org.gcube.fullstackapps.informationsystemmonitor.config;

View File

@ -0,0 +1,17 @@
package org.gcube.fullstackapps.informationsystemmonitor.domain;
import java.io.Serializable;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class TestDialogDTO implements Serializable {
private static final long serialVersionUID = 1L;
private String status;
}

View File

@ -0,0 +1,4 @@
/**
* JPA domain objects.
*/
package org.gcube.fullstackapps.informationsystemmonitor.domain;

View File

@ -0,0 +1,4 @@
/**
* Spring Data JPA repositories.
*/
package org.gcube.fullstackapps.informationsystemmonitor.repository;

View File

@ -0,0 +1,15 @@
package org.gcube.fullstackapps.informationsystemmonitor.security;
/**
* Constants for Spring Security authorities.
*/
public final class AuthoritiesConstants {
public static final String ADMIN = "ROLE_ADMIN";
public static final String USER = "ROLE_USER";
public static final String ANONYMOUS = "ROLE_ANONYMOUS";
private AuthoritiesConstants() {}
}

View File

@ -0,0 +1,167 @@
package org.gcube.fullstackapps.informationsystemmonitor.security;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Stream;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.oauth2.core.oidc.user.DefaultOidcUser;
import org.springframework.security.oauth2.server.resource.authentication.JwtAuthenticationToken;
/**
* Utility class for Spring Security.
*/
public final class SecurityUtils {
private static final Logger logger = LoggerFactory.getLogger(SecurityUtils.class);
public static final String CLAIMS_NAMESPACE = "https://www.jhipster.tech/";
private SecurityUtils() {
}
/**
* Get the login of the current user.
*
* @return the login of the current user.
*/
public static Optional<String> getCurrentUserLogin() {
SecurityContext securityContext = SecurityContextHolder.getContext();
return Optional.ofNullable(extractPrincipal(securityContext.getAuthentication()));
}
private static String extractPrincipal(Authentication authentication) {
logger.debug("extractPrincipal: {}", authentication);
if (authentication == null) {
return null;
} else if (authentication.getPrincipal() instanceof UserDetails) {
UserDetails springSecurityUser = (UserDetails) authentication.getPrincipal();
return springSecurityUser.getUsername();
} else if (authentication instanceof JwtAuthenticationToken) {
return (String) ((JwtAuthenticationToken) authentication).getToken().getClaims().get("preferred_username");
} else if (authentication.getPrincipal() instanceof DefaultOidcUser) {
Map<String, Object> attributes = ((DefaultOidcUser) authentication.getPrincipal()).getAttributes();
if (attributes.containsKey("preferred_username")) {
return (String) attributes.get("preferred_username");
}
} else if (authentication.getPrincipal() instanceof String) {
return (String) authentication.getPrincipal();
}
return null;
}
/**
* Check if a user is authenticated.
*
* @return true if the user is authenticated, false otherwise.
*/
public static boolean isAuthenticated() {
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
return authentication != null
&& getAuthorities(authentication).noneMatch(AuthoritiesConstants.ANONYMOUS::equals);
}
/**
* Checks if the current user has any of the authorities.
*
* @param authorities the authorities to check.
* @return true if the current user has any of the authorities, false otherwise.
*/
public static boolean hasCurrentUserAnyOfAuthorities(String... authorities) {
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
return (authentication != null && getAuthorities(authentication)
.anyMatch(authority -> Arrays.asList(authorities).contains(authority)));
}
/**
* Checks if the current user has none of the authorities.
*
* @param authorities the authorities to check.
* @return true if the current user has none of the authorities, false
* otherwise.
*/
public static boolean hasCurrentUserNoneOfAuthorities(String... authorities) {
return !hasCurrentUserAnyOfAuthorities(authorities);
}
/**
* Checks if the current user has a specific authority.
*
* @param authority the authority to check.
* @return true if the current user has the authority, false otherwise.
*/
public static boolean hasCurrentUserThisAuthority(String authority) {
return hasCurrentUserAnyOfAuthorities(authority);
}
private static Stream<String> getAuthorities(Authentication authentication) {
logger.debug("getAuthorities: {}", authentication);
Collection<? extends GrantedAuthority> authorities = authentication instanceof JwtAuthenticationToken
? extractAuthorityFromClaims(((JwtAuthenticationToken) authentication).getToken().getClaims())
: authentication.getAuthorities();
return authorities.stream().map(GrantedAuthority::getAuthority);
}
public static List<GrantedAuthority> extractAuthorityFromClaims(Map<String, Object> claims) {
logger.debug("extractAuthorityFromClaims: {}", claims);
return mapRolesToGrantedAuthorities(getRolesFromClaims(claims));
}
@SuppressWarnings("unchecked")
private static Collection<String> getRolesFromClaims(Map<String, Object> claims) {
logger.debug("getRolesFromClaims(): {}", claims);
// return (Collection<String>) claims.getOrDefault(
// "groups",
// claims.getOrDefault("roles", claims.getOrDefault(CLAIMS_NAMESPACE + "roles",
// new ArrayList<>()))
// );
if (claims.get("resource_access") != null) {
logger.debug("ResourceAccess: {}",claims.get("resource_access").getClass());
Map<String,Object> scope=(Map<String,Object>)claims.get("resource_access");
ArrayList<String> roles = new ArrayList<>();
for (String key : scope.keySet()) {
logger.info("Default Scope: {}",key);
roles=((Map<String, ArrayList<String>>)scope.get(key)).get("roles");
break;
}
logger.info("D4Science Roles: {}",roles);
return roles;
} else {
logger.debug("D4Science Roles: {}");
return new ArrayList<String>();
}
}
private static List<GrantedAuthority> mapRolesToGrantedAuthorities(Collection<String> roles) {
logger.debug("mapRolesToGrantedAuthorities(): {}", roles);
List<GrantedAuthority> ga = new ArrayList<>();
boolean isAdmin = false;
for (String role : roles) {
if (role.compareTo("Member") == 0) {
isAdmin = true;
break;
}
}
if (isAdmin) {
ga.add(new SimpleGrantedAuthority(AuthoritiesConstants.ADMIN));
} else {
ga.add(new SimpleGrantedAuthority(AuthoritiesConstants.USER));
}
logger.info("GrantedAuthority: {}",ga);
return ga;
}
}

View File

@ -0,0 +1,33 @@
package org.gcube.fullstackapps.informationsystemmonitor.security.oauth2;
import java.util.List;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.security.oauth2.core.OAuth2Error;
import org.springframework.security.oauth2.core.OAuth2TokenValidator;
import org.springframework.security.oauth2.core.OAuth2TokenValidatorResult;
import org.springframework.security.oauth2.jwt.Jwt;
import org.springframework.util.Assert;
public class AudienceValidator implements OAuth2TokenValidator<Jwt> {
private final Logger log = LoggerFactory.getLogger(AudienceValidator.class);
private final OAuth2Error error = new OAuth2Error("invalid_token", "The required audience is missing", null);
private final List<String> allowedAudience;
public AudienceValidator(List<String> allowedAudience) {
Assert.notEmpty(allowedAudience, "Allowed audience should not be null or empty.");
this.allowedAudience = allowedAudience;
}
public OAuth2TokenValidatorResult validate(Jwt jwt) {
List<String> audience = jwt.getAudience();
if (audience.stream().anyMatch(allowedAudience::contains)) {
return OAuth2TokenValidatorResult.success();
} else {
log.warn("Invalid audience: {}", audience);
return OAuth2TokenValidatorResult.failure(error);
}
}
}

View File

@ -0,0 +1,136 @@
package org.gcube.fullstackapps.informationsystemmonitor.security.oauth2;
import java.time.Duration;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.stream.StreamSupport;
import org.gcube.fullstackapps.informationsystemmonitor.security.SecurityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.convert.converter.Converter;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.security.oauth2.client.registration.ClientRegistration;
import org.springframework.security.oauth2.jwt.MappedJwtClaimSetConverter;
import org.springframework.security.oauth2.server.resource.web.BearerTokenResolver;
import org.springframework.security.oauth2.server.resource.web.DefaultBearerTokenResolver;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.github.benmanes.caffeine.cache.Cache;
import com.github.benmanes.caffeine.cache.Caffeine;
/**
* Claim converter to add custom claims by retrieving the user from the userinfo endpoint.
*/
public class CustomClaimConverter implements Converter<Map<String, Object>, Map<String, Object>> {
private static final Logger logger = LoggerFactory.getLogger(CustomClaimConverter.class);
private final BearerTokenResolver bearerTokenResolver = new DefaultBearerTokenResolver();
private final MappedJwtClaimSetConverter delegate = MappedJwtClaimSetConverter.withDefaults(Collections.emptyMap());
private final RestTemplate restTemplate;
private final ClientRegistration registration;
// See https://github.com/jhipster/generator-jhipster/issues/18868
// We don't use a distributed cache or the user selected cache implementation here on purpose
private final Cache<String, ObjectNode> users = Caffeine
.newBuilder()
.maximumSize(10_000)
.expireAfterWrite(Duration.ofHours(1))
.recordStats()
.build();
public CustomClaimConverter(ClientRegistration registration, RestTemplate restTemplate) {
this.registration = registration;
this.restTemplate = restTemplate;
}
public Map<String, Object> convert(Map<String, Object> claims) {
logger.debug("convert()");
Map<String, Object> convertedClaims = this.delegate.convert(claims);
// Only look up user information if identity claims are missing
if (claims.containsKey("given_name") && claims.containsKey("family_name")) {
return convertedClaims;
}
RequestAttributes attributes = RequestContextHolder.getRequestAttributes();
if (attributes instanceof ServletRequestAttributes) {
// Retrieve and set the token
String token = bearerTokenResolver.resolve(((ServletRequestAttributes) attributes).getRequest());
logger.debug("Token: {}",token);
HttpHeaders headers = new HttpHeaders();
headers.set("Authorization", buildBearer(token));
// Retrieve user info from OAuth provider if not already loaded
ObjectNode user = users.get(
claims.get("sub").toString(),
s -> {
ResponseEntity<ObjectNode> userInfo = restTemplate.exchange(
registration.getProviderDetails().getUserInfoEndpoint().getUri(),
HttpMethod.GET,
new HttpEntity<String>(headers),
ObjectNode.class
);
return userInfo.getBody();
}
);
logger.debug("User Info: {}",user);
// Add custom claims
if (user != null) {
convertedClaims.put("preferred_username", user.get("preferred_username").asText());
if (user.has("given_name")) {
convertedClaims.put("given_name", user.get("given_name").asText());
}
if (user.has("family_name")) {
convertedClaims.put("family_name", user.get("family_name").asText());
}
if (user.has("email")) {
convertedClaims.put("email", user.get("email").asText());
}
// Allow full name in a name claim - happens with Auth0
if (user.has("name")) {
String[] name = user.get("name").asText().split("\\s+");
if (name.length > 0) {
convertedClaims.put("given_name", name[0]);
convertedClaims.put("family_name", String.join(" ", Arrays.copyOfRange(name, 1, name.length)));
}
}
if (user.has("groups")) {
List<String> groups = StreamSupport
.stream(user.get("groups").spliterator(), false)
.map(JsonNode::asText)
.collect(Collectors.toList());
convertedClaims.put("groups", groups);
}
if (user.has(SecurityUtils.CLAIMS_NAMESPACE + "roles")) {
List<String> roles = StreamSupport
.stream(user.get(SecurityUtils.CLAIMS_NAMESPACE + "roles").spliterator(), false)
.map(JsonNode::asText)
.collect(Collectors.toList());
convertedClaims.put("roles", roles);
}
}
}
logger.debug("Claims: "+convertedClaims.toString());
return convertedClaims;
}
private String buildBearer(String token) {
return "Bearer " + token;
}
}

View File

@ -0,0 +1,25 @@
package org.gcube.fullstackapps.informationsystemmonitor.security.oauth2;
import java.util.Collection;
import org.gcube.fullstackapps.informationsystemmonitor.security.SecurityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.convert.converter.Converter;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.oauth2.jwt.Jwt;
import org.springframework.stereotype.Component;
@Component
public class JwtGrantedAuthorityConverter implements Converter<Jwt, Collection<GrantedAuthority>> {
private static final Logger logger = LoggerFactory.getLogger(JwtGrantedAuthorityConverter.class);
public JwtGrantedAuthorityConverter() {
logger.debug("New JwtGrantedAuthorityConverter: created");
}
@Override
public Collection<GrantedAuthority> convert(Jwt jwt) {
logger.debug("convert(): {}",jwt);
return SecurityUtils.extractAuthorityFromClaims(jwt.getClaims());
}
}

View File

@ -0,0 +1,155 @@
package org.gcube.fullstackapps.informationsystemmonitor.security.oauth2;
import com.fasterxml.jackson.annotation.JsonProperty;
import java.io.Serializable;
import java.util.UUID;
public class OAuthIdpTokenResponseDTO implements Serializable {
private static final long serialVersionUID = 1L;
@JsonProperty("token_type")
private String tokenType;
private String scope;
@JsonProperty("expires_in")
private Long expiresIn;
@JsonProperty("ext_expires_in")
private Long extExpiresIn;
@JsonProperty("expires_on")
private Long expiresOn;
@JsonProperty("not-before-policy")
private Long notBefore;
private UUID resource;
@JsonProperty("access_token")
private String accessToken;
@JsonProperty("refresh_token")
private String refreshToken;
@JsonProperty("id_token")
private String idToken;
@JsonProperty("session_state")
private String sessionState;
@JsonProperty("refresh_expires_in")
private String refreshExpiresIn;
public OAuthIdpTokenResponseDTO() {
// Empty constructor for serialization.
}
public String getRefreshExpiresIn() {
return refreshExpiresIn;
}
public void setRefreshExpiresIn(String refreshExpiresIn) {
this.refreshExpiresIn = refreshExpiresIn;
}
public String getSessionState() {
return sessionState;
}
public void setSessionState(String sessionState) {
this.sessionState = sessionState;
}
public String getTokenType() {
return tokenType;
}
public void setTokenType(String tokenType) {
this.tokenType = tokenType;
}
public String getScope() {
return scope;
}
public void setScope(String scope) {
this.scope = scope;
}
public Long getExpiresIn() {
return expiresIn;
}
public void setExpiresIn(Long expiresIn) {
this.expiresIn = expiresIn;
}
public Long getExtExpiresIn() {
return extExpiresIn;
}
public void setExtExpiresIn(Long extExpiresIn) {
this.extExpiresIn = extExpiresIn;
}
public Long getExpiresOn() {
return expiresOn;
}
public void setExpiresOn(Long expiresOn) {
this.expiresOn = expiresOn;
}
public Long getNotBefore() {
return notBefore;
}
public void setNotBefore(Long notBefore) {
this.notBefore = notBefore;
}
public UUID getResource() {
return resource;
}
public void setResource(UUID resource) {
this.resource = resource;
}
public String getAccessToken() {
return accessToken;
}
public void setAccessToken(String accessToken) {
this.accessToken = accessToken;
}
public String getRefreshToken() {
return refreshToken;
}
public void setRefreshToken(String refreshToken) {
this.refreshToken = refreshToken;
}
public String getIdToken() {
return idToken;
}
public void setIdToken(String idToken) {
this.idToken = idToken;
}
@Override
public String toString() {
return "OAuthIdpTokenResponseDTO [tokenType=" + tokenType + ", scope=" + scope + ", expiresIn=" + expiresIn
+ ", extExpiresIn=" + extExpiresIn + ", expiresOn=" + expiresOn + ", notBefore=" + notBefore
+ ", resource=" + resource + ", accessToken=" + accessToken + ", refreshToken=" + refreshToken
+ ", idToken=" + idToken + ", sessionState=" + sessionState + ", refreshExpiresIn=" + refreshExpiresIn
+ "]";
}
}

View File

@ -0,0 +1,4 @@
/**
* Spring Security configuration.
*/
package org.gcube.fullstackapps.informationsystemmonitor.security;

View File

@ -0,0 +1,46 @@
package org.gcube.fullstackapps.informationsystemmonitor.service;
import java.util.ArrayList;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.oauth2.client.AuthorizedClientServiceOAuth2AuthorizedClientManager;
import org.springframework.security.oauth2.core.oidc.user.DefaultOidcUser;
import org.springframework.security.web.authentication.WebAuthenticationDetails;
import org.springframework.stereotype.Service;
import org.springframework.web.context.request.RequestContextHolder;
@Service
public class ContextService {
private final Logger log = LoggerFactory.getLogger(ContextService.class);
public ArrayList<String> all(){
ArrayList<String> scopes=new ArrayList<>();
scopes.add("gcube");
scopes.add("gcube/devsec");
scopes.add("gcube/devsec/devVRE");
log.debug("Scopes found: {}", scopes);
Authentication auth=SecurityContextHolder.getContext().getAuthentication();
DefaultOidcUser userDetails = (DefaultOidcUser) auth.getPrincipal();
log.debug("UserDetails: {}",userDetails.toString());
WebAuthenticationDetails details=(WebAuthenticationDetails)auth.getDetails();
log.debug("Provaci: {}",details);
String sessionId=RequestContextHolder.currentRequestAttributes().getSessionId();
log.debug("SessionId: {}",sessionId);
return scopes;
}
}

View File

@ -0,0 +1,51 @@
package org.gcube.fullstackapps.informationsystemmonitor.service;
import java.util.ArrayList;
import java.util.List;
import org.gcube.common.authorization.utils.manager.SecretManager;
import org.gcube.common.authorization.utils.manager.SecretManagerProvider;
import org.gcube.common.authorization.utils.secret.JWTSecret;
import org.gcube.common.authorization.utils.secret.Secret;
import org.gcube.informationsystem.contexts.impl.entities.ContextImpl;
import org.gcube.informationsystem.contexts.reference.entities.Context;
import org.gcube.informationsystem.resourceregistry.client.ResourceRegistryClient;
import org.gcube.informationsystem.resourceregistry.client.ResourceRegistryClientFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
/**
* Service class for managing InformationSystem resources.
*/
@Service
public class InformationSystemService {
private static final Logger log = LoggerFactory.getLogger(InformationSystemService.class);
public void setUma(String umaToken) throws Exception {
log.debug("Set Uma: [umaToken={}]",umaToken);
SecretManagerProvider.instance.reset();
SecretManager secretManager = new SecretManager();
Secret secret = new JWTSecret(umaToken);
secretManager.addSecret(secret);
secretManager.set();
SecretManagerProvider.instance.set(secretManager);
}
public List<Context> getAllContext(String context) throws Exception {
log.debug("GetAllContext: [context={}]",context);
ResourceRegistryClient resourceRegistryClient= ResourceRegistryClientFactory.create(context);
//List<Context> contexts=new ArrayList<>();
//contexts.add(new ContextImpl("/gcube"));
List<Context>contexts=resourceRegistryClient.getAllContext();
log.debug("AllContext: {}",contexts);
return contexts;
}
}

View File

@ -0,0 +1,151 @@
package org.gcube.fullstackapps.informationsystemmonitor.service;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Set;
import org.gcube.fullstackapps.informationsystemmonitor.config.Constants;
import org.gcube.fullstackapps.informationsystemmonitor.security.AuthoritiesConstants;
import org.gcube.fullstackapps.informationsystemmonitor.service.dto.AdminUserDTO;
import org.gcube.fullstackapps.informationsystemmonitor.service.dto.RealmAccessDTO;
import org.gcube.fullstackapps.informationsystemmonitor.service.dto.ResourceAccessDTO;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.security.authentication.AbstractAuthenticationToken;
import org.springframework.security.oauth2.client.authentication.OAuth2AuthenticationToken;
import org.springframework.security.oauth2.server.resource.authentication.JwtAuthenticationToken;
import org.springframework.stereotype.Service;
import com.nimbusds.jose.shaded.json.JSONArray;
import com.nimbusds.jose.shaded.json.JSONObject;
/**
* Service class for managing users.
*/
@Service
public class UserService {
private static final Logger logger = LoggerFactory.getLogger(UserService.class);
/**
* Returns the user from an OAuth 2.0 login or resource server with JWT.
*
* @param authToken the authentication token.
* @return the user from the authentication.
*/
public AdminUserDTO getUserFromAuthentication(AbstractAuthenticationToken authToken) {
Map<String, Object> attributes;
if (authToken instanceof JwtAuthenticationToken) {
logger.debug("AuthToken is a JwtAuthenticationToken");
attributes = ((JwtAuthenticationToken) authToken).getTokenAttributes();
} else if (authToken instanceof OAuth2AuthenticationToken) {
logger.debug("AuthToken is a OAuth2AuthenticationToken");
OAuth2AuthenticationToken oauth2Token = ((OAuth2AuthenticationToken) authToken);
attributes = oauth2Token.getPrincipal().getAttributes();
} else {
throw new IllegalArgumentException("AuthenticationToken is not OAuth2 or JWT!");
}
logger.debug("Attributes: {}", attributes);
AdminUserDTO user = getUser(attributes);
Set<String> authorities= new HashSet<>();
authorities.add(AuthoritiesConstants.ADMIN);
user.setAuthorities(authorities);
//user.setAuthorities(
// authToken.getAuthorities().stream().map(GrantedAuthority::getAuthority).collect(Collectors.toSet()));
return user;
}
private static AdminUserDTO getUser(Map<String, Object> details) {
AdminUserDTO user = new AdminUserDTO();
Boolean activated = Boolean.TRUE;
String sub = String.valueOf(details.get("sub"));
String username = null;
if (details.get("preferred_username") != null) {
username = ((String) details.get("preferred_username")).toLowerCase();
}
// handle resource server JWT, where sub claim is email and uid is ID
if (details.get("uid") != null) {
user.setId((String) details.get("uid"));
user.setLogin(sub);
} else {
user.setId(sub);
}
if (username != null) {
user.setLogin(username);
} else if (user.getLogin() == null) {
user.setLogin(user.getId());
}
if (details.get("given_name") != null) {
user.setFirstName((String) details.get("given_name"));
} else if (details.get("name") != null) {
user.setFirstName((String) details.get("name"));
}
if (details.get("family_name") != null) {
user.setLastName((String) details.get("family_name"));
}
if (details.get("email_verified") != null) {
activated = (Boolean) details.get("email_verified");
}
if (details.get("email") != null) {
user.setEmail(((String) details.get("email")).toLowerCase());
} else if (sub.contains("|") && (username != null && username.contains("@"))) {
// special handling for Auth0
user.setEmail(username);
} else {
user.setEmail(sub);
}
if (details.get("langKey") != null) {
user.setLangKey((String) details.get("langKey"));
} else if (details.get("locale") != null) {
// trim off country code if it exists
String locale = (String) details.get("locale");
if (locale.contains("_")) {
locale = locale.substring(0, locale.indexOf('_'));
} else if (locale.contains("-")) {
locale = locale.substring(0, locale.indexOf('-'));
}
user.setLangKey(locale.toLowerCase());
} else {
// set langKey to default if not specified by IdP
user.setLangKey(Constants.DEFAULT_LANGUAGE);
}
if (details.get("picture") != null) {
user.setImageUrl((String) details.get("picture"));
}
if (details.get("realm_access") != null) {
//com.nimbusds.jose.shaded.json.
JSONObject realmAccessJSON=(JSONObject)details.get("realm_access");
JSONArray rolesJSON=(JSONArray)realmAccessJSON.get("roles");
ArrayList<String> roles=new ArrayList<>();
for(int i=0;i<rolesJSON.size();i++) {
roles.add((String)rolesJSON.get(i));
}
RealmAccessDTO realmAccessDTO=new RealmAccessDTO(roles);
user.setRealmAccessDTO(realmAccessDTO);
}
if (details.get("resource_access") != null) {
JSONObject resourceAccessJSON=(JSONObject)details.get("resource_access");
logger.debug("ResourceAccess KeySet: {}",resourceAccessJSON.keySet());
LinkedHashMap<String, ArrayList<String>> resourceAccess=new LinkedHashMap<>();
for(String key: resourceAccessJSON.keySet()) {
JSONObject valueJSON=(JSONObject)resourceAccessJSON.get(key);
JSONArray rolesJSON=(JSONArray) valueJSON.get("roles");
ArrayList<String> roles=new ArrayList<>();
for(int i=0;i<rolesJSON.size();i++) {
roles.add((String)rolesJSON.get(i));
}
resourceAccess.put(key, roles);
}
ResourceAccessDTO resourceAccessDTO=new ResourceAccessDTO(resourceAccess);
user.setResourceAccessDTO(resourceAccessDTO);
}
user.setActivated(activated);
return user;
}
}

View File

@ -0,0 +1,154 @@
package org.gcube.fullstackapps.informationsystemmonitor.service.dto;
import java.io.Serializable;
import java.util.Arrays;
import java.util.Set;
import javax.validation.constraints.Email;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.Pattern;
import javax.validation.constraints.Size;
import org.gcube.fullstackapps.informationsystemmonitor.config.Constants;
/**
* A DTO representing a user, with his authorities.
*/
public class AdminUserDTO implements Serializable {
private static final long serialVersionUID = 1L;
private String id;
private Set<String> authorities;
@NotBlank
@Pattern(regexp = Constants.LOGIN_REGEX)
@Size(min = 1, max = 50)
private String login;
@Size(max = 50)
private String firstName;
@Size(max = 50)
private String lastName;
@Email
@Size(min = 5, max = 254)
private String email;
@Size(max = 256)
private String imageUrl;
private boolean activated = false;
@Size(min = 2, max = 10)
private String langKey;
private RealmAccessDTO realmAccessDTO;
private ResourceAccessDTO resourceAccessDTO;
// private Set<String> authorities;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public Set<String> getAuthorities() {
return authorities;
}
public void setAuthorities(Set<String> authorities) {
this.authorities = authorities;
}
public String getLogin() {
return login;
}
public void setLogin(String login) {
this.login = login;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getImageUrl() {
return imageUrl;
}
public void setImageUrl(String imageUrl) {
this.imageUrl = imageUrl;
}
public boolean isActivated() {
return activated;
}
public void setActivated(boolean activated) {
this.activated = activated;
}
public String getLangKey() {
return langKey;
}
public void setLangKey(String langKey) {
this.langKey = langKey;
}
public static long getSerialversionuid() {
return serialVersionUID;
}
public RealmAccessDTO getRealmAccessDTO() {
return realmAccessDTO;
}
public void setRealmAccessDTO(RealmAccessDTO realmAccessDTO) {
this.realmAccessDTO = realmAccessDTO;
}
public ResourceAccessDTO getResourceAccessDTO() {
return resourceAccessDTO;
}
public void setResourceAccessDTO(ResourceAccessDTO resourceAccessDTO) {
this.resourceAccessDTO = resourceAccessDTO;
}
@Override
public String toString() {
return "AdminUserDTO [id=" + id + ", authorities=" + authorities + ", login=" + login + ", firstName="
+ firstName + ", lastName=" + lastName + ", email=" + email + ", imageUrl=" + imageUrl + ", activated="
+ activated + ", langKey=" + langKey + ", realmAccessDTO=" + realmAccessDTO + ", resourceAccessDTO="
+ resourceAccessDTO + "]";
}
}

View File

@ -0,0 +1,20 @@
package org.gcube.fullstackapps.informationsystemmonitor.service.dto;
import java.io.Serializable;
import java.util.ArrayList;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class RealmAccessDTO implements Serializable {
private static final long serialVersionUID = 1L;
private ArrayList<String> roles;
}

View File

@ -0,0 +1,20 @@
package org.gcube.fullstackapps.informationsystemmonitor.service.dto;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class ResourceAccessDTO implements Serializable {
private static final long serialVersionUID = 1L;
private LinkedHashMap<String, ArrayList<String>> resourceAccess;
}

View File

@ -0,0 +1,17 @@
package org.gcube.fullstackapps.informationsystemmonitor.service.dto;
import java.io.Serializable;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class TestDialogDTO implements Serializable {
private static final long serialVersionUID = 1L;
private String status;
}

View File

@ -0,0 +1,25 @@
package org.gcube.fullstackapps.informationsystemmonitor.service.dto;
import java.io.Serializable;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class UmaResponseDTO implements Serializable {
private static final long serialVersionUID = 1L;
private boolean upgraded;
private String access_token;
private int expires_in;
private int refresh_expires_in;
private String refresh_token;
private String token_type;
private int not_before_policy;
}

View File

@ -0,0 +1,40 @@
package org.gcube.fullstackapps.informationsystemmonitor.service.dto;
import java.io.Serializable;
/**
* A DTO representing a user, with only the public attributes.
*/
public class UserDTO implements Serializable {
private static final long serialVersionUID = 1L;
private String id;
private String login;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getLogin() {
return login;
}
public void setLogin(String login) {
this.login = login;
}
// prettier-ignore
@Override
public String toString() {
return "UserDTO{" +
"id='" + id + '\'' +
", login='" + login + '\'' +
"}";
}
}

View File

@ -0,0 +1,4 @@
/**
* Data Transfer Objects.
*/
package org.gcube.fullstackapps.informationsystemmonitor.service.dto;

View File

@ -0,0 +1,4 @@
/**
* Service layer beans.
*/
package org.gcube.fullstackapps.informationsystemmonitor.service;

View File

@ -0,0 +1,87 @@
package org.gcube.fullstackapps.informationsystemmonitor.web.filter;
import java.io.IOException;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.oauth2.client.OAuth2AuthorizeRequest;
import org.springframework.security.oauth2.client.OAuth2AuthorizedClient;
import org.springframework.security.oauth2.client.OAuth2AuthorizedClientManager;
import org.springframework.security.oauth2.client.authentication.OAuth2AuthenticationToken;
import org.springframework.security.oauth2.client.registration.ClientRegistrationRepository;
import org.springframework.security.oauth2.client.web.DefaultOAuth2AuthorizationRequestResolver;
import org.springframework.security.oauth2.client.web.OAuth2AuthorizationRequestRedirectFilter;
import org.springframework.security.oauth2.client.web.OAuth2AuthorizationRequestResolver;
import org.springframework.security.oauth2.client.web.OAuth2AuthorizedClientRepository;
import org.springframework.security.oauth2.core.endpoint.OAuth2AuthorizationRequest;
import org.springframework.security.web.DefaultRedirectStrategy;
import org.springframework.security.web.RedirectStrategy;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;
/**
* Refresh oauth2 tokens.
*/
@Component
public class OAuth2RefreshTokensWebFilter extends OncePerRequestFilter {
private final OAuth2AuthorizedClientManager clientManager;
private final OAuth2AuthorizedClientRepository authorizedClientRepository;
private final OAuth2AuthorizationRequestResolver authorizationRequestResolver;
private final RedirectStrategy authorizationRedirectStrategy = new DefaultRedirectStrategy();
public OAuth2RefreshTokensWebFilter(
OAuth2AuthorizedClientManager clientManager,
OAuth2AuthorizedClientRepository authorizedClientRepository,
ClientRegistrationRepository clientRegistrationRepository
) {
this.clientManager = clientManager;
this.authorizedClientRepository = authorizedClientRepository;
this.authorizationRequestResolver =
new DefaultOAuth2AuthorizationRequestResolver(
clientRegistrationRepository,
OAuth2AuthorizationRequestRedirectFilter.DEFAULT_AUTHORIZATION_REQUEST_BASE_URI
);
}
@Override
public void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
throws IOException, ServletException {
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
if ((authentication instanceof OAuth2AuthenticationToken)) {
try {
OAuth2AuthorizedClient authorizedClient = authorizedClient((OAuth2AuthenticationToken) authentication);
//logger.debug("Oauth2RefreshTokensWebFilter: "+authorizedClient.getRefreshToken().getTokenValue());
this.authorizedClientRepository.saveAuthorizedClient(authorizedClient, authentication, request, response);
} catch (Exception e) {
OAuth2AuthorizationRequest authorizationRequest = this.authorizationRequestResolver.resolve(request);
if (authorizationRequest != null) {
this.authorizationRedirectStrategy.sendRedirect(request, response, authorizationRequest.getAuthorizationRequestUri());
return;
}
}
}
filterChain.doFilter(request, response);
}
private OAuth2AuthorizedClient authorizedClient(OAuth2AuthenticationToken oauth2Authentication) {
String clientRegistrationId = oauth2Authentication.getAuthorizedClientRegistrationId();
OAuth2AuthorizeRequest request = OAuth2AuthorizeRequest
.withClientRegistrationId(clientRegistrationId)
.principal(oauth2Authentication)
.build();
if (clientManager == null) {
throw new IllegalStateException(
"No OAuth2AuthorizedClientManager bean was found. Did you include the " +
"org.springframework.boot:spring-boot-starter-oauth2-client dependency?"
);
}
return clientManager.authorize(request);
}
}

View File

@ -0,0 +1,97 @@
package org.gcube.fullstackapps.informationsystemmonitor.web.rest;
import java.security.Principal;
import javax.servlet.http.HttpServletRequest;
import org.gcube.fullstackapps.informationsystemmonitor.config.TokenManager;
import org.gcube.fullstackapps.informationsystemmonitor.service.UserService;
import org.gcube.fullstackapps.informationsystemmonitor.service.dto.AdminUserDTO;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.security.authentication.AbstractAuthenticationToken;
import org.springframework.security.oauth2.client.authentication.OAuth2AuthenticationToken;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.util.UriUtils;
import lombok.RequiredArgsConstructor;
/**
* REST controller for managing the current user's account.
*/
@RestController
@RequestMapping("/api")
@RequiredArgsConstructor
public class AccountResource {
private static class AccountResourceException extends RuntimeException {
private static final long serialVersionUID = 1L;
private AccountResourceException(String message) {
super(message);
}
}
private final Logger log = LoggerFactory.getLogger(AccountResource.class);
private final TokenManager umaManager;
private final UserService userService;
/**
* {@code GET /account} : get the current user.
*
* @param principal the current user; resolves to {@code null} if not authenticated.
* @return the current user.
* @throws AccountResourceException {@code 500 (Internal Server Error)} if the user couldn't be returned.
*/
@GetMapping("/account")
public AdminUserDTO getAccount(Principal principal) {
if (principal instanceof AbstractAuthenticationToken) {
return userService.getUserFromAuthentication((AbstractAuthenticationToken) principal);
} else {
throw new AccountResourceException("User could not be found");
}
}
/**
* {@code GET /authenticate} : check if the user is authenticated, and return its login.
*
* @param request the HTTP request.
* @return the login if the user is authenticated.
*/
@GetMapping("/authenticate")
public String isAuthenticated(HttpServletRequest request) {
log.debug("REST request to check if the current user is authenticated");
return request.getRemoteUser();
}
@GetMapping("/idtoken")
public String idtoken(OAuth2AuthenticationToken token) {
log.debug("REST request to check token: {}",token);
return token.toString();
}
@GetMapping("/accesstoken")
public String accesstoken() {
log.debug("Request access token");
String accessToken=umaManager.getAccessToken();
return accessToken;
}
@GetMapping("/umatoken")
public String umatoken() {
log.debug("Request uma token");
String context=UriUtils.encode("/gcube", "UTF-8");
String umaToken=umaManager.getUmaToken(context);
return umaToken;
}
}

View File

@ -0,0 +1,52 @@
package org.gcube.fullstackapps.informationsystemmonitor.web.rest;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* Resource to return information about OIDC properties
*/
@RestController
@RequestMapping("/api")
public class AuthInfoResource {
@Value("${spring.security.oauth2.client.provider.oidc.issuer-uri:}")
private String issuer;
@Value("${spring.security.oauth2.client.registration.oidc.client-id:}")
private String clientId;
@GetMapping("/auth-info")
public AuthInfoVM getAuthInfo() {
return new AuthInfoVM(issuer, clientId);
}
class AuthInfoVM {
private String issuer;
private String clientId;
AuthInfoVM(String issuer, String clientId) {
this.issuer = issuer;
this.clientId = clientId;
}
public String getIssuer() {
return this.issuer;
}
public void setIssuer(String issuer) {
this.issuer = issuer;
}
public String getClientId() {
return clientId;
}
public void setClientId(String clientId) {
this.clientId = clientId;
}
}
}

View File

@ -0,0 +1,17 @@
package org.gcube.fullstackapps.informationsystemmonitor.web.rest;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
@Controller
public class ClientForwardController {
/**
* Forwards any unmapped paths (except those containing a period) to the client {@code index.html}.
* @return forward to client {@code index.html}.
*/
@GetMapping(value = "/**/{path:[^\\.]*}")
public String forward() {
return "forward:/";
}
}

View File

@ -0,0 +1,79 @@
package org.gcube.fullstackapps.informationsystemmonitor.web.rest;
import java.util.ArrayList;
import org.gcube.fullstackapps.informationsystemmonitor.service.ContextService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.oauth2.client.OAuth2AuthorizedClient;
import org.springframework.security.oauth2.client.OAuth2AuthorizedClientService;
import org.springframework.security.oauth2.client.authentication.OAuth2AuthenticationToken;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.util.UriUtils;
import lombok.RequiredArgsConstructor;
/**
* ScopesDiscoveryResource controller
*/
@RestController
@RequestMapping("/api/context")
@RequiredArgsConstructor
public class ContextResource {
private final Logger log = LoggerFactory.getLogger(ContextResource.class);
private final ContextService contextService;
private final OAuth2AuthorizedClientService authorizedClientService;
/**
* GET all
*/
@GetMapping("/all")
public ArrayList<String> all() {
log.debug("Request Scope Discovery");
OAuth2AuthenticationToken oAuth2AuthenticationToken=(OAuth2AuthenticationToken) SecurityContextHolder.getContext().getAuthentication();
log.debug("OAuth2AuthenticationToken: {}",oAuth2AuthenticationToken);
OAuth2AuthorizedClient client = authorizedClientService
.loadAuthorizedClient(oAuth2AuthenticationToken.getAuthorizedClientRegistrationId(), oAuth2AuthenticationToken.getName());
log.debug("AccessToken: {}",client.getAccessToken().getTokenValue());
/*String userInfoEndpointUri = client.getClientRegistration().getProviderDetails().getUserInfoEndpoint().getUri();
if (!StringUtils.isEmpty(userInfoEndpointUri)) {
HttpHeaders headers = new HttpHeaders();
headers.add(HttpHeaders.AUTHORIZATION, "Bearer " + client.getAccessToken().getTokenValue());
HttpEntity entity = new HttpEntity("", headers);
RestTemplate restTemplate = new RestTemplate();
ResponseEntity<Map> response = restTemplate.exchange(userInfoEndpointUri, HttpMethod.GET, entity, Map.class);
Map userAttributes = response.getBody();
model.addAttribute("name", userAttributes.get("name"));
}*/
return contextService.all();
}
@GetMapping("/encode")
public String encodeContext() {
String contextEncoded=UriUtils.encode("/gcube", "UTF-8");
return contextEncoded;
}
@GetMapping("/decode")
public String decodeContext() {
String contextEncoded=UriUtils.decode("%2Fgcube", "UTF-8");
return contextEncoded;
}
}

View File

@ -0,0 +1,60 @@
package org.gcube.fullstackapps.informationsystemmonitor.web.rest;
import java.util.List;
import org.gcube.com.fasterxml.jackson.databind.ObjectMapper;
import org.gcube.fullstackapps.informationsystemmonitor.config.TokenManager;
import org.gcube.fullstackapps.informationsystemmonitor.service.InformationSystemService;
import org.gcube.informationsystem.contexts.reference.entities.Context;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.util.UriUtils;
import lombok.RequiredArgsConstructor;
import tech.jhipster.web.util.HeaderUtil;
/**
* REST controller for managing the current user's account.
*/
@RestController
@RequestMapping("/api/is")
@RequiredArgsConstructor
public class InformationSystemResource {
private final Logger log = LoggerFactory.getLogger(InformationSystemResource.class);
@Value("${jhipster.clientApp.name}")
private String applicationName;
private final TokenManager tokenManager;
private final InformationSystemService informationSystemService;
@GetMapping("/allcontext")
public ResponseEntity<String> allcontext() {
log.debug("Request uma token");
String rootContext = tokenManager.getRootContext();
String contextEncoded = UriUtils.encode(rootContext, "UTF-8");
String umaToken = tokenManager.getUmaToken(contextEncoded);
try {
informationSystemService.setUma(umaToken);
List<Context> contexts = informationSystemService.getAllContext(rootContext);
ObjectMapper om = new ObjectMapper();
String sc = om.writeValueAsString(contexts);
return ResponseEntity.ok().body(sc);
//return new ResponseEntity<List<Context>>(contexts, HttpStatus.OK);
} catch (Exception e) {
log.error(e.getLocalizedMessage(), e);
return ResponseEntity.noContent()
.headers(HeaderUtil.createAlert(applicationName, e.getLocalizedMessage(), "")).build();
}
}
}

Some files were not shown because too many files have changed in this diff Show More