[DEV] review with new model

This commit is contained in:
Edouard DUPIN 2023-10-14 12:22:21 +02:00
parent f4d7438918
commit 4f8a34590e
22 changed files with 996 additions and 1116 deletions

View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<classpath> <classpath>
<classpathentry kind="src" output="out/maven/classes" path="src"> <classpathentry including="**/*.java" kind="src" output="out/maven/classes" path="src">
<attributes> <attributes>
<attribute name="optional" value="true"/> <attribute name="optional" value="true"/>
<attribute name="maven.pomderived" value="true"/> <attribute name="maven.pomderived" value="true"/>
@ -13,11 +13,6 @@
<attribute name="maven.pomderived" value="true"/> <attribute name="maven.pomderived" value="true"/>
</attributes> </attributes>
</classpathentry> </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"> <classpathentry kind="con" path="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER">
<attributes> <attributes>
<attribute name="maven.pomderived" value="true"/> <attribute name="maven.pomderived" value="true"/>
@ -25,10 +20,16 @@
</classpathentry> </classpathentry>
<classpathentry excluding="**" kind="src" output="out/maven/test-classes" path="test/resources"> <classpathentry excluding="**" kind="src" output="out/maven/test-classes" path="test/resources">
<attributes> <attributes>
<attribute name="maven.pomderived" value="true"/>
<attribute name="test" value="true"/> <attribute name="test" value="true"/>
<attribute name="maven.pomderived" value="true"/>
<attribute name="optional" value="true"/> <attribute name="optional" value="true"/>
</attributes> </attributes>
</classpathentry> </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"/> <classpathentry kind="output" path="out/maven/classes"/>
</classpath> </classpath>

View File

@ -1,5 +1,5 @@
services: services:
db_service: kar_db_service:
image: mysql:latest image: mysql:latest
restart: always restart: always
environment: environment:
@ -9,20 +9,20 @@ services:
#- /workspace/data/global/db:/var/lib/mysql #- /workspace/data/global/db:/var/lib/mysql
mem_limit: 300m mem_limit: 300m
ports: ports:
- 3306:3306 - 3906:3306
healthcheck: healthcheck:
test: ["CMD", "mysqladmin" ,"ping", "-h", "localhost"] test: ["CMD", "mysqladmin" ,"ping", "-h", "localhost"]
timeout: 10s timeout: 10s
retries: 5 retries: 5
start_period: 20s start_period: 20s
adminer_service: kar_adminer_service:
image: adminer:latest image: adminer:latest
restart: always restart: always
ports: ports:
- 10079:8080 - 18079:8080
links: links:
- db_service:db - kar_db_service:db
#read_only: true #read_only: true
mem_limit: 100m mem_limit: 100m

View File

@ -24,7 +24,7 @@
<dependency> <dependency>
<groupId>kangaroo-and-rabbit</groupId> <groupId>kangaroo-and-rabbit</groupId>
<artifactId>archidata</artifactId> <artifactId>archidata</artifactId>
<version>0.3.7</version> <version>0.4.0</version>
</dependency> </dependency>
<!-- testing --> <!-- testing -->
<dependency> <dependency>
@ -159,7 +159,25 @@
<nohelp>true</nohelp> <nohelp>true</nohelp>
</configuration> </configuration>
</plugin> </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> </plugins>
<testResources> <testResources>
<testResource> <testResource>
<directory>${basedir}/test/resources</directory> <directory>${basedir}/test/resources</directory>

View File

@ -1,8 +1,25 @@
package org.kar.karso; 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.filter.OptionFilter;
import org.kar.archidata.migration.MigrationEngine; 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.ApplicationResource;
import org.kar.karso.api.ApplicationTokenResource; import org.kar.karso.api.ApplicationTokenResource;
import org.kar.karso.api.Front; import org.kar.karso.api.Front;
@ -16,38 +33,26 @@ import org.kar.karso.migration.Initialization;
import org.kar.karso.util.ConfigVariable; import org.kar.karso.util.ConfigVariable;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; 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 jakarta.ws.rs.core.UriBuilder;
import java.net.URI;
public class WebLauncher { public class WebLauncher {
final static Logger LOGGER = LoggerFactory.getLogger(WebLauncher.class); private final static Logger LOGGER = LoggerFactory.getLogger(WebLauncher.class);
protected ResourceConfig rc = null; protected ResourceConfig rc = null;
HttpServer server = null; HttpServer server = null;
public WebLauncher() { public WebLauncher() {
ConfigBaseVariable.bdDatabase = "karso"; ConfigBaseVariable.bdDatabase = "karso";
GenericAddOn.addGenericAddOn();
} }
private static URI getBaseURI() { private static URI getBaseURI() {
return UriBuilder.fromUri(ConfigBaseVariable.getlocalAddress()).build(); 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.LOGGER.info("[START] application wake UP");
WebLauncher launcher = new WebLauncher(); final WebLauncher launcher = new WebLauncher();
launcher.migrateDB(); launcher.migrateDB();
launcher.process(); launcher.process();
@ -58,7 +63,7 @@ public class WebLauncher {
public void migrateDB() throws Exception { public void migrateDB() throws Exception {
WebLauncher.LOGGER.info("Create migration engine"); WebLauncher.LOGGER.info("Create migration engine");
MigrationEngine migrationEngine = new MigrationEngine(); final MigrationEngine migrationEngine = new MigrationEngine();
WebLauncher.LOGGER.info("Add initialization"); WebLauncher.LOGGER.info("Add initialization");
migrationEngine.setInit(new Initialization()); migrationEngine.setInit(new Initialization());
WebLauncher.LOGGER.info("Add migration since last version"); WebLauncher.LOGGER.info("Add migration since last version");
@ -71,7 +76,7 @@ public class WebLauncher {
public void process() throws InterruptedException { public void process() throws InterruptedException {
try { try {
JWTWrapper.initLocalToken(ConfigVariable.getUUIDKeyRoot()); JWTWrapper.initLocalToken(ConfigVariable.getUUIDKeyRoot());
} catch (Exception e1) { } catch (final Exception e1) {
// TODO Auto-generated catch block // TODO Auto-generated catch block
e1.printStackTrace(); e1.printStackTrace();
LOGGER.info("Wait 10 seconds ...."); LOGGER.info("Wait 10 seconds ....");
@ -82,47 +87,47 @@ public class WebLauncher {
// =================================================================== // ===================================================================
// Configure resources // Configure resources
// =================================================================== // ===================================================================
rc = new ResourceConfig(); this.rc = new ResourceConfig();
// global authentication system // global authentication system
rc.register(OptionFilter.class); this.rc.register(OptionFilter.class);
rc.register(CORSFilter.class); this.rc.register(CORSFilter.class);
rc.register(KarsoAuthenticationFilter.class); this.rc.register(KarsoAuthenticationFilter.class);
// register exception catcher // register exception catcher
rc.register(InputExceptionCatcher.class); this.rc.register(InputExceptionCatcher.class);
rc.register(SystemExceptionCatcher.class); this.rc.register(SystemExceptionCatcher.class);
rc.register(FailExceptionCatcher.class); this.rc.register(FailExceptionCatcher.class);
rc.register(FailException404API.class); this.rc.register(FailException404API.class);
rc.register(ExceptionCatcher.class); this.rc.register(ExceptionCatcher.class);
// add default resource: // add default resource:
rc.register(UserResource.class); this.rc.register(UserResource.class);
rc.register(PublicKeyResource.class); this.rc.register(PublicKeyResource.class);
rc.register(ApplicationResource.class); this.rc.register(ApplicationResource.class);
rc.register(ApplicationTokenResource.class); this.rc.register(ApplicationTokenResource.class);
rc.register(SystemConfigResource.class); this.rc.register(SystemConfigResource.class);
rc.register(RightResource.class); this.rc.register(RightResource.class);
rc.register(Front.class); this.rc.register(Front.class);
rc.register(HealthCheck.class); this.rc.register(HealthCheck.class);
// add jackson to be discover when we are ins stand-alone server // add jackson to be discover when we are ins stand-alone server
rc.register(JacksonFeature.class); this.rc.register(JacksonFeature.class);
// enable this to show low level request // enable this to show low level request
//rc.property(LoggingFeature.LOGGING_FEATURE_LOGGER_LEVEL_SERVER, Level.WARNING.getName()); //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() { Runtime.getRuntime().addShutdownHook(new Thread(new Runnable() {
@Override @Override
public void run() { public void run() {
LOGGER.info("Stopping server.."); LOGGER.info("Stopping server..");
server.shutdownNow(); WebLauncher.this.server.shutdownNow();
} }
}, "shutdownHook")); }, "shutdownHook"));
// =================================================================== // ===================================================================
// run JERSEY // run JERSEY
// =================================================================== // ===================================================================
try { try {
server.start(); this.server.start();
LOGGER.info("Jersey app started at {}", getBaseURI()); 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."); LOGGER.error("There was an error while starting Grizzly HTTP server.");
e.printStackTrace(); e.printStackTrace();
} }

View File

@ -7,36 +7,39 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
public class WebLauncherLocal extends WebLauncher { public class WebLauncherLocal extends WebLauncher {
final Logger logger = LoggerFactory.getLogger(WebLauncherLocal.class); private static final Logger LOGGER = LoggerFactory.getLogger(WebLauncherLocal.class);
private WebLauncherLocal() {} private WebLauncherLocal() {}
public static void main(String[] args) throws InterruptedException { public static void main(final String[] args) throws InterruptedException {
WebLauncherLocal launcher = new WebLauncherLocal(); final WebLauncherLocal launcher = new WebLauncherLocal();
launcher.process(); launcher.process();
launcher.logger.info("end-configure the server & wait finish process:"); LOGGER.info("end-configure the server & wait finish process:");
Thread.currentThread().join(); Thread.currentThread().join();
launcher.logger.info("STOP the REST server:"); LOGGER.info("STOP the REST server:");
} }
@Override @Override
public void process() throws InterruptedException { public void process() throws InterruptedException {
if (true) { if (true) {
// for local test: // for local test:
ConfigBaseVariable.apiAdress = "http://0.0.0.0:15080/karso/api/"; 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... // create a unique key for test ==> not retrieve the token every load...
ConfigVariable.uuid_for_key_generation = "lkjlkjlkjlmkjqmwlsdkjqfsdlkf88QJSDMLQKSndmLQKZNERMAL"; ConfigVariable.uuid_for_key_generation = "lkjlkjlkjlmkjqmwlsdkjqfsdlkf88QJSDMLQKSndmLQKZNERMAL";
//ConfigBaseVariable.dbType = "sqlite"; //ConfigBaseVariable.dbType = "sqlite";
//ConfigBaseVariable.dbHost = "./bdd_base.sqlite"; //ConfigBaseVariable.dbHost = "./bdd_base.sqlite";
} }
try { try {
super.migrateDB(); super.migrateDB();
} catch (Exception e) { } catch (final Exception e) {
// TODO Auto-generated catch block
e.printStackTrace(); e.printStackTrace();
while (true) { while (true) {
logger.error("Migration fail ==> waiting intervention of administrator..."); LOGGER.error("============================================================================");
Thread.sleep(60*60*1000); LOGGER.error("== Migration fail ==> waiting intervention of administrator...");
LOGGER.error("============================================================================");
Thread.sleep(60 * 60 * 1000);
} }
} }
super.process(); super.process();

View File

@ -1,107 +1,113 @@
package org.kar.karso.api; 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.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; 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.Context;
import jakarta.ws.rs.core.MediaType; import jakarta.ws.rs.core.MediaType;
import jakarta.ws.rs.core.Response; import jakarta.ws.rs.core.Response;
import jakarta.ws.rs.core.SecurityContext; import jakarta.ws.rs.core.SecurityContext;
@Path("/application") @Path("/application")
@Produces( MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON)
public class ApplicationResource { public class ApplicationResource {
final Logger logger = LoggerFactory.getLogger(ApplicationResource.class); final Logger logger = LoggerFactory.getLogger(ApplicationResource.class);
public ApplicationResource() { public ApplicationResource() {}
}
public List<Long> getUserListOfApplication(Long userId) { public List<Long> getUserListOfApplication(final Long userId) {
List<Long> out = new ArrayList<>(); final List<Long> out = new ArrayList<>();
List<UserLinkApplication> links = null; List<UserLinkApplication> links = null;
try { try {
links = SqlWrapper.getsWhere(UserLinkApplication.class, links = SqlWrapper.getsWhere(UserLinkApplication.class, new QuerryAnd(new QuerryCondition("user_id", "=", userId), new QuerryCondition("deleted", "=", 0)), false);
List.of( } catch (final Exception e) {
new WhereCondition("user_id", "=", userId),
new WhereCondition("deleted", "=", 0)
), false);
} catch (Exception e) {
// TODO Auto-generated catch block // TODO Auto-generated catch block
e.printStackTrace(); e.printStackTrace();
String result = "SERVER Internal error"; final String result = "SERVER Internal error";
logger.error(" result: {}", result); this.logger.error(" result: {}", result);
return out; return out;
} }
for (UserLinkApplication app : links) { for (final UserLinkApplication app : links) {
out.add(app.application_id); out.add(app.application_id);
} }
return out; 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; List<UserLinkApplication> links = null;
try { try {
links = SqlWrapper.getsWhere(UserLinkApplication.class, links = SqlWrapper.getsWhere(UserLinkApplication.class, new QuerryAnd(new QuerryCondition("application_id", "=", applicationId), new QuerryCondition("deleted", "=", 0)), false);
List.of( } catch (final Exception e) {
new WhereCondition("application_id", "=", applicationId),
new WhereCondition("deleted", "=", 0)
), false);
} catch (Exception e) {
// TODO Auto-generated catch block // TODO Auto-generated catch block
e.printStackTrace(); e.printStackTrace();
String result = "SERVER Internal error"; final String result = "SERVER Internal error";
logger.error(" result: {}", result); this.logger.error(" result: {}", result);
return out; return out;
} }
logger.debug("Find list of user for an application: {}", links); this.logger.debug("Find list of user for an application: {}", links);
for (UserLinkApplication app : links) { for (final UserLinkApplication app : links) {
out.add(app.user_id); out.add(app.user_id);
} }
return out; return out;
} }
//////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////
// //
// Generic /application/ // Generic /application/
// //
//////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////
@GET @GET
@RolesAllowed(value= {"USER", "ADMIN"}) @RolesAllowed(value = { "USER", "ADMIN" })
public List<Application> getApplications(@Context SecurityContext sc) throws Exception { public List<Application> getApplications(@Context final SecurityContext sc) throws Exception {
GenericContext gc = (GenericContext) sc.getUserPrincipal(); final GenericContext gc = (GenericContext) sc.getUserPrincipal();
logger.debug("getApplications"); this.logger.debug("getApplications");
// TODO filter with the list of element available in his authorizations ... // 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)) { if (gc.userByToken.hasRight("ADMIN", true)) {
return tmp; return tmp;
} }
List<Long> regular = this.getUserListOfApplication(gc.userByToken.id); final List<Long> regular = getUserListOfApplication(gc.userByToken.id);
List<Application> out = new ArrayList<>(); final List<Application> out = new ArrayList<>();
for (Application app : tmp) { for (final Application app : tmp) {
if (regular.indexOf(app.id) != -1) { if (regular.indexOf(app.id) != -1) {
out.add(app); out.add(app);
} }
} }
return out; return out;
} }
@POST @POST
@RolesAllowed("ADMIN") @RolesAllowed("ADMIN")
public Application create(Application application) throws Exception { public Application create(final Application application) throws Exception {
logger.debug("create new application {}", application); this.logger.debug("create new application {}", application);
// verify login or email is correct: // verify login or email is correct:
if (application.name == null || application.name.length() < 5) { if (application.name == null || application.name.length() < 5) {
throw new InputException("name", "create application (name too small: '" + application.name + "')"); throw new InputException("name", "create application (name too small: '" + application.name + "')");
@ -115,178 +121,171 @@ public class ApplicationResource {
application.modify_date = null; application.modify_date = null;
return SqlWrapper.insert(application); return SqlWrapper.insert(application);
} }
//////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////
// //
// Generic /application/{id} // Generic /application/{id}
// //
//////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////
@GET @GET
@Path("{id}") @Path("{id}")
@RolesAllowed("ADMIN") @RolesAllowed("ADMIN")
public Application get(@PathParam("id") Long id) throws Exception { public Application get(@PathParam("id") final Long id) throws Exception {
return SqlWrapper.get(Application.class, id); 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 @DELETE
@Path("{id}") @Path("{id}")
@RolesAllowed("ADMIN") @RolesAllowed("ADMIN")
@Produces( value = MediaType.TEXT_PLAIN ) @Produces(value = MediaType.TEXT_PLAIN)
public void remove(@Context SecurityContext sc, @PathParam("id") long applicationId) throws Exception { public void remove(@Context final SecurityContext sc, @PathParam("id") final long applicationId) throws Exception {
SqlWrapper.setDelete(Application.class, applicationId); SqlWrapper.setDelete(Application.class, applicationId);
} }
//////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////
// //
// Generic /{id}/* // Generic /{id}/*
// //
//////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////
@GET
@GET @Path("{id}/users")
@Path("{id}/users") @RolesAllowed(value = { "ADMIN" })
@RolesAllowed(value= {"ADMIN"}) public List<Long> getApplicationUsers(@PathParam("id") final Long applicationId) throws Exception {
public List<Long> getApplicationUsers(@PathParam("id") Long applicationId) throws Exception { // special case for SSO: (all user have access on the SSO...).
// special case for SSO: (all user have access on the SSO...).
this.logger.debug("Request list of user for an applciation: {}", applicationId);
logger.debug("Request list of user for an applciation: {}", applicationId);
return getListOfUsers(applicationId); return getListOfUsers(applicationId);
} }
//////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////
// //
// Generic /application/* // Generic /application/*
// //
//////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////
@GET
@GET @Path("small")
@Path("small") @RolesAllowed(value = { "USER", "ADMIN" })
@RolesAllowed(value= {"USER", "ADMIN"}) public List<ApplicationSmall> getApplicationsSmall(@Context final SecurityContext sc) throws Exception {
public List<ApplicationSmall> getApplicationsSmall(@Context SecurityContext sc) throws Exception { final GenericContext gc = (GenericContext) sc.getUserPrincipal();
GenericContext gc = (GenericContext) sc.getUserPrincipal(); this.logger.debug("getApplications");
logger.debug("getApplications"); final List<Application> tmp = SqlWrapper.gets(Application.class, false);
List<Application> tmp = SqlWrapper.gets(Application.class, false); final List<Long> regular = getUserListOfApplication(gc.userByToken.id);
List<Long> regular = this.getUserListOfApplication(gc.userByToken.id); final List<ApplicationSmall> out = new ArrayList<>();
List<ApplicationSmall> out = new ArrayList<>(); for (final Application app : tmp) {
for (Application app : tmp) { if (regular.indexOf(app.id) != -1) {
if (regular.indexOf(app.id) != -1) { out.add(new ApplicationSmall(app.name, app.description, app.redirect));
out.add(new ApplicationSmall(app.name, app.description, app.redirect)); }
} }
}
return out; return out;
} }
public record AddUserData(long userId) {}; public record AddUserData(
// TODO : review the function to correct admin only access... long userId) {};
@POST
@Path("{id}/users") // TODO : review the function to correct admin only access...
@RolesAllowed(value= {"ADMIN"}) @POST
public boolean addUser(@PathParam("id") Long applicationId, AddUserData data) throws Exception { @Path("{id}/users")
logger.debug("getApplications"); @RolesAllowed(value = { "ADMIN" })
SqlWrapper.addLink(UserAuth.class, data.userId, "application", applicationId); 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; return true;
} }
// TODO : review the function to correct admin only access... // TODO : review the function to correct admin only access...
@DELETE @DELETE
@Path("{id}/users") @Path("{id}/users")
@RolesAllowed(value= {"ADMIN"}) @RolesAllowed(value = { "ADMIN" })
public boolean rmUser(@PathParam("id") Long applicationId, AddUserData data) throws Exception { public boolean rmUser(@PathParam("id") final Long applicationId, final AddUserData data) throws Exception {
logger.debug("getApplications"); this.logger.debug("getApplications");
SqlWrapper.removeLink(UserAuth.class, data.userId, "application", applicationId); AddOnSQLTableExternalLink.removeLink(UserAuth.class, data.userId, "application", applicationId);
return true; return true;
} }
// TODO : review the function to correct admin only access... // TODO : review the function to correct admin only access...
@GET @GET
@Path("{id}/rights") @Path("{id}/rights")
@RolesAllowed(value= {"ADMIN"}) @RolesAllowed(value = { "ADMIN" })
public List<RightDescription> getRightsDescription(@PathParam("id") Long applicationId) throws Exception { public List<RightDescription> getRightsDescription(@PathParam("id") final Long applicationId) throws Exception {
logger.debug("getApplications rights"); this.logger.debug("getApplications rights");
return SqlWrapper.getsWhere(RightDescription.class, List.of( return SqlWrapper.getsWhere(RightDescription.class, new QuerryCondition("applicationId", "=", applicationId), false);
new WhereCondition("applicationId", "=", applicationId)),
false);
} }
@GET @GET
@Path("get_token") @Path("get_token")
@RolesAllowed(value= {"USER", "ADMIN"}) @RolesAllowed(value = { "USER", "ADMIN" })
public Response getClientToken(@Context SecurityContext sc, @QueryParam("application") String application) throws Exception { public Response getClientToken(@Context final SecurityContext sc, @QueryParam("application") final String application) throws Exception {
GenericContext gc = (GenericContext) sc.getUserPrincipal(); final GenericContext gc = (GenericContext) sc.getUserPrincipal();
logger.info("get application TOKEN application name='{}'", application); this.logger.info("get application TOKEN application name='{}'", application);
logger.debug("== USER ? {}", gc.userByToken.name); this.logger.debug("== USER ? {}", gc.userByToken.name);
if (application == null) { if (application == null) {
String result = "Input error missing parameter: 'application'"; final String result = "Input error missing parameter: 'application'";
logger.debug(" result: {}", result); this.logger.debug(" result: {}", result);
return Response.status(406).entity(result).build(); return Response.status(406).entity(result).build();
} }
String applicationName = application; String applicationName = application;
boolean isDev = false; boolean isDev = false;
if (applicationName.endsWith("-dev")) { if (applicationName.endsWith("-dev")) {
applicationName = applicationName.substring(0, applicationName.length()-4); applicationName = applicationName.substring(0, applicationName.length() - 4);
isDev = true; isDev = true;
} }
logger.debug("Search for '{}' base of '{}'", applicationName, application); this.logger.debug("Search for '{}' base of '{}'", applicationName, application);
Application appl = null; Application appl = null;
try { try {
appl = SqlWrapper.getWhere(Application.class, List.of(new WhereCondition("name", "=", applicationName)), false); appl = SqlWrapper.getWhere(Application.class, new QuerryCondition("name", "=", applicationName), false);
} catch (Exception e) { } catch (final Exception e) {
// TODO Auto-generated catch block // TODO Auto-generated catch block
e.printStackTrace(); e.printStackTrace();
String result = "SERVER Internal error"; final String result = "SERVER Internal error";
logger.debug(" result: {}", result); this.logger.debug(" result: {}", result);
return Response.status(500).entity(result).build(); return Response.status(500).entity(result).build();
} }
if (appl == null) { if (appl == null) {
String result = "Authentiocate-wrong email/login '" + applicationName + "')"; final String result = "Authentiocate-wrong email/login '" + applicationName + "')";
logger.error(" result: {}", result); this.logger.error(" result: {}", result);
return Response.status(401).entity(result).build(); return Response.status(401).entity(result).build();
} }
UserLinkApplication links = null; UserLinkApplication links = null;
try { try {
links = SqlWrapper.getWhere(UserLinkApplication.class, links = SqlWrapper.getWhere(UserLinkApplication.class,
List.of( new QuerryAnd(new QuerryCondition("user_id", "=", gc.userByToken.id), new QuerryCondition("deleted", "=", 0), new QuerryCondition("application_id", "=", appl.id)), false);
new WhereCondition("user_id", "=", gc.userByToken.id), } catch (final Exception e) {
new WhereCondition("deleted", "=", 0),
new WhereCondition("application_id", "=", appl.id)
), false);
} catch (Exception e) {
// TODO Auto-generated catch block // TODO Auto-generated catch block
e.printStackTrace(); e.printStackTrace();
String result = "SERVER Internal error"; final String result = "SERVER Internal error";
logger.error(" result: {}", result); this.logger.error(" result: {}", result);
return Response.status(500).entity(result).build(); return Response.status(500).entity(result).build();
} }
if (links == null) { if (links == null) {
String result = "Authenticate impossible ==> application not accessible '" + applicationName + "'"; final String result = "Authenticate impossible ==> application not accessible '" + applicationName + "'";
logger.error(" result: {}", result); this.logger.error(" result: {}", result);
return Response.status(401).entity(result).build(); return Response.status(401).entity(result).build();
} }
// Get the USER Right // 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 (!applicationRight.containsKey("USER")) {
// If the USER is not override, the system add by default USER // If the USER is not override, the system add by default USER
applicationRight.put("USER", true); 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 // 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); 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); //logger.debug(" ==> generate token: {}", ret);
String returnAdress = appl.redirect; String returnAdress = appl.redirect;
if (isDev) { if (isDev) {
@ -294,44 +293,44 @@ public class ApplicationResource {
} }
return Response.status(201).entity("{ \"url\":\"" + returnAdress + "\", \"jwt\":\"" + ret + "\"}").build(); return Response.status(201).entity("{ \"url\":\"" + returnAdress + "\", \"jwt\":\"" + ret + "\"}").build();
} }
@GET @GET
@Path("return") @Path("return")
@RolesAllowed(value= {"USER", "ADMIN"}) @RolesAllowed(value = { "USER", "ADMIN" })
public Response logOut(@Context SecurityContext sc, @QueryParam("application") String application) { public Response logOut(@Context final SecurityContext sc, @QueryParam("application") final String application) {
logger.debug("====================================="); this.logger.debug("=====================================");
logger.debug("Get log_out()"); this.logger.debug("Get log_out()");
logger.debug("====================================="); this.logger.debug("=====================================");
GenericContext gc = (GenericContext) sc.getUserPrincipal(); final GenericContext gc = (GenericContext) sc.getUserPrincipal();
logger.debug("== USER ? {}", gc.userByToken); this.logger.debug("== USER ? {}", gc.userByToken);
if (application == null) { if (application == null) {
String result = "Input error missing parameter: 'application'"; final String result = "Input error missing parameter: 'application'";
logger.error(" result: {}", result); this.logger.error(" result: {}", result);
return Response.status(406).entity(result).build(); return Response.status(406).entity(result).build();
} }
String applicationName = application; String applicationName = application;
boolean isDev = false; boolean isDev = false;
if (applicationName.endsWith("-dev")) { if (applicationName.endsWith("-dev")) {
applicationName = applicationName.substring(0, applicationName.length()-4); applicationName = applicationName.substring(0, applicationName.length() - 4);
isDev = true; isDev = true;
} }
logger.debug("Search for '{}' base of '{}'", applicationName, application); this.logger.debug("Search for '{}' base of '{}'", applicationName, application);
Application appl = null; Application appl = null;
try { try {
appl = SqlWrapper.getWhere(Application.class, "name", "=", applicationName); appl = SqlWrapper.getWhere(Application.class, new QuerryCondition("name", "=", applicationName));
} catch (Exception e) { } catch (final Exception e) {
// TODO Auto-generated catch block // TODO Auto-generated catch block
e.printStackTrace(); e.printStackTrace();
String result = "SERVER Internal error"; final String result = "SERVER Internal error";
logger.error(" result: {}", result); this.logger.error(" result: {}", result);
return Response.status(500).entity(result).build(); return Response.status(500).entity(result).build();
} }
if (appl == null) { if (appl == null) {
String result = "Authentiocate-wrong email/login '" + applicationName + "')"; final String result = "Authentiocate-wrong email/login '" + applicationName + "')";
logger.error(" result: {}", result); this.logger.error(" result: {}", result);
return Response.status(404).entity(result).build(); return Response.status(404).entity(result).build();
} }
String returnAdress = appl.redirect; String returnAdress = appl.redirect;
@ -341,37 +340,4 @@ public class ApplicationResource {
return Response.status(201).entity("{ \"url\":\"" + returnAdress + "\"}").build(); return Response.status(201).entity("{ \"url\":\"" + returnAdress + "\"}").build();
} }
} }

View File

@ -1,178 +1,137 @@
package org.kar.karso.api; 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.sql.Timestamp;
import java.time.OffsetDateTime; import java.time.OffsetDateTime;
import java.time.ZoneOffset; import java.time.ZoneOffset;
import java.util.List; 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.Context;
import jakarta.ws.rs.core.MediaType; import jakarta.ws.rs.core.MediaType;
import jakarta.ws.rs.core.Response; import jakarta.ws.rs.core.Response;
import jakarta.ws.rs.core.SecurityContext; import jakarta.ws.rs.core.SecurityContext;
@Path("/application_token") @Path("/application_token")
@Produces( MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON)
public class ApplicationTokenResource { public class ApplicationTokenResource {
final Logger logger = LoggerFactory.getLogger(ApplicationTokenResource.class); final Logger logger = LoggerFactory.getLogger(ApplicationTokenResource.class);
public ApplicationTokenResource() { public ApplicationTokenResource() {}
}
//////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////
// //
// Generic /application_token/{applicationId} // Generic /application_token/{applicationId}
// //
//////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////
@GET @GET
@Path("{applicationId}") @Path("{applicationId}")
@RolesAllowed(value= {"ADMIN"}) @RolesAllowed(value = { "ADMIN" })
public List<ApplicationToken> gets(@Context SecurityContext sc, @PathParam("applicationId") Long applicationId) throws Exception { public List<ApplicationToken> gets(@Context final SecurityContext sc, @PathParam("applicationId") final Long applicationId) throws Exception {
List<ApplicationToken> values = SqlWrapper.getsWhere(ApplicationToken.class, final List<ApplicationToken> values = SqlWrapper.getsWhere(ApplicationToken.class, new QuerryCondition("parentId", "=", applicationId), false);
List.of( // clean all tokens this is a secret:
new WhereCondition("parentId", "=", applicationId) for (final ApplicationToken elem : values) {
), elem.token = null;
false); }
// clean all tokens this is a secret: return values;
for (ApplicationToken elem : values) {
elem.token = null;
}
return values;
} }
@DELETE @DELETE
@Path("{applicationId}/{tokenId}") @Path("{applicationId}/{tokenId}")
@RolesAllowed(value= {"ADMIN"}) @RolesAllowed(value = { "ADMIN" })
public Response delete( public Response delete(@Context final SecurityContext sc, @PathParam("applicationId") final Long applicationId, @PathParam("tokenId") final Integer tokenId) throws Exception {
@Context SecurityContext sc, final int nbRemoved = SqlWrapper.setDeleteWhere(ApplicationToken.class, new QuerryAnd(new QuerryCondition("parentId", "=", applicationId), new QuerryCondition("id", "=", tokenId)));
@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)
)
);
if (nbRemoved == 0) { if (nbRemoved == 0) {
return Response.notModified("{}").build(); return Response.notModified("{}").build();
} }
if (nbRemoved == 0) { if (nbRemoved == 0) {
return Response.serverError().build(); 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 private String multipartCorrection(final String data) {
token = SqlWrapper.insert(token); if (data == null) {
// here we return the token to permit to the user to see it to set it in the application. return null;
return token; }
} if (data.isEmpty()) {
/* return null;
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] 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]
*/
} }

View File

@ -1,66 +1,60 @@
package org.kar.karso.api; 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.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; 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") @Path("/right")
@Produces({MediaType.APPLICATION_JSON}) @Produces({ MediaType.APPLICATION_JSON })
public class RightResource { public class RightResource {
final static Logger logger = LoggerFactory.getLogger(RightResource.class); final static Logger logger = LoggerFactory.getLogger(RightResource.class);
public static List<RightDescription> getApplicationRightDecription(long applicationId) throws Exception { public static List<RightDescription> getApplicationRightDecription(final long applicationId) throws Exception {
return SqlWrapper.getsWhere(RightDescription.class, return SqlWrapper.getsWhere(RightDescription.class, new QuerryAnd(new QuerryCondition("applicationId", "=", applicationId), new QuerryCondition("deleted", "=", 0)));
List.of(
new WhereCondition("applicationId", "=", applicationId),
new WhereCondition("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, return SqlWrapper.getsWhere(Right.class,
List.of( new QuerryAnd(new QuerryCondition("applicationId", "=", applicationId), new QuerryCondition("userId", "=", userId), new QuerryCondition("deleted", "=", 0)));
new WhereCondition("applicationId", "=", applicationId),
new WhereCondition("userId", "=", userId),
new WhereCondition("deleted", "=", 0)
));
} }
public static Map<String, Object> getUserRight(long userId, long applicationId) throws Exception { public static Map<String, Object> getUserRight(final long userId, final long applicationId) throws Exception {
Map<String, Object> out = new HashMap<>(); final Map<String, Object> out = new HashMap<>();
List<RightDescription> rightsDescriptions = getApplicationRightDecription(applicationId); final List<RightDescription> rightsDescriptions = getApplicationRightDecription(applicationId);
logger.debug("Get some descriptions: {} applicationId={}", rightsDescriptions.size(), applicationId); logger.debug("Get some descriptions: {} applicationId={}", rightsDescriptions.size(), applicationId);
if (rightsDescriptions != null && rightsDescriptions.size() != 0) { 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); logger.debug("Get some user right: {}userID={}", rights.size(), userId);
for (RightDescription description : rightsDescriptions) { for (final RightDescription description : rightsDescriptions) {
if (description == null) { if (description == null) {
// TODO: this is a really strange case to manage later... // TODO: this is a really strange case to manage later...
continue; continue;
} }
Right right = rights.stream() final Right right = rights.stream().filter(elem -> elem.rightDescriptionId == description.id).findAny().orElse(null);
.filter(elem -> elem.rightDescriptionId == description.id)
.findAny()
.orElse(null);
if (right != null) { if (right != null) {
out.put(description.key, Transform.convertToType(description.type, right.value)); 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)); out.put(description.key, Transform.convertToType(description.type, description.defaultValue));
} else { } else {
out.put(description.key, null); out.put(description.key, null);
@ -71,39 +65,37 @@ public class RightResource {
logger.debug("Does not manage Karso right..."); logger.debug("Does not manage Karso right...");
} }
return out; 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); logger.debug("Get some descriptions: {} applicationId={}", rightsDescriptions.size(), applicationId);
if (rightsDescriptions == null || rightsDescriptions.size() == 0) { if (rightsDescriptions == null || rightsDescriptions.size() == 0) {
throw new IllegalArgumentException("Request change right on an application that does not manage any right"); 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); logger.debug("Get some user right: {}userID={}", rights.size(), userId);
for (RightDescription description : rightsDescriptions) { for (final RightDescription description : rightsDescriptions) {
if (description == null) { if (description == null) {
// TODO: this is a really strange case to manage later... // TODO: this is a really strange case to manage later...
continue; continue;
} }
Object newValue = delta.get(description.key); final Object newValue = delta.get(description.key);
if (newValue == null) { if (newValue == null) {
//No need to update or create... //No need to update or create...
continue; continue;
} }
String convertedValue = Transform.convertToStringCheck(description.type, newValue); final String convertedValue = Transform.convertToStringCheck(description.type, newValue);
if (convertedValue == null) { if (convertedValue == null) {
throw new IllegalArgumentException("Uncompatible value:'" + description.type + "'"); throw new IllegalArgumentException("Uncompatible value:'" + description.type + "'");
} }
Right right = rights.stream() Right right = rights.stream().filter(elem -> elem.rightDescriptionId == description.id).findAny().orElse(null);
.filter(elem -> elem.rightDescriptionId == description.id)
.findAny()
.orElse(null);
if (right != null) { if (right != null) {
// The value exist, we need to update it // The value exist, we need to update it
logger.debug("Request update a knonwn parameter: {} with {}", description.key, newValue); logger.debug("Request update a knonwn parameter: {} with {}", description.key, newValue);
right.value = convertedValue; right.value = convertedValue;
SqlWrapper.update(right, right.id, List.of("value")); SqlWrapper.update(right, right.id, List.of("value"));
} else { } else {
// we need to create it // we need to create it
logger.debug("Request create parameter: {} with {}", description.key, newValue); logger.debug("Request create parameter: {} with {}", description.key, newValue);
right = new Right(); right = new Right();
@ -114,45 +106,43 @@ public class RightResource {
SqlWrapper.insert(right); SqlWrapper.insert(right);
} }
} }
} }
@GET
@GET @RolesAllowed("ADMIN")
@RolesAllowed("ADMIN") public List<Right> get() throws Exception {
public List<Right> get() throws Exception { return SqlWrapper.gets(Right.class, false);
return SqlWrapper.gets(Right.class, false); }
}
@POST
@POST @RolesAllowed("ADMIN")
@RolesAllowed("ADMIN") @Consumes(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON) public Right post(final String jsonRequest) throws Exception {
public Right post(String jsonRequest) throws Exception { return SqlWrapper.insertWithJson(Right.class, jsonRequest);
return SqlWrapper.insertWithJson(Right.class, jsonRequest); }
}
@GET
@GET @Path("{id}")
@Path("{id}") @RolesAllowed("ADMIN")
@RolesAllowed("ADMIN") public static Right getWithId(@PathParam("id") final Long id) throws Exception {
public static Right getWithId(@PathParam("id") Long id) throws Exception { return SqlWrapper.get(Right.class, id);
return SqlWrapper.get(Right.class, id); }
}
@PUT
@PUT @Path("{id}")
@Path("{id}") @RolesAllowed("ADMIN")
@RolesAllowed("ADMIN") @Consumes(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON) public Right put(@PathParam("id") final Long id, final String jsonRequest) throws Exception {
public Right put(@PathParam("id") Long id, String jsonRequest) throws Exception { SqlWrapper.update(Right.class, id, jsonRequest);
SqlWrapper.update(Right.class, id, jsonRequest); return SqlWrapper.get(Right.class, id);
return SqlWrapper.get(Right.class, id); }
}
@DELETE
@DELETE @Path("{id}")
@Path("{id}") @RolesAllowed("ADMIN")
@RolesAllowed("ADMIN") public Response delete(@PathParam("id") final Long id) throws Exception {
public Response delete(@PathParam("id") Long id) throws Exception { SqlWrapper.setDelete(Right.class, id);
SqlWrapper.setDelete(Right.class, id); return Response.ok().build();
return Response.ok().build(); }
}
} }

View File

@ -1,101 +1,106 @@
package org.kar.karso.api; package org.kar.karso.api;
import org.kar.archidata.SqlWrapper; import java.util.List;
import org.kar.karso.model.*;
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.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.ObjectMapper;
import org.kar.archidata.annotation.security.PermitAll; import jakarta.ws.rs.Consumes;
import org.kar.archidata.annotation.security.RolesAllowed; import jakarta.ws.rs.GET;
import org.kar.archidata.exception.NotFoundException; import jakarta.ws.rs.PUT;
import jakarta.ws.rs.Path;
import java.util.List; import jakarta.ws.rs.PathParam;
import jakarta.ws.rs.Produces;
import jakarta.ws.rs.*;
import jakarta.ws.rs.core.Context; import jakarta.ws.rs.core.Context;
import jakarta.ws.rs.core.MediaType; import jakarta.ws.rs.core.MediaType;
import jakarta.ws.rs.core.Response; import jakarta.ws.rs.core.Response;
import jakarta.ws.rs.core.SecurityContext; import jakarta.ws.rs.core.SecurityContext;
@Path("/system_config") @Path("/system_config")
@Produces( MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON)
public class SystemConfigResource { public class SystemConfigResource {
final Logger logger = LoggerFactory.getLogger(SystemConfigResource.class); final Logger logger = LoggerFactory.getLogger(SystemConfigResource.class);
public static class GetSignUpAvaillable { public static class GetSignUpAvaillable {
public boolean signup; public boolean signup;
public GetSignUpAvaillable(boolean availlable) { public GetSignUpAvaillable(final boolean availlable) {
this.signup = availlable; this.signup = availlable;
} }
public GetSignUpAvaillable() { public GetSignUpAvaillable() {
signup = false; this.signup = false;
} }
} }
public SystemConfigResource() { public SystemConfigResource() {}
}
@GET @GET
@Path("is_sign_up_availlable") @Path("is_sign_up_availlable")
@PermitAll @PermitAll
public GetSignUpAvaillable isSignUpAvaillable() throws Exception { public GetSignUpAvaillable isSignUpAvaillable() throws Exception {
Settings set = SqlWrapper.getWhere(Settings.class, "key", "=", "SIGN_UP_ENABLE", false); final Settings set = SqlWrapper.getWhere(Settings.class, new QuerryCondition("key", "=", "SIGN_UP_ENABLE"), false);
if (set == null) { if (set == null) {
throw new NotFoundException("Value does not exist"); throw new NotFoundException("Value does not exist");
} }
boolean availlable = "true".equalsIgnoreCase(set.value); final boolean availlable = "true".equalsIgnoreCase(set.value);
GetSignUpAvaillable tmp = new GetSignUpAvaillable(availlable); final GetSignUpAvaillable tmp = new GetSignUpAvaillable(availlable);
logger.debug("mlkmlk {}", tmp.signup); this.logger.debug("mlkmlk {}", tmp.signup);
return tmp; return tmp;
} }
@GET @GET
@Path("key/{key}") @Path("key/{key}")
@RolesAllowed(value= {"USER", "ADMIN"}) @RolesAllowed(value = { "USER", "ADMIN" })
public Response getKey(@Context SecurityContext sc, @PathParam("key") String key) throws Exception { public Response getKey(@Context final SecurityContext sc, @PathParam("key") final String key) throws Exception {
Settings set = SqlWrapper.getWhere(Settings.class, "key", "=", key, false); final Settings set = SqlWrapper.getWhere(Settings.class, new QuerryCondition("key", "=", key), false);
if (set == null) { if (set == null) {
throw new NotFoundException("Value does not exist"); throw new NotFoundException("Value does not exist");
} }
if (set.type.equals("BOOLEAN")) { if (set.type.equals("BOOLEAN")) {
boolean availlable = "true".equalsIgnoreCase(set.value); final boolean availlable = "true".equalsIgnoreCase(set.value);
return Response.status(200).entity("{ \"value\":" + availlable + "}").build(); return Response.status(200).entity("{ \"value\":" + availlable + "}").build();
} }
if (set.type.equals("NUMBER")) { if (set.type.equals("NUMBER")) {
double value = Double.parseDouble(set.value); final double value = Double.parseDouble(set.value);
return Response.status(200).entity("{ \"value\":" + value + "}").build(); return Response.status(200).entity("{ \"value\":" + value + "}").build();
} }
return Response.status(200).entity("{ \"value\":\"" + set.value + "\"}").build(); return Response.status(200).entity("{ \"value\":\"" + set.value + "\"}").build();
} }
@PUT
@Path("key/{key}") @PUT
@RolesAllowed(value= {"ADMIN"}) @Path("key/{key}")
@Consumes(MediaType.APPLICATION_JSON) @RolesAllowed(value = { "ADMIN" })
public Response setKey(@Context SecurityContext sc, @PathParam("key") String key, String jsonRequest) throws Exception { @Consumes(MediaType.APPLICATION_JSON)
Settings res = null; public Response setKey(@Context final SecurityContext sc, @PathParam("key") final String key, final String jsonRequest) throws Exception {
try { Settings res = null;
res = SqlWrapper.getWhere(Settings.class, "key", "=", key, false); try {
} catch (Exception e) { res = SqlWrapper.getWhere(Settings.class, new QuerryCondition("key", "=", key), false);
} catch (final Exception e) {
// TODO Auto-generated catch block // TODO Auto-generated catch block
e.printStackTrace(); e.printStackTrace();
String result = "Can not find the Key"; final String result = "Can not find the Key";
return Response.status(404).entity(result).build(); return Response.status(404).entity(result).build();
} }
ObjectMapper mapper = new ObjectMapper(); final ObjectMapper mapper = new ObjectMapper();
// Read the tree to filter injection of data: // Read the tree to filter injection of data:
JsonNode root = mapper.readTree(jsonRequest); final JsonNode root = mapper.readTree(jsonRequest);
JsonNode value = root.findPath("value"); final JsonNode value = root.findPath("value");
res.value = value.asText(); res.value = value.asText();
logger.debug("Update value : {}", res.value); this.logger.debug("Update value : {}", res.value);
SqlWrapper.update(res, res.id, List.of("value")); SqlWrapper.update(res, res.id, List.of("value"));
return Response.status(201).entity("{ \"value\":\"" + res.value + "\"}").build(); return Response.status(201).entity("{ \"value\":\"" + res.value + "\"}").build();
} }
} }

View File

@ -1,41 +1,53 @@
package org.kar.karso.api; package org.kar.karso.api;
import org.kar.archidata.model.GetToken; import java.nio.charset.StandardCharsets;
import org.kar.archidata.SqlWrapper; import java.security.MessageDigest;
import org.kar.archidata.WhereCondition; 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.PermitAll;
import org.kar.archidata.annotation.security.RolesAllowed; import org.kar.archidata.annotation.security.RolesAllowed;
import org.kar.archidata.exception.FailException; import org.kar.archidata.exception.FailException;
import org.kar.archidata.exception.InputException; import org.kar.archidata.exception.InputException;
import org.kar.archidata.exception.SystemException; import org.kar.archidata.exception.SystemException;
import org.kar.archidata.filter.GenericContext; 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.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.kar.karso.util.ConfigVariable;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonInclude;
import org.kar.archidata.util.JWTWrapper; import jakarta.ws.rs.Consumes;
import jakarta.ws.rs.*; 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.Context;
import jakarta.ws.rs.core.MediaType; import jakarta.ws.rs.core.MediaType;
import jakarta.ws.rs.core.Response; import jakarta.ws.rs.core.Response;
import jakarta.ws.rs.core.SecurityContext; 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") @Path("/users")
@Produces( MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON)
public class UserResource { public class UserResource {
final Logger logger = LoggerFactory.getLogger(UserResource.class); final Logger logger = LoggerFactory.getLogger(UserResource.class);
@ -43,98 +55,93 @@ public class UserResource {
public class UserOut { public class UserOut {
public long id; public long id;
public String login; public String login;
public UserOut(long id, String login) {
super(); public UserOut(final long id, final String login) {
this.id = id; this.id = id;
this.login = login; this.login = login;
} }
} }
public UserResource() { public UserResource() {}
}
@GET @GET
@RolesAllowed("ADMIN") @RolesAllowed("ADMIN")
public List<UserAuthGet> getUsers() throws Exception { public List<UserAuthGet> getUsers() throws Exception {
return SqlWrapper.gets(UserAuthGet.class, false); return SqlWrapper.gets(UserAuthGet.class, false);
} }
@GET @GET
@Path("{id}") @Path("{id}")
@RolesAllowed("ADMIN") @RolesAllowed("ADMIN")
public UserAuthGet getUser(@Context SecurityContext sc, @PathParam("id") long userId) throws Exception { public UserAuthGet getUser(@Context final SecurityContext sc, @PathParam("id") final long userId) throws Exception {
//GenericContext gc = (GenericContext) sc.getUserPrincipal(); //GenericContext gc = (GenericContext) sc.getUserPrincipal();
return SqlWrapper.get(UserAuthGet.class, userId); return SqlWrapper.get(UserAuthGet.class, userId);
} }
@POST @POST
@Path("{userId}/application/{applicationId}/link") @Path("{userId}/application/{applicationId}/link")
@RolesAllowed("ADMIN") @RolesAllowed("ADMIN")
public UserAuth linkApplication(@Context SecurityContext sc, public UserAuth linkApplication(@Context final SecurityContext sc, @PathParam("userId") final long userId, @PathParam("applicationId") final long applicationId, final boolean data)
@PathParam("userId") long userId, throws Exception {
@PathParam("applicationId") long applicationId, this.logger.debug("Find typeNode");
boolean data) throws Exception { if (data) {
logger.debug("Find typeNode"); AddOnSQLTableExternalLink.addLink(UserAuth.class, userId, "application", applicationId);
if (data == true) { } else {
SqlWrapper.addLink(UserAuth.class, userId, "application", applicationId); AddOnSQLTableExternalLink.removeLink(UserAuth.class, userId, "application", applicationId);
} else { }
SqlWrapper.removeLink(UserAuth.class, userId, "application", applicationId); return SqlWrapper.get(UserAuth.class, userId);
}
return SqlWrapper.get(UserAuth.class, userId);
} }
@GET @GET
@Path("{userId}/application/{applicationId}/rights") @Path("{userId}/application/{applicationId}/rights")
@RolesAllowed("ADMIN") @RolesAllowed("ADMIN")
public Map<String, Object> getApplicationRight(@Context SecurityContext sc, public Map<String, Object> getApplicationRight(@Context final SecurityContext sc, @PathParam("userId") final long userId, @PathParam("applicationId") final long applicationId) throws Exception {
@PathParam("userId") long userId,
@PathParam("applicationId") long applicationId) throws Exception {
return RightResource.getUserRight(userId, applicationId); return RightResource.getUserRight(userId, applicationId);
} }
@PUT @PUT
@Path("{userId}/application/{applicationId}/rights") @Path("{userId}/application/{applicationId}/rights")
@RolesAllowed("ADMIN") @RolesAllowed("ADMIN")
public Map<String, Object> patchApplicationRight(@Context SecurityContext sc, public Map<String, Object> patchApplicationRight(@Context final SecurityContext sc, @PathParam("userId") final long userId, @PathParam("applicationId") final long applicationId,
@PathParam("userId") long userId, final Map<String, Object> data) throws Exception {
@PathParam("applicationId") long applicationId, Map<String, Object> data) throws Exception { this.logger.info("get data from FRONT: {}", data);
logger.info("get data from FRONT: {}", data);
RightResource.updateUserRight(userId, applicationId, data); RightResource.updateUserRight(userId, applicationId, data);
return RightResource.getUserRight(userId, applicationId); return RightResource.getUserRight(userId, applicationId);
} }
// TODO: check this it might be deprecated ... // TODO: check this it might be deprecated ...
@POST @POST
@Path("{id}/set_admin") @Path("{id}/set_admin")
@RolesAllowed("ADMIN") @RolesAllowed("ADMIN")
public Response setAdmin(@Context SecurityContext sc, @PathParam("id") long userId, boolean data) throws Exception { public Response setAdmin(@Context final SecurityContext sc, @PathParam("id") final long userId, final boolean data) throws Exception {
UserAuth user = new UserAuth(); final UserAuth user = new UserAuth();
user.admin = data; 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) { if (ret == 0) {
return Response.notModified("{}").build(); return Response.notModified("{}").build();
} }
return Response.ok("{}").build(); return Response.ok("{}").build();
} }
@POST @POST
@Path("{id}/set_blocked") @Path("{id}/set_blocked")
@RolesAllowed("ADMIN") @RolesAllowed("ADMIN")
public Response setBlocked(@Context SecurityContext sc, @PathParam("id") long userId, boolean data) throws Exception { public Response setBlocked(@Context final SecurityContext sc, @PathParam("id") final long userId, final boolean data) throws Exception {
UserAuth user = new UserAuth(); final UserAuth user = new UserAuth();
user.blocked = data; 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) { if (ret == 0) {
return Response.notModified("{}").build(); return Response.notModified("{}").build();
} }
return Response.ok("{}").build(); return Response.ok("{}").build();
} }
@POST @POST
@Path("create_new_user") @Path("create_new_user")
@RolesAllowed("ADMIN") @RolesAllowed("ADMIN")
public UserAuthGet createUser(UserCreate user) throws Exception { public UserAuthGet createUser(final UserCreate user) throws Exception {
logger.debug("create new User email={} login={}", user.email, user.login); this.logger.debug("create new User email={} login={}", user.email, user.login);
// verify login or email is correct: // verify login or email is correct:
if (user.login == null || user.login.length() < 6) { if (user.login == null || user.login.length() < 6) {
throw new InputException("login", "Authentiocate-method-error (login too small: '" + user.login + "')"); 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 + "')"); throw new InputException("email", "Authentiocate-method-error (email too small: '" + user.email + "')");
} }
// TODO: check email format // 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"); 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 // Check login does not exist
List<UserAuth> out = SqlWrapper.getsWhere(UserAuth.class, List.of( List<UserAuth> out = SqlWrapper.getsWhere(UserAuth.class, new QuerryCondition("login", "=", user.login), false);
new WhereCondition("login", "=", user.login)
), false);
if (out.size() >= 1) { if (out.size() >= 1) {
throw new FailException(Response.Status.BAD_REQUEST, "Login already used !!!"); throw new FailException(Response.Status.BAD_REQUEST, "Login already used !!!");
} }
// Check email does not exist // Check email does not exist
out = SqlWrapper.getsWhere(UserAuth.class, List.of( out = SqlWrapper.getsWhere(UserAuth.class, new QuerryCondition("email", "=", user.email), false);
new WhereCondition("email", "=", user.email)
), false);
if (out.size() >= 1) { if (out.size() >= 1) {
throw new FailException(Response.Status.BAD_REQUEST, "e-mail already used !!!"); throw new FailException(Response.Status.BAD_REQUEST, "e-mail already used !!!");
} }
// Add new user and return formated dat. // Add new user and return formated dat.
UserAuth newUser = new UserAuth(); final UserAuth newUser = new UserAuth();
newUser.admin = false; newUser.admin = false;
newUser.removed = false; newUser.removed = false;
newUser.blocked = false; newUser.blocked = false;
@ -177,70 +179,68 @@ public class UserResource {
newUser.password = user.password; newUser.password = user.password;
newUser.email = user.email; newUser.email = user.email;
newUser.lastConnection = Timestamp.valueOf(LocalDateTime.now()); newUser.lastConnection = Timestamp.valueOf(LocalDateTime.now());
UserAuth tmp = SqlWrapper.insert(newUser); final UserAuth tmp = SqlWrapper.insert(newUser);
logger.debug("create new user done with id=={}", tmp.id); this.logger.debug("create new user done with id=={}", tmp.id);
return SqlWrapper.get(UserAuthGet.class, tmp.id); return SqlWrapper.get(UserAuthGet.class, tmp.id);
} }
@GET @GET
@Path("me") @Path("me")
@RolesAllowed("USER") @RolesAllowed("USER")
public UserOut getMe(@Context SecurityContext sc) { public UserOut getMe(@Context final SecurityContext sc) {
logger.debug("getMe()"); this.logger.debug("getMe()");
GenericContext gc = (GenericContext) sc.getUserPrincipal(); final GenericContext gc = (GenericContext) sc.getUserPrincipal();
logger.debug("== USER ? {}", gc.userByToken); this.logger.debug("== USER ? {}", gc.userByToken);
return new UserOut(gc.userByToken.id, gc.userByToken.name); return new UserOut(gc.userByToken.id, gc.userByToken.name);
} }
@POST @POST
@Path("password") @Path("password")
@RolesAllowed("USER") @RolesAllowed("USER")
public Response changePassword(@Context SecurityContext sc, ChangePassword data) throws Exception { public Response changePassword(@Context final SecurityContext sc, final ChangePassword data) throws Exception {
logger.debug("ChangePassword()"); this.logger.debug("ChangePassword()");
GenericContext gc = (GenericContext) sc.getUserPrincipal(); final GenericContext gc = (GenericContext) sc.getUserPrincipal();
logger.debug("== USER ? {}", gc.userByToken); this.logger.debug("== USER ? {}", gc.userByToken);
if(data == null) { if (data == null) {
throw new InputException("data", "No data set..."); 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"); throw new InputException("newPassword", "null password, or wrong hash size");
} }
UserAuth user = checkAuthUser(data.method, data.login, data.time, data.password); final UserAuth user = checkAuthUser(data.method, data.login, data.time, data.password);
if (user == null) { if (user == null) {
throw new SystemException("Fail to retrieve the user... (impossible case)"); throw new SystemException("Fail to retrieve the user... (impossible case)");
} }
// Process the update: // Process the update:
user.password = data.newPassword; user.password = data.newPassword;
SqlWrapper.update(user, user.id, List.of("password")); SqlWrapper.update(user, user.id, List.of("password"));
return Response.status(Response.Status.OK).build(); return Response.status(Response.Status.OK).build();
} }
/* /*
@GET @GET
@Path("validipass") @Path("validipass")
@PermitAll @PermitAll
public Response validatePasswordFromEMail(@QueryParam("uuid") String uuid, @QueryParam("securityId") String securityId) { public Response validatePasswordFromEMail(@QueryParam("uuid") String uuid, @QueryParam("securityId") String securityId) {
// Validate new password if OK // Validate new password if OK
// clear the passwordChange, passwordValidation fields // clear the passwordChange, passwordValidation fields
// send an e-mail to confirm the new password has been set. // send an e-mail to confirm the new password has been set.
return Response.status(500).build(); return Response.status(500).build();
} }
*/ */
@GET @GET
@Path("/check_login") @Path("/check_login")
@PermitAll @PermitAll
public Response checkLogin(@QueryParam("login") String login) throws Exception { public Response checkLogin(@QueryParam("login") final String login) throws Exception {
logger.debug("checkLogin: '{}'", login ); this.logger.debug("checkLogin: '{}'", login);
List<UserAuth> out = SqlWrapper.getsWhere(UserAuth.class, List.of( final List<UserAuth> out = SqlWrapper.getsWhere(UserAuth.class, new QuerryCondition("login", "=", login), false);
new WhereCondition("login", "=", login)
), false);
if (out.size() >= 1) { if (out.size() >= 1) {
return Response.ok().build(); 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). // TODO: add an application TOKEN and permit only 50 requested (maybe add an option to disable it).
@GET @GET
@Path("/check_email") @Path("/check_email")
@PermitAll @PermitAll
public Response checkEmail(@QueryParam("email") String email) throws Exception { public Response checkEmail(@QueryParam("email") final String email) throws Exception {
logger.debug("checkEmail: {}", email ); this.logger.debug("checkEmail: {}", email);
List<UserAuth> out = SqlWrapper.getsWhere(UserAuth.class, List.of( final List<UserAuth> out = SqlWrapper.getsWhere(UserAuth.class, new QuerryCondition("email", "=", email), false);
new WhereCondition("email", "=", email)
), false);
if (out.size() >= 1) { if (out.size() >= 1) {
return Response.ok().build(); return Response.ok().build();
} }
throw new NotFoundException("emain does not exist: '" + email + "'"); throw new NotFoundException("emain does not exist: '" + email + "'");
} }
private UserAuth checkAuthUser(final String method, final String login, final String time, final String password) throws Exception {
private UserAuth checkAuthUser(String method, String login, String time, String password) throws Exception {
// check good version: // check good version:
if (!"v1".contentEquals(method)) { if (!"v1".contentEquals(method)) {
throw new InputException("method", "Authentiocate-method-error (wrong version: '" + method + "')"); throw new InputException("method", "Authentiocate-method-error (wrong version: '" + method + "')");
@ -272,29 +269,25 @@ public class UserResource {
if (login.length() < 6) { if (login.length() < 6) {
throw new InputException("login", "Authentiocate-method-error (email or login too small: '" + login + "')"); 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"); throw new InputException("password", "null password, or wrong hash size");
} }
// email or login? // email or login?
String query = "login"; String query = "login";
if (login.contains("@")) { if (login.contains("@")) {
query = "email"; query = "email";
} }
UserAuth user = SqlWrapper.getWhere(UserAuth.class, final UserAuth user = SqlWrapper.getWhere(UserAuth.class, new QuerryCondition(query, "=", login), false);
List.of(
new WhereCondition(query, "=", login)
),
false );
if (user == null) { 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: // 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)) { 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) { if (user.blocked || user.removed) {
throw new FailException(Response.Status.UNAUTHORIZED, "FAIL Authentiocate"); throw new FailException(Response.Status.UNAUTHORIZED, "FAIL Authentiocate");
} }
@ -303,31 +296,31 @@ public class UserResource {
@POST @POST
@Path("/get_token") @Path("/get_token")
@PermitAll @PermitAll
@Consumes(MediaType.APPLICATION_JSON) @Consumes(MediaType.APPLICATION_JSON)
public GetToken getToken(DataGetToken data) throws Exception { public GetToken getToken(final DataGetToken data) throws Exception {
logger.info("User Authenticate: {}", data.login()); this.logger.info("User Authenticate: {}", data.login());
UserAuth user = checkAuthUser(data.method(), data.login(), data.time(), data.password()); final UserAuth user = checkAuthUser(data.method(), data.login(), data.time(), data.password());
// at the point the user has been not deleted and not blocked. // at the point the user has been not deleted and not blocked.
// this authentication is valid only for Karso ==> not for the application // 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 // 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 (!ssoRight.containsKey("USER")) {
// If the USER is not override, the system add by default USER // If the USER is not override, the system add by default USER
ssoRight.put("USER", true); ssoRight.put("USER", true);
} }
logger.debug("Get new token with right: {}", ssoRight); this.logger.debug("Get new token with right: {}", ssoRight);
Map<String, Object> outRight = new HashMap<>(); final Map<String, Object> outRight = new HashMap<>();
String applicationName = "karso"; 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 // 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); outRight.put(applicationName, ssoRight);
// TODO: maybe correct this get of TTL... // 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: // Update last connection:
UserAuth newUser = new UserAuth(); final UserAuth newUser = new UserAuth();
newUser.lastConnection = Timestamp.valueOf(LocalDateTime.now()); newUser.lastConnection = Timestamp.valueOf(LocalDateTime.now());
SqlWrapper.update(newUser, user.id, List.of("lastConnection")); SqlWrapper.update(newUser, user.id, List.of("lastConnection"));
@ -335,55 +328,23 @@ public class UserResource {
return new GetToken(ret); return new GetToken(ret);
} }
public static String bytesToHex(byte[] bytes) { public static String bytesToHex(final byte[] bytes) {
StringBuilder sb = new StringBuilder(); final StringBuilder sb = new StringBuilder();
for (byte b : bytes) { for (final byte b : bytes) {
sb.append(String.format("%02x", b)); sb.append(String.format("%02x", b));
} }
return sb.toString(); return sb.toString();
} }
public String getSHA512(String passwordToHash){ public String getSHA512(final String passwordToHash) {
try { try {
MessageDigest md = MessageDigest.getInstance("SHA-512"); final MessageDigest md = MessageDigest.getInstance("SHA-512");
byte[] bytes = md.digest(passwordToHash.getBytes(StandardCharsets.UTF_8)); final byte[] bytes = md.digest(passwordToHash.getBytes(StandardCharsets.UTF_8));
return bytesToHex(bytes); return bytesToHex(bytes);
} catch (NoSuchAlgorithmException e) { } catch (final NoSuchAlgorithmException e) {
e.printStackTrace(); e.printStackTrace();
} }
return null; return null;
} }
} }

View File

@ -4,44 +4,42 @@ import java.sql.Timestamp;
import java.time.Instant; import java.time.Instant;
import org.kar.archidata.filter.AuthenticationFilter; 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.model.UserByToken;
import org.kar.archidata.sqlWrapper.SqlWrapper;
import org.kar.karso.model.ApplicationToken; import org.kar.karso.model.ApplicationToken;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import jakarta.annotation.Priority; import jakarta.annotation.Priority;
import jakarta.ws.rs.Priorities;
import jakarta.ws.rs.ext.Provider;
//@PreMatching //@PreMatching
@Provider @Provider
@Priority(Priorities.AUTHENTICATION) @Priority(Priorities.AUTHENTICATION)
public class KarsoAuthenticationFilter extends AuthenticationFilter { public class KarsoAuthenticationFilter extends AuthenticationFilter {
final Logger logger = LoggerFactory.getLogger(KarsoAuthenticationFilter.class); 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"); super("karso");
} }
@Override @Override
protected UserByToken validateToken(String authorization) throws Exception { protected UserByToken validateToken(final String authorization) throws Exception {
if (authorization == null || authorization.length() < 25) { if (authorization == null || authorization.length() < 25) {
System.out.println("Application authentication too short '" + authorization + "'"); System.out.println("Application authentication too short '" + authorization + "'");
return null; return null;
} }
String[] elems = authorization.split(":"); final String[] elems = authorization.split(":");
if (elems.length != 2) { if (elems.length != 2) {
System.out.println("Application authentication split error '" + authorization + "'"); System.out.println("Application authentication split error '" + authorization + "'");
return null; 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) { if (value == null) {
System.out.println("Application authentication can not find id '" + authorization + "'"); System.out.println("Application authentication can not find id '" + authorization + "'");
return null; return null;
@ -59,13 +57,13 @@ public class KarsoAuthenticationFilter extends AuthenticationFilter {
// ---------------------------------- // ----------------------------------
// -- All is good !!! // -- All is good !!!
// ---------------------------------- // ----------------------------------
// We are in transition phase the user element will be removed // We are in transition phase the user element will be removed
UserByToken userByToken = new UserByToken(); final UserByToken userByToken = new UserByToken();
userByToken.id = value.id; userByToken.id = value.id;
userByToken.name = value.name; userByToken.name = value.name;
userByToken.parentId = value.parentId; userByToken.parentId = value.parentId;
userByToken.type = UserByToken.TYPE_APPLICATION; userByToken.type = UserByToken.TYPE_APPLICATION;
userByToken.right.put("APPLICATION", true); userByToken.right.put("APPLICATION", true);
return userByToken; return userByToken;
} }
} }

View File

@ -9,14 +9,14 @@ import org.kar.karso.model.Settings;
import org.kar.karso.model.UserAuth; import org.kar.karso.model.UserAuth;
public class Initialization extends MigrationSqlStep { public class Initialization extends MigrationSqlStep {
public static final int KARSO_INITIALISATION_ID = 1; public static final int KARSO_INITIALISATION_ID = 1;
@Override @Override
public String getName() { public String getName() {
return "Initialization"; return "Initialization";
} }
public Initialization() throws Exception { public Initialization() throws Exception {
addClass(Settings.class); addClass(Settings.class);
addClass(UserAuth.class); addClass(UserAuth.class);
@ -24,7 +24,7 @@ public class Initialization extends MigrationSqlStep {
addClass(ApplicationToken.class); addClass(ApplicationToken.class);
addClass(RightDescription.class); addClass(RightDescription.class);
addClass(Right.class); addClass(Right.class);
addAction(""" addAction("""
INSERT INTO `application` (`id`, `name`, `description`, `redirect`, `redirectDev`, `notification`, `ttl`) VALUES INSERT INTO `application` (`id`, `name`, `description`, `redirect`, `redirectDev`, `notification`, `ttl`) VALUES
(1, 'karso', 'Root SSO interface', 'http://atria-soft/karso', '', '', 666); (1, 'karso', 'Root SSO interface', 'http://atria-soft/karso', '', '', 666);
@ -70,6 +70,7 @@ public class Initialization extends MigrationSqlStep {
addAction(""" addAction("""
ALTER TABLE `rightDescription` AUTO_INCREMENT = 1000; ALTER TABLE `rightDescription` AUTO_INCREMENT = 1000;
"""); """);
display();
} }
} }

View File

@ -13,52 +13,43 @@ CREATE TABLE `application` (
import org.kar.archidata.annotation.SQLComment; import org.kar.archidata.annotation.SQLComment;
import org.kar.archidata.annotation.SQLDefault; import org.kar.archidata.annotation.SQLDefault;
import org.kar.archidata.annotation.SQLIfNotExists; 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 org.kar.archidata.model.GenericTable;
import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonInclude;
@SQLTableName ("application") import jakarta.persistence.Column;
import jakarta.persistence.Table;
@Table(name = "application")
@SQLIfNotExists @SQLIfNotExists
@JsonInclude(JsonInclude.Include.NON_NULL) @JsonInclude(JsonInclude.Include.NON_NULL)
public class Application extends GenericTable{ public class Application extends GenericTable {
@SQLLimitSize(256) @Column(length = 256)
public String name; public String name;
@SQLLimitSize(2048) @Column(length = 2048)
public String description; public String description;
@SQLLimitSize(2048) @Column(length = 2048, nullable = false)
@SQLNotNull public String redirect;
public String redirect; @Column(length = 2048)
@SQLLimitSize(2048) @SQLDefault("'http://localhost:4200/sso/'")
@SQLDefault("'http://localhost:4200/sso/'") public String redirectDev;
public String redirectDev; @Column(length = 2048)
@SQLLimitSize(2048) @SQLDefault("'http://localhost:4200/sso/notification'")
@SQLDefault("'http://localhost:4200/sso/notification'") public String notification;
public String notification; @Column(nullable = false)
@SQLNotNull @SQLComment("Expiration time ")
@SQLComment("Expiration time ") @SQLDefault("666")
@SQLDefault("666") public Integer ttl;
public Integer ttl; @Column(nullable = false)
@SQLNotNull @SQLComment("Right is manage with Karso")
@SQLComment("Right is manage with Karso") @SQLDefault("0")
@SQLDefault("0") public Boolean manageRight;
public Boolean manageRight;
public Application() {}
public Application() {
} @Override
public String toString() {
return "Application{" + "id=" + this.id + ", description='" + this.description + '\'' + ", redirect='" + this.redirect + '\'' + ", redirectDev='" + this.redirectDev + '\'' + ", notification='"
@Override + this.notification + '\'' + ", ttl='" + this.ttl + '\'' + '}';
public String toString() { }
return "Application{" +
"id=" + id +
", description='" + description + '\'' +
", redirect='" + redirect + '\'' +
", redirectDev='" + redirectDev + '\'' +
", notification='" + notification + '\'' +
", ttl='" + ttl + '\'' +
'}';
}
} }

View File

@ -1,14 +1,15 @@
package org.kar.karso.model; package org.kar.karso.model;
import org.kar.archidata.annotation.SQLIfNotExists; import org.kar.archidata.annotation.SQLIfNotExists;
import org.kar.archidata.annotation.SQLTableName;
import org.kar.archidata.model.GenericToken; import org.kar.archidata.model.GenericToken;
import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonInclude;
@SQLTableName ("applicationToken") import jakarta.persistence.Table;
@Table(name = "applicationToken")
@SQLIfNotExists @SQLIfNotExists
@JsonInclude(JsonInclude.Include.NON_NULL) @JsonInclude(JsonInclude.Include.NON_NULL)
public class ApplicationToken extends GenericToken { public class ApplicationToken extends GenericToken {
} }

View File

@ -1,35 +1,33 @@
package org.kar.karso.model; package org.kar.karso.model;
import org.kar.archidata.annotation.SQLComment; import org.kar.archidata.annotation.SQLComment;
import org.kar.archidata.annotation.SQLForeignKey; import org.kar.archidata.annotation.SQLForeignKey;
import org.kar.archidata.annotation.SQLIfNotExists; 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 org.kar.archidata.model.GenericTable;
import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonInclude;
@SQLTableName ("right") import jakarta.persistence.Column;
import jakarta.persistence.Table;
@Table(name = "right")
@SQLIfNotExists @SQLIfNotExists
@JsonInclude(JsonInclude.Include.NON_NULL) @JsonInclude(JsonInclude.Include.NON_NULL)
public class Right extends GenericTable { public class Right extends GenericTable {
@SQLNotNull @Column(nullable = false)
@SQLComment("application-ID that have the reference of the right") @SQLComment("application-ID that have the reference of the right")
@SQLForeignKey("application") @SQLForeignKey("application")
public long applicationId; public long applicationId;
@SQLNotNull @Column(nullable = false)
@SQLComment("user-ID ") @SQLComment("user-ID ")
@SQLForeignKey("user") @SQLForeignKey("user")
public long userId; public long userId;
@SQLNotNull @Column(nullable = false)
@SQLComment("rightDescription-ID of the right description") @SQLComment("rightDescription-ID of the right description")
@SQLForeignKey("rightDescription") @SQLForeignKey("rightDescription")
public long rightDescriptionId; public long rightDescriptionId;
@SQLNotNull @Column(length = 1024, nullable = false)
@SQLLimitSize(1024) @SQLComment("Value of the right")
@SQLComment("Value of the right") public String value;
public String value;
} }

View File

@ -4,39 +4,35 @@ import org.kar.archidata.annotation.SQLComment;
import org.kar.archidata.annotation.SQLDefault; import org.kar.archidata.annotation.SQLDefault;
import org.kar.archidata.annotation.SQLForeignKey; import org.kar.archidata.annotation.SQLForeignKey;
import org.kar.archidata.annotation.SQLIfNotExists; 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 org.kar.archidata.model.GenericTable;
import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonInclude;
@SQLTableName ("rightDescription") import jakarta.persistence.Column;
import jakarta.persistence.Table;
@Table(name = "rightDescription")
@SQLIfNotExists @SQLIfNotExists
@JsonInclude(JsonInclude.Include.NON_NULL) @JsonInclude(JsonInclude.Include.NON_NULL)
public class RightDescription extends GenericTable { public class RightDescription extends GenericTable {
@SQLNotNull @Column(nullable = false)
@SQLComment("Application id that have the reference of the right") @SQLComment("Application id that have the reference of the right")
@SQLForeignKey("application") @SQLForeignKey("application")
public long applicationId; public long applicationId;
@SQLNotNull @Column(length = 64, nullable = false)
@SQLLimitSize(64) @SQLComment("Key of the property")
@SQLComment("Key of the property") public String key;
public String key; @Column(length = 1024, nullable = false)
@SQLNotNull @SQLComment("Title of the right")
@SQLLimitSize(1024) public String title;
@SQLComment("Title of the right") @Column(length = 1024, nullable = false)
public String title; @SQLComment("Description of the right")
@SQLNotNull public String description;
@SQLLimitSize(1024) @Column(length = 1024)
@SQLComment("Description of the right") @SQLComment("default value if Never set")
public String description; public String defaultValue;
@SQLLimitSize(1024) @Column(length = 16, nullable = false)
@SQLComment("default value if Never set") @SQLComment("Type of the property")
public String defaultValue; @SQLDefault("\"BOOLEAN\"")
@SQLNotNull public String type = "BOOLEAN"; // this is a place-holder (current type supported BOOLEAN)
@SQLLimitSize(16)
@SQLComment("Type of the property")
@SQLDefault("\"BOOLEAN\"")
public String type = "BOOLEAN"; // this is a place-holder (current type supported BOOLEAN)
} }

View File

@ -13,43 +13,37 @@ CREATE TABLE `application` (
import org.kar.archidata.annotation.SQLComment; import org.kar.archidata.annotation.SQLComment;
import org.kar.archidata.annotation.SQLDefault; import org.kar.archidata.annotation.SQLDefault;
import org.kar.archidata.annotation.SQLIfNotExists; 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 org.kar.archidata.model.GenericTable;
import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonInclude;
import jakarta.persistence.Column;
import jakarta.persistence.Table;
enum PropertyType { enum PropertyType {
STRING, STRING, NUMBER, BOOLEAN,
NUMBER,
BOOLEAN,
} }
@SQLTableName ("settings") @Table(name = "settings")
@SQLIfNotExists @SQLIfNotExists
@JsonInclude(JsonInclude.Include.NON_NULL) @JsonInclude(JsonInclude.Include.NON_NULL)
public class Settings extends GenericTable { public class Settings extends GenericTable {
@SQLLimitSize(512) @Column(length = 512, nullable = false)
@SQLNotNull public String key;
public String key; @SQLComment("Right for the specific element(ADMIN [rw] USER [rw] other [rw])")
@SQLComment("Right for the specific element(ADMIN [rw] USER [rw] other [rw])") @Column(length = 6, nullable = false)
@SQLNotNull @SQLDefault("\"rw----\"")
@SQLLimitSize(6) public String right;
@SQLDefault("\"rw----\"") @SQLComment("Type Of the data")
public String right; @Column(length = 10, nullable = false)
@SQLComment("Type Of the data") public String type;
@SQLNotNull @SQLComment("Value of the configuration")
//public PropertyType type; @Column(nullable = false)
@SQLLimitSize(10) public String value;
public String type;
@SQLComment("Value of the configuration")
@SQLNotNull
public String value;
@Override @Override
public String toString() { 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 + "]";
} }
} }

View File

@ -6,38 +6,36 @@ import java.util.List;
import org.kar.archidata.annotation.SQLComment; import org.kar.archidata.annotation.SQLComment;
import org.kar.archidata.annotation.SQLDefault; import org.kar.archidata.annotation.SQLDefault;
import org.kar.archidata.annotation.SQLIfNotExists; import org.kar.archidata.annotation.SQLIfNotExists;
import org.kar.archidata.annotation.SQLLimitSize; import org.kar.archidata.annotation.addOn.SQLTableExternalLink;
import org.kar.archidata.annotation.SQLNotNull;
import org.kar.archidata.annotation.SQLTableLinkGeneric;
import org.kar.archidata.annotation.SQLTableName;
import org.kar.archidata.model.User; import org.kar.archidata.model.User;
import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonInclude;
@SQLTableName ("user") import jakarta.persistence.Column;
import jakarta.persistence.Table;
@Table(name = "user")
@SQLIfNotExists @SQLIfNotExists
@JsonInclude(JsonInclude.Include.NON_NULL) @JsonInclude(JsonInclude.Include.NON_NULL)
public class UserAuth extends User { public class UserAuth extends User {
@SQLLimitSize(128) @Column(length = 128, nullable = false)
@SQLNotNull
public String password; 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 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 public String passwordValidation; //!< UniqueId to validate the new password
*/ */
@SQLLimitSize(512) @Column(length = 512, nullable = false)
@SQLNotNull
public String email; public String email;
public Timestamp emailValidate; // time of validation public Timestamp emailValidate; // time of validation
@SQLLimitSize(512) @Column(length = 512)
public String newEmail; public String newEmail;
@SQLDefault("'0'") @SQLDefault("'0'")
@SQLNotNull @Column(nullable = false)
public boolean avatar = false; public boolean avatar = false;
@SQLComment("List of accessible application (if not set the application is not available)") @SQLComment("List of accessible application (if not set the application is not available)")
@SQLTableLinkGeneric @SQLTableExternalLink
public List<Long> applications = null; public List<Long> applications = null;
} }

View File

@ -2,21 +2,20 @@ package org.kar.karso.model;
import org.kar.archidata.annotation.SQLDefault; import org.kar.archidata.annotation.SQLDefault;
import org.kar.archidata.annotation.SQLIfNotExists; 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 org.kar.archidata.model.User;
import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonInclude;
@SQLTableName ("user") import jakarta.persistence.Column;
import jakarta.persistence.Table;
@Table(name = "user")
@SQLIfNotExists @SQLIfNotExists
@JsonInclude(JsonInclude.Include.NON_NULL) @JsonInclude(JsonInclude.Include.NON_NULL)
public class UserAuthGet extends User { public class UserAuthGet extends User {
@SQLLimitSize(512) @Column(length = 512, nullable = false)
@SQLNotNull
public String email; public String email;
@SQLDefault("'0'") @SQLDefault("'0'")
@SQLNotNull @Column(nullable = false)
public boolean avatar = false; public boolean avatar = false;
} }

View File

@ -11,15 +11,16 @@ CREATE TABLE `application` (
*/ */
import org.kar.archidata.annotation.SQLIfNotExists; import org.kar.archidata.annotation.SQLIfNotExists;
import org.kar.archidata.annotation.SQLTableName;
import org.kar.archidata.model.GenericTable; import org.kar.archidata.model.GenericTable;
import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonInclude;
@SQLTableName ("user_link_application") import jakarta.persistence.Table;
@Table(name = "user_link_application")
@SQLIfNotExists @SQLIfNotExists
@JsonInclude(JsonInclude.Include.NON_NULL) @JsonInclude(JsonInclude.Include.NON_NULL)
public class UserLinkApplication extends GenericTable{ public class UserLinkApplication extends GenericTable {
public long user_id; public long user_id;
public long application_id; public long application_id;
} }

View File

@ -1,4 +1,5 @@
package test.kar.karso; package test.kar.karso;
import java.util.Map; import java.util.Map;
import org.junit.jupiter.api.AfterAll; 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.ExtendWith;
import org.junit.jupiter.api.extension.ExtensionContext; import org.junit.jupiter.api.extension.ExtensionContext;
import org.junit.jupiter.api.extension.TestExecutionExceptionHandler; import org.junit.jupiter.api.extension.TestExecutionExceptionHandler;
import org.kar.archidata.SqlWrapper;
import org.kar.archidata.exception.RESTErrorResponseExeption; import org.kar.archidata.exception.RESTErrorResponseExeption;
import org.kar.archidata.model.GetToken; import org.kar.archidata.model.GetToken;
import org.kar.archidata.util.ConfigBaseVariable; import org.kar.archidata.util.ConfigBaseVariable;
@ -29,112 +29,108 @@ import com.nimbusds.jwt.JWTClaimsSet;
@ExtendWith(StepwiseExtension.class) @ExtendWith(StepwiseExtension.class)
@TestMethodOrder(MethodOrderer.OrderAnnotation.class) @TestMethodOrder(MethodOrderer.OrderAnnotation.class)
public class TestBase { 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 WebLauncherTest webInterface = null;
static RESTApi api = null; static RESTApi api = null;
public void login(final String login, final String password) {
public void login(String login, String password) {
try { 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()); api.setToken(token.jwt());
} catch (Exception ex) { } catch (final Exception ex) {
Assertions.fail("Can not get Authentication for '" + login + "' ==> " + ex.getMessage()); Assertions.fail("Can not get Authentication for '" + login + "' ==> " + ex.getMessage());
} }
} }
public void loginAdmin() { public void loginAdmin() {
login("karadmin", "adminA@666"); login("karadmin", "adminA@666");
} }
@BeforeAll @BeforeAll
public static void configureWebServer() throws Exception { public static void configureWebServer() throws Exception {
logger.info("configure server ..."); LOGGER.info("configure server ...");
webInterface = new WebLauncherTest(); webInterface = new WebLauncherTest();
logger.info("Create DB"); LOGGER.info("Create DB");
try {
String dbName = "sdfsdfsdfsfsdfsfsfsfsdfsdfsd"; webInterface.migrateDB();
boolean data = SqlWrapper.isDBExist(dbName); } catch (final Exception ex) {
logger.error("exist: {}", data); ex.printStackTrace();
data = SqlWrapper.createDB(dbName); LOGGER.error("Detect an error: {}", ex.getMessage());
logger.error("create: {}", data); }
data = SqlWrapper.isDBExist(dbName); LOGGER.info("Start REST (BEGIN)");
logger.error("exist: {}", data);
System.exit(-1);
logger.info("Start REST (BEGIN)");
webInterface.process(); webInterface.process();
logger.info("Start REST (DONE)"); LOGGER.info("Start REST (DONE)");
api = new RESTApi(ConfigBaseVariable.apiAdress); api = new RESTApi(ConfigBaseVariable.apiAdress);
} }
@AfterAll @AfterAll
public static void stopWebServer() throws InterruptedException { public static void stopWebServer() throws InterruptedException {
logger.info("Kill the web server"); LOGGER.info("Kill the web server");
webInterface = null; webInterface = null;
// TODO: do it better... // TODO: do it better...
} }
@Order(1) @Order(1)
@Test @Test
//@RepeatedTest(10) //@RepeatedTest(10)
public void checkHealthCheck() throws Exception { public void checkHealthCheck() throws Exception {
HealthResult result = api.get(HealthResult.class, "health_check"); final HealthResult result = api.get(HealthResult.class, "health_check");
Assertions.assertEquals(result.value(), "alive and kicking"); Assertions.assertEquals(result.value(), "alive and kicking");
} }
@Order(2) @Order(2)
@Test @Test
public void checkHealthCheckWrongAPI() throws Exception { 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) @Order(3)
@Test @Test
public void firstUserConnect() throws Exception { public void firstUserConnect() throws Exception {
GetToken result = api.post(GetToken.class, "users/get_token", DataGetToken.generate("karadmin", "v1", "202515252", "adminA@666")); final GetToken result = api.post(GetToken.class, "users/get_token", DataGetToken.generate("karadmin", "v1", "202515252", "adminA@666"));
String[] splitted = result.jwt().split("\\."); final String[] splitted = result.jwt().split("\\.");
Assertions.assertEquals(3, splitted.length); Assertions.assertEquals(3, splitted.length);
String authorization = result.jwt(); final String authorization = result.jwt();
logger.debug(" validate token : " + authorization); LOGGER.debug(" validate token : " + authorization);
// Note with local access we get the internal key of the system. // Note with local access we get the internal key of the system.
JWTClaimsSet ret = JWTWrapper.validateToken(authorization, "KarAuth", null); final JWTClaimsSet ret = JWTWrapper.validateToken(authorization, "KarAuth", null);
// check the token is valid !!! (signed and coherent issuer... // check the token is valid !!! (signed and coherent issuer...
Assertions.assertNotNull(ret); Assertions.assertNotNull(ret);
// check userID // check userID
String userUID = ret.getSubject(); final String userUID = ret.getSubject();
long id = Long.parseLong(userUID); final long id = Long.parseLong(userUID);
Assertions.assertEquals(0, id); Assertions.assertEquals(0, id);
String name = (String)ret.getClaim("login"); final String name = (String) ret.getClaim("login");
Assertions.assertEquals("karadmin", name); 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 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("eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9", splitted[0]);
//Assertions.assertEquals("eyJzdWIiOiIwIiwiYXBwbGljYXRpb24iOiJrYXJzbyIsImlzcyI6IkthckF1dGgiLCJyaWdodCI6eyJrYXJzbyI6eyJBRE1JTiI6dHJ1ZSwiVVNFUiI6dHJ1ZX19LCJsb2dpbiI6ImthcmFkbWluIiwiZXhwIjoxNjg0MTk5MTkzLCJpYXQiOjE2ODI3NTU0MjV9", splitted[1]); //Assertions.assertEquals("eyJzdWIiOiIwIiwiYXBwbGljYXRpb24iOiJrYXJzbyIsImlzcyI6IkthckF1dGgiLCJyaWdodCI6eyJrYXJzbyI6eyJBRE1JTiI6dHJ1ZSwiVVNFUiI6dHJ1ZX19LCJsb2dpbiI6ImthcmFkbWluIiwiZXhwIjoxNjg0MTk5MTkzLCJpYXQiOjE2ODI3NTU0MjV9", splitted[1]);
// TODO ... Assertions.assertEquals("????", splitted[2]); // 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); 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 { try {
if ("GET".equals(type)) { if ("GET".equals(type)) {
api.get(String.class, urlOffset); api.get(String.class, urlOffset);
@ -146,22 +142,24 @@ public class TestBase {
api.delete(String.class, urlOffset); api.delete(String.class, urlOffset);
} }
Assertions.fail("Request on URL does not fail as expected: '" + type + "' url='" + 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) { 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); Assertions.assertEquals(errorStatus, ex.status);
} catch (Exception ex) { } catch (final Exception ex) {
logger.error("Unexpected throw error: {}", ex); LOGGER.error("Unexpected throw error: {}", ex);
Assertions.fail("Unexpected throws..."); Assertions.fail("Unexpected throws...");
} }
} }
public void checkWork(String type, String urlOffset) {
public void checkWork(final String type, final String urlOffset) {
checkWork(type, urlOffset, null); 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 { try {
if ("GET".equals(type)) { if ("GET".equals(type)) {
api.get(String.class, urlOffset); api.get(String.class, urlOffset);
@ -173,14 +171,15 @@ public class TestBase {
api.delete(String.class, urlOffset); api.delete(String.class, urlOffset);
} }
//Assertions.fail("Request on URL does not fail as expected: '" + type + "' url='" + 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()); Assertions.fail("Must not fail ... " + ex.toString());
} catch (Exception ex) { } catch (final Exception ex) {
logger.error("Unexpected throw error: {}", ex); LOGGER.error("Unexpected throw error: {}", ex);
Assertions.fail("Unexpected throws..."); Assertions.fail("Unexpected throws...");
} }
} }
@Order(4) @Order(4)
@Test @Test
public void checkUnAuthorizedAPI() throws Exception { public void checkUnAuthorizedAPI() throws Exception {
@ -200,34 +199,33 @@ public class TestBase {
checkFail("GET", "application/small", 401); checkFail("GET", "application/small", 401);
checkFail("GET", "application/get_token", 401); checkFail("GET", "application/get_token", 401);
checkFail("GET", "application/return", 401); checkFail("GET", "application/return", 401);
// /application_token/ section: // /application_token/ section:
checkFail("GET", "application_token/0", 401); checkFail("GET", "application_token/0", 401);
checkFail("DELETE", "application_token/0/5", 401); checkFail("DELETE", "application_token/0/5", 401);
checkFail("DELETE", "application_token/0/create", 401); checkFail("DELETE", "application_token/0/create", 401);
// /front/* // /front/*
checkFail("GET", "front", 404); // no index in test section checkFail("GET", "front", 404); // no index in test section
// health check // health check
checkWork("GET", "health_check"); checkWork("GET", "health_check");
// public_key (only application) // public_key (only application)
checkFail("GET", "public_key", 401); checkFail("GET", "public_key", 401);
checkFail("GET", "public_key/pem", 401); checkFail("GET", "public_key/pem", 401);
// /right // /right
checkFail("GET", "right", 401); checkFail("GET", "right", 401);
checkFail("POST", "right", 401, "{}"); checkFail("POST", "right", 401, "{}");
checkFail("GET", "right/0", 401); checkFail("GET", "right/0", 401);
checkFail("PUT", "right/0", 401, "{}"); checkFail("PUT", "right/0", 401, "{}");
checkFail("DELETE", "right/0", 401); checkFail("DELETE", "right/0", 401);
// /system_config // /system_config
checkWork("GET", "system_config/is_sign_up_availlable"); checkWork("GET", "system_config/is_sign_up_availlable");
checkFail("GET", "system_config/key/skjdfhkjsdhfkjsh", 401); checkFail("GET", "system_config/key/skjdfhkjsdhfkjsh", 401);
checkFail("PUT", "system_config/key/skjdfhkjsdhfkjsh", 401, "{}"); checkFail("PUT", "system_config/key/skjdfhkjsdhfkjsh", 401, "{}");
// /users // /users
checkFail("GET", "users", 401); checkFail("GET", "users", 401);
checkFail("GET", "users/0", 401); checkFail("GET", "users/0", 401);
@ -242,46 +240,43 @@ public class TestBase {
checkWork("GET", "users/check_email?email=admin@admin.ZZZ"); checkWork("GET", "users/check_email?email=admin@admin.ZZZ");
checkFail("GET", "users/check_email?email=ksjhdkjfhskjdh", 404); checkFail("GET", "users/check_email?email=ksjhdkjfhskjdh", 404);
// not testable : get_token // not testable : get_token
} }
@Order(5) @Order(5)
@Test @Test
public void testMeWithToken() throws Exception { public void testMeWithToken() throws Exception {
this.loginAdmin(); loginAdmin();
String result = api.get(String.class, "users/me"); final String result = api.get(String.class, "users/me");
Assertions.assertEquals("{\"id\":0,\"login\":\"karadmin\"}", result); Assertions.assertEquals("{\"id\":0,\"login\":\"karadmin\"}", result);
} }
} }
class StepwiseExtension implements ExecutionCondition, TestExecutionExceptionHandler { class StepwiseExtension implements ExecutionCondition, TestExecutionExceptionHandler {
@Override @Override
public ConditionEvaluationResult evaluateExecutionCondition(ExtensionContext extensionContext) { public ConditionEvaluationResult evaluateExecutionCondition(final ExtensionContext extensionContext) {
ExtensionContext.Namespace namespace = namespaceFor(extensionContext); final ExtensionContext.Namespace namespace = namespaceFor(extensionContext);
ExtensionContext.Store store = storeFor(extensionContext, namespace); final ExtensionContext.Store store = storeFor(extensionContext, namespace);
String value = store.get(StepwiseExtension.class, String.class); final String value = store.get(StepwiseExtension.class, String.class);
return value == null ? ConditionEvaluationResult.enabled("No test failures in stepwise tests") : 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)); : ConditionEvaluationResult.disabled(String.format("Stepwise test disabled due to previous failure in '%s'", value));
} }
@Override @Override
public void handleTestExecutionException(ExtensionContext extensionContext, Throwable throwable) throws Throwable { public void handleTestExecutionException(final ExtensionContext extensionContext, final Throwable throwable) throws Throwable {
ExtensionContext.Namespace namespace = namespaceFor(extensionContext); final ExtensionContext.Namespace namespace = namespaceFor(extensionContext);
ExtensionContext.Store store = storeFor(extensionContext, namespace); final ExtensionContext.Store store = storeFor(extensionContext, namespace);
store.put(StepwiseExtension.class, extensionContext.getDisplayName()); store.put(StepwiseExtension.class, extensionContext.getDisplayName());
throw throwable; throw throwable;
} }
private ExtensionContext.Namespace namespaceFor(ExtensionContext extensionContext){ private ExtensionContext.Namespace namespaceFor(final ExtensionContext extensionContext) {
return ExtensionContext.Namespace.create(StepwiseExtension.class, extensionContext.getParent()); return ExtensionContext.Namespace.create(StepwiseExtension.class, extensionContext.getParent());
} }
private ExtensionContext.Store storeFor(final ExtensionContext extensionContext, final ExtensionContext.Namespace namespace) {
private ExtensionContext.Store storeFor(ExtensionContext extensionContext, ExtensionContext.Namespace namespace){ return extensionContext.getParent().get().getStore(namespace);
return extensionContext.getParent().get().getStore(namespace); }
}
} }

View File

@ -9,20 +9,20 @@ import org.slf4j.LoggerFactory;
public class WebLauncherTest extends WebLauncher { public class WebLauncherTest extends WebLauncher {
final Logger logger = LoggerFactory.getLogger(WebLauncherTest.class); final Logger logger = LoggerFactory.getLogger(WebLauncherTest.class);
public WebLauncherTest() { public WebLauncherTest() {
logger.debug("Configure REST system"); this.logger.debug("Configure REST system");
// for local test: // for local test:
ConfigBaseVariable.apiAdress = "http://127.0.0.1:12345/test/api/"; ConfigBaseVariable.apiAdress = "http://127.0.0.1:12345/test/api/";
ConfigBaseVariable.dbPort = "3306"; ConfigBaseVariable.dbPort = "3306";
// create a unique key for test ==> not retrieve the token every load... // create a unique key for test ==> not retrieve the token every load...
ConfigVariable.uuid_for_key_generation = "lkjlkjlkjlmkjqmwlsdkjqfsdlkf,nmQLSDK,NFMQLKSdjmlKQJSDMLQK,S;ndmLQKZNERMA,ÉL"; ConfigVariable.uuid_for_key_generation = "lkjlkjlkjlmkjqmwlsdkjqfsdlkf,nmQLSDK,NFMQLKSdjmlKQJSDMLQK,S;ndmLQKZNERMA,ÉL";
// for the test we a in memory sqlite.. // for the test we a in memory sqlite..
////ConfigBaseVariable.dbType = "sqlite"; ConfigBaseVariable.dbType = "sqlite";
////ConfigBaseVariable.dbHost = "memory"; ConfigBaseVariable.dbHost = "memory";
// for test we need to connect all time the DB // for test we need to connect all time the DB
////ConfigBaseVariable.dbKeepConnected = "true"; ConfigBaseVariable.dbKeepConnected = "true";
ConfigBaseVariable.dbHost = "localhost"; ConfigBaseVariable.dbHost = "localhost";
ConfigBaseVariable.dbUser = "root"; ConfigBaseVariable.dbUser = "root";