[FEAT] update with a correct type of right management ==> not ready

This commit is contained in:
Edouard DUPIN 2025-01-26 23:40:13 +01:00
parent cbc0705a79
commit 396455d611
10 changed files with 38 additions and 71 deletions

View File

@ -20,7 +20,7 @@
<dependency>
<groupId>kangaroo-and-rabbit</groupId>
<artifactId>archidata</artifactId>
<version>0.20.5-SNAPSHOT</version>
<version>0.21.1-SNAPSHOT</version>
</dependency>
<!-- Loopback of logger JDK logging API to SLF4J -->
<dependency>

View File

@ -15,6 +15,7 @@ import org.kar.archidata.dataAccess.options.Condition;
import org.kar.archidata.exception.InputException;
import org.kar.archidata.exception.SystemException;
import org.kar.archidata.filter.GenericContext;
import org.kar.archidata.filter.PartRight;
import org.kar.archidata.tools.JWTWrapper;
import org.kar.karso.model.AddUserData;
import org.kar.karso.model.Application;
@ -284,10 +285,10 @@ public class ApplicationResource {
"Authenticate impossible ==> application not accessible '" + applicationName + "'");
}
// Get the USER Right
final Map<String, Object> applicationRight = RightResource.getUserRight(gc.userByToken.id, appl.id);
final Map<String, PartRight> applicationRight = RightResource.getUserRight(gc.userByToken.id, appl.id);
if (!applicationRight.containsKey("USER")) {
// If the USER is not override, the system add by default USER
applicationRight.put("USER", true);
applicationRight.put("USER", PartRight.READ_WRITE);
}
final Map<String, Object> outRight = new HashMap<>();
// we set the right in the under map to manage multiple application group right.

View File

@ -9,9 +9,9 @@ import org.kar.archidata.dataAccess.DataAccess;
import org.kar.archidata.dataAccess.QueryAnd;
import org.kar.archidata.dataAccess.QueryCondition;
import org.kar.archidata.dataAccess.options.Condition;
import org.kar.archidata.filter.PartRight;
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;
@ -44,8 +44,8 @@ public class RightResource {
// Formatter:on
}
public static Map<String, Object> getUserRight(final long userId, final long applicationId) throws Exception {
final Map<String, Object> out = new HashMap<>();
public static Map<String, PartRight> getUserRight(final long userId, final long applicationId) throws Exception {
final Map<String, PartRight> out = new HashMap<>();
final List<RightDescription> rightsDescriptions = getApplicationRightDecription(applicationId);
LOGGER.trace("Get some descriptions: {} applicationId={}", rightsDescriptions.size(), applicationId);
if (rightsDescriptions != null && rightsDescriptions.size() != 0) {
@ -62,8 +62,7 @@ public class RightResource {
if (description == null) {
continue;
}
LOGGER.trace(" - id={} key={} type={} default={}", description.id, description.key, description.type,
description.defaultValue);
LOGGER.trace(" - id={} key={}", description.id, description.key);
}
for (final RightDescription description : rightsDescriptions) {
if (description == null) {
@ -72,11 +71,7 @@ public class RightResource {
final Right right = rights.stream().filter(elem -> elem.rightDescriptionId.equals(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);
out.put(description.key, right.value);
}
}
} else {
@ -86,7 +81,7 @@ public class RightResource {
return out;
}
public static void updateUserRight(final long userId, final long applicationId, final Map<String, Object> delta)
public static void updateUserRight(final long userId, final long applicationId, final Map<String, PartRight> delta)
throws Exception {
final List<RightDescription> rightsDescriptions = getApplicationRightDecription(applicationId);
LOGGER.debug("Get some descriptions: {} applicationId={}", rightsDescriptions.size(), applicationId);
@ -100,15 +95,11 @@ public class RightResource {
// TODO: this is a really strange case to manage later...
continue;
}
final Object newValue = delta.get(description.key);
final PartRight newValue = delta.get(description.key);
if (newValue == null) {
//No need to update or create...
continue;
}
final String convertedValue = Transform.convertToStringCheck(description.type, newValue);
if (convertedValue == null) {
throw new IllegalArgumentException("Uncompatible value:'" + description.type + "'");
}
final List<Right> allRights = rights.stream().filter(elem -> elem.rightDescriptionId.equals(description.id))
.toList();
if (allRights.size() > 1) {
@ -122,7 +113,8 @@ public class RightResource {
final Right right = allRights.get(0);
// The value exist, we need to update it
LOGGER.debug("Request update a knonwn parameter: {} with {}", description.key, newValue);
right.value = convertedValue;
right.value = newValue;
// TODO: maybe need to remove the value instead of set a new one ...
DataAccess.update(right, right.id, List.of("value"));
} else {
// we need to create it
@ -131,7 +123,7 @@ public class RightResource {
right.applicationId = applicationId;
right.userId = userId;
right.rightDescriptionId = description.id;
right.value = convertedValue;
right.value = newValue;
DataAccess.insert(right);
}
}

View File

@ -20,6 +20,7 @@ import org.kar.archidata.dataAccess.options.ReadAllColumn;
import org.kar.archidata.exception.FailException;
import org.kar.archidata.exception.SystemException;
import org.kar.archidata.filter.GenericContext;
import org.kar.archidata.filter.PartRight;
import org.kar.archidata.model.GetToken;
import org.kar.archidata.tools.JWTWrapper;
import org.kar.karso.migration.Initialization;
@ -124,7 +125,7 @@ public class UserResource {
@GET
@Path("{userId}/application/{applicationId}/rights")
@RolesAllowed("ADMIN")
public Map<String, Object> getApplicationRight(
public Map<String, PartRight> getApplicationRight(
@Context final SecurityContext sc,
@PathParam("userId") final long userId,
@PathParam("applicationId") final long applicationId) throws Exception {
@ -135,11 +136,11 @@ public class UserResource {
@Path("{userId}/application/{applicationId}/rights")
@RolesAllowed("ADMIN")
@Consumes(MediaType.APPLICATION_JSON)
public Map<String, Object> patchApplicationRight(
public Map<String, PartRight> patchApplicationRight(
@Context final SecurityContext sc,
@PathParam("userId") final long userId,
@PathParam("applicationId") final long applicationId,
final Map<String, Object> data) throws Exception {
final Map<String, PartRight> data) throws Exception {
this.LOGGER.info("Patch data from FRONT: {}", data);
RightResource.updateUserRight(userId, applicationId, data);
return RightResource.getUserRight(userId, applicationId);
@ -168,13 +169,14 @@ public class UserResource {
newRight.applicationId = appKarso.id;
newRight.userId = userId;
newRight.rightDescriptionId = rightsDescription.id;
newRight.value = "true";
newRight.value = PartRight.READ_WRITE;
da.insert(newRight);
return;
} else if (right.value.equals("true")) {
} else if (PartRight.READ_WRITE.equals(right.value)) {
return;
}
right.value = "true";
// TODO: maybe remove ???
right.value = PartRight.READ_WRITE;
final long ret = da.update(right, right.id, List.of("value"));
if (ret == 0) {
throw new FailException(Response.Status.NOT_MODIFIED, "Fail to modify user as an admin.");
@ -252,7 +254,7 @@ public class UserResource {
if (user == null) {
throw new SystemException("Fail to retrieve the user... (impossible case)");
}
if (user.id != gc.userByToken.id) {
if (!user.id.equals(gc.userByToken.id)) {
throw new SystemException("Try to change the password of an other user !!! You are BAD...");
}
// Process the update:
@ -321,11 +323,11 @@ public class UserResource {
// this authentication is valid only for Karso ==> not for the application
final int expirationTimeInMinutes = ConfigVariable.getAuthExpirationTime();
// Get the USER Right (Note: by construction KARSO have application ID = KARSO_INITIALISATION_ID
final Map<String, Object> ssoRight = RightResource.getUserRight(user.id,
final Map<String, PartRight> 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);
ssoRight.put("USER", PartRight.READ_WRITE);
}
LOGGER.debug("Get new token with right: {}", ssoRight);
final Map<String, Object> outRight = new HashMap<>();

View File

@ -4,6 +4,7 @@ import java.util.List;
import org.kar.archidata.dataAccess.DBAccess;
import org.kar.archidata.dataAccess.addOnSQL.AddOnManyToMany;
import org.kar.archidata.filter.PartRight;
import org.kar.archidata.migration.MigrationSqlStep;
import org.kar.karso.api.UserResource;
import org.kar.karso.model.Application;
@ -91,8 +92,6 @@ public class Initialization extends MigrationSqlStep {
rightDescription.key = "ADMIN";
rightDescription.title = "Administrator";
rightDescription.description = "Full administrator Right";
rightDescription.type = "BOOLEAN";
rightDescription.defaultValue = "false";
this.rightDescription = da.insert(rightDescription);
});
addAction((final DBAccess da) -> {
@ -100,7 +99,7 @@ public class Initialization extends MigrationSqlStep {
right.applicationId = this.app.id;
right.userId = this.user.id;
right.rightDescriptionId = this.rightDescription.id;
right.value = "true";
right.value = PartRight.READ_WRITE;
da.insert(right);
});
// we generate an offset to permit to manage some generic upgrade in the future...

View File

@ -1,6 +1,7 @@
package org.kar.karso.model;
import org.kar.archidata.annotation.DataIfNotExists;
import org.kar.archidata.filter.PartRight;
import org.kar.archidata.model.GenericDataSoftDelete;
import com.fasterxml.jackson.annotation.JsonInclude;
@ -15,7 +16,6 @@ import jakarta.persistence.Table;
@DataIfNotExists
@JsonInclude(JsonInclude.Include.NON_NULL)
public class Right extends GenericDataSoftDelete {
@Column(nullable = false)
@Schema(description = "application-ID that have the reference of the right")
@ManyToOne(fetch = FetchType.LAZY, targetEntity = Application.class)
@ -30,5 +30,5 @@ public class Right extends GenericDataSoftDelete {
public Long rightDescriptionId;
@Column(length = 1024, nullable = false)
@Schema(description = "Value of the right")
public String value;
public PartRight value;
}

View File

@ -10,7 +10,6 @@ import jakarta.persistence.Column;
import jakarta.persistence.FetchType;
import jakarta.persistence.ManyToOne;
import jakarta.persistence.Table;
import jakarta.ws.rs.DefaultValue;
@Table(name = "rightDescription")
@DataIfNotExists
@ -29,11 +28,4 @@ public class RightDescription extends GenericDataSoftDelete {
@Column(length = 1024, nullable = false)
@Schema(description = "Description of the right")
public String description;
@Column(length = 1024)
@Schema(description = "default value if Never set")
public String defaultValue;
@Column(length = 16, nullable = false)
@Schema(description = "Type of the property")
@DefaultValue("\"BOOLEAN\"")
public String type = "BOOLEAN"; // this is a place-holder (current type supported BOOLEAN)
}

View File

@ -11,6 +11,8 @@ import org.junit.jupiter.api.Order;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestMethodOrder;
import org.junit.jupiter.api.extension.ExtendWith;
import org.kar.archidata.filter.PartRight;
import org.kar.archidata.filter.RightSafeCaster;
import org.kar.archidata.model.GetToken;
import org.kar.archidata.tools.ConfigBaseVariable;
import org.kar.archidata.tools.JWTWrapper;
@ -84,17 +86,17 @@ public class TestBase {
final Object rowRight = ret.getClaim("right");
Assertions.assertNotNull(rowRight);
final Map<String, Map<String, Object>> rights = (Map<String, Map<String, Object>>) ret.getClaim("right");
final Map<String, Map<String, PartRight>> rights = RightSafeCaster.safeCastAndTransform(ret.getClaim("right"));
// Check if the element contain the basic keys:
Assertions.assertEquals(rights.size(), 1);
Assertions.assertTrue(rights.containsKey("karso"));
final Map<String, Object> applRight = rights.get("karso");
final Map<String, PartRight> 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.assertEquals(PartRight.READ_WRITE, applRight.get("ADMIN"));
Assertions.assertTrue(applRight.containsKey("USER"));
Assertions.assertEquals(true, applRight.get("USER"));
Assertions.assertEquals(PartRight.READ_WRITE, applRight.get("USER"));
//logger.debug("request user: '{}' right: '{}' row='{}'", userUID, applRight, rowRight);

View File

@ -16,7 +16,7 @@ import org.kar.archidata.model.GetToken;
import org.kar.archidata.tools.ConfigBaseVariable;
import org.kar.archidata.tools.RESTApi;
import org.kar.karso.model.DataGetToken;
import org.kar.karso.model.UserAuthGet;
import org.kar.karso.model.UserAuth;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -57,7 +57,7 @@ public class TestUsers {
@Order(1)
@Test
public void getsValue() throws RESTErrorResponseException, IOException, InterruptedException {
final List<UserAuthGet> listUsers = api.gets(UserAuthGet.class, TestUsers.ENDPOINT_NAME);
final List<UserAuth> listUsers = api.gets(UserAuth.class, TestUsers.ENDPOINT_NAME);
Assertions.assertNotNull(listUsers);
Assertions.assertEquals(1, listUsers.size());
Assertions.assertEquals(1, listUsers.get(0).id);

View File

@ -1,33 +1,12 @@
package test.kar.karso;
import org.kar.archidata.tools.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 private static 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";
if (!"true".equalsIgnoreCase(System.getenv("TEST_E2E_MODE"))) {
ConfigBaseVariable.dbType = "sqlite";
ConfigBaseVariable.dbHost = "memory";
// for test we need to connect all time the DB
ConfigBaseVariable.dbKeepConnected = "true";
}
//ConfigBaseVariable.dbHost = "localhost";
//ConfigBaseVariable.dbUser = "root";
//ConfigBaseVariable.dbPassword = "ZERTYSDGFVHSDFGHJYZSDFGSQxfgsqdfgsqdrf4564654";
}
public WebLauncherTest() {}
}