From 7c75c737d7ffe8dbe7db940d4c464ecc76349fe7 Mon Sep 17 00:00:00 2001 From: Edouard DUPIN Date: Thu, 25 May 2023 23:17:50 +0200 Subject: [PATCH] Base of right ready (no add only on bdd) --- back/pom.xml | 4 +- back/src/org/kar/karso/WebLauncherLocal.java | 2 +- back/src/org/kar/karso/api/RightResource.java | 113 ++++++++++++------ back/src/org/kar/karso/api/UserResource.java | 19 +-- .../org/kar/karso/model/RightDescription.java | 3 + .../application-user-right-edit.ts | 26 +--- front/src/base/service/admin-user.ts | 13 +- front/src/common/service/http-wrapper.ts | 28 +++-- 8 files changed, 119 insertions(+), 89 deletions(-) diff --git a/back/pom.xml b/back/pom.xml index 272ef17..ec47e0b 100644 --- a/back/pom.xml +++ b/back/pom.xml @@ -3,7 +3,7 @@ 4.0.0 org.kar karso - 0.4.1 + 0.4.2 diff --git a/back/src/org/kar/karso/WebLauncherLocal.java b/back/src/org/kar/karso/WebLauncherLocal.java index 2e0ce65..0adcadf 100755 --- a/back/src/org/kar/karso/WebLauncherLocal.java +++ b/back/src/org/kar/karso/WebLauncherLocal.java @@ -24,7 +24,7 @@ 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,nmQLSDKNFMQLKSdjmlKQJSDMLQKSndmLQKZNERMAL"; + ConfigVariable.uuid_for_key_generation = "lkjlkjlkjlmkjqmwlsdkjqfsdlkf88QJSDMLQKSndmLQKZNERMAL"; //ConfigBaseVariable.dbType = "sqlite"; //ConfigBaseVariable.dbHost = "./bdd_base.sqlite"; diff --git a/back/src/org/kar/karso/api/RightResource.java b/back/src/org/kar/karso/api/RightResource.java index 33f6574..9d6a965 100644 --- a/back/src/org/kar/karso/api/RightResource.java +++ b/back/src/org/kar/karso/api/RightResource.java @@ -4,8 +4,13 @@ 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; @@ -20,49 +25,46 @@ import java.util.Map; public class RightResource { final static Logger logger = LoggerFactory.getLogger(RightResource.class); - - public static Object transform(String type, String value) { - if ("BOOLEAN".equals(type)) { - return Boolean.valueOf(value); - } else if ("STRING".equals(type)) { - return value; - } else if ("LONG".equals(type)) { - return Long.valueOf(value); - } else if ("NUMBER".equals(type)) { - return Double.valueOf(value); - } else { - return null; - } + public static List getApplicationRightDecription(long applicationId) throws Exception { + return SqlWrapper.getsWhere(RightDescription.class, + List.of( + new WhereCondition("applicationId", "=", applicationId), + new WhereCondition("deleted", "=", 0) + )); } - public static Map getUserRight(long userId, long applicationId) throws Exception { - Map out = new HashMap<>(); - List rightsDescriptions = SqlWrapper.getsWhere(RightDescription.class, - List.of( - new WhereCondition("applicationId", "=", applicationId), - new WhereCondition("deleted", "=", 0) - )); - logger.debug("Get some descriptions: {} applicationId={}", rightsDescriptions.size(), applicationId); - if (rightsDescriptions != null && rightsDescriptions.size() != 0) { - List rights = SqlWrapper.getsWhere(Right.class, + public static List getRawUserRight(long userId, long applicationId) throws Exception { + return SqlWrapper.getsWhere(Right.class, List.of( new WhereCondition("applicationId", "=", applicationId), new WhereCondition("userId", "=", userId), new WhereCondition("deleted", "=", 0) )); + } + + public static Map getUserRight(long userId, long applicationId) throws Exception { + Map out = new HashMap<>(); + List rightsDescriptions = getApplicationRightDecription(applicationId); + logger.debug("Get some descriptions: {} applicationId={}", rightsDescriptions.size(), applicationId); + if (rightsDescriptions != null && rightsDescriptions.size() != 0) { + List rights = getRawUserRight(userId, applicationId); logger.debug("Get some user right: {}userID={}", rights.size(), userId); - if (rights != null && rights.size() != 0) { - for (Right right: rights) { - RightDescription description = rightsDescriptions.stream() - .filter(elem -> right.rightDescriptionId == elem.id) - .findAny() - .orElse(null); - if (description != null) { - out.put(description.key, transform(description.type, right.value)); - } + for (RightDescription description : rightsDescriptions) { + if (description == null) { + // TODO: this is a really strange case to manage later... + continue; + } + Right right = rights.stream() + .filter(elem -> elem.rightDescriptionId == description.id) + .findAny() + .orElse(null); + if (right != null) { + out.put(description.key, Transform.convertToType(description.type, right.value)); + } else if (description.defaultValue != null){ + out.put(description.key, Transform.convertToType(description.type, description.defaultValue)); + } else { + out.put(description.key, null); } - } else { - logger.debug("The User have no specific right..."); } } else { // the application does not manage right with Karso (normal use-case) @@ -70,6 +72,49 @@ public class RightResource { } return out; } + public static void updateUserRight(long userId, long applicationId, Map delta) throws Exception { + List rightsDescriptions = getApplicationRightDecription(applicationId); + logger.debug("Get some descriptions: {} applicationId={}", rightsDescriptions.size(), applicationId); + if (rightsDescriptions == null || rightsDescriptions.size() == 0) { + throw new IllegalArgumentException("Request change right on an application that does not manage any right"); + } + List rights = getRawUserRight(userId, applicationId); + logger.debug("Get some user right: {}userID={}", rights.size(), userId); + for (RightDescription description : rightsDescriptions) { + if (description == null) { + // TODO: this is a really strange case to manage later... + continue; + } + Object newValue = delta.get(description.key); + if (newValue == null) { + //No need to update or create... + continue; + } + String convertedValue = Transform.convertToStringCheck(description.type, newValue); + if (convertedValue == null) { + throw new IllegalArgumentException("Uncompatible value:'" + description.type + "'"); + } + Right right = rights.stream() + .filter(elem -> elem.rightDescriptionId == description.id) + .findAny() + .orElse(null); + if (right != null) { + // The value exist, we need to update it + logger.debug("Request update a knonwn parameter: {} with {}", description.key, newValue); + right.value = convertedValue; + SqlWrapper.update(right, right.id, List.of("value")); + } else { + // we need to create it + logger.debug("Request create parameter: {} with {}", description.key, newValue); + right = new Right(); + right.applicationId = applicationId; + right.userId = userId; + right.rightDescriptionId = description.id; + right.value = convertedValue; + SqlWrapper.insert(right); + } + } + } @GET diff --git a/back/src/org/kar/karso/api/UserResource.java b/back/src/org/kar/karso/api/UserResource.java index 4caf9f6..1b5ecab 100755 --- a/back/src/org/kar/karso/api/UserResource.java +++ b/back/src/org/kar/karso/api/UserResource.java @@ -86,28 +86,21 @@ public class UserResource { @GET @Path("{userId}/application/{applicationId}/rights") @RolesAllowed("ADMIN") - public List getApplicationRight(@Context SecurityContext sc, + public Map getApplicationRight(@Context SecurityContext sc, @PathParam("userId") long userId, @PathParam("applicationId") long applicationId) throws Exception { - return SqlWrapper.getsWhere(Right.class, List.of( - new WhereCondition("applicationId", "=", applicationId), - new WhereCondition("userId", "=", userId)), - false); + return RightResource.getUserRight(userId, applicationId); } + @PUT @Path("{userId}/application/{applicationId}/rights") @RolesAllowed("ADMIN") - public List patchApplicationRight(@Context SecurityContext sc, + public Map patchApplicationRight(@Context SecurityContext sc, @PathParam("userId") long userId, @PathParam("applicationId") long applicationId, Map data) throws Exception { logger.info("get data from FRONT: {}", data); - /* - return SqlWrapper.getsWhere(Right.class, List.of( - new WhereCondition("applicationId", "=", applicationId), - new WhereCondition("userId", "=", userId)), - false); - */ - return null; + RightResource.updateUserRight(userId, applicationId, data); + return RightResource.getUserRight(userId, applicationId); } // TODO: check this it might be deprecated ... diff --git a/back/src/org/kar/karso/model/RightDescription.java b/back/src/org/kar/karso/model/RightDescription.java index f88ab6f..17c2220 100644 --- a/back/src/org/kar/karso/model/RightDescription.java +++ b/back/src/org/kar/karso/model/RightDescription.java @@ -31,6 +31,9 @@ public class RightDescription extends GenericTable { @SQLLimitSize(1024) @SQLComment("Description of the right") public String description; + @SQLLimitSize(1024) + @SQLComment("default value if Never set") + public String defaultValue; @SQLNotNull @SQLLimitSize(16) @SQLComment("Type of the property") diff --git a/front/src/base/scene/application-user-right-edit/application-user-right-edit.ts b/front/src/base/scene/application-user-right-edit/application-user-right-edit.ts index 5812098..b074226 100644 --- a/front/src/base/scene/application-user-right-edit/application-user-right-edit.ts +++ b/front/src/base/scene/application-user-right-edit/application-user-right-edit.ts @@ -10,7 +10,7 @@ import { AdminUserService, ApplicationModel, ApplicationService, ApplicationUser import { ApplicationRightModel } from 'base/service/application'; import { SettingType, SettingsItem } from '../manage-accounts/manage-accounts'; import { UserService } from 'common/service'; -import { isUndefined } from 'common/utils'; +import { isNullOrUndefined, isUndefined } from 'common/utils'; import { AsyncActionState } from 'common/component'; @@ -29,7 +29,7 @@ export class applicationUserRightEditScene implements OnInit { rowRight: ApplicationRightModel[] = []; applicationName: string; userName: string; - userRights: ApplicationUserRight[] = []; + userRights: ApplicationUserRight = {}; constructor( private settingService: SettingsService, @@ -81,7 +81,7 @@ export class applicationUserRightEditScene implements OnInit { this.userAdminService .getApplicationRights(this.userId, this.applicationId) - .then((userRights: ApplicationUserRight[]) => { + .then((userRights: ApplicationUserRight) => { console.log(`getApplicationRights OK response: ${JSON.stringify(userRights, null, 4)}`); self.userRights = userRights; self.configureEditInput(); @@ -130,24 +130,8 @@ export class applicationUserRightEditScene implements OnInit { for (let iii = 0; iii < this.rowRight.length; iii++) { const elem = this.rowRight[iii]; let value = undefined; - for (let jjj = 0; jjj < this.userRights.length; jjj++) { - const elemRight = this.userRights[jjj]; - if (elemRight.rightDescriptionId == elem.id) { - value = elemRight.value; - break; - } - } - // TODO: maybe transfer this in the SERVER API.... - if (!isUndefined(value)) { - if (elem.type === "BOOLEAN") { - value = value.toLowerCase() == 'true'; - } else if (elem.type === "STRING") { - // nothing to do... - } else if (elem.type === "LONG" || elem.type === "NUMBER") { - value = Number(value); - } else { - console.error(`Can not interpret type of the input value model: ${elem.type}`); - } + if (!isNullOrUndefined(this.userRights[elem.key])) { + value = this.userRights[elem.key]; } tmp.push({ type: SettingType.BOOLEAN, diff --git a/front/src/base/service/admin-user.ts b/front/src/base/service/admin-user.ts index a4f5499..18f0269 100644 --- a/front/src/base/service/admin-user.ts +++ b/front/src/base/service/admin-user.ts @@ -32,10 +32,7 @@ interface MessageAnswer_USER_CONNECT { avatar: string; } */ -export interface ApplicationUserRight { - rightDescriptionId: number; - value: string; -} +export type ApplicationUserRight = Object; @Injectable() export class AdminUserService { @@ -354,8 +351,8 @@ export class AdminUserService { }); }); } - // !!!!! la fonction ci dessous ne retourne pas des élément bijectif avec la fuction courente et c'est un problème... - getApplicationRights(userId: number, applicationId: number): Promise { + + getApplicationRights(userId: number, applicationId: number): Promise { const self = this; return new Promise((resolve, reject) => { this.http @@ -373,12 +370,12 @@ export class AdminUserService { resolve(response.data); }) .catch((error: any) => { - reject(`return ERROR ${JSON.stringify(error, null, 2)}`); + reject(error); }); }); } - updateApplicationRights(userId: number, applicationId: number, dataUpdate: object): Promise { + updateApplicationRights(userId: number, applicationId: number, dataUpdate: object): Promise { const self = this; return new Promise((resolve, reject) => { this.http diff --git a/front/src/common/service/http-wrapper.ts b/front/src/common/service/http-wrapper.ts index 4b8bcdd..e42b25f 100644 --- a/front/src/common/service/http-wrapper.ts +++ b/front/src/common/service/http-wrapper.ts @@ -69,9 +69,6 @@ export class HttpWrapperService { } request(properties: HTTPRequest): Promise { - //uriRest:string, headerOption:any, params:any): Promise<{status:number, data:any}> { - //console.log(`-------------------------------------------------------\nHTTP-wrapper GET '${ properties.endPoint }'\n\t\tparams=${ JSON.stringify(properties, null, 2)}`); - let connectionAddresses = this.createRESTCall2({ server: properties.server, api: properties.endPoint, @@ -87,7 +84,6 @@ export class HttpWrapperService { if (properties.requestType !== HTTPRequestModel.GET) { headers['Content-Type'] = properties.contentType; } - //console.log(`disble tocken : ${JSON.stringify(properties)} properties.disableTocken=${properties.disableTocken}`); if ( properties.disableTocken === undefined || properties.disableTocken === null || @@ -119,7 +115,7 @@ export class HttpWrapperService { response .json() .then((value: any) => { - //console.log(`REICEIVE ==> ${response.status}=${ JSON.stringify(value, null, 2)}`); + //console.log(`RECEIVE ==> ${response.status}=${ JSON.stringify(value, null, 2)}`); resolve({ status: response.status, data: value }); }) .catch((reason: any) => { @@ -135,7 +131,13 @@ export class HttpWrapperService { } }) .catch((error: any) => { - reject({ status: error.status, data: error.error }); + reject({ + time: Date(), + status: 999, + error: error, + statusMessage: "Fetch error", + message: "http-wrapper.ts detect an error in the fetch request" + }); }); }); } @@ -164,7 +166,13 @@ export class HttpWrapperService { } }) .catch((error: any) => { - reject({ status: error.status, data: error.error }); + reject({ + time: Date(), + status: 999, + error: error, + statusMessage: "Fetch image error", + message: "http-wrapper.ts detect an error in the fetch request" + }); }); }); } @@ -258,13 +266,13 @@ export class HttpWrapperService { post(uriRest: string, headerOption: any, data: any, progress: ProgressCallback = null) { //console.log(`-------------------------------------------------------\nHTTP-wrapper POST '${ uriRest }'\n\t\theaderOption=${ JSON.stringify(headerOption, null, 2)}\n\t\tdata=${ JSON.stringify(data, null, 2)}`); this.addTokenIfNeeded(headerOption); - let connectionAdresse = this.createRESTCall(uriRest, {}); + let connectionAddresses = this.createRESTCall(uriRest, {}); return new Promise((resolve, reject) => { if (this.displayReturn === true) { - console.log(`call POST ${connectionAdresse} data=${JSON.stringify(data, null, 2)}`); + console.log(`call POST ${connectionAddresses} data=${JSON.stringify(data, null, 2)}`); } - let request = this.http.post(connectionAdresse, data, { + let request = this.http.post(connectionAddresses, data, { headers: new HttpHeaders(headerOption), reportProgress: true, observe: 'events',