From 8a700864d68e529bef8aece9cdf59f545fb94400 Mon Sep 17 00:00:00 2001 From: Edouard DUPIN Date: Mon, 8 May 2023 23:31:50 +0200 Subject: [PATCH] [DEV] migration and right in progress --- back/src/org/kar/karso/WebLauncher.java | 38 ++++---- back/src/org/kar/karso/WebLauncherLocal.java | 17 ++-- .../kar/karso/api/ApplicationResource.java | 87 +++++++++---------- .../karso/api/ApplicationTokenResource.java | 1 + back/src/org/kar/karso/api/UserResource.java | 5 +- .../kar/karso/migration/Initialization.java | 33 +++++-- back/src/org/kar/karso/model/UserAuth.java | 2 - back/test/src/test/kar/karso/TestBase.java | 15 ++-- .../src/test/kar/karso/WebLauncherTest.java | 7 +- docker-compose.yaml | 4 +- .../application-user-edit.html | 4 +- .../application-user-edit.ts | 42 +++++++-- .../base/scene/application/applications.html | 4 + .../base/scene/application/applications.ts | 29 ++++--- front/src/base/service/application-token.ts | 2 +- front/src/base/service/application.ts | 60 ++++++++++++- 16 files changed, 223 insertions(+), 127 deletions(-) diff --git a/back/src/org/kar/karso/WebLauncher.java b/back/src/org/kar/karso/WebLauncher.java index 509ed2d..fbf3144 100755 --- a/back/src/org/kar/karso/WebLauncher.java +++ b/back/src/org/kar/karso/WebLauncher.java @@ -39,7 +39,9 @@ public class WebLauncher { final static Logger LOGGER = LoggerFactory.getLogger(WebLauncher.class); protected ResourceConfig rc = null; HttpServer server = null; - public WebLauncher() {} + public WebLauncher() { + ConfigBaseVariable.bdDatabase = "karso"; + } private static URI getBaseURI() { return UriBuilder.fromUri(ConfigBaseVariable.getlocalAddress()).build(); } @@ -52,15 +54,13 @@ public class WebLauncher { WebLauncher.LOGGER.info("STOP the REST server:"); } - public void generateDB() throws Exception { + public void migrateDB() throws Exception { MigrationEngine migrationEngine = new MigrationEngine(); migrationEngine.setInit(new Initialization()); - migrationEngine.migrate(DBEntry.createInterface(GlobalConfiguration.dbConfig)); + migrationEngine.migrate(GlobalConfiguration.dbConfig); } public void process() throws InterruptedException { - ConfigBaseVariable.bdDatabase = "karso"; - try { JWTWrapper.initLocalToken(ConfigVariable.getUUIDKeyRoot()); } catch (Exception e1) { @@ -71,33 +71,29 @@ public class WebLauncher { return; } - - // =================================================================== // Configure resources // =================================================================== rc = new ResourceConfig(); // global authentication system - rc.register(new OptionFilter()); - // remove cors ==> all time called by an other system... - rc.register(new CORSFilter()); - rc.registerClasses(KarsoAuthenticationFilter.class); + rc.register(OptionFilter.class); + rc.register(CORSFilter.class); + rc.register(KarsoAuthenticationFilter.class); // register exception catcher rc.register(InputExceptionCatcher.class); rc.register(SystemExceptionCatcher.class); rc.register(FailExceptionCatcher.class); rc.register(FailException404API.class); rc.register(ExceptionCatcher.class); - // add default resource: - rc.registerClasses(UserResource.class); - rc.registerClasses(PublicKeyResource.class); - rc.registerClasses(ApplicationResource.class); - rc.registerClasses(ApplicationTokenResource.class); - rc.registerClasses(SystemConfigResource.class); - rc.registerClasses(RightResource.class); - rc.registerClasses(Front.class); - rc.registerClasses(HealthCheck.class); + rc.register(UserResource.class); + rc.register(PublicKeyResource.class); + rc.register(ApplicationResource.class); + rc.register(ApplicationTokenResource.class); + rc.register(SystemConfigResource.class); + rc.register(RightResource.class); + rc.register(Front.class); + rc.register(HealthCheck.class); // add jackson to be discover when we are ins stand-alone server rc.register(JacksonFeature.class); // enable this to show low level request @@ -117,7 +113,7 @@ public class WebLauncher { // =================================================================== try { server.start(); - LOGGER.debug("Jersey app started at {}", getBaseURI()); + LOGGER.info("Jersey app started at {}", getBaseURI()); } catch (Exception e) { LOGGER.error("There was an error while starting Grizzly HTTP server."); e.printStackTrace(); diff --git a/back/src/org/kar/karso/WebLauncherLocal.java b/back/src/org/kar/karso/WebLauncherLocal.java index 1ccaba9..2e0ce65 100755 --- a/back/src/org/kar/karso/WebLauncherLocal.java +++ b/back/src/org/kar/karso/WebLauncherLocal.java @@ -1,11 +1,6 @@ package org.kar.karso; -import java.sql.PreparedStatement; -import java.sql.ResultSet; - -import org.kar.archidata.GlobalConfiguration; -import org.kar.archidata.db.DBEntry; import org.kar.archidata.util.ConfigBaseVariable; import org.kar.karso.util.ConfigVariable; import org.slf4j.Logger; @@ -29,11 +24,21 @@ public class WebLauncherLocal extends WebLauncher { ConfigBaseVariable.apiAdress = "http://0.0.0.0:15080/karso/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"; + ConfigVariable.uuid_for_key_generation = "lkjlkjlkjlmkjqmwlsdkjqfsdlkf,nmQLSDKNFMQLKSdjmlKQJSDMLQKSndmLQKZNERMAL"; //ConfigBaseVariable.dbType = "sqlite"; //ConfigBaseVariable.dbHost = "./bdd_base.sqlite"; } + try { + super.migrateDB(); + } catch (Exception e) { + // TODO Auto-generated catch block + e.printStackTrace(); + while (true) { + logger.error("Migration fail ==> waiting intervention of administrator..."); + Thread.sleep(60*60*1000); + } + } super.process(); } } diff --git a/back/src/org/kar/karso/api/ApplicationResource.java b/back/src/org/kar/karso/api/ApplicationResource.java index 50dd525..2aaa72a 100755 --- a/back/src/org/kar/karso/api/ApplicationResource.java +++ b/back/src/org/kar/karso/api/ApplicationResource.java @@ -187,6 +187,27 @@ public class ApplicationResource { } return out; } + + public record AddUserData(long userId) {}; + // TODO : review the function to correct admin only access... + @POST + @Path("{id}/users") + @RolesAllowed(value= {"ADMIN"}) + public boolean addUser(@PathParam("id") Long applicationId, AddUserData data) throws Exception { + logger.debug("getApplications"); + SqlWrapper.addLink(UserAuth.class, data.userId, "application", applicationId); + return true; + } + + // TODO : review the function to correct admin only access... + @DELETE + @Path("{id}/users") + @RolesAllowed(value= {"ADMIN"}) + public boolean rmUser(@PathParam("id") Long applicationId, AddUserData data) throws Exception { + logger.debug("getApplications"); + SqlWrapper.removeLink(UserAuth.class, data.userId, "application", applicationId); + return true; + } @GET @Path("get_token") @@ -224,52 +245,26 @@ public class ApplicationResource { logger.error(" result: {}", result); return Response.status(401).entity(result).build(); } - if (false) { - // the application id is not streamed in the application liny in the where elements - // get the local user: - UserAuth localUser = null; - try { - localUser = SqlWrapper.get(UserAuth.class, gc.userByToken.id); - } catch (Exception e) { - // TODO Auto-generated catch block - e.printStackTrace(); - String result = "SERVER Internal error"; - logger.error(" result: {}", result); - return Response.status(500).entity(result).build(); - } - if (localUser == null) { - String result = "Authenticate-wrong results '" + applicationName + "')"; - logger.error(" result: {}", result); - return Response.status(401).entity(result).build(); - } - 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 + "'"; - logger.error(" result: {}", result); - return Response.status(401).entity(result).build(); - } - } else { - UserLinkApplication links = null; - try { - links = SqlWrapper.getWhere(UserLinkApplication.class, - List.of( - new WhereCondition("user_id", "=", gc.userByToken.id), - new WhereCondition("deleted", "=", 0), - new WhereCondition("application_id", "=", appl.id) - ), false); - } catch (Exception e) { - // TODO Auto-generated catch block - e.printStackTrace(); - String result = "SERVER Internal error"; - logger.error(" result: {}", result); - return Response.status(500).entity(result).build(); - } - if (links == null) { - String result = "Authenticate impossible ==> application not accessible '" + applicationName + "'"; - logger.error(" result: {}", result); - return Response.status(401).entity(result).build(); - } - } + UserLinkApplication links = null; + try { + links = SqlWrapper.getWhere(UserLinkApplication.class, + List.of( + new WhereCondition("user_id", "=", gc.userByToken.id), + new WhereCondition("deleted", "=", 0), + new WhereCondition("application_id", "=", appl.id) + ), false); + } catch (Exception e) { + // TODO Auto-generated catch block + e.printStackTrace(); + String result = "SERVER Internal error"; + logger.error(" result: {}", result); + return Response.status(500).entity(result).build(); + } + if (links == null) { + String result = "Authenticate impossible ==> application not accessible '" + applicationName + "'"; + logger.error(" result: {}", result); + return Response.status(401).entity(result).build(); + } // Get the USER Right Map applicationRight = RightResource.getUserRight(gc.userByToken.id, appl.id); if (!applicationRight.containsKey("USER")) { diff --git a/back/src/org/kar/karso/api/ApplicationTokenResource.java b/back/src/org/kar/karso/api/ApplicationTokenResource.java index a7c3d85..0462c7e 100755 --- a/back/src/org/kar/karso/api/ApplicationTokenResource.java +++ b/back/src/org/kar/karso/api/ApplicationTokenResource.java @@ -50,6 +50,7 @@ public class ApplicationTokenResource { } return values; } + @DELETE @Path("{applicationId}/{tokenId}") @RolesAllowed(value= {"ADMIN"}) diff --git a/back/src/org/kar/karso/api/UserResource.java b/back/src/org/kar/karso/api/UserResource.java index 44c6d08..49dbc3a 100755 --- a/back/src/org/kar/karso/api/UserResource.java +++ b/back/src/org/kar/karso/api/UserResource.java @@ -9,6 +9,7 @@ import org.kar.archidata.exception.FailException; import org.kar.archidata.exception.InputException; import org.kar.archidata.exception.SystemException; import org.kar.archidata.filter.GenericContext; +import org.kar.karso.migration.Initialization; import org.kar.karso.model.*; import org.kar.karso.util.ConfigVariable; import org.slf4j.Logger; @@ -290,8 +291,8 @@ public class UserResource { // this authentication is valid only for Karso ==> not for the application int expirationTimeInMinutes = ConfigVariable.getAuthExpirationTime(); - // Get the USER Right (Note: by construction KARSO have application ID = 0 - Map ssoRight = RightResource.getUserRight(user.id, 0); + // Get the USER Right (Note: by construction KARSO have application ID = KARSO_INITIALISATION_ID + Map ssoRight = RightResource.getUserRight(user.id, Initialization.KARSO_INITIALISATION_ID); if (!ssoRight.containsKey("USER")) { // If the USER is not override, the system add by default USER ssoRight.put("USER", true); diff --git a/back/src/org/kar/karso/migration/Initialization.java b/back/src/org/kar/karso/migration/Initialization.java index c1b7a7e..3dd2f89 100644 --- a/back/src/org/kar/karso/migration/Initialization.java +++ b/back/src/org/kar/karso/migration/Initialization.java @@ -1,6 +1,5 @@ package org.kar.karso.migration; -import org.kar.archidata.migration.MigrationModel; import org.kar.archidata.migration.MigrationSqlStep; import org.kar.karso.model.Application; import org.kar.karso.model.ApplicationToken; @@ -11,29 +10,29 @@ import org.kar.karso.model.UserAuth; public class Initialization extends MigrationSqlStep { + public static final int KARSO_INITIALISATION_ID = 1; + @Override public String getName() { - return Initialization.class.getCanonicalName(); + return "Initialization"; } public Initialization() throws Exception { - addClass(Settings.class); addClass(UserAuth.class); addClass(Application.class); addClass(ApplicationToken.class); addClass(RightDescription.class); addClass(Right.class); - addClass(MigrationModel.class); - // default admin: "karadmin" password: "adminA@666" addAction(""" INSERT INTO `application` (`id`, `name`, `description`, `redirect`, `redirectDev`, `notification`, `ttl`) VALUES - ('0', 'karso', 'Root SSO interface', 'http://atria-soft/karso', '', '', '666'); + (1, 'karso', 'Root SSO interface', 'http://atria-soft/karso', '', '', 666); """); + // default admin: "karadmin" password: "adminA@666" addAction(""" INSERT INTO `user` (`id`, `login`, `password`, `email`, `admin`) VALUES - ('0', 'karadmin', '0ddcac5ede3f1300a1ce5948ab15112f2810130531d578ab8bc4dc131652d7cf7a3ff6e827eb957bff43bc2c65a6a1d46722e5b3a2343ac3176a33ea7250080b', + (1, 'karadmin', '0ddcac5ede3f1300a1ce5948ab15112f2810130531d578ab8bc4dc131652d7cf7a3ff6e827eb957bff43bc2c65a6a1d46722e5b3a2343ac3176a33ea7250080b', 'admin@admin.ZZZ', 1); """); addAction(""" @@ -45,11 +44,27 @@ public class Initialization extends MigrationSqlStep { """); addAction(""" INSERT INTO `rightDescription` (`id`, `applicationId`, `key`, `title`, `description`, `type`) VALUES - (0, 0, 'ADMIN', 'Administrator', 'Full administrator Right', 'BOOLEAN'); + (1, 1, 'ADMIN', 'Administrator', 'Full administrator Right', 'BOOLEAN'); """); addAction(""" INSERT INTO `right` (`applicationId`, `userId`, `rightDescriptionId`, `value`) VALUES - (0, 0, 0, 'true'); + (1, 1, 1, 'true'); + """); + // we generate an offset to permit to manage some generic upgrade in the future... + addAction(""" + ALTER TABLE application AUTO_INCREMENT = 1000; + """); + addAction(""" + ALTER TABLE user AUTO_INCREMENT = 1000; + """); + addAction(""" + ALTER TABLE settings AUTO_INCREMENT = 1000; + """); + addAction(""" + ALTER TABLE right AUTO_INCREMENT = 1000; + """); + addAction(""" + ALTER TABLE rightDescription AUTO_INCREMENT = 1000; """); } diff --git a/back/src/org/kar/karso/model/UserAuth.java b/back/src/org/kar/karso/model/UserAuth.java index 97ea299..6af605a 100644 --- a/back/src/org/kar/karso/model/UserAuth.java +++ b/back/src/org/kar/karso/model/UserAuth.java @@ -30,8 +30,6 @@ public class UserAuth extends User { @SQLLimitSize(512) @SQLNotNull public String email; - @SQLNotNull - @SQLDefault("'0'") public Timestamp emailValidate; // time of validation @SQLLimitSize(512) public String newEmail; diff --git a/back/test/src/test/kar/karso/TestBase.java b/back/test/src/test/kar/karso/TestBase.java index 6bdb8fe..3b9c2af 100644 --- a/back/test/src/test/kar/karso/TestBase.java +++ b/back/test/src/test/kar/karso/TestBase.java @@ -1,7 +1,4 @@ package test.kar.karso; -import java.io.IOException; -import java.sql.PreparedStatement; -import java.sql.ResultSet; import java.util.Map; import org.junit.jupiter.api.AfterAll; @@ -16,9 +13,7 @@ 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.GlobalConfiguration; import org.kar.archidata.SqlWrapper; -import org.kar.archidata.db.DBEntry; import org.kar.archidata.exception.RESTErrorResponseExeption; import org.kar.archidata.model.GetToken; import org.kar.archidata.util.ConfigBaseVariable; @@ -54,16 +49,18 @@ public class TestBase { } @BeforeAll - public static void configureWebServer() throws InterruptedException { + public static void configureWebServer() throws Exception { logger.info("configure server ..."); webInterface = new WebLauncherTest(); logger.info("Create DB"); - String dbName = "qsqsdqsdqsdqsd"; + String dbName = "sdfsdfsdfsfsdfsfsfsfsdfsdfsd"; boolean data = SqlWrapper.isDBExist(dbName); - logger.error(" - {}", data); + logger.error("exist: {}", data); data = SqlWrapper.createDB(dbName); - logger.error(" - {}", data); + logger.error("create: {}", data); + data = SqlWrapper.isDBExist(dbName); + logger.error("exist: {}", data); System.exit(-1); logger.info("Start REST (BEGIN)"); diff --git a/back/test/src/test/kar/karso/WebLauncherTest.java b/back/test/src/test/kar/karso/WebLauncherTest.java index e54425c..de3a4d8 100755 --- a/back/test/src/test/kar/karso/WebLauncherTest.java +++ b/back/test/src/test/kar/karso/WebLauncherTest.java @@ -24,11 +24,8 @@ public class WebLauncherTest extends WebLauncher { ////ConfigBaseVariable.dbKeepConnected = "true"; - ConfigBaseVariable.dbHost = "192.168.14.100"; - ConfigBaseVariable.dbPort = "20006"; + ConfigBaseVariable.dbHost = "localhost"; ConfigBaseVariable.dbUser = "root"; - ConfigBaseVariable.dbPassword = "password"; - ConfigBaseVariable.bdDatabase = ""; - + ConfigBaseVariable.dbPassword = "ZERTYSDGFVHSDFGHJYZSDFGSQxfgsqdfgsqdrf4564654"; } } diff --git a/docker-compose.yaml b/docker-compose.yaml index c9c9064..ace3475 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -10,7 +10,7 @@ services: ports: - 3306:3306 volumes: - - /workspace/data/global/db:/var/lib/mysql + - ./db:/var/lib/mysql mem_limit: 400m healthcheck: test: ["CMD", "mysqladmin" ,"ping", "-h", "localhost"] @@ -24,7 +24,7 @@ services: - karauth_db_service # # condition: service_healthy ports: - - 17079:8080 + - 10079:8080 links: - karauth_db_service:db #read_only: true diff --git a/front/src/base/scene/application-user-edit/application-user-edit.html b/front/src/base/scene/application-user-edit/application-user-edit.html index ca1e3f6..52b72c5 100644 --- a/front/src/base/scene/application-user-edit/application-user-edit.html +++ b/front/src/base/scene/application-user-edit/application-user-edit.html @@ -47,9 +47,9 @@ {{user.id}} {{user.login}} - diff --git a/front/src/base/scene/application-user-edit/application-user-edit.ts b/front/src/base/scene/application-user-edit/application-user-edit.ts index a2420dd..3799cc4 100644 --- a/front/src/base/scene/application-user-edit/application-user-edit.ts +++ b/front/src/base/scene/application-user-edit/application-user-edit.ts @@ -96,13 +96,45 @@ export class ApplicationUserEditScene implements OnInit { */ } + onRemoveApplicationUser(value: boolean, user: any) { + console.log(`changeState : ${JSON.stringify(value, null, 2)}`); + const self = this; + this.applicationService.rmUser(this.id, user.id) + .then((response: boolean) => { + if (response === true) { + self.notUsers.push(user); + const index = self.users.indexOf(user, 0); + if (index > -1) { + self.users.splice(index, 1); + } + } else { + // TODO: manage error + } + }) + .catch((error: any) => { + console.log(`return ERROR ${JSON.stringify(error, null, 2)}`); + }); + //this.cdr.detectChanges(); + } onAddApplicationUser(value: boolean, user: any) { console.log(`changeState : ${JSON.stringify(value, null, 2)}`); - - j'en suis la ... add user une application - //this.createTokenDisabled = value; - // we do not change the main ref ==> notify angular that something have change and need to be re-render??? - this.cdr.detectChanges(); + const self = this; + this.applicationService.addUser(this.id, user.id) + .then((response: boolean) => { + if (response === true) { + self.users.push(user); + const index = self.notUsers.indexOf(user, 0); + if (index > -1) { + self.notUsers.splice(index, 1); + } + } else { + // TODO: manage error + } + }) + .catch((error: any) => { + console.log(`return ERROR ${JSON.stringify(error, null, 2)}`); + }); + //this.cdr.detectChanges(); } formatTimestamp(unix_timestamp: number) { diff --git a/front/src/base/scene/application/applications.html b/front/src/base/scene/application/applications.html index c492879..54e1bfe 100644 --- a/front/src/base/scene/application/applications.html +++ b/front/src/base/scene/application/applications.html @@ -28,6 +28,10 @@ (click)="onEditApplication($event, application)" type="submit"> edit   +