[DEV] review with new model
This commit is contained in:
parent
f4d7438918
commit
4f8a34590e
@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<classpath>
|
||||
<classpathentry kind="src" output="out/maven/classes" path="src">
|
||||
<classpathentry including="**/*.java" kind="src" output="out/maven/classes" path="src">
|
||||
<attributes>
|
||||
<attribute name="optional" value="true"/>
|
||||
<attribute name="maven.pomderived" value="true"/>
|
||||
@ -13,11 +13,6 @@
|
||||
<attribute name="maven.pomderived" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER">
|
||||
<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"/>
|
||||
@ -25,10 +20,16 @@
|
||||
</classpathentry>
|
||||
<classpathentry excluding="**" kind="src" output="out/maven/test-classes" path="test/resources">
|
||||
<attributes>
|
||||
<attribute name="maven.pomderived" value="true"/>
|
||||
<attribute name="test" value="true"/>
|
||||
<attribute name="maven.pomderived" value="true"/>
|
||||
<attribute name="optional" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER">
|
||||
<attributes>
|
||||
<attribute name="module" value="true"/>
|
||||
<attribute name="maven.pomderived" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="output" path="out/maven/classes"/>
|
||||
</classpath>
|
||||
|
@ -1,5 +1,5 @@
|
||||
services:
|
||||
db_service:
|
||||
kar_db_service:
|
||||
image: mysql:latest
|
||||
restart: always
|
||||
environment:
|
||||
@ -9,20 +9,20 @@ services:
|
||||
#- /workspace/data/global/db:/var/lib/mysql
|
||||
mem_limit: 300m
|
||||
ports:
|
||||
- 3306:3306
|
||||
- 3906:3306
|
||||
healthcheck:
|
||||
test: ["CMD", "mysqladmin" ,"ping", "-h", "localhost"]
|
||||
timeout: 10s
|
||||
retries: 5
|
||||
start_period: 20s
|
||||
|
||||
adminer_service:
|
||||
kar_adminer_service:
|
||||
image: adminer:latest
|
||||
restart: always
|
||||
ports:
|
||||
- 10079:8080
|
||||
- 18079:8080
|
||||
links:
|
||||
- db_service:db
|
||||
- kar_db_service:db
|
||||
#read_only: true
|
||||
mem_limit: 100m
|
||||
|
||||
|
20
back/pom.xml
20
back/pom.xml
@ -24,7 +24,7 @@
|
||||
<dependency>
|
||||
<groupId>kangaroo-and-rabbit</groupId>
|
||||
<artifactId>archidata</artifactId>
|
||||
<version>0.3.7</version>
|
||||
<version>0.4.0</version>
|
||||
</dependency>
|
||||
<!-- testing -->
|
||||
<dependency>
|
||||
@ -159,7 +159,25 @@
|
||||
<nohelp>true</nohelp>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.codehaus.mojo</groupId>
|
||||
<artifactId>exec-maven-plugin</artifactId>
|
||||
<version>3.1.0</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>exec-application</id>
|
||||
<phase>package</phase>
|
||||
<goals>
|
||||
<goal>java</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
<configuration>
|
||||
<mainClass>org.kar.karso.WebLauncher</mainClass>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
|
||||
<testResources>
|
||||
<testResource>
|
||||
<directory>${basedir}/test/resources</directory>
|
||||
|
@ -1,8 +1,25 @@
|
||||
|
||||
package org.kar.karso;
|
||||
|
||||
import java.net.URI;
|
||||
|
||||
import org.glassfish.grizzly.http.server.HttpServer;
|
||||
import org.glassfish.jersey.grizzly2.httpserver.GrizzlyHttpServerFactory;
|
||||
import org.glassfish.jersey.jackson.JacksonFeature;
|
||||
import org.glassfish.jersey.server.ResourceConfig;
|
||||
import org.kar.archidata.GlobalConfiguration;
|
||||
//import org.kar.archidata.model.Migration;
|
||||
import org.kar.archidata.catcher.ExceptionCatcher;
|
||||
import org.kar.archidata.catcher.FailException404API;
|
||||
import org.kar.archidata.catcher.FailExceptionCatcher;
|
||||
import org.kar.archidata.catcher.InputExceptionCatcher;
|
||||
import org.kar.archidata.catcher.SystemExceptionCatcher;
|
||||
import org.kar.archidata.filter.CORSFilter;
|
||||
import org.kar.archidata.filter.OptionFilter;
|
||||
import org.kar.archidata.migration.MigrationEngine;
|
||||
import org.kar.archidata.sqlWrapper.GenericAddOn;
|
||||
import org.kar.archidata.util.ConfigBaseVariable;
|
||||
import org.kar.archidata.util.JWTWrapper;
|
||||
import org.kar.karso.api.ApplicationResource;
|
||||
import org.kar.karso.api.ApplicationTokenResource;
|
||||
import org.kar.karso.api.Front;
|
||||
@ -16,38 +33,26 @@ import org.kar.karso.migration.Initialization;
|
||||
import org.kar.karso.util.ConfigVariable;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.kar.archidata.GlobalConfiguration;
|
||||
//import org.kar.archidata.model.Migration;
|
||||
import org.kar.archidata.catcher.ExceptionCatcher;
|
||||
import org.kar.archidata.catcher.FailException404API;
|
||||
import org.kar.archidata.catcher.FailExceptionCatcher;
|
||||
import org.kar.archidata.catcher.InputExceptionCatcher;
|
||||
import org.kar.archidata.catcher.SystemExceptionCatcher;
|
||||
import org.kar.archidata.filter.CORSFilter;
|
||||
import org.kar.archidata.util.ConfigBaseVariable;
|
||||
import org.kar.archidata.util.JWTWrapper;
|
||||
import org.glassfish.grizzly.http.server.HttpServer;
|
||||
import org.glassfish.jersey.grizzly2.httpserver.GrizzlyHttpServerFactory;
|
||||
import org.glassfish.jersey.jackson.JacksonFeature;
|
||||
import org.glassfish.jersey.server.ResourceConfig;
|
||||
|
||||
import jakarta.ws.rs.core.UriBuilder;
|
||||
import java.net.URI;
|
||||
|
||||
public class WebLauncher {
|
||||
final static Logger LOGGER = LoggerFactory.getLogger(WebLauncher.class);
|
||||
private final static Logger LOGGER = LoggerFactory.getLogger(WebLauncher.class);
|
||||
protected ResourceConfig rc = null;
|
||||
HttpServer server = null;
|
||||
|
||||
public WebLauncher() {
|
||||
ConfigBaseVariable.bdDatabase = "karso";
|
||||
GenericAddOn.addGenericAddOn();
|
||||
}
|
||||
|
||||
private static URI getBaseURI() {
|
||||
return UriBuilder.fromUri(ConfigBaseVariable.getlocalAddress()).build();
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
public static void main(final String[] args) throws Exception {
|
||||
WebLauncher.LOGGER.info("[START] application wake UP");
|
||||
WebLauncher launcher = new WebLauncher();
|
||||
final WebLauncher launcher = new WebLauncher();
|
||||
launcher.migrateDB();
|
||||
|
||||
launcher.process();
|
||||
@ -58,7 +63,7 @@ public class WebLauncher {
|
||||
|
||||
public void migrateDB() throws Exception {
|
||||
WebLauncher.LOGGER.info("Create migration engine");
|
||||
MigrationEngine migrationEngine = new MigrationEngine();
|
||||
final MigrationEngine migrationEngine = new MigrationEngine();
|
||||
WebLauncher.LOGGER.info("Add initialization");
|
||||
migrationEngine.setInit(new Initialization());
|
||||
WebLauncher.LOGGER.info("Add migration since last version");
|
||||
@ -71,7 +76,7 @@ public class WebLauncher {
|
||||
public void process() throws InterruptedException {
|
||||
try {
|
||||
JWTWrapper.initLocalToken(ConfigVariable.getUUIDKeyRoot());
|
||||
} catch (Exception e1) {
|
||||
} catch (final Exception e1) {
|
||||
// TODO Auto-generated catch block
|
||||
e1.printStackTrace();
|
||||
LOGGER.info("Wait 10 seconds ....");
|
||||
@ -82,47 +87,47 @@ public class WebLauncher {
|
||||
// ===================================================================
|
||||
// Configure resources
|
||||
// ===================================================================
|
||||
rc = new ResourceConfig();
|
||||
// global authentication system
|
||||
rc.register(OptionFilter.class);
|
||||
rc.register(CORSFilter.class);
|
||||
rc.register(KarsoAuthenticationFilter.class);
|
||||
// register exception catcher
|
||||
rc.register(InputExceptionCatcher.class);
|
||||
rc.register(SystemExceptionCatcher.class);
|
||||
rc.register(FailExceptionCatcher.class);
|
||||
rc.register(FailException404API.class);
|
||||
rc.register(ExceptionCatcher.class);
|
||||
this.rc = new ResourceConfig();
|
||||
// global authentication system
|
||||
this.rc.register(OptionFilter.class);
|
||||
this.rc.register(CORSFilter.class);
|
||||
this.rc.register(KarsoAuthenticationFilter.class);
|
||||
// register exception catcher
|
||||
this.rc.register(InputExceptionCatcher.class);
|
||||
this.rc.register(SystemExceptionCatcher.class);
|
||||
this.rc.register(FailExceptionCatcher.class);
|
||||
this.rc.register(FailException404API.class);
|
||||
this.rc.register(ExceptionCatcher.class);
|
||||
// add default resource:
|
||||
rc.register(UserResource.class);
|
||||
rc.register(PublicKeyResource.class);
|
||||
rc.register(ApplicationResource.class);
|
||||
rc.register(ApplicationTokenResource.class);
|
||||
rc.register(SystemConfigResource.class);
|
||||
rc.register(RightResource.class);
|
||||
rc.register(Front.class);
|
||||
rc.register(HealthCheck.class);
|
||||
this.rc.register(UserResource.class);
|
||||
this.rc.register(PublicKeyResource.class);
|
||||
this.rc.register(ApplicationResource.class);
|
||||
this.rc.register(ApplicationTokenResource.class);
|
||||
this.rc.register(SystemConfigResource.class);
|
||||
this.rc.register(RightResource.class);
|
||||
this.rc.register(Front.class);
|
||||
this.rc.register(HealthCheck.class);
|
||||
// add jackson to be discover when we are ins stand-alone server
|
||||
rc.register(JacksonFeature.class);
|
||||
// enable this to show low level request
|
||||
this.rc.register(JacksonFeature.class);
|
||||
// enable this to show low level request
|
||||
//rc.property(LoggingFeature.LOGGING_FEATURE_LOGGER_LEVEL_SERVER, Level.WARNING.getName());
|
||||
|
||||
server = GrizzlyHttpServerFactory.createHttpServer(getBaseURI(), rc);
|
||||
this.server = GrizzlyHttpServerFactory.createHttpServer(getBaseURI(), this.rc);
|
||||
Runtime.getRuntime().addShutdownHook(new Thread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
LOGGER.info("Stopping server..");
|
||||
server.shutdownNow();
|
||||
WebLauncher.this.server.shutdownNow();
|
||||
}
|
||||
}, "shutdownHook"));
|
||||
|
||||
// ===================================================================
|
||||
// ===================================================================
|
||||
// run JERSEY
|
||||
// ===================================================================
|
||||
// ===================================================================
|
||||
try {
|
||||
server.start();
|
||||
this.server.start();
|
||||
LOGGER.info("Jersey app started at {}", getBaseURI());
|
||||
} catch (Exception e) {
|
||||
} catch (final Exception e) {
|
||||
LOGGER.error("There was an error while starting Grizzly HTTP server.");
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
@ -7,36 +7,39 @@ import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
public class WebLauncherLocal extends WebLauncher {
|
||||
final Logger logger = LoggerFactory.getLogger(WebLauncherLocal.class);
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(WebLauncherLocal.class);
|
||||
|
||||
private WebLauncherLocal() {}
|
||||
|
||||
public static void main(String[] args) throws InterruptedException {
|
||||
WebLauncherLocal launcher = new WebLauncherLocal();
|
||||
|
||||
public static void main(final String[] args) throws InterruptedException {
|
||||
final WebLauncherLocal launcher = new WebLauncherLocal();
|
||||
launcher.process();
|
||||
launcher.logger.info("end-configure the server & wait finish process:");
|
||||
LOGGER.info("end-configure the server & wait finish process:");
|
||||
Thread.currentThread().join();
|
||||
launcher.logger.info("STOP the REST server:");
|
||||
LOGGER.info("STOP the REST server:");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void process() throws InterruptedException {
|
||||
if (true) {
|
||||
// for local test:
|
||||
ConfigBaseVariable.apiAdress = "http://0.0.0.0:15080/karso/api/";
|
||||
ConfigBaseVariable.dbPort = "3306";
|
||||
ConfigBaseVariable.dbPort = "3906";
|
||||
// create a unique key for test ==> not retrieve the token every load...
|
||||
ConfigVariable.uuid_for_key_generation = "lkjlkjlkjlmkjqmwlsdkjqfsdlkf88QJSDMLQKSndmLQKZNERMAL";
|
||||
//ConfigBaseVariable.dbType = "sqlite";
|
||||
//ConfigBaseVariable.dbHost = "./bdd_base.sqlite";
|
||||
|
||||
|
||||
}
|
||||
try {
|
||||
super.migrateDB();
|
||||
} catch (Exception e) {
|
||||
// TODO Auto-generated catch block
|
||||
} catch (final Exception e) {
|
||||
e.printStackTrace();
|
||||
while (true) {
|
||||
logger.error("Migration fail ==> waiting intervention of administrator...");
|
||||
Thread.sleep(60*60*1000);
|
||||
LOGGER.error("============================================================================");
|
||||
LOGGER.error("== Migration fail ==> waiting intervention of administrator...");
|
||||
LOGGER.error("============================================================================");
|
||||
Thread.sleep(60 * 60 * 1000);
|
||||
}
|
||||
}
|
||||
super.process();
|
||||
|
@ -1,107 +1,113 @@
|
||||
package org.kar.karso.api;
|
||||
|
||||
import org.kar.archidata.SqlWrapper;
|
||||
import org.kar.archidata.WhereCondition;
|
||||
import org.kar.archidata.filter.GenericContext;
|
||||
import org.kar.karso.model.*;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.kar.archidata.util.JWTWrapper;
|
||||
import org.kar.archidata.annotation.security.RolesAllowed;
|
||||
import org.kar.archidata.exception.InputException;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import jakarta.ws.rs.*;
|
||||
import org.kar.archidata.annotation.security.RolesAllowed;
|
||||
import org.kar.archidata.exception.InputException;
|
||||
import org.kar.archidata.filter.GenericContext;
|
||||
import org.kar.archidata.sqlWrapper.QuerryAnd;
|
||||
import org.kar.archidata.sqlWrapper.QuerryCondition;
|
||||
import org.kar.archidata.sqlWrapper.SqlWrapper;
|
||||
import org.kar.archidata.sqlWrapper.addOn.AddOnSQLTableExternalLink;
|
||||
import org.kar.archidata.util.JWTWrapper;
|
||||
import org.kar.karso.model.Application;
|
||||
import org.kar.karso.model.ApplicationSmall;
|
||||
import org.kar.karso.model.RightDescription;
|
||||
import org.kar.karso.model.UserAuth;
|
||||
import org.kar.karso.model.UserLinkApplication;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import jakarta.ws.rs.Consumes;
|
||||
import jakarta.ws.rs.DELETE;
|
||||
import jakarta.ws.rs.GET;
|
||||
import jakarta.ws.rs.POST;
|
||||
import jakarta.ws.rs.PUT;
|
||||
import jakarta.ws.rs.Path;
|
||||
import jakarta.ws.rs.PathParam;
|
||||
import jakarta.ws.rs.Produces;
|
||||
import jakarta.ws.rs.QueryParam;
|
||||
import jakarta.ws.rs.core.Context;
|
||||
import jakarta.ws.rs.core.MediaType;
|
||||
import jakarta.ws.rs.core.Response;
|
||||
import jakarta.ws.rs.core.SecurityContext;
|
||||
|
||||
|
||||
@Path("/application")
|
||||
@Produces( MediaType.APPLICATION_JSON)
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
public class ApplicationResource {
|
||||
final Logger logger = LoggerFactory.getLogger(ApplicationResource.class);
|
||||
|
||||
public ApplicationResource() {
|
||||
}
|
||||
public List<Long> getUserListOfApplication(Long userId) {
|
||||
List<Long> out = new ArrayList<>();
|
||||
public ApplicationResource() {}
|
||||
|
||||
public List<Long> getUserListOfApplication(final Long userId) {
|
||||
final List<Long> out = new ArrayList<>();
|
||||
List<UserLinkApplication> links = null;
|
||||
try {
|
||||
links = SqlWrapper.getsWhere(UserLinkApplication.class,
|
||||
List.of(
|
||||
new WhereCondition("user_id", "=", userId),
|
||||
new WhereCondition("deleted", "=", 0)
|
||||
), false);
|
||||
} catch (Exception e) {
|
||||
try {
|
||||
links = SqlWrapper.getsWhere(UserLinkApplication.class, new QuerryAnd(new QuerryCondition("user_id", "=", userId), new QuerryCondition("deleted", "=", 0)), false);
|
||||
} catch (final Exception e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
String result = "SERVER Internal error";
|
||||
logger.error(" result: {}", result);
|
||||
final String result = "SERVER Internal error";
|
||||
this.logger.error(" result: {}", result);
|
||||
return out;
|
||||
}
|
||||
for (UserLinkApplication app : links) {
|
||||
out.add(app.application_id);
|
||||
}
|
||||
return out;
|
||||
for (final UserLinkApplication app : links) {
|
||||
out.add(app.application_id);
|
||||
}
|
||||
return out;
|
||||
}
|
||||
public List<Long> getListOfUsers(Long applicationId) {
|
||||
List<Long> out = new ArrayList<>();
|
||||
|
||||
public List<Long> getListOfUsers(final Long applicationId) {
|
||||
final List<Long> out = new ArrayList<>();
|
||||
List<UserLinkApplication> links = null;
|
||||
try {
|
||||
links = SqlWrapper.getsWhere(UserLinkApplication.class,
|
||||
List.of(
|
||||
new WhereCondition("application_id", "=", applicationId),
|
||||
new WhereCondition("deleted", "=", 0)
|
||||
), false);
|
||||
} catch (Exception e) {
|
||||
try {
|
||||
links = SqlWrapper.getsWhere(UserLinkApplication.class, new QuerryAnd(new QuerryCondition("application_id", "=", applicationId), new QuerryCondition("deleted", "=", 0)), false);
|
||||
} catch (final Exception e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
String result = "SERVER Internal error";
|
||||
logger.error(" result: {}", result);
|
||||
final String result = "SERVER Internal error";
|
||||
this.logger.error(" result: {}", result);
|
||||
return out;
|
||||
}
|
||||
logger.debug("Find list of user for an application: {}", links);
|
||||
for (UserLinkApplication app : links) {
|
||||
out.add(app.user_id);
|
||||
}
|
||||
return out;
|
||||
this.logger.debug("Find list of user for an application: {}", links);
|
||||
for (final UserLinkApplication app : links) {
|
||||
out.add(app.user_id);
|
||||
}
|
||||
return out;
|
||||
}
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Generic /application/
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@GET
|
||||
@RolesAllowed(value= {"USER", "ADMIN"})
|
||||
public List<Application> getApplications(@Context SecurityContext sc) throws Exception {
|
||||
GenericContext gc = (GenericContext) sc.getUserPrincipal();
|
||||
logger.debug("getApplications");
|
||||
@GET
|
||||
@RolesAllowed(value = { "USER", "ADMIN" })
|
||||
public List<Application> getApplications(@Context final SecurityContext sc) throws Exception {
|
||||
final GenericContext gc = (GenericContext) sc.getUserPrincipal();
|
||||
this.logger.debug("getApplications");
|
||||
// TODO filter with the list of element available in his authorizations ...
|
||||
List<Application> tmp = SqlWrapper.gets(Application.class, false);
|
||||
final List<Application> tmp = SqlWrapper.gets(Application.class, false);
|
||||
if (gc.userByToken.hasRight("ADMIN", true)) {
|
||||
return tmp;
|
||||
}
|
||||
List<Long> regular = this.getUserListOfApplication(gc.userByToken.id);
|
||||
List<Application> out = new ArrayList<>();
|
||||
for (Application app : tmp) {
|
||||
if (regular.indexOf(app.id) != -1) {
|
||||
out.add(app);
|
||||
}
|
||||
}
|
||||
final List<Long> regular = getUserListOfApplication(gc.userByToken.id);
|
||||
final List<Application> out = new ArrayList<>();
|
||||
for (final Application app : tmp) {
|
||||
if (regular.indexOf(app.id) != -1) {
|
||||
out.add(app);
|
||||
}
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
@POST
|
||||
@RolesAllowed("ADMIN")
|
||||
public Application create(Application application) throws Exception {
|
||||
logger.debug("create new application {}", application);
|
||||
@RolesAllowed("ADMIN")
|
||||
public Application create(final Application application) throws Exception {
|
||||
this.logger.debug("create new application {}", application);
|
||||
// verify login or email is correct:
|
||||
if (application.name == null || application.name.length() < 5) {
|
||||
throw new InputException("name", "create application (name too small: '" + application.name + "')");
|
||||
@ -115,178 +121,171 @@ public class ApplicationResource {
|
||||
application.modify_date = null;
|
||||
return SqlWrapper.insert(application);
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Generic /application/{id}
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@GET
|
||||
@Path("{id}")
|
||||
@RolesAllowed("ADMIN")
|
||||
public Application get(@PathParam("id") Long id) throws Exception {
|
||||
return SqlWrapper.get(Application.class, id);
|
||||
}
|
||||
@GET
|
||||
@Path("{id}")
|
||||
@RolesAllowed("ADMIN")
|
||||
public Application get(@PathParam("id") final Long id) throws Exception {
|
||||
return SqlWrapper.get(Application.class, id);
|
||||
}
|
||||
|
||||
@PUT
|
||||
@Path("{id}")
|
||||
@RolesAllowed("ADMIN")
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
public Application put(@PathParam("id") final Long id, final String jsonRequest) throws Exception {
|
||||
SqlWrapper.update(Application.class, id, jsonRequest);
|
||||
return SqlWrapper.get(Application.class, id);
|
||||
}
|
||||
|
||||
@PUT
|
||||
@Path("{id}")
|
||||
@RolesAllowed("ADMIN")
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
public Application put(@PathParam("id") Long id, String jsonRequest) throws Exception {
|
||||
SqlWrapper.update(Application.class, id, jsonRequest);
|
||||
return SqlWrapper.get(Application.class, id);
|
||||
}
|
||||
|
||||
@DELETE
|
||||
@Path("{id}")
|
||||
@RolesAllowed("ADMIN")
|
||||
@Produces( value = MediaType.TEXT_PLAIN )
|
||||
public void remove(@Context SecurityContext sc, @PathParam("id") long applicationId) throws Exception {
|
||||
@RolesAllowed("ADMIN")
|
||||
@Produces(value = MediaType.TEXT_PLAIN)
|
||||
public void remove(@Context final SecurityContext sc, @PathParam("id") final long applicationId) throws Exception {
|
||||
SqlWrapper.setDelete(Application.class, applicationId);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Generic /{id}/*
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
@GET
|
||||
@Path("{id}/users")
|
||||
@RolesAllowed(value= {"ADMIN"})
|
||||
public List<Long> getApplicationUsers(@PathParam("id") Long applicationId) throws Exception {
|
||||
// special case for SSO: (all user have access on the SSO...).
|
||||
|
||||
logger.debug("Request list of user for an applciation: {}", applicationId);
|
||||
|
||||
@GET
|
||||
@Path("{id}/users")
|
||||
@RolesAllowed(value = { "ADMIN" })
|
||||
public List<Long> getApplicationUsers(@PathParam("id") final Long applicationId) throws Exception {
|
||||
// special case for SSO: (all user have access on the SSO...).
|
||||
|
||||
this.logger.debug("Request list of user for an applciation: {}", applicationId);
|
||||
return getListOfUsers(applicationId);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Generic /application/*
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
@GET
|
||||
@Path("small")
|
||||
@RolesAllowed(value= {"USER", "ADMIN"})
|
||||
public List<ApplicationSmall> getApplicationsSmall(@Context SecurityContext sc) throws Exception {
|
||||
GenericContext gc = (GenericContext) sc.getUserPrincipal();
|
||||
logger.debug("getApplications");
|
||||
List<Application> tmp = SqlWrapper.gets(Application.class, false);
|
||||
List<Long> regular = this.getUserListOfApplication(gc.userByToken.id);
|
||||
List<ApplicationSmall> out = new ArrayList<>();
|
||||
for (Application app : tmp) {
|
||||
if (regular.indexOf(app.id) != -1) {
|
||||
out.add(new ApplicationSmall(app.name, app.description, app.redirect));
|
||||
}
|
||||
}
|
||||
|
||||
@GET
|
||||
@Path("small")
|
||||
@RolesAllowed(value = { "USER", "ADMIN" })
|
||||
public List<ApplicationSmall> getApplicationsSmall(@Context final SecurityContext sc) throws Exception {
|
||||
final GenericContext gc = (GenericContext) sc.getUserPrincipal();
|
||||
this.logger.debug("getApplications");
|
||||
final List<Application> tmp = SqlWrapper.gets(Application.class, false);
|
||||
final List<Long> regular = getUserListOfApplication(gc.userByToken.id);
|
||||
final List<ApplicationSmall> out = new ArrayList<>();
|
||||
for (final Application app : tmp) {
|
||||
if (regular.indexOf(app.id) != -1) {
|
||||
out.add(new ApplicationSmall(app.name, app.description, app.redirect));
|
||||
}
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
public record AddUserData(long userId) {};
|
||||
// TODO : review the function to correct admin only access...
|
||||
@POST
|
||||
@Path("{id}/users")
|
||||
@RolesAllowed(value= {"ADMIN"})
|
||||
public boolean addUser(@PathParam("id") Long applicationId, AddUserData data) throws Exception {
|
||||
logger.debug("getApplications");
|
||||
SqlWrapper.addLink(UserAuth.class, data.userId, "application", applicationId);
|
||||
public record AddUserData(
|
||||
long userId) {};
|
||||
|
||||
// TODO : review the function to correct admin only access...
|
||||
@POST
|
||||
@Path("{id}/users")
|
||||
@RolesAllowed(value = { "ADMIN" })
|
||||
public boolean addUser(@PathParam("id") final Long applicationId, final AddUserData data) throws Exception {
|
||||
this.logger.debug("getApplications");
|
||||
AddOnSQLTableExternalLink.addLink(UserAuth.class, data.userId, "application", applicationId);
|
||||
return true;
|
||||
}
|
||||
|
||||
// TODO : review the function to correct admin only access...
|
||||
@DELETE
|
||||
@Path("{id}/users")
|
||||
@RolesAllowed(value= {"ADMIN"})
|
||||
public boolean rmUser(@PathParam("id") Long applicationId, AddUserData data) throws Exception {
|
||||
logger.debug("getApplications");
|
||||
SqlWrapper.removeLink(UserAuth.class, data.userId, "application", applicationId);
|
||||
// TODO : review the function to correct admin only access...
|
||||
@DELETE
|
||||
@Path("{id}/users")
|
||||
@RolesAllowed(value = { "ADMIN" })
|
||||
public boolean rmUser(@PathParam("id") final Long applicationId, final AddUserData data) throws Exception {
|
||||
this.logger.debug("getApplications");
|
||||
AddOnSQLTableExternalLink.removeLink(UserAuth.class, data.userId, "application", applicationId);
|
||||
return true;
|
||||
}
|
||||
|
||||
// TODO : review the function to correct admin only access...
|
||||
@GET
|
||||
@Path("{id}/rights")
|
||||
@RolesAllowed(value= {"ADMIN"})
|
||||
public List<RightDescription> getRightsDescription(@PathParam("id") Long applicationId) throws Exception {
|
||||
logger.debug("getApplications rights");
|
||||
return SqlWrapper.getsWhere(RightDescription.class, List.of(
|
||||
new WhereCondition("applicationId", "=", applicationId)),
|
||||
false);
|
||||
|
||||
// TODO : review the function to correct admin only access...
|
||||
@GET
|
||||
@Path("{id}/rights")
|
||||
@RolesAllowed(value = { "ADMIN" })
|
||||
public List<RightDescription> getRightsDescription(@PathParam("id") final Long applicationId) throws Exception {
|
||||
this.logger.debug("getApplications rights");
|
||||
return SqlWrapper.getsWhere(RightDescription.class, new QuerryCondition("applicationId", "=", applicationId), false);
|
||||
}
|
||||
|
||||
@GET
|
||||
@Path("get_token")
|
||||
@RolesAllowed(value= {"USER", "ADMIN"})
|
||||
public Response getClientToken(@Context SecurityContext sc, @QueryParam("application") String application) throws Exception {
|
||||
GenericContext gc = (GenericContext) sc.getUserPrincipal();
|
||||
logger.info("get application TOKEN application name='{}'", application);
|
||||
logger.debug("== USER ? {}", gc.userByToken.name);
|
||||
|
||||
@GET
|
||||
@Path("get_token")
|
||||
@RolesAllowed(value = { "USER", "ADMIN" })
|
||||
public Response getClientToken(@Context final SecurityContext sc, @QueryParam("application") final String application) throws Exception {
|
||||
final GenericContext gc = (GenericContext) sc.getUserPrincipal();
|
||||
this.logger.info("get application TOKEN application name='{}'", application);
|
||||
this.logger.debug("== USER ? {}", gc.userByToken.name);
|
||||
|
||||
if (application == null) {
|
||||
String result = "Input error missing parameter: 'application'";
|
||||
logger.debug(" result: {}", result);
|
||||
final String result = "Input error missing parameter: 'application'";
|
||||
this.logger.debug(" result: {}", result);
|
||||
return Response.status(406).entity(result).build();
|
||||
}
|
||||
String applicationName = application;
|
||||
boolean isDev = false;
|
||||
if (applicationName.endsWith("-dev")) {
|
||||
applicationName = applicationName.substring(0, applicationName.length()-4);
|
||||
isDev = true;
|
||||
}
|
||||
logger.debug("Search for '{}' base of '{}'", applicationName, application);
|
||||
|
||||
String applicationName = application;
|
||||
boolean isDev = false;
|
||||
if (applicationName.endsWith("-dev")) {
|
||||
applicationName = applicationName.substring(0, applicationName.length() - 4);
|
||||
isDev = true;
|
||||
}
|
||||
this.logger.debug("Search for '{}' base of '{}'", applicationName, application);
|
||||
|
||||
Application appl = null;
|
||||
try {
|
||||
appl = SqlWrapper.getWhere(Application.class, List.of(new WhereCondition("name", "=", applicationName)), false);
|
||||
} catch (Exception e) {
|
||||
try {
|
||||
appl = SqlWrapper.getWhere(Application.class, new QuerryCondition("name", "=", applicationName), false);
|
||||
} catch (final Exception e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
String result = "SERVER Internal error";
|
||||
logger.debug(" result: {}", result);
|
||||
final String result = "SERVER Internal error";
|
||||
this.logger.debug(" result: {}", result);
|
||||
return Response.status(500).entity(result).build();
|
||||
}
|
||||
|
||||
|
||||
if (appl == null) {
|
||||
String result = "Authentiocate-wrong email/login '" + applicationName + "')";
|
||||
logger.error(" result: {}", result);
|
||||
final String result = "Authentiocate-wrong email/login '" + applicationName + "')";
|
||||
this.logger.error(" result: {}", result);
|
||||
return Response.status(401).entity(result).build();
|
||||
}
|
||||
UserLinkApplication links = null;
|
||||
try {
|
||||
links = SqlWrapper.getWhere(UserLinkApplication.class,
|
||||
List.of(
|
||||
new WhereCondition("user_id", "=", gc.userByToken.id),
|
||||
new WhereCondition("deleted", "=", 0),
|
||||
new WhereCondition("application_id", "=", appl.id)
|
||||
), false);
|
||||
} catch (Exception e) {
|
||||
try {
|
||||
links = SqlWrapper.getWhere(UserLinkApplication.class,
|
||||
new QuerryAnd(new QuerryCondition("user_id", "=", gc.userByToken.id), new QuerryCondition("deleted", "=", 0), new QuerryCondition("application_id", "=", appl.id)), false);
|
||||
} catch (final Exception e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
String result = "SERVER Internal error";
|
||||
logger.error(" result: {}", result);
|
||||
final String result = "SERVER Internal error";
|
||||
this.logger.error(" result: {}", result);
|
||||
return Response.status(500).entity(result).build();
|
||||
}
|
||||
if (links == null) {
|
||||
String result = "Authenticate impossible ==> application not accessible '" + applicationName + "'";
|
||||
logger.error(" result: {}", result);
|
||||
final String result = "Authenticate impossible ==> application not accessible '" + applicationName + "'";
|
||||
this.logger.error(" result: {}", result);
|
||||
return Response.status(401).entity(result).build();
|
||||
}
|
||||
// Get the USER Right
|
||||
Map<String, Object> applicationRight = RightResource.getUserRight(gc.userByToken.id, appl.id);
|
||||
final Map<String, Object> applicationRight = RightResource.getUserRight(gc.userByToken.id, appl.id);
|
||||
if (!applicationRight.containsKey("USER")) {
|
||||
// If the USER is not override, the system add by default USER
|
||||
applicationRight.put("USER", true);
|
||||
}
|
||||
Map<String, Object> outRight = new HashMap<>();
|
||||
final Map<String, Object> outRight = new HashMap<>();
|
||||
// we set the right in the under map to manage multiple application group right. and in some application user can see other user or all user of the application
|
||||
outRight.put(applicationName, applicationRight);
|
||||
String ret = JWTWrapper.generateJWToken(gc.userByToken.id, gc.userByToken.name, "KarAuth", applicationName, outRight, -appl.ttl);
|
||||
final String ret = JWTWrapper.generateJWToken(gc.userByToken.id, gc.userByToken.name, "KarAuth", applicationName, outRight, -appl.ttl);
|
||||
//logger.debug(" ==> generate token: {}", ret);
|
||||
String returnAdress = appl.redirect;
|
||||
if (isDev) {
|
||||
@ -294,44 +293,44 @@ public class ApplicationResource {
|
||||
}
|
||||
return Response.status(201).entity("{ \"url\":\"" + returnAdress + "\", \"jwt\":\"" + ret + "\"}").build();
|
||||
}
|
||||
|
||||
@GET
|
||||
@Path("return")
|
||||
@RolesAllowed(value= {"USER", "ADMIN"})
|
||||
public Response logOut(@Context SecurityContext sc, @QueryParam("application") String application) {
|
||||
logger.debug("=====================================");
|
||||
logger.debug("Get log_out()");
|
||||
logger.debug("=====================================");
|
||||
GenericContext gc = (GenericContext) sc.getUserPrincipal();
|
||||
logger.debug("== USER ? {}", gc.userByToken);
|
||||
|
||||
@GET
|
||||
@Path("return")
|
||||
@RolesAllowed(value = { "USER", "ADMIN" })
|
||||
public Response logOut(@Context final SecurityContext sc, @QueryParam("application") final String application) {
|
||||
this.logger.debug("=====================================");
|
||||
this.logger.debug("Get log_out()");
|
||||
this.logger.debug("=====================================");
|
||||
final GenericContext gc = (GenericContext) sc.getUserPrincipal();
|
||||
this.logger.debug("== USER ? {}", gc.userByToken);
|
||||
|
||||
if (application == null) {
|
||||
String result = "Input error missing parameter: 'application'";
|
||||
logger.error(" result: {}", result);
|
||||
final String result = "Input error missing parameter: 'application'";
|
||||
this.logger.error(" result: {}", result);
|
||||
return Response.status(406).entity(result).build();
|
||||
}
|
||||
String applicationName = application;
|
||||
boolean isDev = false;
|
||||
if (applicationName.endsWith("-dev")) {
|
||||
applicationName = applicationName.substring(0, applicationName.length()-4);
|
||||
isDev = true;
|
||||
}
|
||||
logger.debug("Search for '{}' base of '{}'", applicationName, application);
|
||||
|
||||
String applicationName = application;
|
||||
boolean isDev = false;
|
||||
if (applicationName.endsWith("-dev")) {
|
||||
applicationName = applicationName.substring(0, applicationName.length() - 4);
|
||||
isDev = true;
|
||||
}
|
||||
this.logger.debug("Search for '{}' base of '{}'", applicationName, application);
|
||||
|
||||
Application appl = null;
|
||||
try {
|
||||
appl = SqlWrapper.getWhere(Application.class, "name", "=", applicationName);
|
||||
} catch (Exception e) {
|
||||
try {
|
||||
appl = SqlWrapper.getWhere(Application.class, new QuerryCondition("name", "=", applicationName));
|
||||
} catch (final Exception e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
String result = "SERVER Internal error";
|
||||
logger.error(" result: {}", result);
|
||||
final String result = "SERVER Internal error";
|
||||
this.logger.error(" result: {}", result);
|
||||
return Response.status(500).entity(result).build();
|
||||
}
|
||||
|
||||
|
||||
if (appl == null) {
|
||||
String result = "Authentiocate-wrong email/login '" + applicationName + "')";
|
||||
logger.error(" result: {}", result);
|
||||
final String result = "Authentiocate-wrong email/login '" + applicationName + "')";
|
||||
this.logger.error(" result: {}", result);
|
||||
return Response.status(404).entity(result).build();
|
||||
}
|
||||
String returnAdress = appl.redirect;
|
||||
@ -341,37 +340,4 @@ public class ApplicationResource {
|
||||
return Response.status(201).entity("{ \"url\":\"" + returnAdress + "\"}").build();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -1,178 +1,137 @@
|
||||
package org.kar.karso.api;
|
||||
|
||||
import org.kar.archidata.SqlWrapper;
|
||||
import org.kar.archidata.WhereCondition;
|
||||
import org.kar.karso.model.*;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.kar.archidata.annotation.security.RolesAllowed;
|
||||
import org.kar.archidata.exception.InputException;
|
||||
|
||||
import java.sql.Timestamp;
|
||||
import java.time.OffsetDateTime;
|
||||
import java.time.ZoneOffset;
|
||||
import java.util.List;
|
||||
|
||||
import jakarta.ws.rs.*;
|
||||
import org.kar.archidata.annotation.security.RolesAllowed;
|
||||
import org.kar.archidata.exception.InputException;
|
||||
import org.kar.archidata.sqlWrapper.QuerryAnd;
|
||||
import org.kar.archidata.sqlWrapper.QuerryCondition;
|
||||
import org.kar.archidata.sqlWrapper.SqlWrapper;
|
||||
import org.kar.karso.model.ApplicationToken;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import jakarta.ws.rs.DELETE;
|
||||
import jakarta.ws.rs.GET;
|
||||
import jakarta.ws.rs.POST;
|
||||
import jakarta.ws.rs.Path;
|
||||
import jakarta.ws.rs.PathParam;
|
||||
import jakarta.ws.rs.Produces;
|
||||
import jakarta.ws.rs.core.Context;
|
||||
import jakarta.ws.rs.core.MediaType;
|
||||
import jakarta.ws.rs.core.Response;
|
||||
import jakarta.ws.rs.core.SecurityContext;
|
||||
|
||||
|
||||
|
||||
@Path("/application_token")
|
||||
@Produces( MediaType.APPLICATION_JSON)
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
public class ApplicationTokenResource {
|
||||
final Logger logger = LoggerFactory.getLogger(ApplicationTokenResource.class);
|
||||
|
||||
public ApplicationTokenResource() {
|
||||
}
|
||||
public ApplicationTokenResource() {}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Generic /application_token/{applicationId}
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@GET
|
||||
@Path("{applicationId}")
|
||||
@RolesAllowed(value= {"ADMIN"})
|
||||
public List<ApplicationToken> gets(@Context SecurityContext sc, @PathParam("applicationId") Long applicationId) throws Exception {
|
||||
List<ApplicationToken> values = SqlWrapper.getsWhere(ApplicationToken.class,
|
||||
List.of(
|
||||
new WhereCondition("parentId", "=", applicationId)
|
||||
),
|
||||
false);
|
||||
// clean all tokens this is a secret:
|
||||
for (ApplicationToken elem : values) {
|
||||
elem.token = null;
|
||||
}
|
||||
return values;
|
||||
|
||||
@GET
|
||||
@Path("{applicationId}")
|
||||
@RolesAllowed(value = { "ADMIN" })
|
||||
public List<ApplicationToken> gets(@Context final SecurityContext sc, @PathParam("applicationId") final Long applicationId) throws Exception {
|
||||
final List<ApplicationToken> values = SqlWrapper.getsWhere(ApplicationToken.class, new QuerryCondition("parentId", "=", applicationId), false);
|
||||
// clean all tokens this is a secret:
|
||||
for (final ApplicationToken elem : values) {
|
||||
elem.token = null;
|
||||
}
|
||||
return values;
|
||||
}
|
||||
|
||||
@DELETE
|
||||
@Path("{applicationId}/{tokenId}")
|
||||
@RolesAllowed(value= {"ADMIN"})
|
||||
public Response delete(
|
||||
@Context SecurityContext sc,
|
||||
@PathParam("applicationId") Long applicationId,
|
||||
@PathParam("tokenId") Integer tokenId) throws Exception {
|
||||
int nbRemoved = SqlWrapper.setDeleteWhere(ApplicationToken.class,
|
||||
List.of(
|
||||
new WhereCondition("parentId", "=", applicationId),
|
||||
new WhereCondition("id", "=", tokenId)
|
||||
)
|
||||
);
|
||||
|
||||
@DELETE
|
||||
@Path("{applicationId}/{tokenId}")
|
||||
@RolesAllowed(value = { "ADMIN" })
|
||||
public Response delete(@Context final SecurityContext sc, @PathParam("applicationId") final Long applicationId, @PathParam("tokenId") final Integer tokenId) throws Exception {
|
||||
final int nbRemoved = SqlWrapper.setDeleteWhere(ApplicationToken.class, new QuerryAnd(new QuerryCondition("parentId", "=", applicationId), new QuerryCondition("id", "=", tokenId)));
|
||||
if (nbRemoved == 0) {
|
||||
return Response.notModified("{}").build();
|
||||
}
|
||||
if (nbRemoved == 0) {
|
||||
return Response.serverError().build();
|
||||
}
|
||||
return Response.ok("{}").build();
|
||||
return Response.ok("{}").build();
|
||||
}
|
||||
|
||||
private String multipartCorrection(String data) {
|
||||
if (data == null) {
|
||||
return null;
|
||||
}
|
||||
if (data.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
if (data.contentEquals("null")) {
|
||||
return null;
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
static String randomToken() {
|
||||
int len = 48;
|
||||
String valid_element = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvxyz0123456789#_@-~*!?";
|
||||
// creating a StringBuffer size of AlphaNumericStr
|
||||
StringBuilder out = new StringBuilder(len);
|
||||
int iii;
|
||||
for (iii=0; iii<len; iii++) {
|
||||
//generating a random number using math.random()
|
||||
int ch = (int)(valid_element.length() * Math.random());
|
||||
//adding Random character one by one at the end of s
|
||||
out.append(valid_element.charAt(ch));
|
||||
}
|
||||
return out.toString();
|
||||
}
|
||||
public record CreateRequest(String name, Integer validity) {};
|
||||
@POST
|
||||
@Path("/{applicationId}/create")
|
||||
@RolesAllowed("ADMIN")
|
||||
public ApplicationToken createToken(
|
||||
@Context SecurityContext sc,
|
||||
@PathParam("applicationId") Long applicationId,
|
||||
CreateRequest request
|
||||
) throws Exception {
|
||||
logger.info("get user application TOKEN: app='{}' user='???'", applicationId);
|
||||
// correct input string stream :
|
||||
String name = multipartCorrection(request.name());
|
||||
//validity = multipartCorrection(validity);
|
||||
logger.debug("create a new token...");
|
||||
if (applicationId == null) {
|
||||
throw new InputException("applicationId", "can not be null");
|
||||
}
|
||||
int maximum = 365*5;
|
||||
Integer validity = request.validity();
|
||||
if (validity == null || validity < 0 || validity > maximum) {
|
||||
validity = maximum;
|
||||
}
|
||||
logger.warn("validity= {}", validity);
|
||||
// todo: set validity timestamp ...
|
||||
// TODO: check if application exist ...
|
||||
ApplicationToken token = new ApplicationToken();
|
||||
token.token = randomToken();
|
||||
token.name = multipartCorrection(name);
|
||||
token.parentId = applicationId;
|
||||
OffsetDateTime now = OffsetDateTime.now( ZoneOffset.UTC );
|
||||
logger.warn("Check Timestamp now = {}", now);
|
||||
token.endValidityTime = Timestamp.from(now.plusDays(validity).toInstant());
|
||||
logger.warn("token.endValidityTime = {}", token.endValidityTime);
|
||||
|
||||
// insert in the BDD
|
||||
token = SqlWrapper.insert(token);
|
||||
// here we return the token to permit to the user to see it to set it in the application.
|
||||
return token;
|
||||
}
|
||||
/*
|
||||
Cannot find a deserializer for non-concrete Map type [map type; class jakarta.ws.rs.core.MultivaluedMap, [simple type, class java.lang.String] -> [collection type; class java.util.List, contains [simple type, class java.lang.String]]]
|
||||
at [Source: (org.glassfish.jersey.message.internal.ReaderInterceptorExecutor$UnCloseableInputStream); line: 1, column: 1]
|
||||
*/
|
||||
private String multipartCorrection(final String data) {
|
||||
if (data == null) {
|
||||
return null;
|
||||
}
|
||||
if (data.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
if (data.contentEquals("null")) {
|
||||
return null;
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
static String randomToken() {
|
||||
final int len = 48;
|
||||
final String valid_element = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvxyz0123456789#_@-~*!?";
|
||||
// creating a StringBuffer size of AlphaNumericStr
|
||||
final StringBuilder out = new StringBuilder(len);
|
||||
int iii;
|
||||
for (iii = 0; iii < len; iii++) {
|
||||
//generating a random number using math.random()
|
||||
final int ch = (int) (valid_element.length() * Math.random());
|
||||
//adding Random character one by one at the end of s
|
||||
out.append(valid_element.charAt(ch));
|
||||
}
|
||||
return out.toString();
|
||||
}
|
||||
|
||||
public record CreateRequest(
|
||||
String name,
|
||||
Integer validity) {};
|
||||
|
||||
@POST
|
||||
@Path("/{applicationId}/create")
|
||||
@RolesAllowed("ADMIN")
|
||||
public ApplicationToken createToken(@Context final SecurityContext sc, @PathParam("applicationId") final Long applicationId, final CreateRequest request) throws Exception {
|
||||
this.logger.info("get user application TOKEN: app='{}' user='???'", applicationId);
|
||||
// correct input string stream :
|
||||
final String name = multipartCorrection(request.name());
|
||||
//validity = multipartCorrection(validity);
|
||||
this.logger.debug("create a new token...");
|
||||
if (applicationId == null) {
|
||||
throw new InputException("applicationId", "can not be null");
|
||||
}
|
||||
final int maximum = 365 * 5;
|
||||
Integer validity = request.validity();
|
||||
if (validity == null || validity < 0 || validity > maximum) {
|
||||
validity = maximum;
|
||||
}
|
||||
this.logger.warn("validity= {}", validity);
|
||||
// todo: set validity timestamp ...
|
||||
// TODO: check if application exist ...
|
||||
ApplicationToken token = new ApplicationToken();
|
||||
token.token = randomToken();
|
||||
token.name = multipartCorrection(name);
|
||||
token.parentId = applicationId;
|
||||
final OffsetDateTime now = OffsetDateTime.now(ZoneOffset.UTC);
|
||||
this.logger.warn("Check Timestamp now = {}", now);
|
||||
token.endValidityTime = Timestamp.from(now.plusDays(validity).toInstant());
|
||||
this.logger.warn("token.endValidityTime = {}", token.endValidityTime);
|
||||
|
||||
// insert in the BDD
|
||||
token = SqlWrapper.insert(token);
|
||||
// here we return the token to permit to the user to see it to set it in the application.
|
||||
return token;
|
||||
}
|
||||
/*
|
||||
Cannot find a deserializer for non-concrete Map type [map type; class jakarta.ws.rs.core.MultivaluedMap, [simple type, class java.lang.String] -> [collection type; class java.util.List, contains [simple type, class java.lang.String]]]
|
||||
at [Source: (org.glassfish.jersey.message.internal.ReaderInterceptorExecutor$UnCloseableInputStream); line: 1, column: 1]
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -1,66 +1,60 @@
|
||||
package org.kar.karso.api;
|
||||
|
||||
import org.kar.archidata.SqlWrapper;
|
||||
import org.kar.archidata.WhereCondition;
|
||||
import org.kar.karso.model.Right;
|
||||
import org.kar.karso.model.RightDescription;
|
||||
import org.kar.karso.util.Transform;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.kar.archidata.annotation.SQLComment;
|
||||
import org.kar.archidata.annotation.SQLForeignKey;
|
||||
import org.kar.archidata.annotation.SQLLimitSize;
|
||||
import org.kar.archidata.annotation.SQLNotNull;
|
||||
import org.kar.archidata.annotation.security.RolesAllowed;
|
||||
import jakarta.ws.rs.*;
|
||||
import jakarta.ws.rs.core.MediaType;
|
||||
import jakarta.ws.rs.core.Response;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.kar.archidata.annotation.security.RolesAllowed;
|
||||
import org.kar.archidata.sqlWrapper.QuerryAnd;
|
||||
import org.kar.archidata.sqlWrapper.QuerryCondition;
|
||||
import org.kar.archidata.sqlWrapper.SqlWrapper;
|
||||
import org.kar.karso.model.Right;
|
||||
import org.kar.karso.model.RightDescription;
|
||||
import org.kar.karso.util.Transform;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import jakarta.ws.rs.Consumes;
|
||||
import jakarta.ws.rs.DELETE;
|
||||
import jakarta.ws.rs.GET;
|
||||
import jakarta.ws.rs.POST;
|
||||
import jakarta.ws.rs.PUT;
|
||||
import jakarta.ws.rs.Path;
|
||||
import jakarta.ws.rs.PathParam;
|
||||
import jakarta.ws.rs.Produces;
|
||||
import jakarta.ws.rs.core.MediaType;
|
||||
import jakarta.ws.rs.core.Response;
|
||||
|
||||
@Path("/right")
|
||||
@Produces({MediaType.APPLICATION_JSON})
|
||||
@Produces({ MediaType.APPLICATION_JSON })
|
||||
public class RightResource {
|
||||
final static Logger logger = LoggerFactory.getLogger(RightResource.class);
|
||||
|
||||
public static List<RightDescription> getApplicationRightDecription(long applicationId) throws Exception {
|
||||
return SqlWrapper.getsWhere(RightDescription.class,
|
||||
List.of(
|
||||
new WhereCondition("applicationId", "=", applicationId),
|
||||
new WhereCondition("deleted", "=", 0)
|
||||
));
|
||||
|
||||
public static List<RightDescription> getApplicationRightDecription(final long applicationId) throws Exception {
|
||||
return SqlWrapper.getsWhere(RightDescription.class, new QuerryAnd(new QuerryCondition("applicationId", "=", applicationId), new QuerryCondition("deleted", "=", 0)));
|
||||
}
|
||||
|
||||
public static List<Right> getRawUserRight(long userId, long applicationId) throws Exception {
|
||||
|
||||
public static List<Right> getRawUserRight(final long userId, final long applicationId) throws Exception {
|
||||
return SqlWrapper.getsWhere(Right.class,
|
||||
List.of(
|
||||
new WhereCondition("applicationId", "=", applicationId),
|
||||
new WhereCondition("userId", "=", userId),
|
||||
new WhereCondition("deleted", "=", 0)
|
||||
));
|
||||
new QuerryAnd(new QuerryCondition("applicationId", "=", applicationId), new QuerryCondition("userId", "=", userId), new QuerryCondition("deleted", "=", 0)));
|
||||
}
|
||||
|
||||
public static Map<String, Object> getUserRight(long userId, long applicationId) throws Exception {
|
||||
Map<String, Object> out = new HashMap<>();
|
||||
List<RightDescription> rightsDescriptions = getApplicationRightDecription(applicationId);
|
||||
public static Map<String, Object> getUserRight(final long userId, final long applicationId) throws Exception {
|
||||
final Map<String, Object> out = new HashMap<>();
|
||||
final List<RightDescription> rightsDescriptions = getApplicationRightDecription(applicationId);
|
||||
logger.debug("Get some descriptions: {} applicationId={}", rightsDescriptions.size(), applicationId);
|
||||
if (rightsDescriptions != null && rightsDescriptions.size() != 0) {
|
||||
List<Right> rights = getRawUserRight(userId, applicationId);
|
||||
final List<Right> rights = getRawUserRight(userId, applicationId);
|
||||
logger.debug("Get some user right: {}userID={}", rights.size(), userId);
|
||||
for (RightDescription description : rightsDescriptions) {
|
||||
for (final RightDescription description : rightsDescriptions) {
|
||||
if (description == null) {
|
||||
// TODO: this is a really strange case to manage later...
|
||||
continue;
|
||||
}
|
||||
Right right = rights.stream()
|
||||
.filter(elem -> elem.rightDescriptionId == description.id)
|
||||
.findAny()
|
||||
.orElse(null);
|
||||
final Right right = rights.stream().filter(elem -> elem.rightDescriptionId == description.id).findAny().orElse(null);
|
||||
if (right != null) {
|
||||
out.put(description.key, Transform.convertToType(description.type, right.value));
|
||||
} else if (description.defaultValue != null){
|
||||
} else if (description.defaultValue != null) {
|
||||
out.put(description.key, Transform.convertToType(description.type, description.defaultValue));
|
||||
} else {
|
||||
out.put(description.key, null);
|
||||
@ -71,39 +65,37 @@ public class RightResource {
|
||||
logger.debug("Does not manage Karso right...");
|
||||
}
|
||||
return out;
|
||||
}
|
||||
public static void updateUserRight(long userId, long applicationId, Map<String, Object> delta) throws Exception {
|
||||
List<RightDescription> rightsDescriptions = getApplicationRightDecription(applicationId);
|
||||
}
|
||||
|
||||
public static void updateUserRight(final long userId, final long applicationId, final Map<String, Object> delta) throws Exception {
|
||||
final List<RightDescription> rightsDescriptions = getApplicationRightDecription(applicationId);
|
||||
logger.debug("Get some descriptions: {} applicationId={}", rightsDescriptions.size(), applicationId);
|
||||
if (rightsDescriptions == null || rightsDescriptions.size() == 0) {
|
||||
throw new IllegalArgumentException("Request change right on an application that does not manage any right");
|
||||
}
|
||||
List<Right> rights = getRawUserRight(userId, applicationId);
|
||||
final List<Right> rights = getRawUserRight(userId, applicationId);
|
||||
logger.debug("Get some user right: {}userID={}", rights.size(), userId);
|
||||
for (RightDescription description : rightsDescriptions) {
|
||||
for (final RightDescription description : rightsDescriptions) {
|
||||
if (description == null) {
|
||||
// TODO: this is a really strange case to manage later...
|
||||
continue;
|
||||
}
|
||||
Object newValue = delta.get(description.key);
|
||||
final Object newValue = delta.get(description.key);
|
||||
if (newValue == null) {
|
||||
//No need to update or create...
|
||||
continue;
|
||||
}
|
||||
String convertedValue = Transform.convertToStringCheck(description.type, newValue);
|
||||
final String convertedValue = Transform.convertToStringCheck(description.type, newValue);
|
||||
if (convertedValue == null) {
|
||||
throw new IllegalArgumentException("Uncompatible value:'" + description.type + "'");
|
||||
}
|
||||
Right right = rights.stream()
|
||||
.filter(elem -> elem.rightDescriptionId == description.id)
|
||||
.findAny()
|
||||
.orElse(null);
|
||||
Right right = rights.stream().filter(elem -> elem.rightDescriptionId == description.id).findAny().orElse(null);
|
||||
if (right != null) {
|
||||
// The value exist, we need to update it
|
||||
logger.debug("Request update a knonwn parameter: {} with {}", description.key, newValue);
|
||||
right.value = convertedValue;
|
||||
SqlWrapper.update(right, right.id, List.of("value"));
|
||||
} else {
|
||||
} else {
|
||||
// we need to create it
|
||||
logger.debug("Request create parameter: {} with {}", description.key, newValue);
|
||||
right = new Right();
|
||||
@ -114,45 +106,43 @@ public class RightResource {
|
||||
SqlWrapper.insert(right);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@GET
|
||||
@RolesAllowed("ADMIN")
|
||||
public List<Right> get() throws Exception {
|
||||
return SqlWrapper.gets(Right.class, false);
|
||||
}
|
||||
|
||||
@POST
|
||||
@RolesAllowed("ADMIN")
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
public Right post(String jsonRequest) throws Exception {
|
||||
return SqlWrapper.insertWithJson(Right.class, jsonRequest);
|
||||
}
|
||||
|
||||
@GET
|
||||
@Path("{id}")
|
||||
@RolesAllowed("ADMIN")
|
||||
public static Right getWithId(@PathParam("id") Long id) throws Exception {
|
||||
return SqlWrapper.get(Right.class, id);
|
||||
}
|
||||
|
||||
@PUT
|
||||
@Path("{id}")
|
||||
@RolesAllowed("ADMIN")
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
public Right put(@PathParam("id") Long id, String jsonRequest) throws Exception {
|
||||
SqlWrapper.update(Right.class, id, jsonRequest);
|
||||
return SqlWrapper.get(Right.class, id);
|
||||
}
|
||||
|
||||
@DELETE
|
||||
@Path("{id}")
|
||||
@RolesAllowed("ADMIN")
|
||||
public Response delete(@PathParam("id") Long id) throws Exception {
|
||||
SqlWrapper.setDelete(Right.class, id);
|
||||
return Response.ok().build();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@GET
|
||||
@RolesAllowed("ADMIN")
|
||||
public List<Right> get() throws Exception {
|
||||
return SqlWrapper.gets(Right.class, false);
|
||||
}
|
||||
|
||||
@POST
|
||||
@RolesAllowed("ADMIN")
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
public Right post(final String jsonRequest) throws Exception {
|
||||
return SqlWrapper.insertWithJson(Right.class, jsonRequest);
|
||||
}
|
||||
|
||||
@GET
|
||||
@Path("{id}")
|
||||
@RolesAllowed("ADMIN")
|
||||
public static Right getWithId(@PathParam("id") final Long id) throws Exception {
|
||||
return SqlWrapper.get(Right.class, id);
|
||||
}
|
||||
|
||||
@PUT
|
||||
@Path("{id}")
|
||||
@RolesAllowed("ADMIN")
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
public Right put(@PathParam("id") final Long id, final String jsonRequest) throws Exception {
|
||||
SqlWrapper.update(Right.class, id, jsonRequest);
|
||||
return SqlWrapper.get(Right.class, id);
|
||||
}
|
||||
|
||||
@DELETE
|
||||
@Path("{id}")
|
||||
@RolesAllowed("ADMIN")
|
||||
public Response delete(@PathParam("id") final Long id) throws Exception {
|
||||
SqlWrapper.setDelete(Right.class, id);
|
||||
return Response.ok().build();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
@ -1,101 +1,106 @@
|
||||
package org.kar.karso.api;
|
||||
|
||||
import org.kar.archidata.SqlWrapper;
|
||||
import org.kar.karso.model.*;
|
||||
import java.util.List;
|
||||
|
||||
import org.kar.archidata.annotation.security.PermitAll;
|
||||
import org.kar.archidata.annotation.security.RolesAllowed;
|
||||
import org.kar.archidata.exception.NotFoundException;
|
||||
import org.kar.archidata.sqlWrapper.QuerryCondition;
|
||||
import org.kar.archidata.sqlWrapper.SqlWrapper;
|
||||
import org.kar.karso.model.Settings;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
|
||||
import org.kar.archidata.annotation.security.PermitAll;
|
||||
import org.kar.archidata.annotation.security.RolesAllowed;
|
||||
import org.kar.archidata.exception.NotFoundException;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import jakarta.ws.rs.*;
|
||||
import jakarta.ws.rs.Consumes;
|
||||
import jakarta.ws.rs.GET;
|
||||
import jakarta.ws.rs.PUT;
|
||||
import jakarta.ws.rs.Path;
|
||||
import jakarta.ws.rs.PathParam;
|
||||
import jakarta.ws.rs.Produces;
|
||||
import jakarta.ws.rs.core.Context;
|
||||
import jakarta.ws.rs.core.MediaType;
|
||||
import jakarta.ws.rs.core.Response;
|
||||
import jakarta.ws.rs.core.SecurityContext;
|
||||
|
||||
|
||||
@Path("/system_config")
|
||||
@Produces( MediaType.APPLICATION_JSON)
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
public class SystemConfigResource {
|
||||
final Logger logger = LoggerFactory.getLogger(SystemConfigResource.class);
|
||||
|
||||
public static class GetSignUpAvaillable {
|
||||
public boolean signup;
|
||||
|
||||
public GetSignUpAvaillable(boolean availlable) {
|
||||
public GetSignUpAvaillable(final boolean availlable) {
|
||||
this.signup = availlable;
|
||||
}
|
||||
|
||||
public GetSignUpAvaillable() {
|
||||
signup = false;
|
||||
this.signup = false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public SystemConfigResource() {
|
||||
}
|
||||
public SystemConfigResource() {}
|
||||
|
||||
@GET
|
||||
@Path("is_sign_up_availlable")
|
||||
@PermitAll
|
||||
public GetSignUpAvaillable isSignUpAvaillable() throws Exception {
|
||||
Settings set = SqlWrapper.getWhere(Settings.class, "key", "=", "SIGN_UP_ENABLE", false);
|
||||
if (set == null) {
|
||||
throw new NotFoundException("Value does not exist");
|
||||
@GET
|
||||
@Path("is_sign_up_availlable")
|
||||
@PermitAll
|
||||
public GetSignUpAvaillable isSignUpAvaillable() throws Exception {
|
||||
final Settings set = SqlWrapper.getWhere(Settings.class, new QuerryCondition("key", "=", "SIGN_UP_ENABLE"), false);
|
||||
if (set == null) {
|
||||
throw new NotFoundException("Value does not exist");
|
||||
}
|
||||
boolean availlable = "true".equalsIgnoreCase(set.value);
|
||||
GetSignUpAvaillable tmp = new GetSignUpAvaillable(availlable);
|
||||
logger.debug("mlkmlk {}", tmp.signup);
|
||||
final boolean availlable = "true".equalsIgnoreCase(set.value);
|
||||
final GetSignUpAvaillable tmp = new GetSignUpAvaillable(availlable);
|
||||
this.logger.debug("mlkmlk {}", tmp.signup);
|
||||
return tmp;
|
||||
}
|
||||
|
||||
@GET
|
||||
@Path("key/{key}")
|
||||
@RolesAllowed(value= {"USER", "ADMIN"})
|
||||
public Response getKey(@Context SecurityContext sc, @PathParam("key") String key) throws Exception {
|
||||
Settings set = SqlWrapper.getWhere(Settings.class, "key", "=", key, false);
|
||||
if (set == null) {
|
||||
throw new NotFoundException("Value does not exist");
|
||||
@GET
|
||||
@Path("key/{key}")
|
||||
@RolesAllowed(value = { "USER", "ADMIN" })
|
||||
public Response getKey(@Context final SecurityContext sc, @PathParam("key") final String key) throws Exception {
|
||||
final Settings set = SqlWrapper.getWhere(Settings.class, new QuerryCondition("key", "=", key), false);
|
||||
if (set == null) {
|
||||
throw new NotFoundException("Value does not exist");
|
||||
}
|
||||
if (set.type.equals("BOOLEAN")) {
|
||||
boolean availlable = "true".equalsIgnoreCase(set.value);
|
||||
return Response.status(200).entity("{ \"value\":" + availlable + "}").build();
|
||||
}
|
||||
if (set.type.equals("NUMBER")) {
|
||||
double value = Double.parseDouble(set.value);
|
||||
return Response.status(200).entity("{ \"value\":" + value + "}").build();
|
||||
}
|
||||
return Response.status(200).entity("{ \"value\":\"" + set.value + "\"}").build();
|
||||
if (set.type.equals("BOOLEAN")) {
|
||||
final boolean availlable = "true".equalsIgnoreCase(set.value);
|
||||
return Response.status(200).entity("{ \"value\":" + availlable + "}").build();
|
||||
}
|
||||
if (set.type.equals("NUMBER")) {
|
||||
final double value = Double.parseDouble(set.value);
|
||||
return Response.status(200).entity("{ \"value\":" + value + "}").build();
|
||||
}
|
||||
return Response.status(200).entity("{ \"value\":\"" + set.value + "\"}").build();
|
||||
}
|
||||
@PUT
|
||||
@Path("key/{key}")
|
||||
@RolesAllowed(value= {"ADMIN"})
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
public Response setKey(@Context SecurityContext sc, @PathParam("key") String key, String jsonRequest) throws Exception {
|
||||
Settings res = null;
|
||||
try {
|
||||
res = SqlWrapper.getWhere(Settings.class, "key", "=", key, false);
|
||||
} catch (Exception e) {
|
||||
|
||||
@PUT
|
||||
@Path("key/{key}")
|
||||
@RolesAllowed(value = { "ADMIN" })
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
public Response setKey(@Context final SecurityContext sc, @PathParam("key") final String key, final String jsonRequest) throws Exception {
|
||||
Settings res = null;
|
||||
try {
|
||||
res = SqlWrapper.getWhere(Settings.class, new QuerryCondition("key", "=", key), false);
|
||||
} catch (final Exception e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
String result = "Can not find the Key";
|
||||
final String result = "Can not find the Key";
|
||||
return Response.status(404).entity(result).build();
|
||||
}
|
||||
ObjectMapper mapper = new ObjectMapper();
|
||||
// Read the tree to filter injection of data:
|
||||
JsonNode root = mapper.readTree(jsonRequest);
|
||||
JsonNode value = root.findPath("value");
|
||||
|
||||
res.value = value.asText();
|
||||
logger.debug("Update value : {}", res.value);
|
||||
SqlWrapper.update(res, res.id, List.of("value"));
|
||||
return Response.status(201).entity("{ \"value\":\"" + res.value + "\"}").build();
|
||||
final ObjectMapper mapper = new ObjectMapper();
|
||||
// Read the tree to filter injection of data:
|
||||
final JsonNode root = mapper.readTree(jsonRequest);
|
||||
final JsonNode value = root.findPath("value");
|
||||
|
||||
res.value = value.asText();
|
||||
this.logger.debug("Update value : {}", res.value);
|
||||
SqlWrapper.update(res, res.id, List.of("value"));
|
||||
return Response.status(201).entity("{ \"value\":\"" + res.value + "\"}").build();
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,41 +1,53 @@
|
||||
package org.kar.karso.api;
|
||||
|
||||
import org.kar.archidata.model.GetToken;
|
||||
import org.kar.archidata.SqlWrapper;
|
||||
import org.kar.archidata.WhereCondition;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.security.MessageDigest;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.sql.Timestamp;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.kar.archidata.annotation.security.PermitAll;
|
||||
import org.kar.archidata.annotation.security.RolesAllowed;
|
||||
import org.kar.archidata.exception.FailException;
|
||||
import org.kar.archidata.exception.InputException;
|
||||
import org.kar.archidata.exception.SystemException;
|
||||
import org.kar.archidata.filter.GenericContext;
|
||||
import org.kar.archidata.model.GetToken;
|
||||
import org.kar.archidata.sqlWrapper.QuerryCondition;
|
||||
import org.kar.archidata.sqlWrapper.SqlWrapper;
|
||||
import org.kar.archidata.sqlWrapper.addOn.AddOnSQLTableExternalLink;
|
||||
import org.kar.archidata.util.JWTWrapper;
|
||||
import org.kar.karso.migration.Initialization;
|
||||
import org.kar.karso.model.*;
|
||||
import org.kar.karso.model.ChangePassword;
|
||||
import org.kar.karso.model.DataGetToken;
|
||||
import org.kar.karso.model.UserAuth;
|
||||
import org.kar.karso.model.UserAuthGet;
|
||||
import org.kar.karso.model.UserCreate;
|
||||
import org.kar.karso.util.ConfigVariable;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonInclude;
|
||||
|
||||
import org.kar.archidata.util.JWTWrapper;
|
||||
import jakarta.ws.rs.*;
|
||||
import jakarta.ws.rs.Consumes;
|
||||
import jakarta.ws.rs.GET;
|
||||
import jakarta.ws.rs.NotFoundException;
|
||||
import jakarta.ws.rs.POST;
|
||||
import jakarta.ws.rs.PUT;
|
||||
import jakarta.ws.rs.Path;
|
||||
import jakarta.ws.rs.PathParam;
|
||||
import jakarta.ws.rs.Produces;
|
||||
import jakarta.ws.rs.QueryParam;
|
||||
import jakarta.ws.rs.core.Context;
|
||||
import jakarta.ws.rs.core.MediaType;
|
||||
import jakarta.ws.rs.core.Response;
|
||||
import jakarta.ws.rs.core.SecurityContext;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.security.MessageDigest;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.sql.Timestamp;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
|
||||
@Path("/users")
|
||||
@Produces( MediaType.APPLICATION_JSON)
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
public class UserResource {
|
||||
final Logger logger = LoggerFactory.getLogger(UserResource.class);
|
||||
|
||||
@ -43,98 +55,93 @@ public class UserResource {
|
||||
public class UserOut {
|
||||
public long id;
|
||||
public String login;
|
||||
public UserOut(long id, String login) {
|
||||
super();
|
||||
|
||||
public UserOut(final long id, final String login) {
|
||||
this.id = id;
|
||||
this.login = login;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public UserResource() {
|
||||
}
|
||||
public UserResource() {}
|
||||
|
||||
@GET
|
||||
@RolesAllowed("ADMIN")
|
||||
@RolesAllowed("ADMIN")
|
||||
public List<UserAuthGet> getUsers() throws Exception {
|
||||
return SqlWrapper.gets(UserAuthGet.class, false);
|
||||
}
|
||||
|
||||
@GET
|
||||
@Path("{id}")
|
||||
@RolesAllowed("ADMIN")
|
||||
public UserAuthGet getUser(@Context SecurityContext sc, @PathParam("id") long userId) throws Exception {
|
||||
//GenericContext gc = (GenericContext) sc.getUserPrincipal();
|
||||
return SqlWrapper.get(UserAuthGet.class, userId);
|
||||
@RolesAllowed("ADMIN")
|
||||
public UserAuthGet getUser(@Context final SecurityContext sc, @PathParam("id") final long userId) throws Exception {
|
||||
//GenericContext gc = (GenericContext) sc.getUserPrincipal();
|
||||
return SqlWrapper.get(UserAuthGet.class, userId);
|
||||
}
|
||||
|
||||
@POST
|
||||
@Path("{userId}/application/{applicationId}/link")
|
||||
@RolesAllowed("ADMIN")
|
||||
public UserAuth linkApplication(@Context SecurityContext sc,
|
||||
@PathParam("userId") long userId,
|
||||
@PathParam("applicationId") long applicationId,
|
||||
boolean data) throws Exception {
|
||||
logger.debug("Find typeNode");
|
||||
if (data == true) {
|
||||
SqlWrapper.addLink(UserAuth.class, userId, "application", applicationId);
|
||||
} else {
|
||||
SqlWrapper.removeLink(UserAuth.class, userId, "application", applicationId);
|
||||
}
|
||||
return SqlWrapper.get(UserAuth.class, userId);
|
||||
@RolesAllowed("ADMIN")
|
||||
public UserAuth linkApplication(@Context final SecurityContext sc, @PathParam("userId") final long userId, @PathParam("applicationId") final long applicationId, final boolean data)
|
||||
throws Exception {
|
||||
this.logger.debug("Find typeNode");
|
||||
if (data) {
|
||||
AddOnSQLTableExternalLink.addLink(UserAuth.class, userId, "application", applicationId);
|
||||
} else {
|
||||
AddOnSQLTableExternalLink.removeLink(UserAuth.class, userId, "application", applicationId);
|
||||
}
|
||||
return SqlWrapper.get(UserAuth.class, userId);
|
||||
}
|
||||
|
||||
@GET
|
||||
@Path("{userId}/application/{applicationId}/rights")
|
||||
@RolesAllowed("ADMIN")
|
||||
public Map<String, Object> getApplicationRight(@Context SecurityContext sc,
|
||||
@PathParam("userId") long userId,
|
||||
@PathParam("applicationId") long applicationId) throws Exception {
|
||||
@RolesAllowed("ADMIN")
|
||||
public Map<String, Object> getApplicationRight(@Context final SecurityContext sc, @PathParam("userId") final long userId, @PathParam("applicationId") final long applicationId) throws Exception {
|
||||
return RightResource.getUserRight(userId, applicationId);
|
||||
}
|
||||
|
||||
@PUT
|
||||
@Path("{userId}/application/{applicationId}/rights")
|
||||
@RolesAllowed("ADMIN")
|
||||
public Map<String, Object> patchApplicationRight(@Context SecurityContext sc,
|
||||
@PathParam("userId") long userId,
|
||||
@PathParam("applicationId") long applicationId, Map<String, Object> data) throws Exception {
|
||||
logger.info("get data from FRONT: {}", data);
|
||||
@RolesAllowed("ADMIN")
|
||||
public Map<String, Object> patchApplicationRight(@Context final SecurityContext sc, @PathParam("userId") final long userId, @PathParam("applicationId") final long applicationId,
|
||||
final Map<String, Object> data) throws Exception {
|
||||
this.logger.info("get data from FRONT: {}", data);
|
||||
RightResource.updateUserRight(userId, applicationId, data);
|
||||
return RightResource.getUserRight(userId, applicationId);
|
||||
}
|
||||
|
||||
// TODO: check this it might be deprecated ...
|
||||
|
||||
// TODO: check this it might be deprecated ...
|
||||
@POST
|
||||
@Path("{id}/set_admin")
|
||||
@RolesAllowed("ADMIN")
|
||||
public Response setAdmin(@Context SecurityContext sc, @PathParam("id") long userId, boolean data) throws Exception {
|
||||
UserAuth user = new UserAuth();
|
||||
@RolesAllowed("ADMIN")
|
||||
public Response setAdmin(@Context final SecurityContext sc, @PathParam("id") final long userId, final boolean data) throws Exception {
|
||||
final UserAuth user = new UserAuth();
|
||||
user.admin = data;
|
||||
int ret = SqlWrapper.update(user, userId, List.of("admin"));
|
||||
final int ret = SqlWrapper.update(user, userId, List.of("admin"));
|
||||
if (ret == 0) {
|
||||
return Response.notModified("{}").build();
|
||||
return Response.notModified("{}").build();
|
||||
}
|
||||
return Response.ok("{}").build();
|
||||
return Response.ok("{}").build();
|
||||
}
|
||||
|
||||
@POST
|
||||
@Path("{id}/set_blocked")
|
||||
@RolesAllowed("ADMIN")
|
||||
public Response setBlocked(@Context SecurityContext sc, @PathParam("id") long userId, boolean data) throws Exception {
|
||||
UserAuth user = new UserAuth();
|
||||
@RolesAllowed("ADMIN")
|
||||
public Response setBlocked(@Context final SecurityContext sc, @PathParam("id") final long userId, final boolean data) throws Exception {
|
||||
final UserAuth user = new UserAuth();
|
||||
user.blocked = data;
|
||||
int ret = SqlWrapper.update(user, userId, List.of("blocked"));
|
||||
final int ret = SqlWrapper.update(user, userId, List.of("blocked"));
|
||||
if (ret == 0) {
|
||||
return Response.notModified("{}").build();
|
||||
}
|
||||
return Response.ok("{}").build();
|
||||
return Response.ok("{}").build();
|
||||
}
|
||||
|
||||
@POST
|
||||
@Path("create_new_user")
|
||||
@RolesAllowed("ADMIN")
|
||||
public UserAuthGet createUser(UserCreate user) throws Exception {
|
||||
logger.debug("create new User email={} login={}", user.email, user.login);
|
||||
@RolesAllowed("ADMIN")
|
||||
public UserAuthGet createUser(final UserCreate user) throws Exception {
|
||||
this.logger.debug("create new User email={} login={}", user.email, user.login);
|
||||
// verify login or email is correct:
|
||||
if (user.login == null || user.login.length() < 6) {
|
||||
throw new InputException("login", "Authentiocate-method-error (login too small: '" + user.login + "')");
|
||||
@ -145,30 +152,25 @@ public class UserResource {
|
||||
throw new InputException("email", "Authentiocate-method-error (email too small: '" + user.email + "')");
|
||||
}
|
||||
// TODO: check email format
|
||||
|
||||
if(user.password == null || user.password.length() != 128) {
|
||||
|
||||
if (user.password == null || user.password.length() != 128) {
|
||||
throw new InputException("password", "null password, or wrong hash size");
|
||||
}
|
||||
// TODO: verify if the data are a hash ...
|
||||
|
||||
|
||||
}
|
||||
// TODO: verify if the data are a hash ...
|
||||
|
||||
// Check login does not exist
|
||||
List<UserAuth> out = SqlWrapper.getsWhere(UserAuth.class, List.of(
|
||||
new WhereCondition("login", "=", user.login)
|
||||
), false);
|
||||
List<UserAuth> out = SqlWrapper.getsWhere(UserAuth.class, new QuerryCondition("login", "=", user.login), false);
|
||||
if (out.size() >= 1) {
|
||||
throw new FailException(Response.Status.BAD_REQUEST, "Login already used !!!");
|
||||
}
|
||||
// Check email does not exist
|
||||
out = SqlWrapper.getsWhere(UserAuth.class, List.of(
|
||||
new WhereCondition("email", "=", user.email)
|
||||
), false);
|
||||
out = SqlWrapper.getsWhere(UserAuth.class, new QuerryCondition("email", "=", user.email), false);
|
||||
if (out.size() >= 1) {
|
||||
throw new FailException(Response.Status.BAD_REQUEST, "e-mail already used !!!");
|
||||
}
|
||||
|
||||
|
||||
// Add new user and return formated dat.
|
||||
UserAuth newUser = new UserAuth();
|
||||
final UserAuth newUser = new UserAuth();
|
||||
newUser.admin = false;
|
||||
newUser.removed = false;
|
||||
newUser.blocked = false;
|
||||
@ -177,70 +179,68 @@ public class UserResource {
|
||||
newUser.password = user.password;
|
||||
newUser.email = user.email;
|
||||
newUser.lastConnection = Timestamp.valueOf(LocalDateTime.now());
|
||||
UserAuth tmp = SqlWrapper.insert(newUser);
|
||||
logger.debug("create new user done with id=={}", tmp.id);
|
||||
return SqlWrapper.get(UserAuthGet.class, tmp.id);
|
||||
final UserAuth tmp = SqlWrapper.insert(newUser);
|
||||
this.logger.debug("create new user done with id=={}", tmp.id);
|
||||
return SqlWrapper.get(UserAuthGet.class, tmp.id);
|
||||
}
|
||||
|
||||
@GET
|
||||
@Path("me")
|
||||
@RolesAllowed("USER")
|
||||
public UserOut getMe(@Context SecurityContext sc) {
|
||||
logger.debug("getMe()");
|
||||
GenericContext gc = (GenericContext) sc.getUserPrincipal();
|
||||
logger.debug("== USER ? {}", gc.userByToken);
|
||||
return new UserOut(gc.userByToken.id, gc.userByToken.name);
|
||||
}
|
||||
@GET
|
||||
@Path("me")
|
||||
@RolesAllowed("USER")
|
||||
public UserOut getMe(@Context final SecurityContext sc) {
|
||||
this.logger.debug("getMe()");
|
||||
final GenericContext gc = (GenericContext) sc.getUserPrincipal();
|
||||
this.logger.debug("== USER ? {}", gc.userByToken);
|
||||
return new UserOut(gc.userByToken.id, gc.userByToken.name);
|
||||
}
|
||||
|
||||
@POST
|
||||
@Path("password")
|
||||
@RolesAllowed("USER")
|
||||
public Response changePassword(@Context SecurityContext sc, ChangePassword data) throws Exception {
|
||||
logger.debug("ChangePassword()");
|
||||
GenericContext gc = (GenericContext) sc.getUserPrincipal();
|
||||
logger.debug("== USER ? {}", gc.userByToken);
|
||||
|
||||
if(data == null) {
|
||||
@POST
|
||||
@Path("password")
|
||||
@RolesAllowed("USER")
|
||||
public Response changePassword(@Context final SecurityContext sc, final ChangePassword data) throws Exception {
|
||||
this.logger.debug("ChangePassword()");
|
||||
final GenericContext gc = (GenericContext) sc.getUserPrincipal();
|
||||
this.logger.debug("== USER ? {}", gc.userByToken);
|
||||
|
||||
if (data == null) {
|
||||
throw new InputException("data", "No data set...");
|
||||
}
|
||||
if(data.newPassword == null || data.newPassword.length() != 128) {
|
||||
}
|
||||
if (data.newPassword == null || data.newPassword.length() != 128) {
|
||||
throw new InputException("newPassword", "null password, or wrong hash size");
|
||||
}
|
||||
UserAuth user = checkAuthUser(data.method, data.login, data.time, data.password);
|
||||
if (user == null) {
|
||||
}
|
||||
final UserAuth user = checkAuthUser(data.method, data.login, data.time, data.password);
|
||||
if (user == null) {
|
||||
throw new SystemException("Fail to retrieve the user... (impossible case)");
|
||||
}
|
||||
// Process the update:
|
||||
user.password = data.newPassword;
|
||||
SqlWrapper.update(user, user.id, List.of("password"));
|
||||
return Response.status(Response.Status.OK).build();
|
||||
}
|
||||
|
||||
/*
|
||||
@GET
|
||||
@Path("validipass")
|
||||
@PermitAll
|
||||
public Response validatePasswordFromEMail(@QueryParam("uuid") String uuid, @QueryParam("securityId") String securityId) {
|
||||
|
||||
// Validate new password if OK
|
||||
|
||||
// clear the passwordChange, passwordValidation fields
|
||||
|
||||
// send an e-mail to confirm the new password has been set.
|
||||
|
||||
|
||||
// Process the update:
|
||||
user.password = data.newPassword;
|
||||
SqlWrapper.update(user, user.id, List.of("password"));
|
||||
return Response.status(Response.Status.OK).build();
|
||||
}
|
||||
|
||||
/*
|
||||
@GET
|
||||
@Path("validipass")
|
||||
@PermitAll
|
||||
public Response validatePasswordFromEMail(@QueryParam("uuid") String uuid, @QueryParam("securityId") String securityId) {
|
||||
|
||||
// Validate new password if OK
|
||||
|
||||
// clear the passwordChange, passwordValidation fields
|
||||
|
||||
// send an e-mail to confirm the new password has been set.
|
||||
|
||||
|
||||
return Response.status(500).build();
|
||||
}
|
||||
*/
|
||||
|
||||
}
|
||||
*/
|
||||
|
||||
@GET
|
||||
@Path("/check_login")
|
||||
@PermitAll
|
||||
public Response checkLogin(@QueryParam("login") String login) throws Exception {
|
||||
logger.debug("checkLogin: '{}'", login );
|
||||
List<UserAuth> out = SqlWrapper.getsWhere(UserAuth.class, List.of(
|
||||
new WhereCondition("login", "=", login)
|
||||
), false);
|
||||
@PermitAll
|
||||
public Response checkLogin(@QueryParam("login") final String login) throws Exception {
|
||||
this.logger.debug("checkLogin: '{}'", login);
|
||||
final List<UserAuth> out = SqlWrapper.getsWhere(UserAuth.class, new QuerryCondition("login", "=", login), false);
|
||||
if (out.size() >= 1) {
|
||||
return Response.ok().build();
|
||||
}
|
||||
@ -250,20 +250,17 @@ public class UserResource {
|
||||
// TODO: add an application TOKEN and permit only 50 requested (maybe add an option to disable it).
|
||||
@GET
|
||||
@Path("/check_email")
|
||||
@PermitAll
|
||||
public Response checkEmail(@QueryParam("email") String email) throws Exception {
|
||||
logger.debug("checkEmail: {}", email );
|
||||
List<UserAuth> out = SqlWrapper.getsWhere(UserAuth.class, List.of(
|
||||
new WhereCondition("email", "=", email)
|
||||
), false);
|
||||
@PermitAll
|
||||
public Response checkEmail(@QueryParam("email") final String email) throws Exception {
|
||||
this.logger.debug("checkEmail: {}", email);
|
||||
final List<UserAuth> out = SqlWrapper.getsWhere(UserAuth.class, new QuerryCondition("email", "=", email), false);
|
||||
if (out.size() >= 1) {
|
||||
return Response.ok().build();
|
||||
}
|
||||
throw new NotFoundException("emain does not exist: '" + email + "'");
|
||||
}
|
||||
|
||||
|
||||
private UserAuth checkAuthUser(String method, String login, String time, String password) throws Exception {
|
||||
private UserAuth checkAuthUser(final String method, final String login, final String time, final String password) throws Exception {
|
||||
// check good version:
|
||||
if (!"v1".contentEquals(method)) {
|
||||
throw new InputException("method", "Authentiocate-method-error (wrong version: '" + method + "')");
|
||||
@ -272,29 +269,25 @@ public class UserResource {
|
||||
if (login.length() < 6) {
|
||||
throw new InputException("login", "Authentiocate-method-error (email or login too small: '" + login + "')");
|
||||
}
|
||||
if(password == null || password.length() != 128) {
|
||||
if (password == null || password.length() != 128) {
|
||||
throw new InputException("password", "null password, or wrong hash size");
|
||||
}
|
||||
}
|
||||
// email or login?
|
||||
String query = "login";
|
||||
if (login.contains("@")) {
|
||||
query = "email";
|
||||
}
|
||||
UserAuth user = SqlWrapper.getWhere(UserAuth.class,
|
||||
List.of(
|
||||
new WhereCondition(query, "=", login)
|
||||
),
|
||||
false );
|
||||
|
||||
final UserAuth user = SqlWrapper.getWhere(UserAuth.class, new QuerryCondition(query, "=", login), false);
|
||||
|
||||
if (user == null) {
|
||||
throw new FailException(Response.Status.PRECONDITION_FAILED , "FAIL Authentiocate-wrong email/login '" + login + "')");
|
||||
throw new FailException(Response.Status.PRECONDITION_FAILED, "FAIL Authentiocate-wrong email/login '" + login + "')");
|
||||
}
|
||||
// Check the password:
|
||||
String passwodCheck = getSHA512("login='" + login + "';pass='" + user.password + "';date='" + time + "'");
|
||||
final String passwodCheck = getSHA512("login='" + login + "';pass='" + user.password + "';date='" + time + "'");
|
||||
if (!passwodCheck.contentEquals(password)) {
|
||||
throw new FailException(Response.Status.PRECONDITION_FAILED , "Password error ...");
|
||||
throw new FailException(Response.Status.PRECONDITION_FAILED, "Password error ...");
|
||||
}
|
||||
logger.debug(" ==> pass nearly all test : admin={} blocked={} removed={}", user.admin, user.blocked, user.removed);
|
||||
this.logger.debug(" ==> pass nearly all test : admin={} blocked={} removed={}", user.admin, user.blocked, user.removed);
|
||||
if (user.blocked || user.removed) {
|
||||
throw new FailException(Response.Status.UNAUTHORIZED, "FAIL Authentiocate");
|
||||
}
|
||||
@ -303,31 +296,31 @@ public class UserResource {
|
||||
|
||||
@POST
|
||||
@Path("/get_token")
|
||||
@PermitAll
|
||||
@PermitAll
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
public GetToken getToken(DataGetToken data) throws Exception {
|
||||
logger.info("User Authenticate: {}", data.login());
|
||||
UserAuth user = checkAuthUser(data.method(), data.login(), data.time(), data.password());
|
||||
public GetToken getToken(final DataGetToken data) throws Exception {
|
||||
this.logger.info("User Authenticate: {}", data.login());
|
||||
final UserAuth user = checkAuthUser(data.method(), data.login(), data.time(), data.password());
|
||||
// at the point the user has been not deleted and not blocked.
|
||||
// this authentication is valid only for Karso ==> not for the application
|
||||
int expirationTimeInMinutes = ConfigVariable.getAuthExpirationTime();
|
||||
final int expirationTimeInMinutes = ConfigVariable.getAuthExpirationTime();
|
||||
|
||||
// Get the USER Right (Note: by construction KARSO have application ID = KARSO_INITIALISATION_ID
|
||||
Map<String, Object> ssoRight = RightResource.getUserRight(user.id, Initialization.KARSO_INITIALISATION_ID);
|
||||
final Map<String, Object> ssoRight = RightResource.getUserRight(user.id, Initialization.KARSO_INITIALISATION_ID);
|
||||
if (!ssoRight.containsKey("USER")) {
|
||||
// If the USER is not override, the system add by default USER
|
||||
ssoRight.put("USER", true);
|
||||
}
|
||||
logger.debug("Get new token with right: {}", ssoRight);
|
||||
Map<String, Object> outRight = new HashMap<>();
|
||||
String applicationName = "karso";
|
||||
this.logger.debug("Get new token with right: {}", ssoRight);
|
||||
final Map<String, Object> outRight = new HashMap<>();
|
||||
final String applicationName = "karso";
|
||||
// we set the right in the under map to manage multiple application group right. and in some application user can see other user or all user of the application
|
||||
outRight.put(applicationName, ssoRight);
|
||||
// TODO: maybe correct this get of TTL...
|
||||
String ret = JWTWrapper.generateJWToken(user.id, user.login, "KarAuth", applicationName, outRight, expirationTimeInMinutes);
|
||||
final String ret = JWTWrapper.generateJWToken(user.id, user.login, "KarAuth", applicationName, outRight, expirationTimeInMinutes);
|
||||
|
||||
// Update last connection:
|
||||
UserAuth newUser = new UserAuth();
|
||||
final UserAuth newUser = new UserAuth();
|
||||
newUser.lastConnection = Timestamp.valueOf(LocalDateTime.now());
|
||||
SqlWrapper.update(newUser, user.id, List.of("lastConnection"));
|
||||
|
||||
@ -335,55 +328,23 @@ public class UserResource {
|
||||
return new GetToken(ret);
|
||||
}
|
||||
|
||||
public static String bytesToHex(byte[] bytes) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (byte b : bytes) {
|
||||
public static String bytesToHex(final byte[] bytes) {
|
||||
final StringBuilder sb = new StringBuilder();
|
||||
for (final byte b : bytes) {
|
||||
sb.append(String.format("%02x", b));
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
public String getSHA512(String passwordToHash){
|
||||
public String getSHA512(final String passwordToHash) {
|
||||
try {
|
||||
MessageDigest md = MessageDigest.getInstance("SHA-512");
|
||||
byte[] bytes = md.digest(passwordToHash.getBytes(StandardCharsets.UTF_8));
|
||||
final MessageDigest md = MessageDigest.getInstance("SHA-512");
|
||||
final byte[] bytes = md.digest(passwordToHash.getBytes(StandardCharsets.UTF_8));
|
||||
return bytesToHex(bytes);
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
} catch (final NoSuchAlgorithmException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -4,44 +4,42 @@ import java.sql.Timestamp;
|
||||
import java.time.Instant;
|
||||
|
||||
import org.kar.archidata.filter.AuthenticationFilter;
|
||||
|
||||
import jakarta.ws.rs.Priorities;
|
||||
import jakarta.ws.rs.ext.Provider;
|
||||
|
||||
import org.kar.archidata.SqlWrapper;
|
||||
import org.kar.archidata.model.UserByToken;
|
||||
import org.kar.archidata.sqlWrapper.SqlWrapper;
|
||||
import org.kar.karso.model.ApplicationToken;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import jakarta.annotation.Priority;
|
||||
import jakarta.ws.rs.Priorities;
|
||||
import jakarta.ws.rs.ext.Provider;
|
||||
|
||||
//@PreMatching
|
||||
@Provider
|
||||
@Priority(Priorities.AUTHENTICATION)
|
||||
public class KarsoAuthenticationFilter extends AuthenticationFilter {
|
||||
final Logger logger = LoggerFactory.getLogger(KarsoAuthenticationFilter.class);
|
||||
|
||||
//curl http://0.0.0.0:15080/karso/api/public_key/pem --output plop.txt -H "Authorization: Zota 1:U0sJM1m@-STSdfg4365fJOFUGbR4kFycBu1qGZPwf7gW6k2WWRBzTPUH7QutCgPw-SDss45_563sSDFdfg@dsf@456" --verbose
|
||||
|
||||
public KarsoAuthenticationFilter() {
|
||||
//curl http://0.0.0.0:15080/karso/api/public_key/pem --output plop.txt -H "Authorization: Zota 1:U0sJM1m@-STSdfg4365fJOFUGbR4kFycBu1qGZPwf7gW6k2WWRBzTPUH7QutCgPw-SDss45_563sSDFdfg@dsf@456" --verbose
|
||||
|
||||
public KarsoAuthenticationFilter() {
|
||||
super("karso");
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected UserByToken validateToken(String authorization) throws Exception {
|
||||
protected UserByToken validateToken(final String authorization) throws Exception {
|
||||
if (authorization == null || authorization.length() < 25) {
|
||||
System.out.println("Application authentication too short '" + authorization + "'");
|
||||
return null;
|
||||
}
|
||||
String[] elems = authorization.split(":");
|
||||
final String[] elems = authorization.split(":");
|
||||
if (elems.length != 2) {
|
||||
System.out.println("Application authentication split error '" + authorization + "'");
|
||||
return null;
|
||||
}
|
||||
Long indexToken = Long.parseLong(elems[0]);
|
||||
final Long indexToken = Long.parseLong(elems[0]);
|
||||
|
||||
ApplicationToken value = SqlWrapper.get(ApplicationToken.class, indexToken);
|
||||
final ApplicationToken value = SqlWrapper.get(ApplicationToken.class, indexToken);
|
||||
if (value == null) {
|
||||
System.out.println("Application authentication can not find id '" + authorization + "'");
|
||||
return null;
|
||||
@ -59,13 +57,13 @@ public class KarsoAuthenticationFilter extends AuthenticationFilter {
|
||||
// ----------------------------------
|
||||
// -- All is good !!!
|
||||
// ----------------------------------
|
||||
// We are in transition phase the user element will be removed
|
||||
UserByToken userByToken = new UserByToken();
|
||||
userByToken.id = value.id;
|
||||
userByToken.name = value.name;
|
||||
userByToken.parentId = value.parentId;
|
||||
userByToken.type = UserByToken.TYPE_APPLICATION;
|
||||
userByToken.right.put("APPLICATION", true);
|
||||
return userByToken;
|
||||
}
|
||||
// We are in transition phase the user element will be removed
|
||||
final UserByToken userByToken = new UserByToken();
|
||||
userByToken.id = value.id;
|
||||
userByToken.name = value.name;
|
||||
userByToken.parentId = value.parentId;
|
||||
userByToken.type = UserByToken.TYPE_APPLICATION;
|
||||
userByToken.right.put("APPLICATION", true);
|
||||
return userByToken;
|
||||
}
|
||||
}
|
||||
|
@ -9,14 +9,14 @@ import org.kar.karso.model.Settings;
|
||||
import org.kar.karso.model.UserAuth;
|
||||
|
||||
public class Initialization extends MigrationSqlStep {
|
||||
|
||||
public static final int KARSO_INITIALISATION_ID = 1;
|
||||
|
||||
public static final int KARSO_INITIALISATION_ID = 1;
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "Initialization";
|
||||
}
|
||||
|
||||
|
||||
public Initialization() throws Exception {
|
||||
addClass(Settings.class);
|
||||
addClass(UserAuth.class);
|
||||
@ -24,7 +24,7 @@ public class Initialization extends MigrationSqlStep {
|
||||
addClass(ApplicationToken.class);
|
||||
addClass(RightDescription.class);
|
||||
addClass(Right.class);
|
||||
|
||||
|
||||
addAction("""
|
||||
INSERT INTO `application` (`id`, `name`, `description`, `redirect`, `redirectDev`, `notification`, `ttl`) VALUES
|
||||
(1, 'karso', 'Root SSO interface', 'http://atria-soft/karso', '', '', 666);
|
||||
@ -70,6 +70,7 @@ public class Initialization extends MigrationSqlStep {
|
||||
addAction("""
|
||||
ALTER TABLE `rightDescription` AUTO_INCREMENT = 1000;
|
||||
""");
|
||||
display();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -13,52 +13,43 @@ CREATE TABLE `application` (
|
||||
import org.kar.archidata.annotation.SQLComment;
|
||||
import org.kar.archidata.annotation.SQLDefault;
|
||||
import org.kar.archidata.annotation.SQLIfNotExists;
|
||||
import org.kar.archidata.annotation.SQLLimitSize;
|
||||
import org.kar.archidata.annotation.SQLNotNull;
|
||||
import org.kar.archidata.annotation.SQLTableName;
|
||||
import org.kar.archidata.model.GenericTable;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonInclude;
|
||||
|
||||
@SQLTableName ("application")
|
||||
import jakarta.persistence.Column;
|
||||
import jakarta.persistence.Table;
|
||||
|
||||
@Table(name = "application")
|
||||
@SQLIfNotExists
|
||||
@JsonInclude(JsonInclude.Include.NON_NULL)
|
||||
public class Application extends GenericTable{
|
||||
@SQLLimitSize(256)
|
||||
public String name;
|
||||
@SQLLimitSize(2048)
|
||||
public String description;
|
||||
@SQLLimitSize(2048)
|
||||
@SQLNotNull
|
||||
public String redirect;
|
||||
@SQLLimitSize(2048)
|
||||
@SQLDefault("'http://localhost:4200/sso/'")
|
||||
public String redirectDev;
|
||||
@SQLLimitSize(2048)
|
||||
@SQLDefault("'http://localhost:4200/sso/notification'")
|
||||
public String notification;
|
||||
@SQLNotNull
|
||||
@SQLComment("Expiration time ")
|
||||
@SQLDefault("666")
|
||||
public Integer ttl;
|
||||
@SQLNotNull
|
||||
@SQLComment("Right is manage with Karso")
|
||||
@SQLDefault("0")
|
||||
public Boolean manageRight;
|
||||
|
||||
public Application() {
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Application{" +
|
||||
"id=" + id +
|
||||
", description='" + description + '\'' +
|
||||
", redirect='" + redirect + '\'' +
|
||||
", redirectDev='" + redirectDev + '\'' +
|
||||
", notification='" + notification + '\'' +
|
||||
", ttl='" + ttl + '\'' +
|
||||
'}';
|
||||
}
|
||||
public class Application extends GenericTable {
|
||||
@Column(length = 256)
|
||||
public String name;
|
||||
@Column(length = 2048)
|
||||
public String description;
|
||||
@Column(length = 2048, nullable = false)
|
||||
public String redirect;
|
||||
@Column(length = 2048)
|
||||
@SQLDefault("'http://localhost:4200/sso/'")
|
||||
public String redirectDev;
|
||||
@Column(length = 2048)
|
||||
@SQLDefault("'http://localhost:4200/sso/notification'")
|
||||
public String notification;
|
||||
@Column(nullable = false)
|
||||
@SQLComment("Expiration time ")
|
||||
@SQLDefault("666")
|
||||
public Integer ttl;
|
||||
@Column(nullable = false)
|
||||
@SQLComment("Right is manage with Karso")
|
||||
@SQLDefault("0")
|
||||
public Boolean manageRight;
|
||||
|
||||
public Application() {}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Application{" + "id=" + this.id + ", description='" + this.description + '\'' + ", redirect='" + this.redirect + '\'' + ", redirectDev='" + this.redirectDev + '\'' + ", notification='"
|
||||
+ this.notification + '\'' + ", ttl='" + this.ttl + '\'' + '}';
|
||||
}
|
||||
}
|
||||
|
@ -1,14 +1,15 @@
|
||||
package org.kar.karso.model;
|
||||
|
||||
import org.kar.archidata.annotation.SQLIfNotExists;
|
||||
import org.kar.archidata.annotation.SQLTableName;
|
||||
import org.kar.archidata.model.GenericToken;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonInclude;
|
||||
|
||||
@SQLTableName ("applicationToken")
|
||||
import jakarta.persistence.Table;
|
||||
|
||||
@Table(name = "applicationToken")
|
||||
@SQLIfNotExists
|
||||
@JsonInclude(JsonInclude.Include.NON_NULL)
|
||||
public class ApplicationToken extends GenericToken {
|
||||
|
||||
|
||||
}
|
@ -1,35 +1,33 @@
|
||||
package org.kar.karso.model;
|
||||
|
||||
|
||||
import org.kar.archidata.annotation.SQLComment;
|
||||
import org.kar.archidata.annotation.SQLForeignKey;
|
||||
import org.kar.archidata.annotation.SQLIfNotExists;
|
||||
import org.kar.archidata.annotation.SQLLimitSize;
|
||||
import org.kar.archidata.annotation.SQLNotNull;
|
||||
import org.kar.archidata.annotation.SQLTableName;
|
||||
import org.kar.archidata.model.GenericTable;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonInclude;
|
||||
|
||||
@SQLTableName ("right")
|
||||
import jakarta.persistence.Column;
|
||||
import jakarta.persistence.Table;
|
||||
|
||||
@Table(name = "right")
|
||||
@SQLIfNotExists
|
||||
@JsonInclude(JsonInclude.Include.NON_NULL)
|
||||
public class Right extends GenericTable {
|
||||
|
||||
@SQLNotNull
|
||||
@SQLComment("application-ID that have the reference of the right")
|
||||
@SQLForeignKey("application")
|
||||
public long applicationId;
|
||||
@SQLNotNull
|
||||
@SQLComment("user-ID ")
|
||||
@SQLForeignKey("user")
|
||||
public long userId;
|
||||
@SQLNotNull
|
||||
@SQLComment("rightDescription-ID of the right description")
|
||||
@SQLForeignKey("rightDescription")
|
||||
public long rightDescriptionId;
|
||||
@SQLNotNull
|
||||
@SQLLimitSize(1024)
|
||||
@SQLComment("Value of the right")
|
||||
public String value;
|
||||
|
||||
@Column(nullable = false)
|
||||
@SQLComment("application-ID that have the reference of the right")
|
||||
@SQLForeignKey("application")
|
||||
public long applicationId;
|
||||
@Column(nullable = false)
|
||||
@SQLComment("user-ID ")
|
||||
@SQLForeignKey("user")
|
||||
public long userId;
|
||||
@Column(nullable = false)
|
||||
@SQLComment("rightDescription-ID of the right description")
|
||||
@SQLForeignKey("rightDescription")
|
||||
public long rightDescriptionId;
|
||||
@Column(length = 1024, nullable = false)
|
||||
@SQLComment("Value of the right")
|
||||
public String value;
|
||||
}
|
||||
|
@ -4,39 +4,35 @@ import org.kar.archidata.annotation.SQLComment;
|
||||
import org.kar.archidata.annotation.SQLDefault;
|
||||
import org.kar.archidata.annotation.SQLForeignKey;
|
||||
import org.kar.archidata.annotation.SQLIfNotExists;
|
||||
import org.kar.archidata.annotation.SQLLimitSize;
|
||||
import org.kar.archidata.annotation.SQLNotNull;
|
||||
import org.kar.archidata.annotation.SQLTableName;
|
||||
import org.kar.archidata.model.GenericTable;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonInclude;
|
||||
|
||||
@SQLTableName ("rightDescription")
|
||||
import jakarta.persistence.Column;
|
||||
import jakarta.persistence.Table;
|
||||
|
||||
@Table(name = "rightDescription")
|
||||
@SQLIfNotExists
|
||||
@JsonInclude(JsonInclude.Include.NON_NULL)
|
||||
public class RightDescription extends GenericTable {
|
||||
@SQLNotNull
|
||||
@SQLComment("Application id that have the reference of the right")
|
||||
@SQLForeignKey("application")
|
||||
public long applicationId;
|
||||
@SQLNotNull
|
||||
@SQLLimitSize(64)
|
||||
@SQLComment("Key of the property")
|
||||
public String key;
|
||||
@SQLNotNull
|
||||
@SQLLimitSize(1024)
|
||||
@SQLComment("Title of the right")
|
||||
public String title;
|
||||
@SQLNotNull
|
||||
@SQLLimitSize(1024)
|
||||
@SQLComment("Description of the right")
|
||||
public String description;
|
||||
@SQLLimitSize(1024)
|
||||
@SQLComment("default value if Never set")
|
||||
public String defaultValue;
|
||||
@SQLNotNull
|
||||
@SQLLimitSize(16)
|
||||
@SQLComment("Type of the property")
|
||||
@SQLDefault("\"BOOLEAN\"")
|
||||
public String type = "BOOLEAN"; // this is a place-holder (current type supported BOOLEAN)
|
||||
@Column(nullable = false)
|
||||
@SQLComment("Application id that have the reference of the right")
|
||||
@SQLForeignKey("application")
|
||||
public long applicationId;
|
||||
@Column(length = 64, nullable = false)
|
||||
@SQLComment("Key of the property")
|
||||
public String key;
|
||||
@Column(length = 1024, nullable = false)
|
||||
@SQLComment("Title of the right")
|
||||
public String title;
|
||||
@Column(length = 1024, nullable = false)
|
||||
@SQLComment("Description of the right")
|
||||
public String description;
|
||||
@Column(length = 1024)
|
||||
@SQLComment("default value if Never set")
|
||||
public String defaultValue;
|
||||
@Column(length = 16, nullable = false)
|
||||
@SQLComment("Type of the property")
|
||||
@SQLDefault("\"BOOLEAN\"")
|
||||
public String type = "BOOLEAN"; // this is a place-holder (current type supported BOOLEAN)
|
||||
}
|
@ -13,43 +13,37 @@ CREATE TABLE `application` (
|
||||
import org.kar.archidata.annotation.SQLComment;
|
||||
import org.kar.archidata.annotation.SQLDefault;
|
||||
import org.kar.archidata.annotation.SQLIfNotExists;
|
||||
import org.kar.archidata.annotation.SQLLimitSize;
|
||||
import org.kar.archidata.annotation.SQLNotNull;
|
||||
import org.kar.archidata.annotation.SQLTableName;
|
||||
import org.kar.archidata.model.GenericTable;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonInclude;
|
||||
|
||||
import jakarta.persistence.Column;
|
||||
import jakarta.persistence.Table;
|
||||
|
||||
enum PropertyType {
|
||||
STRING,
|
||||
NUMBER,
|
||||
BOOLEAN,
|
||||
STRING, NUMBER, BOOLEAN,
|
||||
}
|
||||
|
||||
@SQLTableName ("settings")
|
||||
@Table(name = "settings")
|
||||
@SQLIfNotExists
|
||||
@JsonInclude(JsonInclude.Include.NON_NULL)
|
||||
public class Settings extends GenericTable {
|
||||
@SQLLimitSize(512)
|
||||
@SQLNotNull
|
||||
public String key;
|
||||
@SQLComment("Right for the specific element(ADMIN [rw] USER [rw] other [rw])")
|
||||
@SQLNotNull
|
||||
@SQLLimitSize(6)
|
||||
@SQLDefault("\"rw----\"")
|
||||
public String right;
|
||||
@SQLComment("Type Of the data")
|
||||
@SQLNotNull
|
||||
//public PropertyType type;
|
||||
@SQLLimitSize(10)
|
||||
public String type;
|
||||
@SQLComment("Value of the configuration")
|
||||
@SQLNotNull
|
||||
public String value;
|
||||
@Column(length = 512, nullable = false)
|
||||
public String key;
|
||||
@SQLComment("Right for the specific element(ADMIN [rw] USER [rw] other [rw])")
|
||||
@Column(length = 6, nullable = false)
|
||||
@SQLDefault("\"rw----\"")
|
||||
public String right;
|
||||
@SQLComment("Type Of the data")
|
||||
@Column(length = 10, nullable = false)
|
||||
public String type;
|
||||
@SQLComment("Value of the configuration")
|
||||
@Column(nullable = false)
|
||||
public String value;
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Settings [key=" + key + ", value=" + value + ", id=" + id + ", deleted=" + deleted + "]";
|
||||
return "Settings [key=" + this.key + ", value=" + this.value + ", id=" + this.id + ", deleted=" + this.deleted + "]";
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -6,38 +6,36 @@ import java.util.List;
|
||||
import org.kar.archidata.annotation.SQLComment;
|
||||
import org.kar.archidata.annotation.SQLDefault;
|
||||
import org.kar.archidata.annotation.SQLIfNotExists;
|
||||
import org.kar.archidata.annotation.SQLLimitSize;
|
||||
import org.kar.archidata.annotation.SQLNotNull;
|
||||
import org.kar.archidata.annotation.SQLTableLinkGeneric;
|
||||
import org.kar.archidata.annotation.SQLTableName;
|
||||
import org.kar.archidata.annotation.addOn.SQLTableExternalLink;
|
||||
import org.kar.archidata.model.User;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonInclude;
|
||||
|
||||
@SQLTableName ("user")
|
||||
import jakarta.persistence.Column;
|
||||
import jakarta.persistence.Table;
|
||||
|
||||
@Table(name = "user")
|
||||
@SQLIfNotExists
|
||||
@JsonInclude(JsonInclude.Include.NON_NULL)
|
||||
public class UserAuth extends User {
|
||||
@SQLLimitSize(128)
|
||||
@SQLNotNull
|
||||
@Column(length = 128, nullable = false)
|
||||
public String password;
|
||||
/*
|
||||
@SQLLimitSize(128)
|
||||
/*
|
||||
@Column(length = 128)
|
||||
public String passwordChange; //!< When change a password, the new password is set in temporary area and wait the email validation
|
||||
@SQLLimitSize(128)
|
||||
@Column(length = 128)
|
||||
public String passwordValidation; //!< UniqueId to validate the new password
|
||||
*/
|
||||
@SQLLimitSize(512)
|
||||
@SQLNotNull
|
||||
*/
|
||||
@Column(length = 512, nullable = false)
|
||||
public String email;
|
||||
public Timestamp emailValidate; // time of validation
|
||||
@SQLLimitSize(512)
|
||||
@Column(length = 512)
|
||||
public String newEmail;
|
||||
@SQLDefault("'0'")
|
||||
@SQLNotNull
|
||||
@SQLDefault("'0'")
|
||||
@Column(nullable = false)
|
||||
public boolean avatar = false;
|
||||
@SQLComment("List of accessible application (if not set the application is not available)")
|
||||
@SQLTableLinkGeneric
|
||||
public List<Long> applications = null;
|
||||
|
||||
@SQLComment("List of accessible application (if not set the application is not available)")
|
||||
@SQLTableExternalLink
|
||||
public List<Long> applications = null;
|
||||
|
||||
}
|
||||
|
@ -2,21 +2,20 @@ package org.kar.karso.model;
|
||||
|
||||
import org.kar.archidata.annotation.SQLDefault;
|
||||
import org.kar.archidata.annotation.SQLIfNotExists;
|
||||
import org.kar.archidata.annotation.SQLLimitSize;
|
||||
import org.kar.archidata.annotation.SQLNotNull;
|
||||
import org.kar.archidata.annotation.SQLTableName;
|
||||
import org.kar.archidata.model.User;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonInclude;
|
||||
|
||||
@SQLTableName ("user")
|
||||
import jakarta.persistence.Column;
|
||||
import jakarta.persistence.Table;
|
||||
|
||||
@Table(name = "user")
|
||||
@SQLIfNotExists
|
||||
@JsonInclude(JsonInclude.Include.NON_NULL)
|
||||
public class UserAuthGet extends User {
|
||||
@SQLLimitSize(512)
|
||||
@SQLNotNull
|
||||
public class UserAuthGet extends User {
|
||||
@Column(length = 512, nullable = false)
|
||||
public String email;
|
||||
@SQLDefault("'0'")
|
||||
@SQLNotNull
|
||||
@SQLDefault("'0'")
|
||||
@Column(nullable = false)
|
||||
public boolean avatar = false;
|
||||
}
|
||||
|
@ -11,15 +11,16 @@ CREATE TABLE `application` (
|
||||
*/
|
||||
|
||||
import org.kar.archidata.annotation.SQLIfNotExists;
|
||||
import org.kar.archidata.annotation.SQLTableName;
|
||||
import org.kar.archidata.model.GenericTable;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonInclude;
|
||||
|
||||
@SQLTableName ("user_link_application")
|
||||
import jakarta.persistence.Table;
|
||||
|
||||
@Table(name = "user_link_application")
|
||||
@SQLIfNotExists
|
||||
@JsonInclude(JsonInclude.Include.NON_NULL)
|
||||
public class UserLinkApplication extends GenericTable{
|
||||
public long user_id;
|
||||
public long application_id;
|
||||
public class UserLinkApplication extends GenericTable {
|
||||
public long user_id;
|
||||
public long application_id;
|
||||
}
|
||||
|
@ -1,4 +1,5 @@
|
||||
package test.kar.karso;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import org.junit.jupiter.api.AfterAll;
|
||||
@ -13,7 +14,6 @@ import org.junit.jupiter.api.extension.ExecutionCondition;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.junit.jupiter.api.extension.ExtensionContext;
|
||||
import org.junit.jupiter.api.extension.TestExecutionExceptionHandler;
|
||||
import org.kar.archidata.SqlWrapper;
|
||||
import org.kar.archidata.exception.RESTErrorResponseExeption;
|
||||
import org.kar.archidata.model.GetToken;
|
||||
import org.kar.archidata.util.ConfigBaseVariable;
|
||||
@ -29,112 +29,108 @@ import com.nimbusds.jwt.JWTClaimsSet;
|
||||
@ExtendWith(StepwiseExtension.class)
|
||||
@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
|
||||
public class TestBase {
|
||||
final static Logger logger = LoggerFactory.getLogger(WebLauncherTest.class);
|
||||
|
||||
private final static Logger LOGGER = LoggerFactory.getLogger(TestBase.class);
|
||||
|
||||
static WebLauncherTest webInterface = null;
|
||||
static RESTApi api = null;
|
||||
|
||||
|
||||
public void login(String login, String password) {
|
||||
public void login(final String login, final String password) {
|
||||
try {
|
||||
GetToken token = api.post(GetToken.class, "users/get_token", DataGetToken.generate(login, "v1", "202515252", password));
|
||||
final GetToken token = api.post(GetToken.class, "users/get_token", DataGetToken.generate(login, "v1", "202515252", password));
|
||||
api.setToken(token.jwt());
|
||||
} catch (Exception ex) {
|
||||
} catch (final Exception ex) {
|
||||
Assertions.fail("Can not get Authentication for '" + login + "' ==> " + ex.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void loginAdmin() {
|
||||
login("karadmin", "adminA@666");
|
||||
}
|
||||
|
||||
|
||||
@BeforeAll
|
||||
public static void configureWebServer() throws Exception {
|
||||
logger.info("configure server ...");
|
||||
LOGGER.info("configure server ...");
|
||||
webInterface = new WebLauncherTest();
|
||||
logger.info("Create DB");
|
||||
|
||||
String dbName = "sdfsdfsdfsfsdfsfsfsfsdfsdfsd";
|
||||
boolean data = SqlWrapper.isDBExist(dbName);
|
||||
logger.error("exist: {}", data);
|
||||
data = SqlWrapper.createDB(dbName);
|
||||
logger.error("create: {}", data);
|
||||
data = SqlWrapper.isDBExist(dbName);
|
||||
logger.error("exist: {}", data);
|
||||
System.exit(-1);
|
||||
|
||||
logger.info("Start REST (BEGIN)");
|
||||
LOGGER.info("Create DB");
|
||||
try {
|
||||
webInterface.migrateDB();
|
||||
} catch (final Exception ex) {
|
||||
ex.printStackTrace();
|
||||
LOGGER.error("Detect an error: {}", ex.getMessage());
|
||||
}
|
||||
LOGGER.info("Start REST (BEGIN)");
|
||||
webInterface.process();
|
||||
logger.info("Start REST (DONE)");
|
||||
LOGGER.info("Start REST (DONE)");
|
||||
api = new RESTApi(ConfigBaseVariable.apiAdress);
|
||||
}
|
||||
|
||||
@AfterAll
|
||||
public static void stopWebServer() throws InterruptedException {
|
||||
logger.info("Kill the web server");
|
||||
LOGGER.info("Kill the web server");
|
||||
webInterface = null;
|
||||
// TODO: do it better...
|
||||
}
|
||||
|
||||
|
||||
@Order(1)
|
||||
@Test
|
||||
//@RepeatedTest(10)
|
||||
public void checkHealthCheck() throws Exception {
|
||||
HealthResult result = api.get(HealthResult.class, "health_check");
|
||||
Assertions.assertEquals(result.value(), "alive and kicking");
|
||||
final HealthResult result = api.get(HealthResult.class, "health_check");
|
||||
Assertions.assertEquals(result.value(), "alive and kicking");
|
||||
}
|
||||
|
||||
|
||||
@Order(2)
|
||||
@Test
|
||||
public void checkHealthCheckWrongAPI() throws Exception {
|
||||
Assertions.assertThrows(RESTErrorResponseExeption.class, ()->api.get(HealthResult.class, "health_checks"));
|
||||
Assertions.assertThrows(RESTErrorResponseExeption.class, () -> api.get(HealthResult.class, "health_checks"));
|
||||
}
|
||||
|
||||
|
||||
@Order(3)
|
||||
@Test
|
||||
public void firstUserConnect() throws Exception {
|
||||
GetToken result = api.post(GetToken.class, "users/get_token", DataGetToken.generate("karadmin", "v1", "202515252", "adminA@666"));
|
||||
String[] splitted = result.jwt().split("\\.");
|
||||
final GetToken result = api.post(GetToken.class, "users/get_token", DataGetToken.generate("karadmin", "v1", "202515252", "adminA@666"));
|
||||
final String[] splitted = result.jwt().split("\\.");
|
||||
Assertions.assertEquals(3, splitted.length);
|
||||
String authorization = result.jwt();
|
||||
logger.debug(" validate token : " + authorization);
|
||||
// Note with local access we get the internal key of the system.
|
||||
JWTClaimsSet ret = JWTWrapper.validateToken(authorization, "KarAuth", null);
|
||||
// check the token is valid !!! (signed and coherent issuer...
|
||||
Assertions.assertNotNull(ret);
|
||||
// check userID
|
||||
String userUID = ret.getSubject();
|
||||
long id = Long.parseLong(userUID);
|
||||
Assertions.assertEquals(0, id);
|
||||
String name = (String)ret.getClaim("login");
|
||||
Assertions.assertEquals("karadmin", name);
|
||||
|
||||
|
||||
Object rowRight = ret.getClaim("right");
|
||||
Assertions.assertNotNull(rowRight);
|
||||
Map<String, Map<String,Object>> rights = (Map<String, Map<String,Object>>) ret.getClaim("right");
|
||||
// Check if the element contain the basic keys:
|
||||
Assertions.assertEquals(rights.size(), 1);
|
||||
Assertions.assertTrue(rights.containsKey("karso"));
|
||||
Map<String, Object> applRight = rights.get("karso");
|
||||
//logger.error("full right: {}", applRight);
|
||||
Assertions.assertEquals(applRight.size(), 2);
|
||||
Assertions.assertTrue(applRight.containsKey("ADMIN"));
|
||||
Assertions.assertEquals(true, applRight.get("ADMIN"));
|
||||
Assertions.assertTrue(applRight.containsKey("USER"));
|
||||
Assertions.assertEquals(true, applRight.get("USER"));
|
||||
|
||||
//logger.debug("request user: '{}' right: '{}' row='{}'", userUID, applRight, rowRight);
|
||||
final String authorization = result.jwt();
|
||||
LOGGER.debug(" validate token : " + authorization);
|
||||
// Note with local access we get the internal key of the system.
|
||||
final JWTClaimsSet ret = JWTWrapper.validateToken(authorization, "KarAuth", null);
|
||||
// check the token is valid !!! (signed and coherent issuer...
|
||||
Assertions.assertNotNull(ret);
|
||||
// check userID
|
||||
final String userUID = ret.getSubject();
|
||||
final long id = Long.parseLong(userUID);
|
||||
Assertions.assertEquals(0, id);
|
||||
final String name = (String) ret.getClaim("login");
|
||||
Assertions.assertEquals("karadmin", name);
|
||||
|
||||
final Object rowRight = ret.getClaim("right");
|
||||
Assertions.assertNotNull(rowRight);
|
||||
final Map<String, Map<String, Object>> rights = (Map<String, Map<String, Object>>) ret.getClaim("right");
|
||||
// Check if the element contain the basic keys:
|
||||
Assertions.assertEquals(rights.size(), 1);
|
||||
Assertions.assertTrue(rights.containsKey("karso"));
|
||||
final Map<String, Object> applRight = rights.get("karso");
|
||||
//logger.error("full right: {}", applRight);
|
||||
Assertions.assertEquals(applRight.size(), 2);
|
||||
Assertions.assertTrue(applRight.containsKey("ADMIN"));
|
||||
Assertions.assertEquals(true, applRight.get("ADMIN"));
|
||||
Assertions.assertTrue(applRight.containsKey("USER"));
|
||||
Assertions.assertEquals(true, applRight.get("USER"));
|
||||
|
||||
//logger.debug("request user: '{}' right: '{}' row='{}'", userUID, applRight, rowRight);
|
||||
|
||||
//Assertions.assertEquals("eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9", splitted[0]);
|
||||
//Assertions.assertEquals("eyJzdWIiOiIwIiwiYXBwbGljYXRpb24iOiJrYXJzbyIsImlzcyI6IkthckF1dGgiLCJyaWdodCI6eyJrYXJzbyI6eyJBRE1JTiI6dHJ1ZSwiVVNFUiI6dHJ1ZX19LCJsb2dpbiI6ImthcmFkbWluIiwiZXhwIjoxNjg0MTk5MTkzLCJpYXQiOjE2ODI3NTU0MjV9", splitted[1]);
|
||||
// TODO ... Assertions.assertEquals("????", splitted[2]);
|
||||
}
|
||||
|
||||
public void checkFail(String type, String urlOffset, int errorStatus) {
|
||||
|
||||
public void checkFail(final String type, final String urlOffset, final int errorStatus) {
|
||||
checkFail(type, urlOffset, errorStatus, null);
|
||||
}
|
||||
public void checkFail(String type, String urlOffset, int errorStatus, String data) {
|
||||
logger.info("Test API: url={} urlOffset={}", type, urlOffset);
|
||||
|
||||
public void checkFail(final String type, final String urlOffset, final int errorStatus, final String data) {
|
||||
LOGGER.info("Test API: url={} urlOffset={}", type, urlOffset);
|
||||
try {
|
||||
if ("GET".equals(type)) {
|
||||
api.get(String.class, urlOffset);
|
||||
@ -146,22 +142,24 @@ public class TestBase {
|
||||
api.delete(String.class, urlOffset);
|
||||
}
|
||||
Assertions.fail("Request on URL does not fail as expected: '" + type + "' url='" + urlOffset + "'");
|
||||
} catch (RESTErrorResponseExeption ex) {
|
||||
} catch (final RESTErrorResponseExeption ex) {
|
||||
if (errorStatus != ex.status) {
|
||||
logger.error("Fail in test with the wrong return errors: {}", ex.toString());
|
||||
LOGGER.error("Fail in test with the wrong return errors: {}", ex.toString());
|
||||
}
|
||||
Assertions.assertEquals(errorStatus, ex.status);
|
||||
} catch (Exception ex) {
|
||||
logger.error("Unexpected throw error: {}", ex);
|
||||
} catch (final Exception ex) {
|
||||
LOGGER.error("Unexpected throw error: {}", ex);
|
||||
Assertions.fail("Unexpected throws...");
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
public void checkWork(String type, String urlOffset) {
|
||||
|
||||
public void checkWork(final String type, final String urlOffset) {
|
||||
checkWork(type, urlOffset, null);
|
||||
}
|
||||
public void checkWork(String type, String urlOffset, String data) {
|
||||
logger.info("Test API: url={} urlOffset={}", type, urlOffset);
|
||||
|
||||
public void checkWork(final String type, final String urlOffset, final String data) {
|
||||
LOGGER.info("Test API: url={} urlOffset={}", type, urlOffset);
|
||||
try {
|
||||
if ("GET".equals(type)) {
|
||||
api.get(String.class, urlOffset);
|
||||
@ -173,14 +171,15 @@ public class TestBase {
|
||||
api.delete(String.class, urlOffset);
|
||||
}
|
||||
//Assertions.fail("Request on URL does not fail as expected: '" + type + "' url='" + urlOffset + "'");
|
||||
} catch (RESTErrorResponseExeption ex) {
|
||||
} catch (final RESTErrorResponseExeption ex) {
|
||||
Assertions.fail("Must not fail ... " + ex.toString());
|
||||
} catch (Exception ex) {
|
||||
logger.error("Unexpected throw error: {}", ex);
|
||||
} catch (final Exception ex) {
|
||||
LOGGER.error("Unexpected throw error: {}", ex);
|
||||
Assertions.fail("Unexpected throws...");
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@Order(4)
|
||||
@Test
|
||||
public void checkUnAuthorizedAPI() throws Exception {
|
||||
@ -200,34 +199,33 @@ public class TestBase {
|
||||
checkFail("GET", "application/small", 401);
|
||||
checkFail("GET", "application/get_token", 401);
|
||||
checkFail("GET", "application/return", 401);
|
||||
|
||||
|
||||
// /application_token/ section:
|
||||
checkFail("GET", "application_token/0", 401);
|
||||
checkFail("DELETE", "application_token/0/5", 401);
|
||||
checkFail("DELETE", "application_token/0/create", 401);
|
||||
|
||||
|
||||
// /front/*
|
||||
checkFail("GET", "front", 404); // no index in test section
|
||||
// health check
|
||||
checkWork("GET", "health_check");
|
||||
|
||||
|
||||
// public_key (only application)
|
||||
checkFail("GET", "public_key", 401);
|
||||
checkFail("GET", "public_key/pem", 401);
|
||||
|
||||
|
||||
// /right
|
||||
checkFail("GET", "right", 401);
|
||||
checkFail("POST", "right", 401, "{}");
|
||||
checkFail("GET", "right/0", 401);
|
||||
checkFail("PUT", "right/0", 401, "{}");
|
||||
checkFail("DELETE", "right/0", 401);
|
||||
|
||||
|
||||
// /system_config
|
||||
checkWork("GET", "system_config/is_sign_up_availlable");
|
||||
checkFail("GET", "system_config/key/skjdfhkjsdhfkjsh", 401);
|
||||
checkFail("PUT", "system_config/key/skjdfhkjsdhfkjsh", 401, "{}");
|
||||
|
||||
|
||||
// /users
|
||||
checkFail("GET", "users", 401);
|
||||
checkFail("GET", "users/0", 401);
|
||||
@ -242,46 +240,43 @@ public class TestBase {
|
||||
checkWork("GET", "users/check_email?email=admin@admin.ZZZ");
|
||||
checkFail("GET", "users/check_email?email=ksjhdkjfhskjdh", 404);
|
||||
// not testable : get_token
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Order(5)
|
||||
@Test
|
||||
public void testMeWithToken() throws Exception {
|
||||
this.loginAdmin();
|
||||
String result = api.get(String.class, "users/me");
|
||||
Assertions.assertEquals("{\"id\":0,\"login\":\"karadmin\"}", result);
|
||||
|
||||
loginAdmin();
|
||||
final String result = api.get(String.class, "users/me");
|
||||
Assertions.assertEquals("{\"id\":0,\"login\":\"karadmin\"}", result);
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
class StepwiseExtension implements ExecutionCondition, TestExecutionExceptionHandler {
|
||||
@Override
|
||||
public ConditionEvaluationResult evaluateExecutionCondition(ExtensionContext extensionContext) {
|
||||
ExtensionContext.Namespace namespace = namespaceFor(extensionContext);
|
||||
ExtensionContext.Store store = storeFor(extensionContext, namespace);
|
||||
String value = store.get(StepwiseExtension.class, String.class);
|
||||
return value == null ? ConditionEvaluationResult.enabled("No test failures in stepwise tests") :
|
||||
ConditionEvaluationResult.disabled(String.format("Stepwise test disabled due to previous failure in '%s'", value));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleTestExecutionException(ExtensionContext extensionContext, Throwable throwable) throws Throwable {
|
||||
ExtensionContext.Namespace namespace = namespaceFor(extensionContext);
|
||||
ExtensionContext.Store store = storeFor(extensionContext, namespace);
|
||||
store.put(StepwiseExtension.class, extensionContext.getDisplayName());
|
||||
throw throwable;
|
||||
}
|
||||
|
||||
private ExtensionContext.Namespace namespaceFor(ExtensionContext extensionContext){
|
||||
return ExtensionContext.Namespace.create(StepwiseExtension.class, extensionContext.getParent());
|
||||
}
|
||||
|
||||
|
||||
private ExtensionContext.Store storeFor(ExtensionContext extensionContext, ExtensionContext.Namespace namespace){
|
||||
return extensionContext.getParent().get().getStore(namespace);
|
||||
}
|
||||
@Override
|
||||
public ConditionEvaluationResult evaluateExecutionCondition(final ExtensionContext extensionContext) {
|
||||
final ExtensionContext.Namespace namespace = namespaceFor(extensionContext);
|
||||
final ExtensionContext.Store store = storeFor(extensionContext, namespace);
|
||||
final String value = store.get(StepwiseExtension.class, String.class);
|
||||
return value == null ? ConditionEvaluationResult.enabled("No test failures in stepwise tests")
|
||||
: ConditionEvaluationResult.disabled(String.format("Stepwise test disabled due to previous failure in '%s'", value));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleTestExecutionException(final ExtensionContext extensionContext, final Throwable throwable) throws Throwable {
|
||||
final ExtensionContext.Namespace namespace = namespaceFor(extensionContext);
|
||||
final ExtensionContext.Store store = storeFor(extensionContext, namespace);
|
||||
store.put(StepwiseExtension.class, extensionContext.getDisplayName());
|
||||
throw throwable;
|
||||
}
|
||||
|
||||
private ExtensionContext.Namespace namespaceFor(final ExtensionContext extensionContext) {
|
||||
return ExtensionContext.Namespace.create(StepwiseExtension.class, extensionContext.getParent());
|
||||
}
|
||||
|
||||
private ExtensionContext.Store storeFor(final ExtensionContext extensionContext, final ExtensionContext.Namespace namespace) {
|
||||
return extensionContext.getParent().get().getStore(namespace);
|
||||
}
|
||||
}
|
||||
|
@ -9,20 +9,20 @@ import org.slf4j.LoggerFactory;
|
||||
|
||||
public class WebLauncherTest extends WebLauncher {
|
||||
final Logger logger = LoggerFactory.getLogger(WebLauncherTest.class);
|
||||
|
||||
public WebLauncherTest() {
|
||||
logger.debug("Configure REST system");
|
||||
this.logger.debug("Configure REST system");
|
||||
// for local test:
|
||||
ConfigBaseVariable.apiAdress = "http://127.0.0.1:12345/test/api/";
|
||||
|
||||
|
||||
ConfigBaseVariable.dbPort = "3306";
|
||||
// create a unique key for test ==> not retrieve the token every load...
|
||||
ConfigVariable.uuid_for_key_generation = "lkjlkjlkjlmkjqmwlsdkjqfsdlkf,nmQLSDK,NFMQLKSdjmlKQJSDMLQK,S;ndmLQKZNERMA,ÉL";
|
||||
// for the test we a in memory sqlite..
|
||||
////ConfigBaseVariable.dbType = "sqlite";
|
||||
////ConfigBaseVariable.dbHost = "memory";
|
||||
// for the test we a in memory sqlite..
|
||||
ConfigBaseVariable.dbType = "sqlite";
|
||||
ConfigBaseVariable.dbHost = "memory";
|
||||
// for test we need to connect all time the DB
|
||||
////ConfigBaseVariable.dbKeepConnected = "true";
|
||||
|
||||
ConfigBaseVariable.dbKeepConnected = "true";
|
||||
|
||||
ConfigBaseVariable.dbHost = "localhost";
|
||||
ConfigBaseVariable.dbUser = "root";
|
||||
|
Loading…
x
Reference in New Issue
Block a user