[DEV] continue integrations
This commit is contained in:
parent
659f9ca306
commit
26ba20d964
2
pom.xml
2
pom.xml
@ -3,7 +3,7 @@
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>kangaroo-and-rabbit</groupId>
|
||||
<artifactId>archidata</artifactId>
|
||||
<version>0.5.0</version>
|
||||
<version>0.5.1</version>
|
||||
<properties>
|
||||
<maven.compiler.version>3.1</maven.compiler.version>
|
||||
<maven.compiler.source>21</maven.compiler.source>
|
||||
|
@ -480,7 +480,7 @@ public class DataAccess {
|
||||
if (options != null) {
|
||||
final CheckFunction check = options.get(CheckFunction.class);
|
||||
if (check != null) {
|
||||
check.getChecker().check(data, null);
|
||||
check.getChecker().check(data, AnnotationTools.getFieldsNames(clazz));
|
||||
}
|
||||
}
|
||||
|
||||
@ -655,11 +655,11 @@ public class DataAccess {
|
||||
* @param jsonData Json data (partial) values to update
|
||||
* @return the number of object updated
|
||||
* @throws Exception */
|
||||
public static <T, ID_TYPE> int updateWithJson(final Class<T> clazz, final ID_TYPE id, final String jsonData) throws Exception {
|
||||
return updateWhereWithJson(clazz, getTableIdCondition(clazz, id), jsonData);
|
||||
public static <T, ID_TYPE> int updateWithJson(final Class<T> clazz, final ID_TYPE id, final String jsonData, final QueryOptions options) throws Exception {
|
||||
return updateWhereWithJson(clazz, getTableIdCondition(clazz, id), jsonData, options);
|
||||
}
|
||||
|
||||
public static <T> int updateWhereWithJson(final Class<T> clazz, final QueryItem condition, final String jsonData) throws Exception {
|
||||
public static <T> int updateWhereWithJson(final Class<T> clazz, final QueryItem condition, final String jsonData, final QueryOptions options) throws Exception {
|
||||
final ObjectMapper mapper = new ObjectMapper();
|
||||
// parse the object to be sure the data are valid:
|
||||
final T data = mapper.readValue(jsonData, clazz);
|
||||
@ -668,7 +668,8 @@ public class DataAccess {
|
||||
final List<String> keys = new ArrayList<>();
|
||||
final var iterator = root.fieldNames();
|
||||
iterator.forEachRemaining(e -> keys.add(e));
|
||||
return updateWhere(data, condition, null, keys);
|
||||
// TODO: set the filter in the Options...
|
||||
return updateWhere(data, condition, options, keys);
|
||||
}
|
||||
|
||||
public static <T, ID_TYPE> int update(final T data, final ID_TYPE id) throws Exception {
|
||||
|
@ -38,7 +38,7 @@ import jakarta.ws.rs.ext.Provider;
|
||||
@Provider
|
||||
@Priority(Priorities.AUTHENTICATION)
|
||||
public class AuthenticationFilter implements ContainerRequestFilter {
|
||||
final Logger logger = LoggerFactory.getLogger(AuthenticationFilter.class);
|
||||
private final static Logger LOGGER = LoggerFactory.getLogger(AuthenticationFilter.class);
|
||||
@Context
|
||||
private ResourceInfo resourceInfo;
|
||||
protected final String applicationName;
|
||||
@ -57,7 +57,7 @@ public class AuthenticationFilter implements ContainerRequestFilter {
|
||||
final Method method = this.resourceInfo.getResourceMethod();
|
||||
// Access denied for all
|
||||
if (method.isAnnotationPresent(DenyAll.class)) {
|
||||
this.logger.debug(" ==> deny all {}", requestContext.getUriInfo().getPath());
|
||||
LOGGER.debug(" ==> deny all {}", requestContext.getUriInfo().getPath());
|
||||
requestContext.abortWith(Response.status(Response.Status.FORBIDDEN).entity("Access blocked !!!").build());
|
||||
return;
|
||||
}
|
||||
@ -70,7 +70,7 @@ public class AuthenticationFilter implements ContainerRequestFilter {
|
||||
}
|
||||
// this is a security guard, all the API must define their access level:
|
||||
if (!method.isAnnotationPresent(RolesAllowed.class)) {
|
||||
this.logger.error(" ==> missing @RolesAllowed {}", requestContext.getUriInfo().getPath());
|
||||
LOGGER.error(" ==> missing @RolesAllowed {}", requestContext.getUriInfo().getPath());
|
||||
requestContext.abortWith(Response.status(Response.Status.FORBIDDEN).entity("Access ILLEGAL !!!").build());
|
||||
return;
|
||||
}
|
||||
@ -94,7 +94,7 @@ public class AuthenticationFilter implements ContainerRequestFilter {
|
||||
final boolean isJwtToken = isTokenBasedAuthentication(authorizationHeader);
|
||||
// Validate the Authorization header data Model "Yota jwt.to.ken" "Zota tokenId:hash(token)"
|
||||
if (!isApplicationToken && !isJwtToken) {
|
||||
this.logger.warn("REJECTED unauthorized: {}", requestContext.getUriInfo().getPath());
|
||||
LOGGER.warn("REJECTED unauthorized: {}", requestContext.getUriInfo().getPath());
|
||||
abortWithUnauthorized(requestContext, "REJECTED unauthorized: " + requestContext.getUriInfo().getPath());
|
||||
return;
|
||||
}
|
||||
@ -106,12 +106,12 @@ public class AuthenticationFilter implements ContainerRequestFilter {
|
||||
try {
|
||||
userByToken = validateJwtToken(token);
|
||||
} catch (final Exception e) {
|
||||
this.logger.error("Fail to validate token: {}", e.getMessage());
|
||||
LOGGER.error("Fail to validate token: {}", e.getMessage());
|
||||
abortWithUnauthorized(requestContext, "Fail to validate token: " + e.getMessage());
|
||||
return;
|
||||
}
|
||||
if (userByToken == null) {
|
||||
this.logger.warn("get a NULL user ...");
|
||||
LOGGER.warn("get a NULL user ...");
|
||||
abortWithUnauthorized(requestContext, "get a NULL user ...");
|
||||
return;
|
||||
}
|
||||
@ -122,12 +122,12 @@ public class AuthenticationFilter implements ContainerRequestFilter {
|
||||
try {
|
||||
userByToken = validateToken(token);
|
||||
} catch (final Exception e) {
|
||||
this.logger.error("Fail to validate token: {}", e.getMessage());
|
||||
LOGGER.error("Fail to validate token: {}", e.getMessage());
|
||||
abortWithUnauthorized(requestContext, "Fail to validate token: " + e.getMessage());
|
||||
return;
|
||||
}
|
||||
if (userByToken == null) {
|
||||
this.logger.warn("get a NULL application ...");
|
||||
LOGGER.warn("get a NULL application ...");
|
||||
abortWithUnauthorized(requestContext, "get a NULL application ...");
|
||||
return;
|
||||
}
|
||||
@ -149,7 +149,7 @@ public class AuthenticationFilter implements ContainerRequestFilter {
|
||||
}
|
||||
// Is user valid?
|
||||
if (!haveRight) {
|
||||
this.logger.error("REJECTED not enought right : {} require: {}", requestContext.getUriInfo().getPath(), roles);
|
||||
LOGGER.error("REJECTED not enought right : {} require: {}", requestContext.getUriInfo().getPath(), roles);
|
||||
requestContext.abortWith(Response.status(Response.Status.UNAUTHORIZED).entity("Not enought RIGHT !!!").build());
|
||||
return;
|
||||
}
|
||||
@ -175,15 +175,15 @@ public class AuthenticationFilter implements ContainerRequestFilter {
|
||||
|
||||
// Abort the filter chain with a 401 status code response
|
||||
// The WWW-Authenticate header is sent along with the response
|
||||
this.logger.warn("abortWithUnauthorized:");
|
||||
LOGGER.warn("abortWithUnauthorized:");
|
||||
final RestErrorResponse ret = new RestErrorResponse(Response.Status.UNAUTHORIZED, "Unauthorized", message);
|
||||
this.logger.error("Error UUID={}", ret.uuid);
|
||||
LOGGER.error("Error UUID={}", ret.uuid);
|
||||
requestContext.abortWith(Response.status(ret.status).header(HttpHeaders.WWW_AUTHENTICATE, AUTHENTICATION_SCHEME + " base64(HEADER).base64(CONTENT).base64(KEY)").entity(ret)
|
||||
.type(MediaType.APPLICATION_JSON).build());
|
||||
}
|
||||
|
||||
protected UserByToken validateToken(final String authorization) throws Exception {
|
||||
this.logger.info("Must be Override by the application implmentation, otherwise it dose not work");
|
||||
LOGGER.info("Must be Override by the application implmentation, otherwise it dose not work");
|
||||
return null;
|
||||
}
|
||||
|
||||
@ -193,7 +193,7 @@ public class AuthenticationFilter implements ContainerRequestFilter {
|
||||
final JWTClaimsSet ret = JWTWrapper.validateToken(authorization, "KarAuth", null);
|
||||
// check the token is valid !!! (signed and coherent issuer...
|
||||
if (ret == null) {
|
||||
this.logger.error("The token is not valid: '{}'", authorization);
|
||||
LOGGER.error("The token is not valid: '{}'", authorization);
|
||||
return null;
|
||||
}
|
||||
// check userID
|
||||
@ -209,7 +209,7 @@ public class AuthenticationFilter implements ContainerRequestFilter {
|
||||
if (rights.containsKey(this.applicationName)) {
|
||||
user.right = rights.get(this.applicationName);
|
||||
} else {
|
||||
this.logger.error("Connect with no right for this application='{}' full Right='{}'", this.applicationName, rights);
|
||||
LOGGER.error("Connect with no right for this application='{}' full Right='{}'", this.applicationName, rights);
|
||||
}
|
||||
}
|
||||
// logger.debug("request user: '{}' right: '{}' row='{}'", userUID, user.right, rowRight);
|
||||
|
35
src/org/kar/archidata/migration/model/Migration1.java
Normal file
35
src/org/kar/archidata/migration/model/Migration1.java
Normal file
@ -0,0 +1,35 @@
|
||||
package org.kar.archidata.migration.model;
|
||||
|
||||
import org.kar.archidata.annotation.DataComment;
|
||||
import org.kar.archidata.annotation.DataDefault;
|
||||
import org.kar.archidata.annotation.DataIfNotExists;
|
||||
import org.kar.archidata.model.GenericDataSoftDelete;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonInclude;
|
||||
|
||||
import jakarta.persistence.Column;
|
||||
import jakarta.persistence.Table;
|
||||
|
||||
// For logs only
|
||||
//public static final String TABLE_NAME = "KAR_migration";
|
||||
|
||||
@Table(name = "KAR_migration")
|
||||
@DataIfNotExists
|
||||
@JsonInclude(JsonInclude.Include.NON_NULL)
|
||||
public class Migration1 extends GenericDataSoftDelete {
|
||||
final static int VERSION_MIGRATION = 1;
|
||||
@DataComment("Name of the migration")
|
||||
@Column(length = 256)
|
||||
public String name;
|
||||
@Column(nullable = false)
|
||||
@DataDefault("'0'")
|
||||
@DataComment("if the migration is well terminated or not")
|
||||
public Boolean terminated = false;
|
||||
@DataComment("index in the migration progression")
|
||||
public Integer stepId = 0;
|
||||
@DataComment("number of element in the migration")
|
||||
public Integer count;
|
||||
@DataComment("Log generate by the migration")
|
||||
@Column(length = 0)
|
||||
public String log = "";
|
||||
}
|
@ -51,13 +51,13 @@ class TestSigner implements JWSSigner {
|
||||
@Override
|
||||
public Set<JWSAlgorithm> supportedJWSAlgorithms() {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
return Set.of(JWSAlgorithm.RS256);
|
||||
}
|
||||
|
||||
@Override
|
||||
public JCAContext getJCAContext() {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
return new JCAContext();
|
||||
}
|
||||
}
|
||||
|
||||
@ -209,8 +209,9 @@ public class JWTWrapper {
|
||||
try {
|
||||
// On the consumer side, parse the JWS and verify its RSA signature
|
||||
final SignedJWT signedJWT = SignedJWT.parse(signedToken);
|
||||
|
||||
if (rsaPublicJWK == null) {
|
||||
if (ConfigBaseVariable.getTestMode() && signedToken.endsWith(TestSigner.test_signature)) {
|
||||
LOGGER.warn("Someone use a test token: {}", signedToken);
|
||||
} else if (rsaPublicJWK == null) {
|
||||
LOGGER.warn("JWT public key is not present !!!");
|
||||
if (!ConfigBaseVariable.getTestMode()) {
|
||||
return null;
|
||||
@ -251,16 +252,16 @@ public class JWTWrapper {
|
||||
return null;
|
||||
}
|
||||
|
||||
public static String createJwtTestToken(final long userID, final String userLogin, final String isuer, final String application, final Map<String, Object> rights) {
|
||||
public static String createJwtTestToken(final long userID, final String userLogin, final String isuer, final String application, final Map<String, Map<String, Object>> rights) {
|
||||
if (!ConfigBaseVariable.getTestMode()) {
|
||||
LOGGER.error("Test mode disable !!!!!");
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
final int timeOutInMunites = 3600 * 24 * 31;
|
||||
final int timeOutInMunites = 3600;
|
||||
|
||||
final Date now = new Date();
|
||||
final Date expiration = new Date(new Date().getTime() - 60 * timeOutInMunites * 1000 /* millisecond */);
|
||||
final Date expiration = new Date(new Date().getTime() + timeOutInMunites * 1000 /* ms */);
|
||||
|
||||
final JWTClaimsSet.Builder builder = new JWTClaimsSet.Builder().subject(Long.toString(userID)).claim("login", userLogin).claim("application", application).issuer(isuer).issueTime(now)
|
||||
.expirationTime(expiration); // Do not ask why we need a "-" here ... this have no meaning
|
||||
@ -278,7 +279,8 @@ public class JWTWrapper {
|
||||
// serialize the output...
|
||||
return signedJWT.serialize();
|
||||
} catch (final Exception ex) {
|
||||
LOGGER.error("Can not generate Test Token...");
|
||||
ex.printStackTrace();
|
||||
LOGGER.error("Can not generate Test Token... {}", ex.getLocalizedMessage());
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
@ -16,6 +16,7 @@ import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.fasterxml.jackson.core.type.TypeReference;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.fasterxml.jackson.databind.exc.MismatchedInputException;
|
||||
|
||||
import jakarta.ws.rs.core.HttpHeaders;
|
||||
|
||||
@ -60,8 +61,12 @@ public class RESTApi {
|
||||
final HttpResponse<String> httpResponse = client.send(request, HttpResponse.BodyHandlers.ofString());
|
||||
if (httpResponse.statusCode() < 200 || httpResponse.statusCode() >= 300) {
|
||||
// LOGGER.error("catch error from REST API: {}", httpResponse.body());
|
||||
final RESTErrorResponseExeption out = mapper.readValue(httpResponse.body(), RESTErrorResponseExeption.class);
|
||||
throw new RESTErrorResponseExeption(out.uuid, out.time, out.error, out.message, out.status, out.statusMessage);
|
||||
try {
|
||||
final RESTErrorResponseExeption out = mapper.readValue(httpResponse.body(), RESTErrorResponseExeption.class);
|
||||
throw new RESTErrorResponseExeption(out.uuid, out.time, out.error, out.message, out.status, out.statusMessage);
|
||||
} catch (final MismatchedInputException ex) {
|
||||
throw new IOException("Fail to get the data [" + httpResponse.statusCode() + "] " + httpResponse.body());
|
||||
}
|
||||
}
|
||||
// LOGGER.error("status code: {}", httpResponse.statusCode());
|
||||
// LOGGER.error("data: {}", httpResponse.body());
|
||||
@ -120,9 +125,16 @@ public class RESTApi {
|
||||
|
||||
public <T, U> T put(final Class<T> clazz, final String urlOffset, final U data) throws RESTErrorResponseExeption, IOException, InterruptedException {
|
||||
final ObjectMapper mapper = new ObjectMapper();
|
||||
final HttpClient client = HttpClient.newHttpClient();
|
||||
final String body = mapper.writeValueAsString(data);
|
||||
return putJson(clazz, urlOffset, body);
|
||||
}
|
||||
|
||||
public <T, U> T putJson(final Class<T> clazz, final String urlOffset, final String body) throws RESTErrorResponseExeption, IOException, InterruptedException {
|
||||
final ObjectMapper mapper = new ObjectMapper();
|
||||
final HttpClient client = HttpClient.newHttpClient();
|
||||
Builder requestBuilding = HttpRequest.newBuilder().uri(URI.create(this.baseUrl + urlOffset));
|
||||
LOGGER.trace("call PUT: {}", URI.create(this.baseUrl + urlOffset));
|
||||
LOGGER.trace("DATA: {}", body);
|
||||
if (this.token != null) {
|
||||
requestBuilding = requestBuilding.header(HttpHeaders.AUTHORIZATION, "Yota " + this.token);
|
||||
}
|
||||
|
99
test/src/test/kar/archidata/TestListJson.java
Normal file
99
test/src/test/kar/archidata/TestListJson.java
Normal file
@ -0,0 +1,99 @@
|
||||
package test.kar.archidata;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
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.ExtendWith;
|
||||
import org.kar.archidata.GlobalConfiguration;
|
||||
import org.kar.archidata.dataAccess.DataAccess;
|
||||
import org.kar.archidata.dataAccess.DataFactory;
|
||||
import org.kar.archidata.db.DBEntry;
|
||||
import org.kar.archidata.tools.ConfigBaseVariable;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import test.kar.archidata.model.SerializeListAsJson;
|
||||
|
||||
@ExtendWith(StepwiseExtension.class)
|
||||
@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
|
||||
public class TestListJson {
|
||||
final static private Logger LOGGER = LoggerFactory.getLogger(TestListJson.class);
|
||||
|
||||
@BeforeAll
|
||||
public static void configureWebServer() throws Exception {
|
||||
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";
|
||||
}
|
||||
// Connect the dataBase...
|
||||
final DBEntry entry = DBEntry.createInterface(GlobalConfiguration.dbConfig);
|
||||
entry.connect();
|
||||
}
|
||||
|
||||
@AfterAll
|
||||
public static void removeDataBase() throws IOException {
|
||||
LOGGER.info("Remove the test db");
|
||||
DBEntry.closeAllForceMode();
|
||||
ConfigBaseVariable.clearAllValue();
|
||||
}
|
||||
|
||||
@Order(1)
|
||||
@Test
|
||||
public void testTableInsertAndRetrieve() throws Exception {
|
||||
final List<String> sqlCommand = DataFactory.createTable(SerializeListAsJson.class);
|
||||
for (final String elem : sqlCommand) {
|
||||
LOGGER.debug("request: '{}'", elem);
|
||||
DataAccess.executeSimpleQuerry(elem, false);
|
||||
}
|
||||
}
|
||||
|
||||
@Order(2)
|
||||
@Test
|
||||
public void testIO() throws Exception {
|
||||
final SerializeListAsJson test = new SerializeListAsJson();
|
||||
test.data = new ArrayList<>();
|
||||
test.data.add(5);
|
||||
test.data.add(2);
|
||||
test.data.add(8);
|
||||
test.data.add(6);
|
||||
test.data.add(51);
|
||||
|
||||
final SerializeListAsJson insertedData = DataAccess.insert(test);
|
||||
|
||||
Assertions.assertNotNull(insertedData);
|
||||
Assertions.assertNotNull(insertedData.id);
|
||||
Assertions.assertTrue(insertedData.id >= 0);
|
||||
Assertions.assertNotNull(insertedData.data);
|
||||
Assertions.assertEquals(5, insertedData.data.size());
|
||||
Assertions.assertEquals(test.data.get(0), insertedData.data.get(0));
|
||||
Assertions.assertEquals(test.data.get(1), insertedData.data.get(1));
|
||||
Assertions.assertEquals(test.data.get(2), insertedData.data.get(2));
|
||||
Assertions.assertEquals(test.data.get(3), insertedData.data.get(3));
|
||||
Assertions.assertEquals(test.data.get(4), insertedData.data.get(4));
|
||||
|
||||
// Try to retrieve all the data:
|
||||
final SerializeListAsJson retrieve = DataAccess.get(SerializeListAsJson.class, insertedData.id);
|
||||
|
||||
Assertions.assertNotNull(retrieve);
|
||||
Assertions.assertNotNull(retrieve.id);
|
||||
Assertions.assertTrue(retrieve.id >= 0);
|
||||
Assertions.assertNotNull(retrieve.data);
|
||||
Assertions.assertEquals(5, retrieve.data.size());
|
||||
Assertions.assertEquals(test.data.get(0), retrieve.data.get(0));
|
||||
Assertions.assertEquals(test.data.get(1), retrieve.data.get(1));
|
||||
Assertions.assertEquals(test.data.get(2), retrieve.data.get(2));
|
||||
Assertions.assertEquals(test.data.get(3), retrieve.data.get(3));
|
||||
Assertions.assertEquals(test.data.get(4), retrieve.data.get(4));
|
||||
}
|
||||
|
||||
}
|
@ -449,7 +449,7 @@ public class TestTypes {
|
||||
"varcharData": null
|
||||
}
|
||||
""";
|
||||
final int nbUpdate = DataAccess.updateWithJson(TypesTable.class, insertedData.id, jsonData);
|
||||
final int nbUpdate = DataAccess.updateWithJson(TypesTable.class, insertedData.id, jsonData, null);
|
||||
Assertions.assertEquals(1, nbUpdate);
|
||||
|
||||
// Get new data
|
||||
|
13
test/src/test/kar/archidata/model/SerializeListAsJson.java
Normal file
13
test/src/test/kar/archidata/model/SerializeListAsJson.java
Normal file
@ -0,0 +1,13 @@
|
||||
package test.kar.archidata.model;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.kar.archidata.annotation.DataJson;
|
||||
import org.kar.archidata.model.GenericData;
|
||||
|
||||
public class SerializeListAsJson extends GenericData {
|
||||
|
||||
@DataJson
|
||||
public List<Integer> data;
|
||||
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user