diff --git a/back/.classpath b/back/.classpath
index 5098305..e705f7e 100644
--- a/back/.classpath
+++ b/back/.classpath
@@ -23,5 +23,12 @@
+
+
+
+
+
+
+
diff --git a/back/.project b/back/.project
index 25af8d9..3c43e57 100644
--- a/back/.project
+++ b/back/.project
@@ -32,12 +32,12 @@
- 1647191868592
+ 1682721079869
30
org.eclipse.core.resources.regexFilterMatcher
- node_modules|.git|__CREATED_BY_JAVA_LANGUAGE_SERVER__
+ node_modules|\.git|__CREATED_BY_JAVA_LANGUAGE_SERVER__
diff --git a/back/pom.xml b/back/pom.xml
index f86dee3..272ef17 100644
--- a/back/pom.xml
+++ b/back/pom.xml
@@ -1,18 +1,17 @@
+
- 4.0.0
- org.kar
- karso
- 0.4.1
-
-
-
3.1
17
17
-
3.1.1
@@ -21,27 +20,30 @@
https://gitea.atria-soft.org/api/packages/kangaroo-and-rabbit/maven
-
-
kangaroo-and-rabbit
archidata
0.3.5
-
-
- org.junit.jupiter
- junit-jupiter-api
- 5.7.2
- test
-
+
+
+ org.slf4j
+ slf4j-simple
+ 2.0.7
+
+
+
+ org.junit.jupiter
+ junit-jupiter-api
+ 5.7.2
+ test
+
-
src
test/src
- ${project.basedir}/out/maven/
+ ${project.basedir}/out/maven/
org.apache.maven.plugins
@@ -53,14 +55,13 @@
- org.codehaus.mojo
- exec-maven-plugin
- 1.4.0
-
- org.kar.karso.WebLauncher
-
+ org.codehaus.mojo
+ exec-maven-plugin
+ 1.4.0
+
+ org.kar.karso.WebLauncher
+
-
org.apache.maven.plugins
@@ -81,41 +82,68 @@
maven-surefire-plugin
3.0.0-M5
-
- maven-assembly-plugin
-
-
-
- fully.qualified.MainClass
-
-
-
- jar-with-dependencies
-
-
-
+
+ maven-assembly-plugin
+
+
+
+ fully.qualified.MainClass
+
+
+
+ jar-with-dependencies
+
+
+
-
report
test
report
+
+
+
+ jacoco-check
+
+ check
+
+
+
+ PACKAGE
+
+
+ LINE
+ COVEREDRATIO
+ 0.50
+
+
+
+
+
- -->
org.apache.maven.plugins
@@ -126,49 +154,12 @@
true
-
-
+
+
+ ${basedir}/test/resources
+
+
@@ -183,4 +174,4 @@
-
+
\ No newline at end of file
diff --git a/back/src/org/kar/karso/WebLauncher.java b/back/src/org/kar/karso/WebLauncher.java
index 956fd3a..ca3aefe 100755
--- a/back/src/org/kar/karso/WebLauncher.java
+++ b/back/src/org/kar/karso/WebLauncher.java
@@ -7,6 +7,7 @@ import org.kar.karso.api.ApplicationTokenResource;
import org.kar.karso.api.Front;
import org.kar.karso.api.HealthCheck;
import org.kar.karso.api.PublicKeyResource;
+import org.kar.karso.api.RightResource;
import org.kar.karso.api.SystemConfigResource;
import org.kar.karso.api.UserResource;
import org.kar.karso.filter.KarsoAuthenticationFilter;
@@ -17,9 +18,12 @@ import org.kar.karso.model.RightDescription;
import org.kar.karso.model.Settings;
import org.kar.karso.model.UserAuth;
import org.kar.karso.util.ConfigVariable;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
//import org.kar.archidata.model.Migration;
import org.kar.archidata.SqlWrapper;
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;
@@ -35,44 +39,67 @@ import jakarta.ws.rs.core.UriBuilder;
import java.net.URI;
public class WebLauncher {
- private WebLauncher() {}
+ final static Logger LOGGER = LoggerFactory.getLogger(WebLauncher.class);
+ protected ResourceConfig rc = null;
+ HttpServer server = null;
+ public WebLauncher() {}
private static URI getBaseURI() {
return UriBuilder.fromUri(ConfigBaseVariable.getlocalAddress()).build();
}
public static void main(String[] args) throws InterruptedException {
- ConfigBaseVariable.bdDatabase =
- "karso";
-
- try {
- JWTWrapper.initLocalToken(ConfigVariable.getUUIDKeyRoot());
- } catch (Exception e1) {
- // TODO Auto-generated catch block
- e1.printStackTrace();
- System.out.println("Wait 10 seconds ....");
- Thread.sleep(10000);
- return;
- }
-
+ WebLauncher launcher = new WebLauncher();
+ launcher.process();
+ WebLauncher.LOGGER.info("end-configure the server & wait finish process:");
+ Thread.currentThread().join();
+ WebLauncher.LOGGER.info("STOP the REST server:");
+ }
+
+ public void generateDB() {
+
// generate the BDD:
try {
String out = "";
out += SqlWrapper.createTable(Settings.class);
+ LOGGER.debug(out);
+ SqlWrapper.executeSimpleQuerry(out);
+ out = "";
out += SqlWrapper.createTable(UserAuth.class);
+ LOGGER.debug(out);
+ SqlWrapper.executeSimpleQuerry(out);
+ out = "";
out += SqlWrapper.createTable(Application.class);
+ LOGGER.debug(out);
+ SqlWrapper.executeSimpleQuerry(out);
+ out = "";
out += SqlWrapper.createTable(ApplicationToken.class);
+ LOGGER.debug(out);
+ SqlWrapper.executeSimpleQuerry(out);
+ out = "";
out += SqlWrapper.createTable(RightDescription.class);
+ LOGGER.debug(out);
+ SqlWrapper.executeSimpleQuerry(out);
+ out = "";
out += SqlWrapper.createTable(Right.class);
+ LOGGER.debug(out);
+ SqlWrapper.executeSimpleQuerry(out);
+ out = "";
// default admin: "karadmin" password: "adminA@666"
out += """
INSERT INTO `application` (`id`, `name`, `description`, `redirect`, `redirectDev`, `notification`, `ttl`) VALUES
('0', 'karso', 'Root SSO interface', 'http://atria-soft/karso', '', '', '666');
""";
+ LOGGER.debug(out);
+ SqlWrapper.executeSimpleQuerry(out);
+ out = "";
out += """
INSERT INTO `user` (`id`, `login`, `password`, `email`, `admin`) VALUES
('0', 'karadmin', '0ddcac5ede3f1300a1ce5948ab15112f2810130531d578ab8bc4dc131652d7cf7a3ff6e827eb957bff43bc2c65a6a1d46722e5b3a2343ac3176a33ea7250080b',
'admin@admin.ZZZ', 1);
""";
+ LOGGER.debug(out);
+ SqlWrapper.executeSimpleQuerry(out);
+ out = "";
out += """
INSERT INTO `settings` (`key`, `right`, `type`, `value`) VALUES
('SIGN_UP_ENABLE', 'rwr-r-', 'BOOLEAN', 'false'),
@@ -80,30 +107,55 @@ public class WebLauncher {
('SIGN_UP_FILTER', 'rw----', 'STRING', '.*'),
('EMAIL_VALIDATION_REQUIRED', 'rwr-r-', 'BOOLEAN', 'false');
""";
+ LOGGER.debug(out);
+ SqlWrapper.executeSimpleQuerry(out);
+ out = "";
out += """
INSERT INTO `rightDescription` (`id`, `applicationId`, `key`, `title`, `description`, `type`) VALUES
(0, 0, 'ADMIN', 'Administrator', 'Full administrator Right', 'BOOLEAN');
""";
+ LOGGER.debug(out);
+ SqlWrapper.executeSimpleQuerry(out);
+ out = "";
out += """
INSERT INTO `right` (`applicationId`, `userId`, `rightDescriptionId`, `value`) VALUES
(0, 0, 0, 'true');
""";
+ LOGGER.debug(out);
+ SqlWrapper.executeSimpleQuerry(out);
+ out = "";
//out += SqlWrapper.createTable(Migration.class);
- System.out.println(out);
+ LOGGER.debug(out);
// Do initialization or migration:
- //SqlWrapper.executeSimpleQuerry(out);
+ SqlWrapper.executeSimpleQuerry(out);
} catch (Exception e) {
// TODO Auto-generated catch block
+ LOGGER.error("can not generate the BD: {}", e.getMessage());
e.printStackTrace();
}
+ }
+
+ public void process() throws InterruptedException {
+ ConfigBaseVariable.bdDatabase = "karso";
+
+ try {
+ JWTWrapper.initLocalToken(ConfigVariable.getUUIDKeyRoot());
+ } catch (Exception e1) {
+ // TODO Auto-generated catch block
+ e1.printStackTrace();
+ LOGGER.info("Wait 10 seconds ....");
+ Thread.sleep(10000);
+ return;
+ }
+
// ===================================================================
// Configure resources
// ===================================================================
- ResourceConfig rc = new ResourceConfig();
+ rc = new ResourceConfig();
// global authentication system
rc.register(new OptionFilter());
// remove cors ==> all time called by an other system...
@@ -113,6 +165,7 @@ public class WebLauncher {
rc.register(InputExceptionCatcher.class);
rc.register(SystemExceptionCatcher.class);
rc.register(FailExceptionCatcher.class);
+ rc.register(FailException404API.class);
rc.register(ExceptionCatcher.class);
// add default resource:
@@ -121,6 +174,7 @@ public class WebLauncher {
rc.registerClasses(ApplicationResource.class);
rc.registerClasses(ApplicationTokenResource.class);
rc.registerClasses(SystemConfigResource.class);
+ rc.registerClasses(RightResource.class);
rc.registerClasses(Front.class);
rc.registerClasses(HealthCheck.class);
// add jackson to be discover when we are ins stand-alone server
@@ -128,11 +182,11 @@ public class WebLauncher {
// enable this to show low level request
//rc.property(LoggingFeature.LOGGING_FEATURE_LOGGER_LEVEL_SERVER, Level.WARNING.getName());
- HttpServer server = GrizzlyHttpServerFactory.createHttpServer(getBaseURI(), rc);
+ server = GrizzlyHttpServerFactory.createHttpServer(getBaseURI(), rc);
Runtime.getRuntime().addShutdownHook(new Thread(new Runnable() {
@Override
public void run() {
- System.out.println("Stopping server..");
+ LOGGER.info("Stopping server..");
server.shutdownNow();
}
}, "shutdownHook"));
@@ -142,10 +196,9 @@ public class WebLauncher {
// ===================================================================
try {
server.start();
- System.out.println("Jersey app started at " + getBaseURI());
- Thread.currentThread().join();
+ LOGGER.debug("Jersey app started at {}", getBaseURI());
} catch (Exception e) {
- System.out.println("There was an error while starting Grizzly HTTP server.");
+ LOGGER.error("There was an error while starting Grizzly HTTP server.");
e.printStackTrace();
}
}
diff --git a/back/src/org/kar/karso/WebLauncherEdgeLocal.java b/back/src/org/kar/karso/WebLauncherEdgeLocal.java
index 298d37b..de3cab4 100755
--- a/back/src/org/kar/karso/WebLauncherEdgeLocal.java
+++ b/back/src/org/kar/karso/WebLauncherEdgeLocal.java
@@ -3,8 +3,11 @@ package org.kar.karso;
import org.kar.archidata.util.ConfigBaseVariable;
import org.kar.karso.util.ConfigVariable;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
public class WebLauncherEdgeLocal {
+ final Logger logger = LoggerFactory.getLogger(WebLauncherEdgeLocal.class);
private WebLauncherEdgeLocal() {}
public static void main(String[] args) throws InterruptedException {
diff --git a/back/src/org/kar/karso/WebLauncherLocal.java b/back/src/org/kar/karso/WebLauncherLocal.java
index 9f7bced..6e3f473 100755
--- a/back/src/org/kar/karso/WebLauncherLocal.java
+++ b/back/src/org/kar/karso/WebLauncherLocal.java
@@ -3,11 +3,22 @@ package org.kar.karso;
import org.kar.archidata.util.ConfigBaseVariable;
import org.kar.karso.util.ConfigVariable;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
-public class WebLauncherLocal {
+public class WebLauncherLocal extends WebLauncher {
+ final Logger logger = LoggerFactory.getLogger(WebLauncherLocal.class);
private WebLauncherLocal() {}
public static void main(String[] args) throws InterruptedException {
+ WebLauncherLocal launcher = new WebLauncherLocal();
+ launcher.process();
+ launcher.logger.info("end-configure the server & wait finish process:");
+ Thread.currentThread().join();
+ launcher.logger.info("STOP the REST server:");
+ }
+ @Override
+ public void process() throws InterruptedException {
if (true) {
// for local test:
ConfigBaseVariable.apiAdress = "http://0.0.0.0:15080/karso/api/";
@@ -18,6 +29,6 @@ public class WebLauncherLocal {
//ConfigBaseVariable.dbHost = "./bdd_base.sqlite";
}
- WebLauncher.main(args);
+ super.process();
}
}
diff --git a/back/src/org/kar/karso/api/ApplicationResource.java b/back/src/org/kar/karso/api/ApplicationResource.java
index 77bc121..50dd525 100755
--- a/back/src/org/kar/karso/api/ApplicationResource.java
+++ b/back/src/org/kar/karso/api/ApplicationResource.java
@@ -4,6 +4,8 @@ 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;
@@ -23,6 +25,7 @@ import jakarta.ws.rs.core.SecurityContext;
@Path("/application")
@Produces( MediaType.APPLICATION_JSON)
public class ApplicationResource {
+ final Logger logger = LoggerFactory.getLogger(ApplicationResource.class);
public ApplicationResource() {
}
@@ -39,7 +42,7 @@ public class ApplicationResource {
// TODO Auto-generated catch block
e.printStackTrace();
String result = "SERVER Internal error";
- System.out.println(" result: " + result);
+ logger.error(" result: {}", result);
return out;
}
for (UserLinkApplication app : links) {
@@ -60,31 +63,26 @@ public class ApplicationResource {
// TODO Auto-generated catch block
e.printStackTrace();
String result = "SERVER Internal error";
- System.out.println(" result: " + result);
+ logger.error(" result: {}", result);
return out;
}
- System.out.println("Find list of user for an application :" + links);
+ logger.debug("Find list of user for an application: {}", links);
for (UserLinkApplication app : links) {
out.add(app.user_id);
}
return out;
}
-
- @GET
- @Path("{id}/users")
- @RolesAllowed(value= {"ADMIN"})
- public List getApplicationUsers(@PathParam("id") Long applicationId) throws Exception {
- // special case for SSO: (all user have access on the SSO...).
-
- System.out.println("Request list of user for an applciation:" + applicationId);
- return getListOfUsers(applicationId);
- }
-
+ ////////////////////////////////////////////////////////////////////////////////////////
+ //
+ // Generic /application/
+ //
+ ////////////////////////////////////////////////////////////////////////////////////////
+
@GET
@RolesAllowed(value= {"USER", "ADMIN"})
public List getApplications(@Context SecurityContext sc) throws Exception {
GenericContext gc = (GenericContext) sc.getUserPrincipal();
- System.out.println("getApplications");
+ logger.debug("getApplications");
// TODO filter with the list of element available in his authorizations ...
List tmp = SqlWrapper.gets(Application.class, false);
if (gc.userByToken.hasRight("ADMIN", true)) {
@@ -99,13 +97,86 @@ public class ApplicationResource {
}
return out;
}
+
+ @POST
+ @RolesAllowed("ADMIN")
+ public Application create(Application application) throws Exception {
+ logger.debug("create new application {}", application);
+ // verify login or email is correct:
+ if (application.name == null || application.name.length() < 5) {
+ throw new InputException("name", "create application (name too small: '" + application.name + "')");
+ }
+ if (application.redirect == null || application.redirect.length() < 6) {
+ throw new InputException("redirect", "create application (redirect too small: '" + application.redirect + "')");
+ }
+ application.id = null;
+ application.create_date = null;
+ application.deleted = null;
+ application.modify_date = null;
+ return SqlWrapper.insert(application);
+ }
+
+
+ ////////////////////////////////////////////////////////////////////////////////////////
+ //
+ // Generic /application/{id}
+ //
+ ////////////////////////////////////////////////////////////////////////////////////////
+
+ @GET
+ @Path("{id}")
+ @RolesAllowed("ADMIN")
+ public Application get(@PathParam("id") Long id) throws Exception {
+ return SqlWrapper.get(Application.class, id);
+ }
+
+ @PUT
+ @Path("{id}")
+ @RolesAllowed("ADMIN")
+ @Consumes(MediaType.APPLICATION_JSON)
+ public Application put(@PathParam("id") Long id, String jsonRequest) throws Exception {
+ SqlWrapper.update(Application.class, id, jsonRequest);
+ return SqlWrapper.get(Application.class, id);
+ }
+
+ @DELETE
+ @Path("{id}")
+ @RolesAllowed("ADMIN")
+ @Produces( value = MediaType.TEXT_PLAIN )
+ public void remove(@Context SecurityContext sc, @PathParam("id") long applicationId) throws Exception {
+ SqlWrapper.setDelete(Application.class, applicationId);
+ }
+
+ ////////////////////////////////////////////////////////////////////////////////////////
+ //
+ // Generic /{id}/*
+ //
+ ////////////////////////////////////////////////////////////////////////////////////////
+
+
+ @GET
+ @Path("{id}/users")
+ @RolesAllowed(value= {"ADMIN"})
+ public List getApplicationUsers(@PathParam("id") Long applicationId) throws Exception {
+ // special case for SSO: (all user have access on the SSO...).
+
+ logger.debug("Request list of user for an applciation: {}", applicationId);
+ return getListOfUsers(applicationId);
+ }
+
+ ////////////////////////////////////////////////////////////////////////////////////////
+ //
+ // Generic /application/*
+ //
+ ////////////////////////////////////////////////////////////////////////////////////////
+
@GET
@Path("small")
@RolesAllowed(value= {"USER", "ADMIN"})
public List getApplicationsSmall(@Context SecurityContext sc) throws Exception {
GenericContext gc = (GenericContext) sc.getUserPrincipal();
- System.out.println("getApplications");
+ logger.debug("getApplications");
List tmp = SqlWrapper.gets(Application.class, false);
List regular = this.getUserListOfApplication(gc.userByToken.id);
List out = new ArrayList<>();
@@ -122,11 +193,11 @@ public class ApplicationResource {
@RolesAllowed(value= {"USER", "ADMIN"})
public Response getClientToken(@Context SecurityContext sc, @QueryParam("application") String application) throws Exception {
GenericContext gc = (GenericContext) sc.getUserPrincipal();
- System.out.println("== USER ? " + gc.userByToken);
+ logger.debug("== USER ? {}", gc.userByToken);
if (application == null) {
String result = "Input error missing parameter: 'application'";
- System.out.println(" result: " + result);
+ logger.debug(" result: {}", result);
return Response.status(406).entity(result).build();
}
String applicationName = application;
@@ -135,7 +206,7 @@ public class ApplicationResource {
applicationName = applicationName.substring(0, applicationName.length()-4);
isDev = true;
}
- System.out.println("Search for '" + applicationName + "' base of '" + application + "'");
+ logger.debug("Search for '{}' base of '{}'", applicationName, application);
Application appl = null;
try {
@@ -144,17 +215,17 @@ public class ApplicationResource {
// TODO Auto-generated catch block
e.printStackTrace();
String result = "SERVER Internal error";
- System.out.println(" result: " + result);
+ logger.debug(" result: {}", result);
return Response.status(500).entity(result).build();
}
if (appl == null) {
String result = "Authentiocate-wrong email/login '" + applicationName + "')";
- System.out.println(" result: " + result);
+ logger.error(" result: {}", result);
return Response.status(401).entity(result).build();
}
if (false) {
- // the pplication id is not streamed in the application liny in the where elements
+ // the application id is not streamed in the application liny in the where elements
// get the local user:
UserAuth localUser = null;
try {
@@ -163,18 +234,18 @@ public class ApplicationResource {
// TODO Auto-generated catch block
e.printStackTrace();
String result = "SERVER Internal error";
- System.out.println(" result: " + result);
+ logger.error(" result: {}", result);
return Response.status(500).entity(result).build();
}
if (localUser == null) {
String result = "Authenticate-wrong results '" + applicationName + "')";
- System.out.println(" result: " + result);
+ logger.error(" result: {}", result);
return Response.status(401).entity(result).build();
}
- System.out.println("Get application list: " + localUser.applications);
+ logger.debug("Get application list: " + localUser.applications);
if (localUser.applications == null || localUser.applications.indexOf((Long)gc.userByToken.id) == -1) {
String result = "Authenticate impossible ==> application not accessible '" + applicationName + "'";
- System.out.println(" result: " + result);
+ logger.error(" result: {}", result);
return Response.status(401).entity(result).build();
}
} else {
@@ -190,12 +261,12 @@ public class ApplicationResource {
// TODO Auto-generated catch block
e.printStackTrace();
String result = "SERVER Internal error";
- System.out.println(" result: " + result);
+ logger.error(" result: {}", result);
return Response.status(500).entity(result).build();
}
if (links == null) {
String result = "Authenticate impossible ==> application not accessible '" + applicationName + "'";
- System.out.println(" result: " + result);
+ logger.error(" result: {}", result);
return Response.status(401).entity(result).build();
}
}
@@ -209,7 +280,7 @@ public class ApplicationResource {
// we set the right in the under map to manage multiple application group right. and in some application user can see other user or all user of the application
outRight.put(applicationName, applicationRight);
String ret = JWTWrapper.generateJWToken(gc.userByToken.id, gc.userByToken.name, "KarAuth", applicationName, outRight, appl.ttl);
- //System.out.println(" ==> generate token: " + ret);
+ //logger.debug(" ==> generate token: {}", ret);
String returnAdress = appl.redirect;
if (isDev) {
returnAdress = appl.redirectDev;
@@ -221,15 +292,15 @@ public class ApplicationResource {
@Path("return")
@RolesAllowed(value= {"USER", "ADMIN"})
public Response logOut(@Context SecurityContext sc, @QueryParam("application") String application) {
- System.out.println("=====================================");
- System.out.println("Get log_out()");
- System.out.println("=====================================");
+ logger.debug("=====================================");
+ logger.debug("Get log_out()");
+ logger.debug("=====================================");
GenericContext gc = (GenericContext) sc.getUserPrincipal();
- System.out.println("== USER ? " + gc.userByToken);
+ logger.debug("== USER ? {}", gc.userByToken);
if (application == null) {
String result = "Input error missing parameter: 'application'";
- System.out.println(" result: " + result);
+ logger.error(" result: {}", result);
return Response.status(406).entity(result).build();
}
String applicationName = application;
@@ -238,7 +309,7 @@ public class ApplicationResource {
applicationName = applicationName.substring(0, applicationName.length()-4);
isDev = true;
}
- System.out.println("Search for '" + applicationName + "' base of '" + application + "'");
+ logger.debug("Search for '{}' base of '{}'", applicationName, application);
Application appl = null;
try {
@@ -247,13 +318,13 @@ public class ApplicationResource {
// TODO Auto-generated catch block
e.printStackTrace();
String result = "SERVER Internal error";
- System.out.println(" result: " + result);
+ logger.error(" result: {}", result);
return Response.status(500).entity(result).build();
}
if (appl == null) {
String result = "Authentiocate-wrong email/login '" + applicationName + "')";
- System.out.println(" result: " + result);
+ logger.error(" result: {}", result);
return Response.status(404).entity(result).build();
}
String returnAdress = appl.redirect;
@@ -263,46 +334,6 @@ public class ApplicationResource {
return Response.status(201).entity("{ \"url\":\"" + returnAdress + "\"}").build();
}
- @DELETE
- @Path("{id}")
- @RolesAllowed("ADMIN")
- @Produces( value = MediaType.TEXT_PLAIN )
- public void remove(@Context SecurityContext sc, @PathParam("id") long applicationId) throws Exception {
- SqlWrapper.setDelete(Application.class, applicationId);
- }
-
- @POST
- @RolesAllowed("ADMIN")
- public Application create(Application application) throws Exception {
- System.out.println("create new application " + application);
- // verify login or email is correct:
- if (application.name == null || application.name.length() < 5) {
- throw new InputException("name", "create application (name too small: '" + application.name + "')");
- }
- if (application.redirect == null || application.redirect.length() < 6) {
- throw new InputException("redirect", "create application (redirect too small: '" + application.redirect + "')");
- }
- application.id = null;
- application.create_date = null;
- application.deleted = null;
- application.modify_date = null;
- return SqlWrapper.insert(application);
- }
-
- @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);
- }
- @GET
- @Path("{id}")
- @RolesAllowed("ADMIN")
- public Application put(@PathParam("id") Long id) throws Exception {
- return SqlWrapper.get(Application.class, id);
- }
}
diff --git a/back/src/org/kar/karso/api/ApplicationTokenResource.java b/back/src/org/kar/karso/api/ApplicationTokenResource.java
index c2256e2..a7c3d85 100755
--- a/back/src/org/kar/karso/api/ApplicationTokenResource.java
+++ b/back/src/org/kar/karso/api/ApplicationTokenResource.java
@@ -1,9 +1,10 @@
package org.kar.karso.api;
-import org.glassfish.jersey.media.multipart.FormDataParam;
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;
@@ -23,10 +24,17 @@ import jakarta.ws.rs.core.SecurityContext;
@Path("/application_token")
@Produces( MediaType.APPLICATION_JSON)
public class ApplicationTokenResource {
+ final Logger logger = LoggerFactory.getLogger(ApplicationTokenResource.class);
public ApplicationTokenResource() {
}
+ ////////////////////////////////////////////////////////////////////////////////////////
+ //
+ // Generic /application_token/{applicationId}
+ //
+ ////////////////////////////////////////////////////////////////////////////////////////
+
@GET
@Path("{applicationId}")
@RolesAllowed(value= {"ADMIN"})
@@ -103,7 +111,7 @@ public class ApplicationTokenResource {
// correct input string stream :
String name = multipartCorrection(request.name());
//validity = multipartCorrection(validity);
- System.out.println("create a nexw token...");
+ logger.debug("create a nexw token...");
if (applicationId == null) {
throw new InputException("applicationId", "can not be null");
}
diff --git a/back/src/org/kar/karso/api/Front.java b/back/src/org/kar/karso/api/Front.java
index 1a1c372..084fea7 100644
--- a/back/src/org/kar/karso/api/Front.java
+++ b/back/src/org/kar/karso/api/Front.java
@@ -4,9 +4,12 @@ import jakarta.ws.rs.*;
import org.kar.archidata.api.FrontGeneric;
import org.kar.karso.util.ConfigVariable;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
@Path("/front")
public class Front extends FrontGeneric {
+ final Logger logger = LoggerFactory.getLogger(FrontGeneric.class);
public Front() {
this.baseFrontFolder = ConfigVariable.getFrontFolder();
}
diff --git a/back/src/org/kar/karso/api/HealthCheck.java b/back/src/org/kar/karso/api/HealthCheck.java
index 1f919ac..3702b71 100644
--- a/back/src/org/kar/karso/api/HealthCheck.java
+++ b/back/src/org/kar/karso/api/HealthCheck.java
@@ -1,19 +1,17 @@
package org.kar.karso.api;
import org.kar.archidata.annotation.security.PermitAll;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
import jakarta.ws.rs.*;
import jakarta.ws.rs.core.MediaType;
@Path("/health_check")
@Produces(MediaType.APPLICATION_JSON)
public class HealthCheck {
- public class HealthResult {
- public String value;
- public HealthResult(String value) {
- this.value = value;
- }
- }
- // todo : do it better...
+ final static Logger LOGGER = LoggerFactory.getLogger(HealthCheck.class);
+ public record HealthResult(String value) {};
@GET
@PermitAll
public HealthResult getHealth() {
diff --git a/back/src/org/kar/karso/api/PublicKeyResource.java b/back/src/org/kar/karso/api/PublicKeyResource.java
index 9915b90..fb306a5 100755
--- a/back/src/org/kar/karso/api/PublicKeyResource.java
+++ b/back/src/org/kar/karso/api/PublicKeyResource.java
@@ -2,10 +2,11 @@ package org.kar.karso.api;
import org.kar.archidata.util.JWTWrapper;
import org.kar.archidata.util.JWTWrapper.PublicKey;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import com.nimbusds.jose.JOSEException;
-import org.kar.archidata.annotation.security.PermitAll;
import org.kar.archidata.annotation.security.RolesAllowed;
import java.security.interfaces.RSAPublicKey;
@@ -17,6 +18,7 @@ import jakarta.ws.rs.core.MediaType;
@Path("/public_key")
@Produces(MediaType.APPLICATION_JSON)
public class PublicKeyResource {
+ final Logger logger = LoggerFactory.getLogger(PublicKeyResource.class);
public PublicKeyResource() {
@@ -24,7 +26,6 @@ public class PublicKeyResource {
// This is for java server that use the same implementation
// curl http://localhost:9993/public_key
@GET
- @PermitAll
@RolesAllowed(value= {"APPLICATION"})
public PublicKey getKey() {
return new PublicKey(JWTWrapper.getPublicKeyJson());
diff --git a/back/src/org/kar/karso/api/RightResource.java b/back/src/org/kar/karso/api/RightResource.java
index 25b44b0..33f6574 100644
--- a/back/src/org/kar/karso/api/RightResource.java
+++ b/back/src/org/kar/karso/api/RightResource.java
@@ -4,6 +4,8 @@ import org.kar.archidata.SqlWrapper;
import org.kar.archidata.WhereCondition;
import org.kar.karso.model.Right;
import org.kar.karso.model.RightDescription;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import org.kar.archidata.annotation.security.RolesAllowed;
import jakarta.ws.rs.*;
import jakarta.ws.rs.core.MediaType;
@@ -16,6 +18,7 @@ import java.util.Map;
@Path("/right")
@Produces({MediaType.APPLICATION_JSON})
public class RightResource {
+ final static Logger logger = LoggerFactory.getLogger(RightResource.class);
public static Object transform(String type, String value) {
@@ -39,7 +42,7 @@ public class RightResource {
new WhereCondition("applicationId", "=", applicationId),
new WhereCondition("deleted", "=", 0)
));
- System.out.println("Get some descriptions: " + rightsDescriptions.size() + " applicationId=" + applicationId);
+ logger.debug("Get some descriptions: {} applicationId={}", rightsDescriptions.size(), applicationId);
if (rightsDescriptions != null && rightsDescriptions.size() != 0) {
List rights = SqlWrapper.getsWhere(Right.class,
List.of(
@@ -47,7 +50,7 @@ public class RightResource {
new WhereCondition("userId", "=", userId),
new WhereCondition("deleted", "=", 0)
));
- System.out.println("Get some user right: " + rights.size() + " userID=" + userId);
+ logger.debug("Get some user right: {}userID={}", rights.size(), userId);
if (rights != null && rights.size() != 0) {
for (Right right: rights) {
RightDescription description = rightsDescriptions.stream()
@@ -59,21 +62,15 @@ public class RightResource {
}
}
} else {
- System.out.println("The User have no specific right...");
+ logger.debug("The User have no specific right...");
}
} else {
// the application does not manage right with Karso (normal use-case)
- System.out.println("Does not manage Karso right...");
+ logger.debug("Does not manage Karso right...");
}
return out;
}
- @GET
- @Path("{id}")
- @RolesAllowed("ADMIN")
- public static Right getWithId(@PathParam("id") Long id) throws Exception {
- return SqlWrapper.get(Right.class, id);
- }
@GET
@RolesAllowed("ADMIN")
@@ -87,6 +84,13 @@ public class RightResource {
public Right post(String jsonRequest) throws Exception {
return SqlWrapper.insertWithJson(Right.class, jsonRequest);
}
+
+ @GET
+ @Path("{id}")
+ @RolesAllowed("ADMIN")
+ public static Right getWithId(@PathParam("id") Long id) throws Exception {
+ return SqlWrapper.get(Right.class, id);
+ }
@PUT
@Path("{id}")
diff --git a/back/src/org/kar/karso/api/SystemConfigResource.java b/back/src/org/kar/karso/api/SystemConfigResource.java
index 17fb3bd..a9f06ce 100755
--- a/back/src/org/kar/karso/api/SystemConfigResource.java
+++ b/back/src/org/kar/karso/api/SystemConfigResource.java
@@ -2,6 +2,8 @@ package org.kar.karso.api;
import org.kar.archidata.SqlWrapper;
import org.kar.karso.model.*;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
@@ -22,6 +24,7 @@ import jakarta.ws.rs.core.SecurityContext;
@Path("/system_config")
@Produces( MediaType.APPLICATION_JSON)
public class SystemConfigResource {
+ final Logger logger = LoggerFactory.getLogger(SystemConfigResource.class);
public static class GetSignUpAvaillable {
public boolean signup;
@@ -48,7 +51,7 @@ public class SystemConfigResource {
}
boolean availlable = "true".equalsIgnoreCase(set.value);
GetSignUpAvaillable tmp = new GetSignUpAvaillable(availlable);
- System.out.println("mlkmlk " + tmp.signup);
+ logger.debug("mlkmlk {}", tmp.signup);
return tmp;
}
@@ -90,7 +93,7 @@ public class SystemConfigResource {
JsonNode value = root.findPath("value");
res.value = value.asText();
- System.out.println("Update value : " + res.value);
+ logger.debug("Update value : {}", res.value);
SqlWrapper.update(res, res.id, List.of("value"));
return Response.status(201).entity("{ \"value\":\"" + res.value + "\"}").build();
}
diff --git a/back/src/org/kar/karso/api/UserResource.java b/back/src/org/kar/karso/api/UserResource.java
index 9d91a80..44c6d08 100755
--- a/back/src/org/kar/karso/api/UserResource.java
+++ b/back/src/org/kar/karso/api/UserResource.java
@@ -11,6 +11,8 @@ import org.kar.archidata.exception.SystemException;
import org.kar.archidata.filter.GenericContext;
import org.kar.karso.model.*;
import org.kar.karso.util.ConfigVariable;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import com.fasterxml.jackson.annotation.JsonInclude;
@@ -34,6 +36,7 @@ import java.time.LocalDateTime;
@Path("/users")
@Produces( MediaType.APPLICATION_JSON)
public class UserResource {
+ final Logger logger = LoggerFactory.getLogger(UserResource.class);
@JsonInclude(JsonInclude.Include.NON_NULL)
public class UserOut {
@@ -59,7 +62,7 @@ public class UserResource {
@Path("{id}")
@RolesAllowed("ADMIN")
public UserAuthGet getUser(@Context SecurityContext sc, @PathParam("id") long userId) throws Exception {
- GenericContext gc = (GenericContext) sc.getUserPrincipal();
+ //GenericContext gc = (GenericContext) sc.getUserPrincipal();
return SqlWrapper.get(UserAuthGet.class, userId);
}
@@ -70,7 +73,7 @@ public class UserResource {
@PathParam("userId") long userId,
@PathParam("applicationId") long applicationId,
boolean data) throws Exception {
- System.out.println("Find typeNode");
+ logger.debug("Find typeNode");
if (data == true) {
SqlWrapper.addLink(UserAuth.class, userId, "application", applicationId);
} else {
@@ -110,7 +113,7 @@ public class UserResource {
@Path("create_new_user")
@RolesAllowed("ADMIN")
public UserAuthGet createUser(UserCreate user) throws Exception {
- System.out.println("create new User email=" + user.email + " login=" + user.login);
+ logger.debug("create new User email={} login={}", user.email, user.login);
// verify login or email is correct:
if (user.login == null || user.login.length() < 6) {
throw new InputException("login", "Authentiocate-method-error (login too small: '" + user.login + "')");
@@ -154,7 +157,7 @@ public class UserResource {
newUser.email = user.email;
newUser.lastConnection = Timestamp.valueOf(LocalDateTime.now());
UserAuth tmp = SqlWrapper.insert(newUser);
- System.out.println("create new user done with id==" + tmp.id);
+ logger.debug("create new user done with id=={}", tmp.id);
return SqlWrapper.get(UserAuthGet.class, tmp.id);
}
@@ -162,9 +165,9 @@ public class UserResource {
@Path("me")
@RolesAllowed("USER")
public UserOut getMe(@Context SecurityContext sc) {
- System.out.println("getMe()");
+ logger.debug("getMe()");
GenericContext gc = (GenericContext) sc.getUserPrincipal();
- System.out.println("== USER ? " + gc.userByToken);
+ logger.debug("== USER ? {}", gc.userByToken);
return new UserOut(gc.userByToken.id, gc.userByToken.name);
}
@@ -172,9 +175,9 @@ public class UserResource {
@Path("password")
@RolesAllowed("USER")
public Response changePassword(@Context SecurityContext sc, ChangePassword data) throws Exception {
- System.out.println("ChangePassword()");
+ logger.debug("ChangePassword()");
GenericContext gc = (GenericContext) sc.getUserPrincipal();
- System.out.println("== USER ? " + gc.userByToken);
+ logger.debug("== USER ? {}", gc.userByToken);
if(data == null) {
throw new InputException("data", "No data set...");
@@ -213,14 +216,14 @@ public class UserResource {
@Path("/check_login")
@PermitAll
public Response checkLogin(@QueryParam("login") String login) throws Exception {
- System.out.println("checkLogin: " + login );
+ logger.debug("checkLogin: '{}'", login );
List out = SqlWrapper.getsWhere(UserAuth.class, List.of(
new WhereCondition("login", "=", login)
), false);
if (out.size() >= 1) {
return Response.ok().build();
}
- return Response.status(404).build();
+ throw new NotFoundException("User does not exist: '" + login + "'");
}
// TODO: add an application TOKEN and permit only 50 requested (maybe add an option to disable it).
@@ -228,14 +231,14 @@ public class UserResource {
@Path("/check_email")
@PermitAll
public Response checkEmail(@QueryParam("email") String email) throws Exception {
- System.out.println("checkEmail: " + email );
+ logger.debug("checkEmail: {}", email );
List out = SqlWrapper.getsWhere(UserAuth.class, List.of(
new WhereCondition("email", "=", email)
), false);
if (out.size() >= 1) {
return Response.ok().build();
}
- return Response.status(404).build();
+ throw new NotFoundException("emain does not exist: '" + email + "'");
}
@@ -270,7 +273,7 @@ public class UserResource {
if (!passwodCheck.contentEquals(password)) {
throw new FailException(Response.Status.PRECONDITION_FAILED , "Password error ...");
}
- System.out.println(" ==> pass nearly all test : admin=" + user.admin + " blocked=" + user.blocked + " removed=" + user.removed);
+ logger.debug(" ==> pass nearly all test : admin={} blocked={} removed={}", user.admin, user.blocked, user.removed);
if (user.blocked || user.removed) {
throw new FailException(Response.Status.UNAUTHORIZED, "FAIL Authentiocate");
}
@@ -282,7 +285,7 @@ public class UserResource {
@PermitAll
@Consumes(MediaType.APPLICATION_JSON)
public GetToken getToken(DataGetToken data) throws Exception {
- UserAuth user = checkAuthUser(data.method, data.login, data.time, data.password);
+ UserAuth user = checkAuthUser(data.method(), data.login(), data.time(), data.password());
// at the point the user has been not deleted and not blocked.
// this authentication is valid only for Karso ==> not for the application
int expirationTimeInMinutes = ConfigVariable.getAuthExpirationTime();
@@ -293,7 +296,7 @@ public class UserResource {
// If the USER is not override, the system add by default USER
ssoRight.put("USER", true);
}
- System.out.println("Get new token with right: " + ssoRight);
+ logger.debug("Get new token with right: {}", ssoRight);
Map outRight = new HashMap<>();
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
@@ -305,7 +308,7 @@ public class UserResource {
newUser.lastConnection = Timestamp.valueOf(LocalDateTime.now());
SqlWrapper.update(newUser, user.id, List.of("lastConnection"));
- //System.out.println(" ==> generate token: " + ret);
+ //logger.debug(" ==> generate token: {}", ret);
return new GetToken(ret);
}
diff --git a/back/src/org/kar/karso/filter/KarsoAuthenticationFilter.java b/back/src/org/kar/karso/filter/KarsoAuthenticationFilter.java
index ec038d2..1f00f39 100644
--- a/back/src/org/kar/karso/filter/KarsoAuthenticationFilter.java
+++ b/back/src/org/kar/karso/filter/KarsoAuthenticationFilter.java
@@ -11,6 +11,8 @@ import jakarta.ws.rs.ext.Provider;
import org.kar.archidata.SqlWrapper;
import org.kar.archidata.model.UserByToken;
import org.kar.karso.model.ApplicationToken;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import jakarta.annotation.Priority;
@@ -18,6 +20,7 @@ import jakarta.annotation.Priority;
@Provider
@Priority(Priorities.AUTHENTICATION)
public class KarsoAuthenticationFilter extends AuthenticationFilter {
+ final Logger logger = LoggerFactory.getLogger(KarsoAuthenticationFilter.class);
//curl http://0.0.0.0:15080/karso/api/public_key/pem --output plop.txt -H "Authorization: Zota 1:U0sJM1m@-STSdfg4365fJOFUGbR4kFycBu1qGZPwf7gW6k2WWRBzTPUH7QutCgPw-SDss45_563sSDFdfg@dsf@456" --verbose
diff --git a/back/src/org/kar/karso/internal/Log.java b/back/src/org/kar/karso/internal/Log.java
deleted file mode 100644
index ab41540..0000000
--- a/back/src/org/kar/karso/internal/Log.java
+++ /dev/null
@@ -1,60 +0,0 @@
-package org.kar.karso.internal;
-
-//import io.scenarium.logger.LogLevel;
-//import io.scenarium.logger.Logger;
-
-public class Log {
-// private static final String LIB_NAME = "logger";
-// private static final String LIB_NAME_DRAW = Logger.getDrawableName(LIB_NAME);
-// private static final boolean PRINT_CRITICAL = Logger.getNeedPrint(LIB_NAME, LogLevel.CRITICAL);
-// private static final boolean PRINT_ERROR = Logger.getNeedPrint(LIB_NAME, LogLevel.ERROR);
-// private static final boolean PRINT_WARNING = Logger.getNeedPrint(LIB_NAME, LogLevel.WARNING);
-// private static final boolean PRINT_INFO = Logger.getNeedPrint(LIB_NAME, LogLevel.INFO);
-// private static final boolean PRINT_DEBUG = Logger.getNeedPrint(LIB_NAME, LogLevel.DEBUG);
-// private static final boolean PRINT_VERBOSE = Logger.getNeedPrint(LIB_NAME, LogLevel.VERBOSE);
-// private static final boolean PRINT_TODO = Logger.getNeedPrint(LIB_NAME, LogLevel.TODO);
-// private static final boolean PRINT_PRINT = Logger.getNeedPrint(LIB_NAME, LogLevel.PRINT);
-//
-// private Log() {}
-//
-// public static void print(String data) {
-// if (PRINT_PRINT)
-// Logger.print(LIB_NAME_DRAW, data);
-// }
-//
-// public static void todo(String data) {
-// if (PRINT_TODO)
-// Logger.todo(LIB_NAME_DRAW, data);
-// }
-//
-// public static void critical(String data) {
-// if (PRINT_CRITICAL)
-// Logger.critical(LIB_NAME_DRAW, data);
-// }
-//
-// public static void error(String data) {
-// if (PRINT_ERROR)
-// Logger.error(LIB_NAME_DRAW, data);
-// }
-//
-// public static void warning(String data) {
-// if (PRINT_WARNING)
-// Logger.warning(LIB_NAME_DRAW, data);
-// }
-//
-// public static void info(String data) {
-// if (PRINT_INFO)
-// Logger.info(LIB_NAME_DRAW, data);
-// }
-//
-// public static void debug(String data) {
-// if (PRINT_DEBUG)
-// Logger.debug(LIB_NAME_DRAW, data);
-// }
-//
-// public static void verbose(String data) {
-// if (PRINT_VERBOSE)
-// Logger.verbose(LIB_NAME_DRAW, data);
-// }
-
-}
diff --git a/back/src/org/kar/karso/model/DataGetToken.java b/back/src/org/kar/karso/model/DataGetToken.java
index db80665..a80f3fb 100644
--- a/back/src/org/kar/karso/model/DataGetToken.java
+++ b/back/src/org/kar/karso/model/DataGetToken.java
@@ -1,8 +1,41 @@
package org.kar.karso.model;
-public class DataGetToken {
- public String login;
- public String method;
- public String time;
- public String password;
+import java.nio.charset.StandardCharsets;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+
+public record DataGetToken(String login,
+ String method,
+ String time,
+ String password
+ ) {
+
+ /*public DataGetToken(String login, String method,
+ String time,
+ String password) {
+ this(login, method, time, password);
+ }*/
+
+ public static String sha512(String passwordToHash) { //, String salt){
+ String generatedPassword = null;
+ try {
+ MessageDigest md = MessageDigest.getInstance("SHA-512");
+ //md.update(salt.getBytes(StandardCharsets.UTF_8));
+ byte[] bytes = md.digest(passwordToHash.getBytes(StandardCharsets.UTF_8));
+ StringBuilder sb = new StringBuilder();
+ for(int i=0; i< bytes.length ;i++){
+ sb.append(Integer.toString((bytes[i] & 0xff) + 0x100, 16).substring(1));
+ }
+ generatedPassword = sb.toString();
+ } catch (NoSuchAlgorithmException e) {
+ e.printStackTrace();
+ }
+ return generatedPassword;
+ }
+ public static DataGetToken generate(String login, String method, String time, String password) {
+ return generateSha(login, method , time , sha512(password));
+ }
+ public static DataGetToken generateSha(String login, String method, String time, String password) {
+ return new DataGetToken(login, method , time , sha512("login='" + login + "';pass='" + password + "';date='" + time + "'"));
+ }
}
diff --git a/back/test/resources/simplelogger.properties b/back/test/resources/simplelogger.properties
new file mode 100644
index 0000000..4314b58
--- /dev/null
+++ b/back/test/resources/simplelogger.properties
@@ -0,0 +1,35 @@
+# SLF4J's SimpleLogger configuration file
+# Simple implementation of Logger that sends all enabled log messages, for all defined loggers, to System.err.
+# Default logging detail level for all instances of SimpleLogger.
+# Must be one of ("trace", "debug", "info", "warn", or "error").
+# If not specified, defaults to "info".
+org.slf4j.simpleLogger.defaultLogLevel=trace
+
+# Logging detail level for a SimpleLogger instance named "xxxxx".
+# Must be one of ("trace", "debug", "info", "warn", or "error").
+# If not specified, the default logging detail level is used.
+#org.slf4j.simpleLogger.log.xxxxx=
+
+# Set to true if you want the current date and time to be included in output messages.
+# Default is false, and will output the number of milliseconds elapsed since startup.
+#org.slf4j.simpleLogger.showDateTime=false
+
+# The date and time format to be used in the output messages.
+# The pattern describing the date and time format is the same that is used in java.text.SimpleDateFormat.
+# If the format is not specified or is invalid, the default format is used.
+# The default format is yyyy-MM-dd HH:mm:ss:SSS Z.
+#org.slf4j.simpleLogger.dateTimeFormat=yyyy-MM-dd HH:mm:ss:SSS Z
+
+# Set to true if you want to output the current thread name.
+# Defaults to true.
+org.slf4j.simpleLogger.showThreadName=true
+
+# Set to true if you want the Logger instance name to be included in output messages.
+# Defaults to true.
+#org.slf4j.simpleLogger.showLogName=true
+
+# Set to true if you want the last component of the name to be included in output messages.
+# Defaults to false.
+#org.slf4j.simpleLogger.showShortLogName=false
+
+
diff --git a/back/test/src/test/kar/karso/TestBase.java b/back/test/src/test/kar/karso/TestBase.java
index 216f0db..7889b2e 100644
--- a/back/test/src/test/kar/karso/TestBase.java
+++ b/back/test/src/test/kar/karso/TestBase.java
@@ -1,36 +1,277 @@
package test.kar.karso;
+import java.util.Map;
-import java.io.IOException;
-import java.net.URI;
-import java.net.http.HttpClient;
-import java.net.http.HttpRequest;
-import java.net.http.HttpResponse;
-
-
-
+import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.MethodOrderer;
+import org.junit.jupiter.api.Order;
import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.TestMethodOrder;
+import org.junit.jupiter.api.extension.ConditionEvaluationResult;
+import org.junit.jupiter.api.extension.ExecutionCondition;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.junit.jupiter.api.extension.ExtensionContext;
+import org.junit.jupiter.api.extension.TestExecutionExceptionHandler;
+import org.kar.archidata.exception.RESTErrorResponseExeption;
+import org.kar.archidata.model.GetToken;
+import org.kar.archidata.util.ConfigBaseVariable;
+import org.kar.archidata.util.JWTWrapper;
+import org.kar.archidata.util.RESTApi;
+import org.kar.karso.api.HealthCheck.HealthResult;
+import org.kar.karso.model.DataGetToken;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import com.nimbusds.jwt.JWTClaimsSet;
+
+@ExtendWith(StepwiseExtension.class)
+@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
public class TestBase {
+ final static Logger logger = LoggerFactory.getLogger(WebLauncherTest.class);
+ static WebLauncherTest webInterface = null;
+ static RESTApi api = null;
+
+
+ public void login(String login, String password) {
+ try {
+ GetToken token = api.post(GetToken.class, "users/get_token", DataGetToken.generate(login, "v1", "202515252", password));
+ api.setToken(token.jwt());
+ } catch (Exception ex) {
+ Assertions.fail("Can not get Authentication for '" + login + "' ==> " + ex.getMessage());
+ }
+ }
+
+ public void loginAdmin() {
+ login("karadmin", "adminA@666");
+ }
+
+ @BeforeAll
+ public static void configureWebServer() throws InterruptedException {
+ logger.info("configure server ...");
+ webInterface = new WebLauncherTest();
+ logger.info("Create DB");
+ webInterface.generateDB();
+ logger.info("Start REST (BEGIN)");
+ webInterface.process();
+ logger.info("Start REST (DONE)");
+ api = new RESTApi(ConfigBaseVariable.apiAdress);
+ }
+ @AfterAll
+ public static void stopWebServer() throws InterruptedException {
+ logger.info("Kill the web server");
+ webInterface = null;
+ // TODO: do it better...
+ }
+
+ @Order(1)
@Test
- public void getData() throws IOException, InterruptedException {
+ //@RepeatedTest(10)
+ public void checkHealthCheck() throws Exception {
+ HealthResult result = api.get(HealthResult.class, "health_check");
+ Assertions.assertEquals(result.value(), "alive and kicking");
+ }
+
+ @Order(2)
+ @Test
+ public void checkHealthCheckWrongAPI() throws Exception {
+ Assertions.assertThrows(RESTErrorResponseExeption.class, ()->api.get(HealthResult.class, "health_checks"));
+ }
+
+ @Order(3)
+ @Test
+ public void firstUserConnect() throws Exception {
+ GetToken result = api.post(GetToken.class, "users/get_token", DataGetToken.generate("karadmin", "v1", "202515252", "adminA@666"));
+ String[] splitted = result.jwt().split("\\.");
+ Assertions.assertEquals(3, splitted.length);
+ String authorization = result.jwt();
+ logger.debug(" validate token : " + authorization);
+ // Note with local access we get the internal key of the system.
+ JWTClaimsSet ret = JWTWrapper.validateToken(authorization, "KarAuth", null);
+ // check the token is valid !!! (signed and coherent issuer...
+ Assertions.assertNotNull(ret);
+ // check userID
+ String userUID = ret.getSubject();
+ long id = Long.parseLong(userUID);
+ Assertions.assertEquals(0, id);
+ String name = (String)ret.getClaim("login");
+ Assertions.assertEquals("karadmin", name);
+
- HttpClient client = HttpClient.newHttpClient();
- //HttpRequest request = HttpRequest.newBuilder().uri(URI.create("http://localhost:5125/health_check" + System.currentTimeMillis()))
- HttpRequest request = HttpRequest.newBuilder().uri(URI.create("https://gitea.atria-soft.org/"))
- .GET().build();
- /*
- HttpRequest request = HttpRequest.newBuilder().uri(URI.create("http://localhost:9200/indexname/typename/" + System.currentTimeMillis()))
- .POST(HttpRequest.BodyPublishers.ofString(jsonString)).setHeader("Content-Type", "application/json").build();
-*/
- HttpResponse httpResponse = client.send(request, HttpResponse.BodyHandlers.ofString());
+ Object rowRight = ret.getClaim("right");
+ Assertions.assertNotNull(rowRight);
+ Map> rights = (Map>) ret.getClaim("right");
+ // Check if the element contain the basic keys:
+ Assertions.assertEquals(rights.size(), 1);
+ Assertions.assertTrue(rights.containsKey("karso"));
+ Map applRight = rights.get("karso");
+ //logger.error("full right: {}", applRight);
+ Assertions.assertEquals(applRight.size(), 2);
+ Assertions.assertTrue(applRight.containsKey("ADMIN"));
+ Assertions.assertEquals(true, applRight.get("ADMIN"));
+ Assertions.assertTrue(applRight.containsKey("USER"));
+ Assertions.assertEquals(true, applRight.get("USER"));
+
+ //logger.debug("request user: '{}' right: '{}' row='{}'", userUID, applRight, rowRight);
+
+ //Assertions.assertEquals("eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9", splitted[0]);
+ //Assertions.assertEquals("eyJzdWIiOiIwIiwiYXBwbGljYXRpb24iOiJrYXJzbyIsImlzcyI6IkthckF1dGgiLCJyaWdodCI6eyJrYXJzbyI6eyJBRE1JTiI6dHJ1ZSwiVVNFUiI6dHJ1ZX19LCJsb2dpbiI6ImthcmFkbWluIiwiZXhwIjoxNjg0MTk5MTkzLCJpYXQiOjE2ODI3NTU0MjV9", splitted[1]);
+ // TODO ... Assertions.assertEquals("????", splitted[2]);
+ }
- Assertions.assertEquals(httpResponse.statusCode(), 200);
- System.out.println("========================================");
- System.out.println("retValue: " + httpResponse.statusCode());
- System.out.println("response: " + httpResponse.body());
- System.out.println("========================================");
+ public void checkFail(String type, String urlOffset, int errorStatus) {
+ checkFail(type, urlOffset, errorStatus, null);
+ }
+ public void checkFail(String type, String urlOffset, int errorStatus, String data) {
+ logger.info("Test API: url={} urlOffset={}", type, urlOffset);
+ try {
+ if ("GET".equals(type)) {
+ api.get(String.class, urlOffset);
+ } else if ("POST".equals(type)) {
+ api.post(String.class, urlOffset, data);
+ } else if ("PUT".equals(type)) {
+ api.put(String.class, urlOffset, data);
+ } else if ("DELETE".equals(type)) {
+ api.delete(String.class, urlOffset);
+ }
+ Assertions.fail("Request on URL does not fail as expected: '" + type + "' url='" + urlOffset + "'");
+ } catch (RESTErrorResponseExeption ex) {
+ if (errorStatus != ex.status) {
+ logger.error("Fail in test with the wrong return errors: {}", ex.toString());
+ }
+ Assertions.assertEquals(errorStatus, ex.status);
+ } catch (Exception ex) {
+ logger.error("Unexpected throw error: {}", ex);
+ Assertions.fail("Unexpected throws...");
+ }
}
-}
\ No newline at end of file
+ public void checkWork(String type, String urlOffset) {
+ checkWork(type, urlOffset, null);
+ }
+ public void checkWork(String type, String urlOffset, String data) {
+ logger.info("Test API: url={} urlOffset={}", type, urlOffset);
+ try {
+ if ("GET".equals(type)) {
+ api.get(String.class, urlOffset);
+ } else if ("POST".equals(type)) {
+ api.post(String.class, urlOffset, data);
+ } else if ("PUT".equals(type)) {
+ api.put(String.class, urlOffset, data);
+ } else if ("DELETE".equals(type)) {
+ api.delete(String.class, urlOffset);
+ }
+ //Assertions.fail("Request on URL does not fail as expected: '" + type + "' url='" + urlOffset + "'");
+ } catch (RESTErrorResponseExeption ex) {
+ Assertions.fail("Must not fail ... " + ex.toString());
+ } catch (Exception ex) {
+ logger.error("Unexpected throw error: {}", ex);
+ Assertions.fail("Unexpected throws...");
+ }
+
+ }
+ @Order(4)
+ @Test
+ public void checkUnAuthorizedAPI() throws Exception {
+ // /application/
+ checkFail("GET", "application/", 401);
+ checkFail("POST", "application/", 401, "{}");
+ checkFail("PUT", "application/", 405, "{}"); // does not exist
+ checkFail("DELETE", "application/", 405); // does not exist
+ // /application/{id}
+ checkFail("GET", "application/0", 401);
+ checkFail("PUT", "application/0", 401, "{}");
+ checkFail("POST", "application/0", 405, "{}");
+ checkFail("DELETE", "application/0", 401);
+ // /application/{id}/*
+ checkFail("GET", "application/0/users", 401);
+ // /application/*
+ checkFail("GET", "application/small", 401);
+ checkFail("GET", "application/get_token", 401);
+ checkFail("GET", "application/return", 401);
+
+ // /application_token/ section:
+ checkFail("GET", "application_token/0", 401);
+ checkFail("DELETE", "application_token/0/5", 401);
+ checkFail("DELETE", "application_token/0/create", 401);
+
+ // /front/*
+ checkFail("GET", "front", 404); // no index in test section
+ // health check
+ checkWork("GET", "health_check");
+
+ // public_key (only application)
+ checkFail("GET", "public_key", 401);
+ checkFail("GET", "public_key/pem", 401);
+
+
+ // /right
+ checkFail("GET", "right", 401);
+ checkFail("POST", "right", 401, "{}");
+ checkFail("GET", "right/0", 401);
+ checkFail("PUT", "right/0", 401, "{}");
+ checkFail("DELETE", "right/0", 401);
+
+ // /system_config
+ checkWork("GET", "system_config/is_sign_up_availlable");
+ checkFail("GET", "system_config/key/skjdfhkjsdhfkjsh", 401);
+ checkFail("PUT", "system_config/key/skjdfhkjsdhfkjsh", 401, "{}");
+
+ // /users
+ checkFail("GET", "users", 401);
+ checkFail("GET", "users/0", 401);
+ checkFail("POST", "users/0/application/0/link", 401, "{}");
+ checkFail("POST", "users/0/set_admin", 401, "{}");
+ checkFail("POST", "users/0/set_blocked", 401, "{}");
+ checkFail("POST", "users/create_new_user", 401, "{}");
+ checkFail("GET", "users/me", 401, "{}");
+ checkFail("POST", "users/password", 401, "{}");
+ checkWork("GET", "users/check_login?login=karadmin");
+ checkFail("GET", "users/check_login?login=jhkjhkjh", 404);
+ checkWork("GET", "users/check_email?email=admin@admin.ZZZ");
+ checkFail("GET", "users/check_email?email=ksjhdkjfhskjdh", 404);
+ // not testable : get_token
+
+ }
+
+ @Order(5)
+ @Test
+ public void testMeWithToken() throws Exception {
+ this.loginAdmin();
+ String result = api.get(String.class, "users/me");
+ Assertions.assertEquals("{\"id\":0,\"login\":\"karadmin\"}", result);
+
+ }
+
+
+}
+
+
+class StepwiseExtension implements ExecutionCondition, TestExecutionExceptionHandler {
+ @Override
+ public ConditionEvaluationResult evaluateExecutionCondition(ExtensionContext extensionContext) {
+ ExtensionContext.Namespace namespace = namespaceFor(extensionContext);
+ ExtensionContext.Store store = storeFor(extensionContext, namespace);
+ String value = store.get(StepwiseExtension.class, String.class);
+ return value == null ? ConditionEvaluationResult.enabled("No test failures in stepwise tests") :
+ ConditionEvaluationResult.disabled(String.format("Stepwise test disabled due to previous failure in '%s'", value));
+ }
+
+ @Override
+ public void handleTestExecutionException(ExtensionContext extensionContext, Throwable throwable) throws Throwable {
+ ExtensionContext.Namespace namespace = namespaceFor(extensionContext);
+ ExtensionContext.Store store = storeFor(extensionContext, namespace);
+ store.put(StepwiseExtension.class, extensionContext.getDisplayName());
+ throw throwable;
+ }
+
+ private ExtensionContext.Namespace namespaceFor(ExtensionContext extensionContext){
+ return ExtensionContext.Namespace.create(StepwiseExtension.class, extensionContext.getParent());
+ }
+
+
+ private ExtensionContext.Store storeFor(ExtensionContext extensionContext, ExtensionContext.Namespace namespace){
+ return extensionContext.getParent().get().getStore(namespace);
+ }
+}
diff --git a/back/test/src/test/kar/karso/WebLauncherTest.java b/back/test/src/test/kar/karso/WebLauncherTest.java
new file mode 100755
index 0000000..3d1c4f1
--- /dev/null
+++ b/back/test/src/test/kar/karso/WebLauncherTest.java
@@ -0,0 +1,25 @@
+
+package test.kar.karso;
+
+import org.kar.archidata.util.ConfigBaseVariable;
+import org.kar.karso.WebLauncher;
+import org.kar.karso.util.ConfigVariable;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class WebLauncherTest extends WebLauncher {
+ final Logger logger = LoggerFactory.getLogger(WebLauncherTest.class);
+ public WebLauncherTest() {
+ logger.debug("Configure REST system");
+ // for local test:
+ ConfigBaseVariable.apiAdress = "http://127.0.0.1:12345/test/api/";
+ ConfigBaseVariable.dbPort = "3306";
+ // create a unique key for test ==> not retrieve the token every load...
+ ConfigVariable.uuid_for_key_generation = "lkjlkjlkjlmkjqmwlsdkjqfsdlkf,nmQLSDK,NFMQLKSdjmlKQJSDMLQK,S;ndmLQKZNERMA,ÉL";
+ // for the test we a in memory sqlite..
+ ConfigBaseVariable.dbType = "sqlite";
+ ConfigBaseVariable.dbHost = "memory";
+ // for test we need to connect all time the DB
+ ConfigBaseVariable.dbKeepConnected = "true";
+ }
+}