pax_global_header 0000666 0000000 0000000 00000000064 14026145425 0014515 g ustar 00root root 0000000 0000000 52 comment=5a8ed6cd3d66f4e79f5407605bc8a56552491f66
ia2-gms-5a8ed6cd3d66f4e79f5407605bc8a56552491f66/ 0000775 0000000 0000000 00000000000 14026145425 0017651 5 ustar 00root root 0000000 0000000 ia2-gms-5a8ed6cd3d66f4e79f5407605bc8a56552491f66/.gitignore 0000664 0000000 0000000 00000001257 14026145425 0021646 0 ustar 00root root 0000000 0000000 .DS_Store
node_modules
gms-ui/dist
gms-ui/node/
# local env files
.env.local
.env.*.local
# Log files
npm-debug.log*
yarn-debug.log*
yarn-error.log*
# Editor directories and files
.idea
.vscode
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?
HELP.md
gms/target/
!.mvn/wrapper/maven-wrapper.jar
!**/src/main/**
!**/src/test/**
### STS ###
.apt_generated
.classpath
.factorypath
.project
.settings
.springBeans
.sts4-cache
### IntelliJ IDEA ###
.idea
*.iws
*.iml
*.ipr
### NetBeans ###
/nbproject/
/nbbuild/
/dist/
/nbdist/
/.nb-gradle/
build/
nbactions.xml
### VS Code ###
.vscode/
/gms/nbactions-release-profile.xml
/gms/node/
**/target/*
nb-configuration.xml
dependency-reduced-pom.xml
ia2-gms-5a8ed6cd3d66f4e79f5407605bc8a56552491f66/.gitlab-ci.yml 0000664 0000000 0000000 00000001423 14026145425 0022305 0 ustar 00root root 0000000 0000000 stages:
- build
- test
- deploy
build_gms_client:
stage: build
tags:
- docker
script:
- cd gms-client/gms-client
- mvn clean package -DskipTests -DfinalName=gms-client
artifacts:
paths:
- gms-client/gms-client/target/gms-client.jar
- gms-client/gms-client/pom.xml
expire_in: 7 days
only:
- master
test_gms_client:
stage: test
tags:
- docker
script:
- cd gms-client/gms-client
- mvn clean test
only:
- master
deploy_gms_client:
stage: deploy
tags:
- docker
script:
- mvn deploy:deploy-file
-Dfile=gms-client/gms-client/target/gms-client.jar
-DrepositoryId=ia2.snapshots
-DpomFile=gms-client/gms-client/pom.xml
-Durl=${IA2_MVN_REPO_SNAPSHOTS}
only:
- master
ia2-gms-5a8ed6cd3d66f4e79f5407605bc8a56552491f66/README.md 0000664 0000000 0000000 00000004047 14026145425 0021135 0 ustar 00root root 0000000 0000000 # IA2 GMS
## Database Docker image
To build the image run **from current directory**:
docker build -f database/Dockerfile --tag gms-db .
To start the image and use the database:
docker run -d -p 5432:5432 -i -t gms-db:latest
## GMS Docker image
To build the image:
mvn clean package dockerfile:build -DskipTests
To run:
docker run --env-file docker-env -d -p 8081:8081 -i -t gms:latest
## Create the first super-admin
The first super admin user must be added manually, then he/she will be able to add other administrators from the UI:
INSERT INTO gms_permission (group_id, user_id, permission, group_path) VALUES('ROOT', '1', 'ADMIN', '');
The value `user_id` is the RAP user id.
## Hooks
It is possible to load external jar files in order to extend the GMS with custom functionalities (implementing the *Hook interfaces and annotating the class with `@org.springframework.stereotype.Component`). Currently only the `GroupsHook` is available.
External jar files need to be specified at application startup using the `LOADER_PATH` environment variable (this is a Spring feature).
## Developer notes
Backend and frontend are 2 separate applications:
* the backend is the Maven application in the gms folder, based on Java and Spring Boot;
* the frontend is the npm application is the gms-ui folder, based on Vue.js.
The Maven application automatically packs the Vue.js products inside the final jar, however the frontend application can be tested isolatedly running `npm run serve` in order to take advantage of the npm autoreload functionalities.
By default http calls are mocked inside the Vue.js application.
In order to rely on real server calls edit the .env.development file in this way:
VUE_APP_API_CLIENT = 'server'
VUE_APP_API_BASE_URL = 'http://localhost:8081/gms/'
This assumes that your backend runs on 8081 port (with dev profile active, in order to enable the CORS policy) and the frontend runs on 8080 port.
First, do the login using the application running on the 8081 port, then you can access the frontend on the 8080.
ia2-gms-5a8ed6cd3d66f4e79f5407605bc8a56552491f66/database/ 0000775 0000000 0000000 00000000000 14026145425 0021415 5 ustar 00root root 0000000 0000000 ia2-gms-5a8ed6cd3d66f4e79f5407605bc8a56552491f66/database/Dockerfile 0000664 0000000 0000000 00000000324 14026145425 0023406 0 ustar 00root root 0000000 0000000 FROM library/postgres:11
COPY gms/src/main/resources/sql/init.sql /docker-entrypoint-initdb.d/
COPY database/user.sql /docker-entrypoint-initdb.d/
ENV ALLOW_IP_RANGE=0.0.0.0/0
ENV POSTGRES_HOST_AUTH_METHOD=trust
ia2-gms-5a8ed6cd3d66f4e79f5407605bc8a56552491f66/database/user.sql 0000664 0000000 0000000 00000000312 14026145425 0023110 0 ustar 00root root 0000000 0000000 CREATE ROLE gms WITH LOGIN PASSWORD 'gms';
GRANT USAGE ON SCHEMA public TO gms;
GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA public TO gms;
GRANT ALL PRIVILEGES ON ALL SEQUENCES IN SCHEMA public TO gms; ia2-gms-5a8ed6cd3d66f4e79f5407605bc8a56552491f66/docker-env 0000664 0000000 0000000 00000000766 14026145425 0021642 0 ustar 00root root 0000000 0000000 SPRING_DATASOURCE_URL=jdbc:postgresql://140.105.79.115:5432/postgres
SECURITY_OAUTH2_CLIENT_ACCESS-TOKEN-URI=http://140.105.79.115/rap-ia2/auth/oauth2/token
SECURITY_OAUTH2_CLIENT_USER-AUTHORIZATION-URI=http://localhost/rap-ia2/auth/oauth2/authorize
SECURITY_OAUTH2_RESOURCE_TOKEN-INFO-URI=http://140.105.79.115/rap-ia2/auth/oauth2/check_token
SECURITY_OAUTH2_RESOURCE_JWK_KEY-SET-URI=http://140.105.79.115/rap-ia2/auth/oidc/jwks
RAP_WS-URL=http://140.105.79.115/rap-ia2/ws
SPRING_PROFILES_ACTIVE=prod
ia2-gms-5a8ed6cd3d66f4e79f5407605bc8a56552491f66/e2e/ 0000775 0000000 0000000 00000000000 14026145425 0020324 5 ustar 00root root 0000000 0000000 ia2-gms-5a8ed6cd3d66f4e79f5407605bc8a56552491f66/e2e/cli_test.py 0000664 0000000 0000000 00000002336 14026145425 0022510 0 ustar 00root root 0000000 0000000 import os
base_cmd = "java -jar ~/code/ia2-gms/gms-client/gms-cli/target/gms-cli.jar --token-file ~/Downloads/token.txt --config-file ~/code/ia2-gms/gms-client/gms-cli/gms.properties "
def exec(cmd):
result = os.popen(base_cmd + cmd).read()
print(result)
return result
assert exec("create-group test false") == "Group created\n"
assert exec("create-group test.test2 true") == "Group created\n"
assert exec("list-groups test") == "test2\n"
assert exec("add-member test.test2 2386") == "Member added\n"
assert exec("add-permission test.test2 2386 VIEW_MEMBERS") == "Permission added\n"
exec("get-user-permissions 2386")
assert exec("get-group-permissions test.test2") == "2386 VIEW_MEMBERS\n"
exec("get-member-email-addresses test.test2 VIEW_MEMBERS")
exec("get-user-groups 2386")
assert exec("set-permission test.test2 2386 ADMIN") == "Permission changed\n"
assert exec("get-group-permissions test.test2") == "2386 ADMIN\n"
assert exec("delete-permission test.test2 2386") == "Permission removed\n"
assert exec("get-group-permissions test.test2") == ""
exec("remove-member test.test2 2386")
exec("get-member-email-addresses test.test2 VIEW_MEMBERS") == ""
exec("delete-group test.test2")
assert exec("list-groups test") == ""
ia2-gms-5a8ed6cd3d66f4e79f5407605bc8a56552491f66/gms-client/ 0000775 0000000 0000000 00000000000 14026145425 0021713 5 ustar 00root root 0000000 0000000 ia2-gms-5a8ed6cd3d66f4e79f5407605bc8a56552491f66/gms-client/gms-cli/ 0000775 0000000 0000000 00000000000 14026145425 0023246 5 ustar 00root root 0000000 0000000 ia2-gms-5a8ed6cd3d66f4e79f5407605bc8a56552491f66/gms-client/gms-cli/.gitignore 0000664 0000000 0000000 00000000515 14026145425 0025237 0 ustar 00root root 0000000 0000000 HELP.md
target/
!.mvn/wrapper/maven-wrapper.jar
!**/src/main/**
!**/src/test/**
### STS ###
.apt_generated
.classpath
.factorypath
.project
.settings
.springBeans
.sts4-cache
### IntelliJ IDEA ###
.idea
*.iws
*.iml
*.ipr
### NetBeans ###
/nbproject/private/
/nbbuild/
/dist/
/nbdist/
/.nb-gradle/
build/
### VS Code ###
.vscode/
ia2-gms-5a8ed6cd3d66f4e79f5407605bc8a56552491f66/gms-client/gms-cli/gms.properties 0000664 0000000 0000000 00000000147 14026145425 0026154 0 ustar 00root root 0000000 0000000 gms_url=http://localhost:8082/gms
client_id=gms_cli
client_secret=gms
rap_url=http://localhost/rap-ia2
ia2-gms-5a8ed6cd3d66f4e79f5407605bc8a56552491f66/gms-client/gms-cli/pom.xml 0000664 0000000 0000000 00000004361 14026145425 0024567 0 ustar 00root root 0000000 0000000
4.0.0
it.inaf.ia2
gms-cli
0.0.1-SNAPSHOT
gms-cli
GMS Command Line Client
12
12
12
${project.groupId}
gms-client
1.0-SNAPSHOT
org.slf4j
slf4j-log4j12
1.7.5
gms-cli
org.apache.maven.plugins
maven-shade-plugin
3.2.3
package
shade
it.inaf.ia2.gms.cli.CLI
ia2.snapshot
http://repo.ia2.inaf.it/maven/repository/snapshots
ia2-gms-5a8ed6cd3d66f4e79f5407605bc8a56552491f66/gms-client/gms-cli/src/ 0000775 0000000 0000000 00000000000 14026145425 0024035 5 ustar 00root root 0000000 0000000 ia2-gms-5a8ed6cd3d66f4e79f5407605bc8a56552491f66/gms-client/gms-cli/src/main/ 0000775 0000000 0000000 00000000000 14026145425 0024761 5 ustar 00root root 0000000 0000000 ia2-gms-5a8ed6cd3d66f4e79f5407605bc8a56552491f66/gms-client/gms-cli/src/main/java/ 0000775 0000000 0000000 00000000000 14026145425 0025702 5 ustar 00root root 0000000 0000000 ia2-gms-5a8ed6cd3d66f4e79f5407605bc8a56552491f66/gms-client/gms-cli/src/main/java/it/ 0000775 0000000 0000000 00000000000 14026145425 0026316 5 ustar 00root root 0000000 0000000 ia2-gms-5a8ed6cd3d66f4e79f5407605bc8a56552491f66/gms-client/gms-cli/src/main/java/it/inaf/ 0000775 0000000 0000000 00000000000 14026145425 0027233 5 ustar 00root root 0000000 0000000 ia2-gms-5a8ed6cd3d66f4e79f5407605bc8a56552491f66/gms-client/gms-cli/src/main/java/it/inaf/ia2/ 0000775 0000000 0000000 00000000000 14026145425 0027706 5 ustar 00root root 0000000 0000000 ia2-gms-5a8ed6cd3d66f4e79f5407605bc8a56552491f66/gms-client/gms-cli/src/main/java/it/inaf/ia2/gms/ 0000775 0000000 0000000 00000000000 14026145425 0030474 5 ustar 00root root 0000000 0000000 cli/ 0000775 0000000 0000000 00000000000 14026145425 0031164 5 ustar 00root root 0000000 0000000 ia2-gms-5a8ed6cd3d66f4e79f5407605bc8a56552491f66/gms-client/gms-cli/src/main/java/it/inaf/ia2/gms CLI.java 0000664 0000000 0000000 00000024520 14026145425 0032441 0 ustar 00root root 0000000 0000000 ia2-gms-5a8ed6cd3d66f4e79f5407605bc8a56552491f66/gms-client/gms-cli/src/main/java/it/inaf/ia2/gms/cli package it.inaf.ia2.gms.cli;
import it.inaf.ia2.client.ClientException;
import it.inaf.ia2.gms.client.GmsClient;
import it.inaf.ia2.gms.client.model.GroupPermission;
import it.inaf.ia2.gms.client.model.Permission;
import it.inaf.ia2.gms.client.model.UserPermission;
import it.inaf.ia2.rap.client.ClientCredentialsRapClient;
import it.inaf.ia2.rap.client.RapClient;
import it.inaf.ia2.rap.data.AccessTokenResponse;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.UncheckedIOException;
import java.util.List;
import java.util.Properties;
public class CLI {
public static void main(String[] args) throws Exception {
new CLI(args).run();
}
private final String args[];
private int argIndex;
private String gmsBaseUrl;
private String rapBaseUrl;
private String clientId;
private String clientSecret;
private String token;
private GmsClient client;
private CLI(String... args) {
this.args = args;
}
private void run() throws Exception {
if (args.length < 2) {
displayUsage();
}
boolean commandParsed = false;
while (argIndex < args.length && !commandParsed) {
switch (args[argIndex]) {
case "--config-file":
loadConfigFromFile(new File(getNextArg()));
break;
case "--token-file":
loadTokenFromFile(new File(getNextArg()));
break;
case "--gms-url":
gmsBaseUrl = getNextArg();
break;
case "--rap-url":
rapBaseUrl = getNextArg();
break;
case "--client-id":
clientId = getNextArg();
break;
case "--client-secret":
clientSecret = getNextArg();
break;
default:
verifyConfigLoaded();
createClient();
try {
parseCommand();
} catch (ClientException ex) {
System.err.println(ex.getMessage());
}
commandParsed = true;
break;
}
argIndex++;
}
if (!commandParsed) {
displayUsage();
}
}
private String getNextArg() {
if (argIndex + 1 == args.length) {
System.err.println("Missing value for option " + args[argIndex]);
System.exit(1);
}
return args[++argIndex];
}
private void verifyConfigLoaded() {
if (gmsBaseUrl == null) {
// Attempt reading gms.properties in current directory
loadConfigFromFile(new File("gms.properties"));
}
if (clientId == null && token == null) {
// Attempt loading token.txt in current directory
loadTokenFromFile(new File("token.txt"));
}
if (token != null && (clientSecret == null || rapBaseUrl == null)) {
System.err.println("Client secret and RAP base URL not configured");
System.exit(1);
}
}
private void createClient() {
client = new GmsClient(gmsBaseUrl);
if (token != null) {
client.setAccessToken(token);
} else {
RapClient rapClient = new ClientCredentialsRapClient(rapBaseUrl)
.setClientId(clientId)
.setClientSecret(clientSecret);
AccessTokenResponse accessTokenResponse = rapClient.getAccessTokenFromClientCredentials();
client.setAccessToken(accessTokenResponse.getAccessToken());
}
}
private void loadConfigFromFile(File config) {
if (!config.exists()) {
System.err.println("Config file " + config.getAbsolutePath() + " doesn't exist");
System.exit(1);
}
Properties properties = new Properties();
try ( InputStream in = new FileInputStream(config)) {
properties.load(in);
} catch (IOException ex) {
throw new UncheckedIOException(ex);
}
gmsBaseUrl = properties.getProperty("gms_url");
if (gmsBaseUrl == null) {
System.err.println("Missing gms_url in gms.properties");
System.exit(1);
}
rapBaseUrl = properties.getProperty("rap_url");
clientId = properties.getProperty("client_id");
clientSecret = properties.getProperty("client_secret");
}
private void loadTokenFromFile(File tokenFile) {
if (!tokenFile.exists()) {
System.err.println("Token file " + tokenFile.getAbsolutePath() + " doesn't exist");
System.exit(1);
}
try ( InputStream in = new FileInputStream(tokenFile)) {
java.util.Scanner s = new java.util.Scanner(in).useDelimiter("\\A");
token = s.next().trim();
} catch (IOException ex) {
throw new UncheckedIOException(ex);
}
}
private void parseCommand() {
switch (args[argIndex]) {
case "list-groups": {
String parent = "";
if (args.length == argIndex + 2) {
parent = args[argIndex + 1];
}
for (String group : client.listGroups(parent, false)) {
System.out.println(group);
}
break;
}
case "create-group":
boolean leaf = false;
if (argIndex + 2 < args.length) {
leaf = Boolean.parseBoolean(args[argIndex + 2]);
}
client.createGroup(args[argIndex + 1], leaf);
System.out.println("Group created");
break;
case "get-group-permissions": {
String parent = "";
if (args.length == argIndex + 2) {
parent = args[argIndex + 1];
}
for (GroupPermission gp : client.getGroupPermissions(parent)) {
System.out.println(gp.getUserId() + " " + gp.getPermission());
}
break;
}
case "delete-group":
client.deleteGroup(getNextArg());
System.out.println("Group deleted");
break;
case "get-user-groups": {
String userId = getNextArg();
String parent = "";
if (args.length == argIndex + 2) {
parent = args[argIndex + 1];
}
for (String group : client.getUserGroups(userId, parent)) {
System.out.println(group);
}
break;
}
case "add-member":
if (argIndex + 2 >= args.length) {
displayUsage();
}
client.addMember(args[argIndex + 1], args[argIndex + 2]);
System.out.println("Member added");
break;
case "remove-member":
if (argIndex + 2 >= args.length) {
displayUsage();
}
client.removeMember(args[argIndex + 1], args[argIndex + 2]);
System.out.println("Member removed");
break;
case "get-user-permissions":
for (UserPermission up : client.getUserPermissions(getNextArg())) {
System.out.println(up.getGroup() + " " + up.getPermission());
}
break;
case "set-permission":
if (argIndex + 3 >= args.length) {
displayUsage();
}
client.setPermission(args[argIndex + 1], args[argIndex + 2], Permission.valueOf(args[argIndex + 3]));
System.out.println("Permission changed");
break;
case "add-permission":
if (argIndex + 3 >= args.length) {
displayUsage();
}
client.addPermission(args[argIndex + 1], args[argIndex + 2], Permission.valueOf(args[argIndex + 3]));
System.out.println("Permission added");
break;
case "delete-permission":
if (argIndex + 2 >= args.length) {
displayUsage();
}
client.removePermission(args[argIndex + 1], args[argIndex + 2]);
System.out.println("Permission removed");
break;
case "get-member-email-addresses":
Permission permission = null;
if (argIndex + 2 < args.length) {
permission = Permission.valueOf(args[argIndex + 2]);
}
List addresses = client.getMemberEmailAddresses(args[argIndex + 1], permission);
for (String address : addresses) {
System.out.println(address);
}
break;
default:
displayUsage();
break;
}
}
private void displayUsage() {
System.out.println("gms-client\n"
+ " [--config-file ]\n"
+ " [--token-file ]\n"
+ " [--gms-url ]\n"
+ " [--rap-url ]\n"
+ " [--client-id ]\n"
+ " [--client-secret ]\n"
+ " list-groups []\n"
+ " create-group []\n"
+ " delete-group \n"
+ " get-user-groups []\n"
+ " get-group-permissions []\n"
+ " get-user-permissions \n"
+ " add-member \n"
+ " remove-member \n"
+ " set-permission \n"
+ " add-permission \n"
+ " delete-permission \n"
+ " get-member-email-addresses []");
System.exit(0);
}
}
ia2-gms-5a8ed6cd3d66f4e79f5407605bc8a56552491f66/gms-client/gms-client/ 0000775 0000000 0000000 00000000000 14026145425 0023755 5 ustar 00root root 0000000 0000000 ia2-gms-5a8ed6cd3d66f4e79f5407605bc8a56552491f66/gms-client/gms-client/pom.xml 0000664 0000000 0000000 00000007001 14026145425 0025270 0 ustar 00root root 0000000 0000000
4.0.0
it.inaf.ia2
gms-client
1.0-SNAPSHOT
jar
UTF-8
14
14
5.6.0
3.5.13
${project.artifactId}-${project.version}
${project.groupId}
rap-client
1.0-SNAPSHOT
org.junit.jupiter
junit-jupiter-api
${junit-jupiter.version}
test
org.junit.jupiter
junit-jupiter-params
${junit-jupiter.version}
test
org.junit.jupiter
junit-jupiter-engine
${junit-jupiter.version}
test
org.mockito
mockito-core
${mockito.version}
test
org.mockito
mockito-inline
${mockito.version}
test
org.mockito
mockito-junit-jupiter
${mockito.version}
test
${finalName}
org.jacoco
jacoco-maven-plugin
0.8.6
prepare-agent
report
test
report
maven-surefire-plugin
2.22.2
ia2.snapshot
http://repo.ia2.inaf.it/maven/repository/snapshots