[DEV] security, restWrapper, catcher exception, sqlite:memory

This commit is contained in:
Edouard DUPIN 2023-04-30 22:44:32 +02:00
parent 7fd93485e6
commit 37212ba70e
26 changed files with 476 additions and 219 deletions

View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" output="out/maven/classes" path="src">
<classpathentry including="**/*.java" kind="src" output="out/maven/classes" path="src">
<attributes>
<attribute name="optional" value="true"/>
<attribute name="maven.pomderived" value="true"/>

View File

@ -20,4 +20,15 @@
<nature>org.eclipse.jdt.core.javanature</nature>
<nature>org.eclipse.m2e.core.maven2Nature</nature>
</natures>
<filteredResources>
<filter>
<id>1682721079856</id>
<name></name>
<type>30</type>
<matcher>
<id>org.eclipse.core.resources.regexFilterMatcher</id>
<arguments>node_modules|\.git|__CREATED_BY_JAVA_LANGUAGE_SERVER__</arguments>
</matcher>
</filter>
</filteredResources>
</projectDescription>

View File

@ -45,6 +45,12 @@
</dependencyManagement>
<dependencies>
<!-- https://mvnrepository.com/artifact/org.slf4j/slf4j-api -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>2.0.7</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.glassfish.jersey.media/jersey-media-multipart -->
<dependency>
<groupId>org.glassfish.jersey.media</groupId>

View File

@ -12,6 +12,7 @@ public class GlobalConfiguration {
Integer.parseInt(ConfigBaseVariable.getDBPort()),
ConfigBaseVariable.getDBLogin(),
ConfigBaseVariable.getDBPassword(),
ConfigBaseVariable.getDBName());
ConfigBaseVariable.getDBName(),
ConfigBaseVariable.getDBKeepConnected());
}
}

View File

@ -24,6 +24,8 @@ import org.kar.archidata.annotation.SQLTableName;
import org.kar.archidata.annotation.SQLUpdateTime;
import org.kar.archidata.db.DBEntry;
import org.kar.archidata.util.ConfigBaseVariable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
@ -34,6 +36,7 @@ import org.kar.archidata.annotation.SQLDeleted;
public class SqlWrapper {
static final Logger logger = LoggerFactory.getLogger(SqlWrapper.class);
public static class ExceptionDBInterface extends Exception {
private static final long serialVersionUID = 1L;
@ -178,7 +181,7 @@ public class SqlWrapper {
if (rs.wasNull()) {
field.set(data, null);
} else {
//System.out.println(" ==> " + tmp);
//logger.debug(" ==> {}", tmp);
field.set(data, tmp);
}
} else if (type == long.class ) {
@ -279,7 +282,7 @@ public class SqlWrapper {
Class<?> clazz = data.getClass();
//public static NodeSmall createNode(String typeInNode, String name, String descrition, Long parentId) {
DBEntry entry = new DBEntry(GlobalConfiguration.dbConfig);
DBEntry entry = DBEntry.createInterface(GlobalConfiguration.dbConfig);
// real add in the BDD:
try {
String tableName = getTableName(clazz);
@ -336,7 +339,7 @@ public class SqlWrapper {
query.append("?");
}
query.append(")");
// System.out.println("generate the query: '" + query.toString() + "'");
// logger.debug("generate the query: '{}'", query.toString());
// prepare the request:
PreparedStatement ps = entry.connection.prepareStatement(query.toString(), Statement.RETURN_GENERATED_KEYS);
Field primaryKeyField = null;
@ -395,7 +398,7 @@ public class SqlWrapper {
throw new SQLException("Creating node failed, no ID obtained (1).");
}
} catch (Exception ex) {
System.out.println("Can not get the UID key inserted ... ");
logger.error("Can not get the UID key inserted ... ");
ex.printStackTrace();
throw new SQLException("Creating node failed, no ID obtained (2).");
}
@ -405,7 +408,7 @@ public class SqlWrapper {
} else if (primaryKeyField.getType() == long.class) {
primaryKeyField.setLong(data, uniqueSQLID);
} else {
System.out.println("Can not manage the primary filed !!!");
logger.error("Can not manage the primary filed !!!");
}
}
//ps.execute();
@ -451,7 +454,7 @@ public class SqlWrapper {
Class<?> clazz = data.getClass();
//public static NodeSmall createNode(String typeInNode, String name, String description, Long parentId) {
DBEntry entry = new DBEntry(GlobalConfiguration.dbConfig);
DBEntry entry = DBEntry.createInterface(GlobalConfiguration.dbConfig);
// real add in the BDD:
try {
String tableName = getTableName(clazz);
@ -507,7 +510,7 @@ public class SqlWrapper {
query.append(primaryKeyField.getName());
query.append("` = ?");
firstField = true;
// System.out.println("generate the querry: '" + query.toString() + "'");
// logger.debug("generate the querry: '{}'", query.toString());
// prepare the request:
PreparedStatement ps = entry.connection.prepareStatement(query.toString(), Statement.RETURN_GENERATED_KEYS);
int iii = 1;
@ -685,14 +688,14 @@ public class SqlWrapper {
}
public static void executeSimpleQuerry(String querry) throws SQLException, IOException {
DBEntry entry = new DBEntry(GlobalConfiguration.dbConfig);
DBEntry entry = DBEntry.createInterface(GlobalConfiguration.dbConfig);
Statement stmt = entry.connection.createStatement();
stmt.executeUpdate(querry);
}
@SuppressWarnings("unchecked")
public static <T> List<T> getsWhere(Class<T> clazz, List<WhereCondition> condition, String orderBy, boolean full, Integer linit) throws Exception {
DBEntry entry = new DBEntry(GlobalConfiguration.dbConfig);
DBEntry entry = DBEntry.createInterface(GlobalConfiguration.dbConfig);
List<T> outs = new ArrayList<>();
// real add in the BDD:
try {
@ -754,7 +757,7 @@ public class SqlWrapper {
query.append(".deleted = false ");
*/
firstField = true;
//System.out.println("generate the query: '" + query.toString() + "'");
//logger.debug("generate the query: '{}'", query.toString());
// prepare the request:
PreparedStatement ps = entry.connection.prepareStatement(query.toString(), Statement.RETURN_GENERATED_KEYS);
whereInjectValue(ps, condition);
@ -820,8 +823,8 @@ public class SqlWrapper {
}
public static <T> List<T> gets(Class<T> clazz, boolean full) throws Exception {
System.out.println("request get " + clazz.getCanonicalName() + " start @" + getCurrentTimeStamp());
DBEntry entry = new DBEntry(GlobalConfiguration.dbConfig);
logger.debug("request get {} start @{}", clazz.getCanonicalName(), getCurrentTimeStamp());
DBEntry entry = DBEntry.createInterface(GlobalConfiguration.dbConfig);
List<T> out = new ArrayList<>();
// real add in the BDD:
try {
@ -914,15 +917,15 @@ public class SqlWrapper {
query.append(tableName);
query.append(".deleted = false ");
firstField = true;
System.out.println("generate the querry: '" + query.toString() + "'");
System.out.println("request get " + clazz.getCanonicalName() + " prepare @" + getCurrentTimeStamp());
logger.info("generate the querry: '{}'", query.toString());
logger.info("request get {} prepare @{}", clazz.getCanonicalName(), getCurrentTimeStamp());
// prepare the request:
PreparedStatement ps = entry.connection.prepareStatement(query.toString(), Statement.RETURN_GENERATED_KEYS);
System.out.println("request get " + clazz.getCanonicalName() + " query @" + getCurrentTimeStamp());
logger.info("request get {} query @{}", clazz.getCanonicalName(), getCurrentTimeStamp());
// execute the request
ResultSet rs = ps.executeQuery();
System.out.println("request get " + clazz.getCanonicalName() + " transform @" + getCurrentTimeStamp());
logger.info("request get {} transform @{}", clazz.getCanonicalName(), getCurrentTimeStamp());
while (rs.next()) {
indexAutoClasify = 0;
@ -949,11 +952,11 @@ public class SqlWrapper {
indexAutoClasify++;
count++;
}
//System.out.println("Read: " + (T)data);
//logger.debug("Read: {}", (T)data);
out.add((T)data);
}
System.out.println("request get " + clazz.getCanonicalName() + " ready @" + getCurrentTimeStamp());
logger.info("request get {} ready @{}", clazz.getCanonicalName(), getCurrentTimeStamp());
} catch (SQLException ex) {
ex.printStackTrace();
@ -966,7 +969,7 @@ public class SqlWrapper {
public static void addLink(Class<?> clazz, long localKey, String table, long remoteKey) throws Exception {
String tableName = getTableName(clazz);
DBEntry entry = new DBEntry(GlobalConfiguration.dbConfig);
DBEntry entry = DBEntry.createInterface(GlobalConfiguration.dbConfig);
long uniqueSQLID = -1;
// real add in the BDD:
try {
@ -991,7 +994,7 @@ public class SqlWrapper {
throw new SQLException("Creating user failed, no ID obtained (1).");
}
} catch (Exception ex) {
System.out.println("Can not get the UID key inserted ... ");
logger.debug("Can not get the UID key inserted ... ");
ex.printStackTrace();
throw new SQLException("Creating user failed, no ID obtained (2).");
}
@ -1005,7 +1008,7 @@ public class SqlWrapper {
}
public static void removeLink(Class<?> clazz, long localKey, String table, long remoteKey) throws Exception {
String tableName = getTableName(clazz);
DBEntry entry = new DBEntry(GlobalConfiguration.dbConfig);
DBEntry entry = DBEntry.createInterface(GlobalConfiguration.dbConfig);
String query = "UPDATE `" + tableName + "_link_" + table + "` SET `modify_date`=" + getDBNow() + ", `deleted`=true WHERE `" + tableName + "_id` = ? AND `" + table + "_id` = ?";
try {
PreparedStatement ps = entry.connection.prepareStatement(query);
@ -1072,7 +1075,7 @@ public class SqlWrapper {
}
public static int setDeleteWhere(Class<?> clazz, List<WhereCondition> condition) throws Exception {
String tableName = getTableName(clazz);
DBEntry entry = new DBEntry(GlobalConfiguration.dbConfig);
DBEntry entry = DBEntry.createInterface(GlobalConfiguration.dbConfig);
StringBuilder query = new StringBuilder();
query.append("UPDATE `");
query.append(tableName);
@ -1100,7 +1103,7 @@ public class SqlWrapper {
public static int unsetDeleteWhere(Class<?> clazz, List<WhereCondition> condition) throws Exception {
String tableName = getTableName(clazz);
DBEntry entry = new DBEntry(GlobalConfiguration.dbConfig);
DBEntry entry = DBEntry.createInterface(GlobalConfiguration.dbConfig);
StringBuilder query = new StringBuilder();
query.append("UPDATE `");
query.append(tableName);
@ -1135,7 +1138,7 @@ public class SqlWrapper {
out.append(tableName);
out.append("` (");
boolean firstField = true;
System.out.println("===> TABLE `" + tableName + "`");
logger.debug("===> TABLE `{}`", tableName);
String primaryKeyValue = null;
for (Field elem : clazz.getFields()) {
@ -1151,7 +1154,7 @@ public class SqlWrapper {
ModelLink linkGeneric = getLinkMode(elem);
String comment = getComment(elem);
String defaultValue = getDefault(elem);
//System.out.println(" ==> elem `" + name + "` primaryKey=" + primaryKey + " linkGeneric=" + linkGeneric);
//logger.debug(" ==> elem `" + name + "` primaryKey=" + primaryKey + " linkGeneric=" + linkGeneric);
if (primaryKey) {
@ -1183,8 +1186,8 @@ public class SqlWrapper {
} else {
otherTable.append("\t\t`id` INTEGER PRIMARY KEY AUTOINCREMENT,\n");
otherTable.append("\t\t`deleted` INTEGER NOT NULL DEFAULT '0',\n");
otherTable.append("\t\t`create_date` INTEGER NOT NULL DEFAULT CURRENT_TIMESTAMP(3),\n");
otherTable.append("\t\t`modify_date` INTEGER NOT NULL DEFAULT CURRENT_TIMESTAMP(3),\n");
otherTable.append("\t\t`create_date` INTEGER NOT NULL DEFAULT CURRENT_TIMESTAMP,\n");
otherTable.append("\t\t`modify_date` INTEGER NOT NULL DEFAULT CURRENT_TIMESTAMP,\n");
}
otherTable.append("\t\t`");
otherTable.append(tableName);
@ -1196,12 +1199,12 @@ public class SqlWrapper {
otherTable.append("\t\t`");
otherTable.append(localName);
if (!ConfigBaseVariable.getDBType().equals("sqlite")) {
otherTable.append("_id` bigint NOT NULL,\n");
otherTable.append("_id` bigint NOT NULL\n");
} else {
otherTable.append("_id` INTEGER NOT NULL,\n");
otherTable.append("_id` INTEGER NOT NULL\n");
}
if (!ConfigBaseVariable.getDBType().equals("sqlite")) {
otherTable.append("\tPRIMARY KEY (`id`)\n");
otherTable.append("\t, PRIMARY KEY (`id`)\n");
}
otherTable.append("\t)");
if (!ConfigBaseVariable.getDBType().equals("sqlite")) {
@ -1245,8 +1248,12 @@ public class SqlWrapper {
}
if (defaultValue == null) {
if (updateTime || createTime) {
if (!ConfigBaseVariable.getDBType().equals("sqlite")) {
out.append("DEFAULT CURRENT_TIMESTAMP ");
} else {
out.append("DEFAULT CURRENT_TIMESTAMP(3) ");
}
}
} else {
out.append("DEFAULT ");
if ("CURRENT_TIMESTAMP(3)".equals(defaultValue) && ConfigBaseVariable.getDBType().equals("sqlite")) {
@ -1258,7 +1265,11 @@ public class SqlWrapper {
}
} else if (defaultValue == null) {
if (updateTime || createTime) {
if (!ConfigBaseVariable.getDBType().equals("sqlite")) {
out.append("DEFAULT CURRENT_TIMESTAMP ");
}else {
out.append("DEFAULT CURRENT_TIMESTAMP(3) ");
}
} else {
out.append("DEFAULT NULL ");
}

View File

@ -27,7 +27,7 @@ public class UserDB {
}
private static void createUsersInfoFromOAuth(long userId, String login) throws IOException {
DBEntry entry = new DBEntry(GlobalConfiguration.dbConfig);
DBEntry entry = DBEntry.createInterface(GlobalConfiguration.dbConfig);
String query = "INSERT INTO `user` (`id`, `login`, `lastConnection`, `admin`, `blocked`, `removed`) VALUE (?,?,now(3),'0','0','0')";
try {
PreparedStatement ps = entry.connection.prepareStatement(query);

View File

@ -274,7 +274,7 @@ public class DataResource {
@QueryParam(HttpHeaders.AUTHORIZATION) String token,
@HeaderParam("Range") String range,
@PathParam("id") Long id) throws Exception {
GenericContext gc = (GenericContext) sc.getUserPrincipal();
//GenericContext gc = (GenericContext) sc.getUserPrincipal();
//System.out.println("===================================================");
//System.out.println("== DATA retriveDataThumbnailId ? " + (gc==null?"null":gc.user));
//System.out.println("===================================================");

View File

@ -49,10 +49,7 @@ public class FrontGeneric {
} else if (extention.equalsIgnoreCase("css")) {
mineType = "text/css";
} else {
return Response.status(403).
entity("Not supported model: '" + fileName + "'").
type("text/plain").
build();
throw new NotSupportedException("Not supported model: '" + fileName + "'");
}
} else {
mineType = "text/html";
@ -62,10 +59,7 @@ public class FrontGeneric {
// reads input image
File download = new File(filePathName);
if (!download.exists()) {
return Response.status(404).
entity("Not Found: '" + fileName + "' extension='" + extention + "'").
type("text/plain").
build();
throw new NotFoundException("Not Found: '" + fileName + "' extension='" + extention + "'");
}
ResponseBuilder response = Response.ok((Object)download);
// use this if I want to download the file:

View File

@ -1,17 +1,20 @@
package org.kar.archidata.catcher;
import jakarta.ws.rs.core.MediaType;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import jakarta.ws.rs.core.Response;
import jakarta.ws.rs.ext.ExceptionMapper;
public class ExceptionCatcher
implements ExceptionMapper<Exception> {
final Logger logger = LoggerFactory.getLogger(ExceptionCatcher.class);
@Override
public Response toResponse(Exception exception) {
System.out.println("Catch exception (not managed...):");
logger.warn("Catch exception (not managed...):");
RestErrorResponse ret = build(exception);
System.out.println("Error UUID=" + ret.uuid);
logger.error("Error UUID={}", ret.uuid);
exception.printStackTrace();
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
.entity(ret)

View File

@ -0,0 +1,29 @@
package org.kar.archidata.catcher;
import jakarta.ws.rs.ClientErrorException;
import jakarta.ws.rs.core.MediaType;
import jakarta.ws.rs.core.Response;
import jakarta.ws.rs.ext.ExceptionMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class FailException404API
implements ExceptionMapper<ClientErrorException> {
final Logger logger = LoggerFactory.getLogger(FailException404API.class);
@Override
public Response toResponse(ClientErrorException exception) {
RestErrorResponse ret = build(exception);
logger.error("Error UUID={}", ret.uuid);
return Response.status(Response.Status.NOT_FOUND)
.entity(ret)
.type(MediaType.APPLICATION_JSON)
.build();
}
private RestErrorResponse build(ClientErrorException exception) {
return new RestErrorResponse(exception.getResponse().getStatusInfo().toEnum(), "Catch system exception" , exception.getMessage());
}
}

View File

@ -5,14 +5,17 @@ import jakarta.ws.rs.core.Response;
import jakarta.ws.rs.ext.ExceptionMapper;
import org.kar.archidata.exception.FailException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class FailExceptionCatcher
implements ExceptionMapper<FailException> {
final Logger logger = LoggerFactory.getLogger(FailExceptionCatcher.class);
@Override
public Response toResponse(FailException exception) {
RestErrorResponse ret = build(exception);
System.out.println("Error UUID=" + ret.uuid);
logger.error("Error UUID={}", ret.uuid);
// Not display backtrace ==> this may be a normal case ...
//exception.printStackTrace();
return Response.status(exception.status)

View File

@ -5,14 +5,17 @@ import jakarta.ws.rs.core.Response;
import jakarta.ws.rs.ext.ExceptionMapper;
import org.kar.archidata.exception.InputException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class InputExceptionCatcher
implements ExceptionMapper<InputException> {
final Logger logger = LoggerFactory.getLogger(InputExceptionCatcher.class);
@Override
public Response toResponse(InputException exception) {
RestErrorResponse ret = build(exception);
System.out.println("Error UUID=" + ret.uuid);
logger.error("Error UUID={}", ret.uuid);
exception.printStackTrace();
return Response.status(exception.status)
.entity(ret)

View File

@ -12,6 +12,7 @@ public class RestErrorResponse {
public String message;
final public int status;
final public String statusMessage;
public RestErrorResponse(Response.Status status, String time, String error, String message) {
this.time = time;
this.error = error;

View File

@ -4,16 +4,18 @@ import jakarta.ws.rs.core.MediaType;
import jakarta.ws.rs.core.Response;
import jakarta.ws.rs.ext.ExceptionMapper;
import org.kar.archidata.exception.InputException;
import org.kar.archidata.exception.SystemException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class SystemExceptionCatcher
implements ExceptionMapper<SystemException> {
final Logger logger = LoggerFactory.getLogger(SystemExceptionCatcher.class);
@Override
public Response toResponse(SystemException exception) {
RestErrorResponse ret = build(exception);
System.out.println("Error UUID=" + ret.uuid);
logger.error("Error UUID={}", ret.uuid);
exception.printStackTrace();
return Response.status(exception.status)
.entity(ret)

View File

@ -7,8 +7,9 @@ public class DBConfig {
private final String login;
private final String password;
private final String dbName;
private final boolean keepConnected;
public DBConfig(String type, String hostname, Integer port, String login, String password, String dbName) {
public DBConfig(String type, String hostname, Integer port, String login, String password, String dbName, boolean keepConnected) {
if (type == null) {
this.type = "mysql";
} else {
@ -27,6 +28,7 @@ public class DBConfig {
this.login = login;
this.password = password;
this.dbName = dbName;
this.keepConnected = keepConnected;
}
@Override
@ -60,9 +62,15 @@ public class DBConfig {
public String getDbName() {
return dbName;
}
public boolean getKeepConnected() {
return keepConnected;
}
public String getUrl() {
if (type.equals("sqlite")) {
if (this.hostname.equals("memory")) {
return "jdbc:sqlite::memory:";
}
return "jdbc:sqlite:" + this.hostname + ".db";
}
return "jdbc:" + this.type + "://" + this.hostname + ":" + this.port + "/" + this.dbName + "?allowPublicKeyRetrieval=true&useSSL=false&serverTimezone=UTC";

View File

@ -3,16 +3,41 @@ package org.kar.archidata.db;
import java.io.Closeable;
import java.io.IOException;
import java.sql.*;
import java.util.ArrayList;
import java.util.List;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class DBEntry implements Closeable {
final static Logger LOGGER = LoggerFactory.getLogger(DBEntry.class);
public DBConfig config;
public Connection connection;
private static List<DBEntry> stored = new ArrayList<>();
public DBEntry(DBConfig config) throws IOException {
private DBEntry(DBConfig config) throws IOException {
this.config = config;
connect();
}
public static DBEntry createInterface(DBConfig config) throws IOException {
if (config.getKeepConnected()) {
for (DBEntry elem : stored) {
if (elem == null) {
continue;
}
if (elem.config.getUrl().equals(config.getUrl())) {
return elem;
}
}
DBEntry tmp = new DBEntry(config);
stored.add(tmp);
return tmp;
} else {
return new DBEntry(config);
}
}
public void connect() throws IOException {
try {
connection = DriverManager.getConnection(config.getUrl(), config.getLogin(), config.getPassword());
@ -21,21 +46,12 @@ public class DBEntry implements Closeable {
}
}
/*
public void test() throws SQLException {
String query = "SELECT * FROM user";
Statement st = connection.createStatement();
ResultSet rs = st.executeQuery(query);
System.out.println("List of user:");
if (rs.next()) {
User user = new User(rs);
System.out.println(" - " + user);
}
}
*/
@Override
public void close() throws IOException {
if (config.getKeepConnected()) {
return;
}
try {
//connection.commit();
connection.close();

View File

@ -0,0 +1,41 @@
package org.kar.archidata.exception;
import java.util.UUID;
public class RESTErrorResponseExeption extends Exception {
public UUID uuid;
public String time;
public String error;
public String message;
public int status;
public String statusMessage;
public RESTErrorResponseExeption() {
super();
this.uuid = null;
this.time = null;
this.error = null;
this.message = null;
this.status = 0;
this.statusMessage = null;
}
public RESTErrorResponseExeption(UUID uuid, String time, String error, String message, int status,
String statusMessage) {
super();
this.uuid = uuid;
this.time = time;
this.error = error;
this.message = message;
this.status = status;
this.statusMessage = statusMessage;
}
@Override
public String toString() {
return "RESTErrorResponseExeption [uuid=" + uuid + ", time=" + time + ", error=" + error + ", message="
+ message + ", status=" + status + ", statusMessage=" + statusMessage + "]";
}
}

View File

@ -0,0 +1,10 @@
package org.kar.archidata.exception;
import jakarta.ws.rs.core.Response;
public class UnAuthorizedException extends FailException {
private static final long serialVersionUID = 1L;
public UnAuthorizedException(String message) {
super(Response.Status.UNAUTHORIZED, message);
}
}

View File

@ -4,7 +4,7 @@ import java.lang.reflect.Method;
import org.kar.archidata.annotation.security.DenyAll;
import org.kar.archidata.annotation.security.PermitAll;
import org.kar.archidata.annotation.security.RolesAllowed;
import org.kar.archidata.catcher.RestErrorResponse;
import jakarta.annotation.Priority;
import jakarta.ws.rs.Priorities;
@ -13,15 +13,16 @@ import jakarta.ws.rs.container.ContainerRequestFilter;
import jakarta.ws.rs.container.ResourceInfo;
import jakarta.ws.rs.core.Context;
import jakarta.ws.rs.core.HttpHeaders;
import jakarta.ws.rs.core.MediaType;
import jakarta.ws.rs.core.MultivaluedMap;
import jakarta.ws.rs.core.Response;
import jakarta.ws.rs.ext.Provider;
import org.kar.archidata.UserDB;
import org.kar.archidata.annotation.security.PermitTokenInURI;
import org.kar.archidata.model.User;
import org.kar.archidata.model.UserByToken;
import org.kar.archidata.util.JWTWrapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.nimbusds.jwt.JWTClaimsSet;
@ -38,6 +39,7 @@ import java.util.Map.Entry;
@Provider
@Priority(Priorities.AUTHENTICATION)
public class AuthenticationFilter implements ContainerRequestFilter {
final Logger logger = LoggerFactory.getLogger(AuthenticationFilter.class);
@Context
private ResourceInfo resourceInfo;
protected final String applicationName;
@ -55,35 +57,35 @@ public class AuthenticationFilter implements ContainerRequestFilter {
@Override
public void filter(ContainerRequestContext requestContext) throws IOException {
/*
System.out.println("-----------------------------------------------------");
System.out.println("---- Check if have authorization ----");
System.out.println("-----------------------------------------------------");
System.out.println(" for:" + requestContext.getUriInfo().getPath());
logger.debug("-----------------------------------------------------");
logger.debug("---- Check if have authorization ----");
logger.debug("-----------------------------------------------------");
logger.debug(" for:{}", requestContext.getUriInfo().getPath());
*/
Method method = resourceInfo.getResourceMethod();
// Access denied for all
if(method.isAnnotationPresent(DenyAll.class)) {
System.out.println(" ==> deny all " + requestContext.getUriInfo().getPath());
logger.debug(" ==> deny all {}", requestContext.getUriInfo().getPath());
requestContext.abortWith(Response.status(Response.Status.FORBIDDEN).entity("Access blocked !!!").build());
return;
}
//Access allowed for all
if( method.isAnnotationPresent(PermitAll.class)) {
//System.out.println(" ==> permit all " + requestContext.getUriInfo().getPath());
//logger.debug(" ==> permit all " + requestContext.getUriInfo().getPath());
// no control ...
return;
}
// this is a security guard, all the API must define their access level:
if(!method.isAnnotationPresent(RolesAllowed.class)) {
System.out.println(" ==> missing @RolesAllowed " + requestContext.getUriInfo().getPath());
logger.error(" ==> missing @RolesAllowed {}", requestContext.getUriInfo().getPath());
requestContext.abortWith(Response.status(Response.Status.FORBIDDEN).entity("Access ILLEGAL !!!").build());
return;
}
// Get the Authorization header from the request
String authorizationHeader = requestContext.getHeaderString(HttpHeaders.AUTHORIZATION);
//System.out.println("authorizationHeader: " + authorizationHeader);
//logger.debug("authorizationHeader: {}", authorizationHeader);
if(authorizationHeader == null && method.isAnnotationPresent(PermitTokenInURI.class)) {
MultivaluedMap<String, String> quaryparam = requestContext.getUriInfo().getQueryParameters();
for (Entry<String, List<String>> item: quaryparam.entrySet()) {
@ -95,46 +97,46 @@ public class AuthenticationFilter implements ContainerRequestFilter {
}
}
}
// System.out.println("authorizationHeader: " + authorizationHeader);
// logger.debug("authorizationHeader: {}", authorizationHeader);
boolean isApplicationToken = isApplicationTokenBasedAuthentication(authorizationHeader);
boolean isJwtToken = isTokenBasedAuthentication(authorizationHeader);
// Validate the Authorization header data Model "Yota jwt.to.ken" "Zota tokenId:hash(token)"
if (!isApplicationToken && !isJwtToken) {
System.out.println("REJECTED unauthorized: " + requestContext.getUriInfo().getPath());
abortWithUnauthorized(requestContext);
logger.warn("REJECTED unauthorized: {}", requestContext.getUriInfo().getPath());
abortWithUnauthorized(requestContext, "REJECTED unauthorized: " + requestContext.getUriInfo().getPath());
return;
}
UserByToken userByToken = null;
if (isJwtToken) {
// Extract the token from the Authorization header (Remove "Yota ")
String token = authorizationHeader.substring(AUTHENTICATION_SCHEME.length()).trim();
//System.out.println("token: " + token);
//logger.debug("token: {}", token);
try {
userByToken = validateJwtToken(token);
} catch (Exception e) {
System.out.println("Fail to validate token: " + e.getMessage());
abortWithUnauthorized(requestContext);
logger.error("Fail to validate token: {}", e.getMessage());
abortWithUnauthorized(requestContext, "Fail to validate token: " + e.getMessage());
return;
}
if (userByToken == null) {
System.out.println("get a NULL user ...");
abortWithUnauthorized(requestContext);
logger.warn("get a NULL user ...");
abortWithUnauthorized(requestContext, "get a NULL user ...");
return;
}
} else {
// Extract the token from the Authorization header (Remove "Zota ")
String token = authorizationHeader.substring(AUTHENTICATION_TOKEN_SCHEME.length()).trim();
//System.out.println("token: " + token);
//logger.debug("token: {}", token);
try {
userByToken = validateToken(token);
} catch (Exception e) {
System.out.println("Fail to validate token: " + e.getMessage());
abortWithUnauthorized(requestContext);
logger.error("Fail to validate token: {}", e.getMessage());
abortWithUnauthorized(requestContext, "Fail to validate token: "+ e.getMessage());
return;
}
if (userByToken == null) {
System.out.println("get a NULL application ...");
abortWithUnauthorized(requestContext);
logger.warn("get a NULL application ...");
abortWithUnauthorized(requestContext, "get a NULL application ...");
return;
}
@ -155,12 +157,12 @@ public class AuthenticationFilter implements ContainerRequestFilter {
}
//Is user valid?
if( ! haveRight) {
System.out.println("REJECTED not enought right : " + requestContext.getUriInfo().getPath() + " require: " + 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;
}
requestContext.setSecurityContext(userContext);
// System.out.println("Get local user : " + user + " / " + userByToken);
// logger.debug("Get local user : {} / {}", user, userByToken);
}
private boolean isTokenBasedAuthentication(String authorizationHeader) {
@ -178,28 +180,32 @@ public class AuthenticationFilter implements ContainerRequestFilter {
}
private void abortWithUnauthorized(ContainerRequestContext requestContext) {
private void abortWithUnauthorized(ContainerRequestContext requestContext, String message) {
// Abort the filter chain with a 401 status code response
// The WWW-Authenticate header is sent along with the response
requestContext.abortWith(
Response.status(Response.Status.UNAUTHORIZED)
logger.warn("abortWithUnauthorized:");
RestErrorResponse ret = new RestErrorResponse(Response.Status.UNAUTHORIZED, "Unauthorized", message);
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(String authorization) throws Exception {
System.out.println("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;
}
// must be override to be good implementation
protected UserByToken validateJwtToken(String authorization) throws Exception {
System.out.println(" validate token : " + authorization);
logger.debug(" validate token : " + authorization);
JWTClaimsSet ret = JWTWrapper.validateToken(authorization, "KarAuth", null);
// check the token is valid !!! (signed and coherent issuer...
if (ret == null) {
System.out.println("The token is not valid: '" + authorization + "'");
logger.error("The token is not valid: '{}'", authorization);
return null;
}
// check userID
@ -215,10 +221,10 @@ public class AuthenticationFilter implements ContainerRequestFilter {
if (rights.containsKey(this.applicationName)) {
user.right = rights.get(this.applicationName);
} else {
System.out.println("Connect with no right for this application '" + this.applicationName + "' full Right='" + rights + "'");
logger.error("Connect with no right for this application='{}' full Right='{}'", this.applicationName, rights);
}
}
System.out.println("request user: '" + userUID + "' right: '" + user.right + "' row='" +rowRight + "'");
logger.debug("request user: '{}' right: '{}' row='{}'", userUID, user.right, rowRight);
return user;
//return UserDB.getUserOrCreate(id, (String)ret.getClaim("login") );
}

View File

@ -1,60 +0,0 @@
package org.kar.archidata.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);
// }
}

View File

@ -3,12 +3,6 @@ package org.kar.archidata.model;
import com.fasterxml.jackson.annotation.JsonInclude;
@JsonInclude(JsonInclude.Include.NON_NULL)
public final class GetToken {
public final String jwt;
public GetToken(String jwt) {
super();
this.jwt = jwt;
}
public record GetToken(String jwt) {
}

View File

@ -15,14 +15,11 @@ CREATE TABLE `user` (
*/
import java.sql.Timestamp;
import java.util.List;
import org.kar.archidata.annotation.SQLComment;
import org.kar.archidata.annotation.SQLDefault;
import org.kar.archidata.annotation.SQLIfNotExists;
import org.kar.archidata.annotation.SQLLimitSize;
import org.kar.archidata.annotation.SQLNotNull;
import org.kar.archidata.annotation.SQLTableLinkGeneric;
import org.kar.archidata.annotation.SQLTableName;
import com.fasterxml.jackson.annotation.JsonInclude;

View File

@ -7,6 +7,7 @@ public class ConfigBaseVariable {
static public String dbHost = System.getenv("DB_HOST");
static public String dbPort = System.getenv("DB_PORT");
static public String dbUser = System.getenv("DB_USER");
static public String dbKeepConnected = System.getenv("DB_KEEP_CONNECTED");
static public String dbPassword = System.getenv("DB_PASSWORD");
static public String bdDatabase = System.getenv("DB_DATABASE");
static public String apiAdress = System.getenv("API_ADDRESS");
@ -69,6 +70,12 @@ public class ConfigBaseVariable {
return bdDatabase;
}
public static boolean getDBKeepConnected() {
if (dbKeepConnected == null) {
return false;
}
return Boolean.parseBoolean(dbKeepConnected);
}
public static String getlocalAddress() {
if (apiAdress == null) {
return "http://0.0.0.0:80/api/";

View File

@ -10,20 +10,18 @@ import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import jakarta.ws.rs.core.Response;
import org.glassfish.jersey.media.multipart.FormDataContentDisposition;
import org.kar.archidata.GlobalConfiguration;
import org.kar.archidata.SqlWrapper;
import org.kar.archidata.model.Data;
import org.kar.archidata.db.DBEntry;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class DataTools {
static final Logger logger = LoggerFactory.getLogger(DataTools.class);
public final static int CHUNK_SIZE = 1024 * 1024; // 1MB chunks
public final static int CHUNK_SIZE_IN = 50 * 1024 * 1024; // 1MB chunks
@ -34,7 +32,7 @@ public class DataTools {
public static void createFolder(String path) throws IOException {
if (!Files.exists(java.nio.file.Path.of(path))) {
System.out.println("Create folder: " + path);
logger.info("Create folder: " + path);
Files.createDirectories(java.nio.file.Path.of(path));
}
}
@ -137,11 +135,11 @@ public class DataTools {
}
String mediaPath = getFileData(out.id);
System.out.println("src = " + tmpPath);
System.out.println("dst = " + mediaPath);
logger.info("src = {}", tmpPath);
logger.info("dst = {}", mediaPath);
Files.move(Paths.get(tmpPath), Paths.get(mediaPath), StandardCopyOption.ATOMIC_MOVE);
System.out.println("Move done");
logger.info("Move done");
// all is done the file is correctly installed...
return out;
}
@ -165,7 +163,7 @@ public class DataTools {
try {
Files.delete(Paths.get(filepath));
} catch (IOException e) {
System.out.println("can not delete temporary file : " + Paths.get(filepath));
logger.info("can not delete temporary file : {}", Paths.get(filepath));
e.printStackTrace();
}
}
@ -183,12 +181,11 @@ public class DataTools {
outpuStream = new FileOutputStream(new File(serverLocation));
while ((read = uploadedInputStream.read(bytes)) != -1) {
//System.out.println("write " + read);
//logger.debug("write {}", read);
md.update(bytes, 0, read);
outpuStream.write(bytes, 0, read);
}
System.out.println("Flush input stream ... " + serverLocation);
System.out.flush();
logger.info("Flush input stream ... {}", serverLocation);
outpuStream.flush();
outpuStream.close();
// create the end of sha512
@ -197,10 +194,10 @@ public class DataTools {
out = bytesToHex(sha512Digest);
uploadedInputStream.close();
} catch (IOException ex) {
System.out.println("Can not write in temporary file ... ");
logger.error("Can not write in temporary file ... ");
ex.printStackTrace();
} catch (NoSuchAlgorithmException ex) {
System.out.println("Can not find sha512 algorithms");
logger.error("Can not find sha512 algorithms");
ex.printStackTrace();
}
return out;
@ -250,12 +247,11 @@ public class DataTools {
fileName = multipartCorrection(fileName);
//public NodeSmall uploadFile(final FormDataMultiPart form) {
System.out.println("Upload media file: " + fileMetaData);
System.out.println(" - id: " + id);
System.out.println(" - file_name: " + fileName);
System.out.println(" - fileInputStream: " + fileInputStream);
System.out.println(" - fileMetaData: " + fileMetaData);
System.out.flush();
logger.info("Upload media file: {}", fileMetaData);
logger.info(" - id: {}", id);
logger.info(" - file_name: ", fileName);
logger.info(" - fileInputStream: {}", fileInputStream);
logger.info(" - fileMetaData: {}", fileMetaData);
T media = SqlWrapper.get(clazz, id);
if (media == null) {
return Response.notModified("Media Id does not exist or removed...").build();
@ -265,8 +261,7 @@ public class DataTools {
String sha512 = saveTemporaryFile(fileInputStream, tmpUID);
Data data = getWithSha512(sha512);
if (data == null) {
System.out.println("Need to add the data in the BDD ... ");
System.out.flush();
logger.info("Need to add the data in the BDD ... ");
try {
data = createNewData(tmpUID, fileName, sha512);
} catch (IOException ex) {
@ -279,16 +274,14 @@ public class DataTools {
return Response.notModified("Error in SQL insertion ...").build();
}
} else if (data.deleted == true) {
System.out.println("Data already exist but deleted");
System.out.flush();
logger.error("Data already exist but deleted");
undelete(data.id);
data.deleted = false;
} else {
System.out.println("Data already exist ... all good");
System.out.flush();
logger.error("Data already exist ... all good");
}
// Fist step: retrieve all the Id of each parents:...
System.out.println("Find typeNode");
logger.info("Find typeNode");
SqlWrapper.addLink(clazz, id, "cover", data.id);
return Response.ok(SqlWrapper.get(clazz, id)).build();
} catch (Exception ex) {

View File

@ -7,10 +7,12 @@ import java.net.HttpURLConnection;
import java.net.URL;
import java.text.ParseException;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.nimbusds.jose.JOSEException;
import com.nimbusds.jose.JOSEObjectType;
@ -26,6 +28,8 @@ import com.nimbusds.jwt.JWTClaimsSet;
import com.nimbusds.jwt.SignedJWT;
public class JWTWrapper {
static final Logger logger = LoggerFactory.getLogger(JWTWrapper.class);
private static RSAKey rsaJWK = null;;
private static RSAKey rsaPublicJWK = null;
@ -41,7 +45,7 @@ public class JWTWrapper {
public static void initLocalTokenRemote(String ssoUri, String application) throws IOException, ParseException {
// check Token:
URL obj = new URL(ssoUri + "public_key");
System.out.println("Request token from:" + obj);
logger.debug("Request token from: {}", obj);
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
con.setRequestMethod("GET");
con.setRequestProperty("User-Agent", application);
@ -54,7 +58,7 @@ public class JWTWrapper {
}
int responseCode = con.getResponseCode();
System.out.println("GET Response Code :: " + responseCode);
logger.debug("GET Response Code :: {}", responseCode);
if (responseCode == HttpURLConnection.HTTP_OK) { // success
BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream()));
@ -65,13 +69,13 @@ public class JWTWrapper {
}
in.close();
// print result
//System.out.println(response.toString());
//logger.debug(response.toString());
ObjectMapper mapper = new ObjectMapper();
PublicKey values = mapper.readValue(response.toString(), PublicKey.class);
rsaPublicJWK = RSAKey.parse(values.key);
return;
}
System.out.println("GET JWT validator token not worked");
logger.debug("GET JWT validator token not worked");
}
public static void initLocalToken(String baseUUID) throws Exception{
@ -84,12 +88,12 @@ public class JWTWrapper {
}
rsaJWK = new RSAKeyGenerator(2048).keyID(generatedStringForKey).generate();
rsaPublicJWK = rsaJWK.toPublicJWK();
//System.out.println("RSA key (all): " + rsaJWK.toJSONString());
//System.out.println("RSA key (pub): " + rsaPublicJWK.toJSONString());
//logger.debug("RSA key (all): " + rsaJWK.toJSONString());
//logger.debug("RSA key (pub): " + rsaPublicJWK.toJSONString());
} catch (JOSEException e) {
// TODO Auto-generated catch block
e.printStackTrace();
System.out.println("Can not generate teh public abnd private keys ...");
logger.debug("Can not generate teh public abnd private keys ...");
rsaJWK = null;
rsaPublicJWK = null;
}
@ -100,7 +104,7 @@ public class JWTWrapper {
rsaPublicJWK = RSAKey.parse(publicKey);
} catch (ParseException e) {
e.printStackTrace();
System.out.println("Can not retrieve public Key !!!!!!!! RSAKey='" + publicKey + "'");
logger.debug("Can not retrieve public Key !!!!!!!! RSAKey='{}'", publicKey);
}
}
@ -128,14 +132,14 @@ public class JWTWrapper {
*/
public static String generateJWToken(long userID, String userLogin, String isuer, String application, Map<String, Object> rights, int timeOutInMunites) {
if (rsaJWK == null) {
System.out.println("JWT private key is not present !!!");
logger.warn("JWT private key is not present !!!");
return null;
}
/*
System.out.println(" ===> expire in : " + timeOutInMunites);
System.out.println(" ===>" + new Date().getTime());
System.out.println(" ===>" + new Date(new Date().getTime()));
System.out.println(" ===>" + new Date(new Date().getTime() - 60 * timeOutInMunites * 1000));
logger.debug(" ===> expire in : " + timeOutInMunites);
logger.debug(" ===>" + new Date().getTime());
logger.debug(" ===>" + new Date(new Date().getTime()));
logger.debug(" ===>" + new Date(new Date().getTime() - 60 * timeOutInMunites * 1000));
*/
try {
// Create RSA-signer with the private key
@ -167,7 +171,7 @@ public class JWTWrapper {
public static JWTClaimsSet validateToken(String signedToken, String isuer, String application) {
if (rsaPublicJWK == null) {
System.out.println("JWT public key is not present !!!");
logger.warn("JWT public key is not present !!!");
return null;
}
try {
@ -176,23 +180,23 @@ public class JWTWrapper {
JWSVerifier verifier = new RSASSAVerifier(rsaPublicJWK);
if (!signedJWT.verify(verifier)) {
System.out.println("JWT token is NOT verified ");
logger.error("JWT token is NOT verified ");
return null;
}
if (!new Date().before(signedJWT.getJWTClaimsSet().getExpirationTime())) {
System.out.println("JWT token is expired now = " + new Date() + " with=" + signedJWT.getJWTClaimsSet().getExpirationTime() );
logger.error("JWT token is expired now = " + new Date() + " with=" + signedJWT.getJWTClaimsSet().getExpirationTime() );
return null;
}
if (!isuer.equals(signedJWT.getJWTClaimsSet().getIssuer())) {
System.out.println("JWT issuer is wong: '" + isuer + "' != '" + signedJWT.getJWTClaimsSet().getIssuer() + "'" );
logger.error("JWT issuer is wong: '" + isuer + "' != '" + signedJWT.getJWTClaimsSet().getIssuer() + "'" );
return null;
}
if (application != null) {
// TODO: verify the token is used for the correct application.
}
// the element must be validated outside ...
//System.out.println("JWT token is verified 'alice' =?= '" + signedJWT.getJWTClaimsSet().getSubject() + "'");
//System.out.println("JWT token isuer 'https://c2id.com' =?= '" + signedJWT.getJWTClaimsSet().getIssuer() + "'");
//logger.debug("JWT token is verified 'alice' =?= '" + signedJWT.getJWTClaimsSet().getSubject() + "'");
//logger.debug("JWT token isuer 'https://c2id.com' =?= '" + signedJWT.getJWTClaimsSet().getIssuer() + "'");
return signedJWT.getJWTClaimsSet();
} catch (JOSEException ex) {
ex.printStackTrace();

View File

@ -0,0 +1,177 @@
package org.kar.archidata.util;
import java.io.IOException;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpRequest.BodyPublishers;
import java.net.http.HttpRequest.Builder;
import java.net.http.HttpResponse;
import java.util.List;
import java.util.Map;
import org.kar.archidata.exception.RESTErrorResponseExeption;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import jakarta.ws.rs.core.HttpHeaders;
public class RESTApi {
final static Logger LOGGER = LoggerFactory.getLogger(RESTApi.class);
final String baseUrl;
private String token = null;
public RESTApi(String baseUrl) {
this.baseUrl = baseUrl;
}
public void setToken(String token) {
this.token = token;
}
public <T> List<T> gets(Class<T> clazz, String urlOffset) throws RESTErrorResponseExeption, IOException, InterruptedException {
ObjectMapper mapper = new ObjectMapper();
HttpClient client = HttpClient.newHttpClient();
Builder requestBuilding = HttpRequest.newBuilder().uri(URI.create(this.baseUrl + urlOffset));
if (token != null) {
requestBuilding = requestBuilding.header(HttpHeaders.AUTHORIZATION, "Yota " + token);
}
HttpRequest request = requestBuilding.GET().build();
HttpResponse<String> httpResponse = client.send(request, HttpResponse.BodyHandlers.ofString());
if (httpResponse.statusCode() < 200 || httpResponse.statusCode() >= 300) {
RESTErrorResponseExeption out = mapper.readValue(httpResponse.body(), RESTErrorResponseExeption.class);
throw out;
}
List<T> out = mapper.readValue(httpResponse.body(), new TypeReference<List<T>>(){});
return out;
}
public <T> T get(Class<T> clazz, String urlOffset) throws RESTErrorResponseExeption, IOException, InterruptedException {
ObjectMapper mapper = new ObjectMapper();
HttpClient client = HttpClient.newHttpClient();
Builder requestBuilding = HttpRequest.newBuilder().uri(URI.create(this.baseUrl + urlOffset));
if (token != null) {
requestBuilding = requestBuilding.header(HttpHeaders.AUTHORIZATION, "Yota " + token);
}
HttpRequest request = requestBuilding.GET().build();
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());
RESTErrorResponseExeption out = mapper.readValue(httpResponse.body(), RESTErrorResponseExeption.class);
throw new RESTErrorResponseExeption(out.uuid, out.time, out.error, out.message, out.status,out.statusMessage);
}
//LOGGER.error("status code: {}", httpResponse.statusCode());
//LOGGER.error("data: {}", httpResponse.body());
if (clazz.equals(String.class)) {
return (T)httpResponse.body();
}
T out = mapper.readValue(httpResponse.body(), clazz);
return out;
}
public <T, U> T post(Class<T> clazz, String urlOffset, U data) throws RESTErrorResponseExeption, IOException, InterruptedException {
ObjectMapper mapper = new ObjectMapper();
HttpClient client = HttpClient.newHttpClient();
String body = mapper.writeValueAsString(data);
Builder requestBuilding = HttpRequest.newBuilder().uri(URI.create(this.baseUrl + urlOffset));
if (token != null) {
requestBuilding = requestBuilding.header(HttpHeaders.AUTHORIZATION, "Yota " + token);
}
requestBuilding = requestBuilding.header("Content-Type", "application/json");
HttpRequest request = requestBuilding.POST(BodyPublishers.ofString(body)).build();
HttpResponse<String> httpResponse = client.send(request, HttpResponse.BodyHandlers.ofString());
if (httpResponse.statusCode() < 200 || httpResponse.statusCode() >= 300) {
LOGGER.error("status code: {}", httpResponse.statusCode());
LOGGER.error("data: {}", httpResponse.body());
RESTErrorResponseExeption out = mapper.readValue(httpResponse.body(), RESTErrorResponseExeption.class);
throw out;
}
if (clazz.equals(String.class)) {
return (T)httpResponse.body();
}
T out = mapper.readValue(httpResponse.body(), clazz);
return out;
}
public <T> T postMap(Class<T> clazz, String urlOffset, Map<String, Object> data) throws RESTErrorResponseExeption, IOException, InterruptedException {
ObjectMapper mapper = new ObjectMapper();
HttpClient client = HttpClient.newHttpClient();
String body = mapper.writeValueAsString(data);
Builder requestBuilding = HttpRequest.newBuilder().uri(URI.create(this.baseUrl + urlOffset));
if (token != null) {
requestBuilding = requestBuilding.header(HttpHeaders.AUTHORIZATION, "Yota " + token);
}
requestBuilding = requestBuilding.header("Content-Type", "application/json");
HttpRequest request = requestBuilding.POST(BodyPublishers.ofString(body)).build();
HttpResponse<String> httpResponse = client.send(request, HttpResponse.BodyHandlers.ofString());
if (httpResponse.statusCode() < 200 || httpResponse.statusCode() >= 300) {
RESTErrorResponseExeption out = mapper.readValue(httpResponse.body(), RESTErrorResponseExeption.class);
throw out;
}
if (clazz.equals(String.class)) {
return (T)httpResponse.body();
}
T out = mapper.readValue(httpResponse.body(), clazz);
return out;
}
public <T, U> T put(Class<T> clazz, String urlOffset, U data) throws RESTErrorResponseExeption, IOException, InterruptedException {
ObjectMapper mapper = new ObjectMapper();
HttpClient client = HttpClient.newHttpClient();
String body = mapper.writeValueAsString(data);
Builder requestBuilding = HttpRequest.newBuilder().uri(URI.create(this.baseUrl + urlOffset));
if (token != null) {
requestBuilding = requestBuilding.header(HttpHeaders.AUTHORIZATION, "Yota " + token);
}
requestBuilding = requestBuilding.header("Content-Type", "application/json");
HttpRequest request = requestBuilding.PUT(BodyPublishers.ofString(body)).build();
HttpResponse<String> httpResponse = client.send(request, HttpResponse.BodyHandlers.ofString());
if (httpResponse.statusCode() < 200 || httpResponse.statusCode() >= 300) {
RESTErrorResponseExeption out = mapper.readValue(httpResponse.body(), RESTErrorResponseExeption.class);
throw out;
}
if (clazz.equals(String.class)) {
return (T)httpResponse.body();
}
T out = mapper.readValue(httpResponse.body(), clazz);
return out;
}
public <T> T putMap(Class<T> clazz, String urlOffset, Map<String, Object> data) throws RESTErrorResponseExeption, IOException, InterruptedException {
ObjectMapper mapper = new ObjectMapper();
HttpClient client = HttpClient.newHttpClient();
String body = mapper.writeValueAsString(data);
Builder requestBuilding = HttpRequest.newBuilder().uri(URI.create(this.baseUrl + urlOffset));
if (token != null) {
requestBuilding = requestBuilding.header(HttpHeaders.AUTHORIZATION, "Yota " + token);
}
requestBuilding = requestBuilding.header("Content-Type", "application/json");
HttpRequest request = requestBuilding.PUT(BodyPublishers.ofString(body)).build();
HttpResponse<String> httpResponse = client.send(request, HttpResponse.BodyHandlers.ofString());
if (httpResponse.statusCode() < 200 || httpResponse.statusCode() >= 300) {
RESTErrorResponseExeption out = mapper.readValue(httpResponse.body(), RESTErrorResponseExeption.class);
throw out;
}
if (clazz.equals(String.class)) {
return (T)httpResponse.body();
}
T out = mapper.readValue(httpResponse.body(), clazz);
return out;
}
public <T, U> T delete(Class<T> clazz, String urlOffset) throws RESTErrorResponseExeption, IOException, InterruptedException {
ObjectMapper mapper = new ObjectMapper();
HttpClient client = HttpClient.newHttpClient();
Builder requestBuilding = HttpRequest.newBuilder().uri(URI.create(this.baseUrl + urlOffset));
if (token != null) {
requestBuilding = requestBuilding.header(HttpHeaders.AUTHORIZATION, "Yota " + token);
}
HttpRequest request = requestBuilding.DELETE().build();
HttpResponse<String> httpResponse = client.send(request, HttpResponse.BodyHandlers.ofString());
if (httpResponse.statusCode() < 200 || httpResponse.statusCode() >= 300) {
RESTErrorResponseExeption out = mapper.readValue(httpResponse.body(), RESTErrorResponseExeption.class);
throw out;
}
if (clazz.equals(String.class)) {
return (T)httpResponse.body();
}
T out = mapper.readValue(httpResponse.body(), clazz);
return out;
}
}