Compare commits
	
		
			19 Commits
		
	
	
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| b9eb17e5c6 | |||
| 6d05b3444c | |||
| 
						 | 
					7b5e034ac2 | ||
| 
						 | 
					b4554a8bdb | ||
| 
						 | 
					ae84d1c6c8 | ||
| 239763cf48 | |||
| 754c422be0 | |||
| 091ac4babd | |||
| dccb6b80d5 | |||
| 5633604d13 | |||
| 96cb8a6e16 | |||
| ebe88e4a8d | |||
| c82ab9f27f | |||
| f914462460 | |||
| 9da5f589db | |||
| a0a35efeaf | |||
| abf1ddcf24 | |||
| 3bbbea87fa | |||
| 25a163d4fa | 
							
								
								
									
										16
									
								
								.github/workflows/assign-pr-author.yml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								.github/workflows/assign-pr-author.yml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,16 @@
 | 
				
			|||||||
 | 
					---
 | 
				
			||||||
 | 
					name: "Assign PR Author as Assignee"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					on:
 | 
				
			||||||
 | 
					  pull_request:
 | 
				
			||||||
 | 
					    types:
 | 
				
			||||||
 | 
					      - opened
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					jobs:
 | 
				
			||||||
 | 
					  assign-pr-author-as-assignee:
 | 
				
			||||||
 | 
					    runs-on: ubuntu-latest
 | 
				
			||||||
 | 
					    steps:
 | 
				
			||||||
 | 
					      - name: "Assign Author as Assignee"
 | 
				
			||||||
 | 
					        uses: itsOliverBott/assign-pr-author-as-assignee@latest
 | 
				
			||||||
 | 
					        with:
 | 
				
			||||||
 | 
					          token: ${{ secrets.GITHUB_TOKEN }}
 | 
				
			||||||
							
								
								
									
										33
									
								
								.github/workflows/check-title.yml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										33
									
								
								.github/workflows/check-title.yml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,33 @@
 | 
				
			|||||||
 | 
					---
 | 
				
			||||||
 | 
					name: "Check PR title"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					on:
 | 
				
			||||||
 | 
					  pull_request:
 | 
				
			||||||
 | 
					    types:
 | 
				
			||||||
 | 
					      - opened
 | 
				
			||||||
 | 
					      - edited
 | 
				
			||||||
 | 
					      - synchronize
 | 
				
			||||||
 | 
					      - ready_for_review
 | 
				
			||||||
 | 
					      - reopened
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					jobs:
 | 
				
			||||||
 | 
					  check-title:
 | 
				
			||||||
 | 
					    runs-on: ubuntu-latest
 | 
				
			||||||
 | 
					    steps:
 | 
				
			||||||
 | 
					      - name: "Check title"
 | 
				
			||||||
 | 
					        uses: Slashgear/action-check-pr-title@v4.3.0
 | 
				
			||||||
 | 
					        with:
 | 
				
			||||||
 | 
					          regexp: "\\[(API,)?(API|DEV-OPS|DOC|FEAT|FIX|FIX\\-CI|STYLE)\\]( \\([A-Za-z0-9.\\-]+\\))? [A-Za-z0-9 ,.'\\-!]+$"
 | 
				
			||||||
 | 
					          helpMessage: |
 | 
				
			||||||
 | 
					            Title of the PR MUST respect format: "[{TYPE}] clear description without typos in english" with {TYPE}:
 | 
				
			||||||
 | 
					              * [API] Change API that permit to access on the application (un-compatibility only). This one can specifically added with [API,{TYPE}]
 | 
				
			||||||
 | 
					              * [DEV-OPS] Update automatic build system, method to deliver application/packages, ...
 | 
				
			||||||
 | 
					              * [DOC] Update or add some documentation.
 | 
				
			||||||
 | 
					              * [FEAT] Develop a new feature
 | 
				
			||||||
 | 
					              * [FIX] When fixing issue
 | 
				
			||||||
 | 
					              * [FIX-CI] When the CI fail to build and we apply a correction to set it work again.
 | 
				
			||||||
 | 
					              * [STYLE] Update of the style tools/checker, or add/remove rules.
 | 
				
			||||||
 | 
					            Examples:
 | 
				
			||||||
 | 
					              [FEAT] My beautiful feature
 | 
				
			||||||
 | 
					              [API,FIX] Change API to fix typo
 | 
				
			||||||
 | 
					              [FIX] (module) Correct part of ...
 | 
				
			||||||
							
								
								
									
										12
									
								
								.github/workflows/maven.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										12
									
								
								.github/workflows/maven.yml
									
									
									
									
										vendored
									
									
								
							@@ -10,19 +10,17 @@ name: Java CI with Maven
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
on:
 | 
					on:
 | 
				
			||||||
  push:
 | 
					  push:
 | 
				
			||||||
    branches: [ "develop" ]
 | 
					    branches:
 | 
				
			||||||
 | 
					      - develop
 | 
				
			||||||
  pull_request:
 | 
					  pull_request:
 | 
				
			||||||
    branches: [ "develop" ]
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
jobs:
 | 
					jobs:
 | 
				
			||||||
  build:
 | 
					  build:
 | 
				
			||||||
 | 
					 | 
				
			||||||
    runs-on: ubuntu-latest
 | 
					    runs-on: ubuntu-latest
 | 
				
			||||||
 | 
					 | 
				
			||||||
    steps:
 | 
					    steps:
 | 
				
			||||||
    - uses: actions/checkout@v3
 | 
					    - uses: actions/checkout@v4
 | 
				
			||||||
    - name: Set up JDK 17
 | 
					    - name: Set up JDK 17
 | 
				
			||||||
      uses: actions/setup-java@v3
 | 
					      uses: actions/setup-java@v4
 | 
				
			||||||
      with:
 | 
					      with:
 | 
				
			||||||
        java-version: '21'
 | 
					        java-version: '21'
 | 
				
			||||||
        distribution: 'temurin'
 | 
					        distribution: 'temurin'
 | 
				
			||||||
@@ -34,4 +32,4 @@ jobs:
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    # Optional: Uploads the full dependency graph to GitHub to improve the quality of Dependabot alerts this repository can receive
 | 
					    # Optional: Uploads the full dependency graph to GitHub to improve the quality of Dependabot alerts this repository can receive
 | 
				
			||||||
    - name: Update dependency graph
 | 
					    - name: Update dependency graph
 | 
				
			||||||
      uses: advanced-security/maven-dependency-submission-action@571e99aab1055c2e71a1e2309b9691de18d6b7d6
 | 
					      uses: advanced-security/maven-dependency-submission-action@4f64ddab9d742a4806eeb588d238e4c311a8397d
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										2
									
								
								pom.xml
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								pom.xml
									
									
									
									
									
								
							@@ -3,7 +3,7 @@
 | 
				
			|||||||
	<modelVersion>4.0.0</modelVersion>
 | 
						<modelVersion>4.0.0</modelVersion>
 | 
				
			||||||
	<groupId>kangaroo-and-rabbit</groupId>
 | 
						<groupId>kangaroo-and-rabbit</groupId>
 | 
				
			||||||
	<artifactId>archidata</artifactId>
 | 
						<artifactId>archidata</artifactId>
 | 
				
			||||||
	<version>0.16.0</version>
 | 
						<version>0.19.0</version>
 | 
				
			||||||
	<properties>
 | 
						<properties>
 | 
				
			||||||
		<java.version>21</java.version>
 | 
							<java.version>21</java.version>
 | 
				
			||||||
		<maven.compiler.version>3.1</maven.compiler.version>
 | 
							<maven.compiler.version>3.1</maven.compiler.version>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -21,6 +21,7 @@ import jakarta.persistence.ManyToMany;
 | 
				
			|||||||
import jakarta.persistence.ManyToOne;
 | 
					import jakarta.persistence.ManyToOne;
 | 
				
			||||||
import jakarta.persistence.OneToMany;
 | 
					import jakarta.persistence.OneToMany;
 | 
				
			||||||
import jakarta.persistence.Table;
 | 
					import jakarta.persistence.Table;
 | 
				
			||||||
 | 
					import jakarta.validation.constraints.Email;
 | 
				
			||||||
import jakarta.validation.constraints.Max;
 | 
					import jakarta.validation.constraints.Max;
 | 
				
			||||||
import jakarta.validation.constraints.Min;
 | 
					import jakarta.validation.constraints.Min;
 | 
				
			||||||
import jakarta.validation.constraints.NotNull;
 | 
					import jakarta.validation.constraints.NotNull;
 | 
				
			||||||
@@ -235,6 +236,14 @@ public class AnnotationTools {
 | 
				
			|||||||
		return ((Pattern) annotation[0]).regexp();
 | 
							return ((Pattern) annotation[0]).regexp();
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						public static boolean getConstraintsEmail(final Field element) throws DataAccessException {
 | 
				
			||||||
 | 
							final Annotation[] annotation = element.getDeclaredAnnotationsByType(Email.class);
 | 
				
			||||||
 | 
							if (annotation.length == 0) {
 | 
				
			||||||
 | 
								return false;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							return true;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	public static boolean isAnnotationGroup(final Field field, final Class<?> annotationType) {
 | 
						public static boolean isAnnotationGroup(final Field field, final Class<?> annotationType) {
 | 
				
			||||||
		try {
 | 
							try {
 | 
				
			||||||
			final Annotation[] anns = field.getAnnotations();
 | 
								final Annotation[] anns = field.getAnnotations();
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1246,6 +1246,10 @@ public class DataAccess {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	public static void addElement(final PreparedStatement ps, final Object value, final CountInOut iii)
 | 
						public static void addElement(final PreparedStatement ps, final Object value, final CountInOut iii)
 | 
				
			||||||
			throws Exception {
 | 
								throws Exception {
 | 
				
			||||||
 | 
							if (value == null) {
 | 
				
			||||||
 | 
								ps.setNull(iii.value, Types.INTEGER);
 | 
				
			||||||
 | 
								return;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
		if (value instanceof final UUID tmp) {
 | 
							if (value instanceof final UUID tmp) {
 | 
				
			||||||
			final byte[] dataByte = UuidUtils.asBytes(tmp);
 | 
								final byte[] dataByte = UuidUtils.asBytes(tmp);
 | 
				
			||||||
			ps.setBytes(iii.value, dataByte);
 | 
								ps.setBytes(iii.value, dataByte);
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -30,7 +30,9 @@ import org.slf4j.LoggerFactory;
 | 
				
			|||||||
import com.fasterxml.jackson.annotation.JsonValue;
 | 
					import com.fasterxml.jackson.annotation.JsonValue;
 | 
				
			||||||
import com.fasterxml.jackson.core.JsonProcessingException;
 | 
					import com.fasterxml.jackson.core.JsonProcessingException;
 | 
				
			||||||
import com.fasterxml.jackson.core.type.TypeReference;
 | 
					import com.fasterxml.jackson.core.type.TypeReference;
 | 
				
			||||||
 | 
					import com.fasterxml.jackson.databind.JavaType;
 | 
				
			||||||
import com.fasterxml.jackson.databind.ObjectMapper;
 | 
					import com.fasterxml.jackson.databind.ObjectMapper;
 | 
				
			||||||
 | 
					import com.fasterxml.jackson.databind.type.TypeFactory;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import jakarta.validation.constraints.NotNull;
 | 
					import jakarta.validation.constraints.NotNull;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -152,7 +154,10 @@ public class AddOnDataJson implements DataAccessAddOn {
 | 
				
			|||||||
				}
 | 
									}
 | 
				
			||||||
				LOGGER.warn("Maybe fail to translate Model in datajson list: List<{}>", listClass.getCanonicalName());
 | 
									LOGGER.warn("Maybe fail to translate Model in datajson list: List<{}>", listClass.getCanonicalName());
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			final Object dataParsed = objectMapper.readValue(jsonData, field.getType());
 | 
								final TypeFactory typeFactory = objectMapper.getTypeFactory();
 | 
				
			||||||
 | 
								final JavaType fieldType = typeFactory.constructType(field.getGenericType());
 | 
				
			||||||
 | 
								final Object dataParsed = objectMapper.readValue(jsonData, fieldType);
 | 
				
			||||||
 | 
								//final Object dataParsed = objectMapper.readValue(jsonData, field.getType());
 | 
				
			||||||
			field.set(data, dataParsed);
 | 
								field.set(data, dataParsed);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -10,9 +10,9 @@ public interface CheckFunctionInterface {
 | 
				
			|||||||
	/** This function implementation is design to check if the updated class is valid of not for insertion
 | 
						/** This function implementation is design to check if the updated class is valid of not for insertion
 | 
				
			||||||
	 * @param baseName NAme of the object to be precise with the use of what fail.
 | 
						 * @param baseName NAme of the object to be precise with the use of what fail.
 | 
				
			||||||
	 * @param data The object that might be injected.
 | 
						 * @param data The object that might be injected.
 | 
				
			||||||
	 * @param filterValue List of fields that might be check. If null, then all column must be checked.
 | 
						 * @param modifiedValue List of fields that might be check. If null, then all column must be checked.
 | 
				
			||||||
	 * @throws Exception Exception is generate if the data are incorrect. */
 | 
						 * @throws Exception Exception is generate if the data are incorrect. */
 | 
				
			||||||
	void check(final String baseName, Object data, List<String> filterValue, final QueryOptions options)
 | 
						void check(final String baseName, Object data, List<String> modifiedValue, final QueryOptions options)
 | 
				
			||||||
			throws Exception;
 | 
								throws Exception;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	default void checkAll(final String baseName, final Object data, final QueryOptions options) throws Exception {
 | 
						default void checkAll(final String baseName, final Object data, final QueryOptions options) throws Exception {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -35,10 +35,13 @@ public class CheckJPA<T> implements CheckFunctionInterface {
 | 
				
			|||||||
	/** By default some element are not read like createAt and UpdatedAt. This option permit to read it. */
 | 
						/** By default some element are not read like createAt and UpdatedAt. This option permit to read it. */
 | 
				
			||||||
	public interface CheckInterface<K> {
 | 
						public interface CheckInterface<K> {
 | 
				
			||||||
		/** This function implementation is design to check if the updated class is valid of not for insertion
 | 
							/** This function implementation is design to check if the updated class is valid of not for insertion
 | 
				
			||||||
 | 
							 * @param baseName Base of the name input that is displayed in exception generated.
 | 
				
			||||||
		 * @param data The object that might be injected.
 | 
							 * @param data The object that might be injected.
 | 
				
			||||||
		 * @param filterValue List of fields that might be check. If null, then all column must be checked.
 | 
							 * @param modifiedValue List of fields that modification is requested.
 | 
				
			||||||
 | 
							 * @param options Some query option that the checker can need to generate basic check.
 | 
				
			||||||
		 * @throws Exception Exception is generate if the data are incorrect. */
 | 
							 * @throws Exception Exception is generate if the data are incorrect. */
 | 
				
			||||||
		void check(final String baseName, final K data, final QueryOptions options) throws Exception;
 | 
							void check(final String baseName, final K data, List<String> modifiedValue, final QueryOptions options)
 | 
				
			||||||
 | 
									throws Exception;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	protected Map<String, List<CheckInterface<T>>> checking = null;
 | 
						protected Map<String, List<CheckInterface<T>>> checking = null;
 | 
				
			||||||
@@ -67,128 +70,182 @@ public class CheckJPA<T> implements CheckFunctionInterface {
 | 
				
			|||||||
			for (final Field field : this.clazz.getFields()) {
 | 
								for (final Field field : this.clazz.getFields()) {
 | 
				
			||||||
				final String fieldName = field.getName(); // AnnotationTools.getFieldName(field);
 | 
									final String fieldName = field.getName(); // AnnotationTools.getFieldName(field);
 | 
				
			||||||
				if (AnnotationTools.isPrimaryKey(field)) {
 | 
									if (AnnotationTools.isPrimaryKey(field)) {
 | 
				
			||||||
					add(fieldName, (final String baseName, final T data, final QueryOptions options) -> {
 | 
										add(fieldName,
 | 
				
			||||||
						throw new InputException(baseName + fieldName,
 | 
												(
 | 
				
			||||||
								"This is a '@Id' (primaryKey) ==> can not be change");
 | 
														final String baseName,
 | 
				
			||||||
					});
 | 
														final T data,
 | 
				
			||||||
 | 
														final List<String> modifiedValue,
 | 
				
			||||||
 | 
														final QueryOptions options) -> {
 | 
				
			||||||
 | 
													throw new InputException(baseName + fieldName,
 | 
				
			||||||
 | 
															"This is a '@Id' (primaryKey) ==> can not be change");
 | 
				
			||||||
 | 
												});
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
				if (AnnotationTools.getConstraintsNotNull(field)) {
 | 
									if (AnnotationTools.getConstraintsNotNull(field)) {
 | 
				
			||||||
					add(fieldName, (final String baseName, final T data, final QueryOptions options) -> {
 | 
										add(fieldName,
 | 
				
			||||||
						if (field.get(data) == null) {
 | 
												(
 | 
				
			||||||
							throw new InputException(baseName + fieldName, "Can not be null");
 | 
														final String baseName,
 | 
				
			||||||
						}
 | 
														final T data,
 | 
				
			||||||
					});
 | 
														final List<String> modifiedValue,
 | 
				
			||||||
 | 
														final QueryOptions options) -> {
 | 
				
			||||||
 | 
													if (field.get(data) == null) {
 | 
				
			||||||
 | 
														throw new InputException(baseName + fieldName, "Can not be null");
 | 
				
			||||||
 | 
													}
 | 
				
			||||||
 | 
												});
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
				if (AnnotationTools.isCreatedAtField(field) || AnnotationTools.isUpdateAtField(field)) {
 | 
									if (AnnotationTools.isCreatedAtField(field) || AnnotationTools.isUpdateAtField(field)) {
 | 
				
			||||||
					add(fieldName, (final String baseName, final T data, final QueryOptions options) -> {
 | 
										add(fieldName,
 | 
				
			||||||
						throw new InputException(baseName + fieldName, "It is forbidden to change this field");
 | 
												(
 | 
				
			||||||
					});
 | 
														final String baseName,
 | 
				
			||||||
 | 
														final T data,
 | 
				
			||||||
 | 
														final List<String> modifiedValue,
 | 
				
			||||||
 | 
														final QueryOptions options) -> {
 | 
				
			||||||
 | 
													throw new InputException(baseName + fieldName, "It is forbidden to change this field");
 | 
				
			||||||
 | 
												});
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				final Class<?> type = field.getType();
 | 
									final Class<?> type = field.getType();
 | 
				
			||||||
				if (type == Long.class || type == long.class) {
 | 
									if (type == Long.class || type == long.class) {
 | 
				
			||||||
					final Long maxValue = AnnotationTools.getConstraintsMax(field);
 | 
										final Long maxValue = AnnotationTools.getConstraintsMax(field);
 | 
				
			||||||
					if (maxValue != null) {
 | 
										if (maxValue != null) {
 | 
				
			||||||
						add(fieldName, (final String baseName, final T data, final QueryOptions options) -> {
 | 
											add(fieldName,
 | 
				
			||||||
							final Object elem = field.get(data);
 | 
													(
 | 
				
			||||||
							if (elem == null) {
 | 
															final String baseName,
 | 
				
			||||||
								return;
 | 
															final T data,
 | 
				
			||||||
							}
 | 
															final List<String> modifiedValue,
 | 
				
			||||||
							final Long elemTyped = (Long) elem;
 | 
															final QueryOptions options) -> {
 | 
				
			||||||
							if (elemTyped > maxValue) {
 | 
														final Object elem = field.get(data);
 | 
				
			||||||
								throw new InputException(baseName + fieldName, "Value too height max: " + maxValue);
 | 
														if (elem == null) {
 | 
				
			||||||
							}
 | 
															return;
 | 
				
			||||||
						});
 | 
														}
 | 
				
			||||||
 | 
														final Long elemTyped = (Long) elem;
 | 
				
			||||||
 | 
														if (elemTyped > maxValue) {
 | 
				
			||||||
 | 
															throw new InputException(baseName + fieldName,
 | 
				
			||||||
 | 
																	"Value too height max: " + maxValue);
 | 
				
			||||||
 | 
														}
 | 
				
			||||||
 | 
													});
 | 
				
			||||||
					}
 | 
										}
 | 
				
			||||||
					final Long minValue = AnnotationTools.getConstraintsMin(field);
 | 
										final Long minValue = AnnotationTools.getConstraintsMin(field);
 | 
				
			||||||
					if (minValue != null) {
 | 
										if (minValue != null) {
 | 
				
			||||||
						add(fieldName, (final String baseName, final T data, final QueryOptions options) -> {
 | 
											add(fieldName,
 | 
				
			||||||
							final Object elem = field.get(data);
 | 
													(
 | 
				
			||||||
							if (elem == null) {
 | 
															final String baseName,
 | 
				
			||||||
								return;
 | 
															final T data,
 | 
				
			||||||
							}
 | 
															final List<String> modifiedValue,
 | 
				
			||||||
							final Long elemTyped = (Long) elem;
 | 
															final QueryOptions options) -> {
 | 
				
			||||||
							if (elemTyped < minValue) {
 | 
														final Object elem = field.get(data);
 | 
				
			||||||
								throw new InputException(baseName + fieldName, "Value too Low min: " + minValue);
 | 
														if (elem == null) {
 | 
				
			||||||
							}
 | 
															return;
 | 
				
			||||||
						});
 | 
														}
 | 
				
			||||||
 | 
														final Long elemTyped = (Long) elem;
 | 
				
			||||||
 | 
														if (elemTyped < minValue) {
 | 
				
			||||||
 | 
															throw new InputException(baseName + fieldName,
 | 
				
			||||||
 | 
																	"Value too Low min: " + minValue);
 | 
				
			||||||
 | 
														}
 | 
				
			||||||
 | 
													});
 | 
				
			||||||
					}
 | 
										}
 | 
				
			||||||
					final ManyToOne annotationManyToOne = AnnotationTools.getManyToOne(field);
 | 
										final ManyToOne annotationManyToOne = AnnotationTools.getManyToOne(field);
 | 
				
			||||||
					if (annotationManyToOne != null && annotationManyToOne.targetEntity() != null) {
 | 
										if (annotationManyToOne != null && annotationManyToOne.targetEntity() != null) {
 | 
				
			||||||
						add(fieldName, (final String baseName, final T data, final QueryOptions options) -> {
 | 
											add(fieldName,
 | 
				
			||||||
							final Object elem = field.get(data);
 | 
													(
 | 
				
			||||||
							if (elem == null) {
 | 
															final String baseName,
 | 
				
			||||||
								return;
 | 
															final T data,
 | 
				
			||||||
							}
 | 
															final List<String> modifiedValue,
 | 
				
			||||||
							final List<ConditionChecker> condCheckers = options.get(ConditionChecker.class);
 | 
															final QueryOptions options) -> {
 | 
				
			||||||
							final Condition conditionCheck = condCheckers.isEmpty() ? null
 | 
														final Object elem = field.get(data);
 | 
				
			||||||
									: condCheckers.get(0).toCondition();
 | 
														if (elem == null) {
 | 
				
			||||||
							final long count = DataAccess.count(annotationManyToOne.targetEntity(), elem,
 | 
															return;
 | 
				
			||||||
									conditionCheck);
 | 
														}
 | 
				
			||||||
							if (count == 0) {
 | 
														final List<ConditionChecker> condCheckers = options.get(ConditionChecker.class);
 | 
				
			||||||
								throw new InputException(baseName + fieldName,
 | 
														final Condition conditionCheck = condCheckers.isEmpty() ? null
 | 
				
			||||||
										"Foreign element does not exist in the DB:" + elem);
 | 
																: condCheckers.get(0).toCondition();
 | 
				
			||||||
							}
 | 
														final long count = DataAccess.count(annotationManyToOne.targetEntity(), elem,
 | 
				
			||||||
						});
 | 
																conditionCheck);
 | 
				
			||||||
 | 
														if (count == 0) {
 | 
				
			||||||
 | 
															throw new InputException(baseName + fieldName,
 | 
				
			||||||
 | 
																	"Foreign element does not exist in the DB:" + elem);
 | 
				
			||||||
 | 
														}
 | 
				
			||||||
 | 
													});
 | 
				
			||||||
					}
 | 
										}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				} else if (type == Integer.class || type == int.class) {
 | 
									} else if (type == Integer.class || type == int.class) {
 | 
				
			||||||
					final Long maxValueRoot = AnnotationTools.getConstraintsMax(field);
 | 
										final Long maxValueRoot = AnnotationTools.getConstraintsMax(field);
 | 
				
			||||||
					if (maxValueRoot != null) {
 | 
										if (maxValueRoot != null) {
 | 
				
			||||||
						final int maxValue = maxValueRoot.intValue();
 | 
											final int maxValue = maxValueRoot.intValue();
 | 
				
			||||||
						add(fieldName, (final String baseName, final T data, final QueryOptions options) -> {
 | 
											add(fieldName,
 | 
				
			||||||
							final Object elem = field.get(data);
 | 
													(
 | 
				
			||||||
							if (elem == null) {
 | 
															final String baseName,
 | 
				
			||||||
								return;
 | 
															final T data,
 | 
				
			||||||
							}
 | 
															final List<String> modifiedValue,
 | 
				
			||||||
							final Integer elemTyped = (Integer) elem;
 | 
															final QueryOptions options) -> {
 | 
				
			||||||
							if (elemTyped > maxValue) {
 | 
														final Object elem = field.get(data);
 | 
				
			||||||
								throw new InputException(baseName + fieldName, "Value too height max: " + maxValue);
 | 
														if (elem == null) {
 | 
				
			||||||
							}
 | 
															return;
 | 
				
			||||||
						});
 | 
														}
 | 
				
			||||||
 | 
														final Integer elemTyped = (Integer) elem;
 | 
				
			||||||
 | 
														if (elemTyped > maxValue) {
 | 
				
			||||||
 | 
															throw new InputException(baseName + fieldName,
 | 
				
			||||||
 | 
																	"Value too height max: " + maxValue);
 | 
				
			||||||
 | 
														}
 | 
				
			||||||
 | 
													});
 | 
				
			||||||
					}
 | 
										}
 | 
				
			||||||
					final Long minValueRoot = AnnotationTools.getConstraintsMin(field);
 | 
										final Long minValueRoot = AnnotationTools.getConstraintsMin(field);
 | 
				
			||||||
					if (minValueRoot != null) {
 | 
										if (minValueRoot != null) {
 | 
				
			||||||
						final int minValue = minValueRoot.intValue();
 | 
											final int minValue = minValueRoot.intValue();
 | 
				
			||||||
						add(fieldName, (final String baseName, final T data, final QueryOptions options) -> {
 | 
											add(fieldName,
 | 
				
			||||||
							final Object elem = field.get(data);
 | 
													(
 | 
				
			||||||
							if (elem == null) {
 | 
															final String baseName,
 | 
				
			||||||
								return;
 | 
															final T data,
 | 
				
			||||||
							}
 | 
															final List<String> modifiedValue,
 | 
				
			||||||
							final Integer elemTyped = (Integer) elem;
 | 
															final QueryOptions options) -> {
 | 
				
			||||||
							if (elemTyped < minValue) {
 | 
														final Object elem = field.get(data);
 | 
				
			||||||
								throw new InputException(baseName + fieldName, "Value too Low min: " + minValue);
 | 
														if (elem == null) {
 | 
				
			||||||
							}
 | 
															return;
 | 
				
			||||||
						});
 | 
														}
 | 
				
			||||||
 | 
														final Integer elemTyped = (Integer) elem;
 | 
				
			||||||
 | 
														if (elemTyped < minValue) {
 | 
				
			||||||
 | 
															throw new InputException(baseName + fieldName,
 | 
				
			||||||
 | 
																	"Value too Low min: " + minValue);
 | 
				
			||||||
 | 
														}
 | 
				
			||||||
 | 
													});
 | 
				
			||||||
					}
 | 
										}
 | 
				
			||||||
					final ManyToOne annotationManyToOne = AnnotationTools.getManyToOne(field);
 | 
										final ManyToOne annotationManyToOne = AnnotationTools.getManyToOne(field);
 | 
				
			||||||
					if (annotationManyToOne != null && annotationManyToOne.targetEntity() != null) {
 | 
										if (annotationManyToOne != null && annotationManyToOne.targetEntity() != null) {
 | 
				
			||||||
						add(fieldName, (final String baseName, final T data, final QueryOptions options) -> {
 | 
											add(fieldName,
 | 
				
			||||||
							final Object elem = field.get(data);
 | 
													(
 | 
				
			||||||
							if (elem == null) {
 | 
															final String baseName,
 | 
				
			||||||
								return;
 | 
															final T data,
 | 
				
			||||||
							}
 | 
															final List<String> modifiedValue,
 | 
				
			||||||
							final long count = DataAccess.count(annotationManyToOne.targetEntity(), elem);
 | 
															final QueryOptions options) -> {
 | 
				
			||||||
							if (count == 0) {
 | 
														final Object elem = field.get(data);
 | 
				
			||||||
								throw new InputException(baseName + fieldName,
 | 
														if (elem == null) {
 | 
				
			||||||
										"Foreign element does not exist in the DB:" + elem);
 | 
															return;
 | 
				
			||||||
							}
 | 
														}
 | 
				
			||||||
						});
 | 
														final long count = DataAccess.count(annotationManyToOne.targetEntity(), elem);
 | 
				
			||||||
 | 
														if (count == 0) {
 | 
				
			||||||
 | 
															throw new InputException(baseName + fieldName,
 | 
				
			||||||
 | 
																	"Foreign element does not exist in the DB:" + elem);
 | 
				
			||||||
 | 
														}
 | 
				
			||||||
 | 
													});
 | 
				
			||||||
					}
 | 
										}
 | 
				
			||||||
				} else if (type == UUID.class) {
 | 
									} else if (type == UUID.class) {
 | 
				
			||||||
					final ManyToOne annotationManyToOne = AnnotationTools.getManyToOne(field);
 | 
										final ManyToOne annotationManyToOne = AnnotationTools.getManyToOne(field);
 | 
				
			||||||
					if (annotationManyToOne != null && annotationManyToOne.targetEntity() != null) {
 | 
										if (annotationManyToOne != null && annotationManyToOne.targetEntity() != null) {
 | 
				
			||||||
						add(fieldName, (final String baseName, final T data, final QueryOptions options) -> {
 | 
											add(fieldName,
 | 
				
			||||||
							final Object elem = field.get(data);
 | 
													(
 | 
				
			||||||
							if (elem == null) {
 | 
															final String baseName,
 | 
				
			||||||
								return;
 | 
															final T data,
 | 
				
			||||||
							}
 | 
															final List<String> modifiedValue,
 | 
				
			||||||
							final long count = DataAccess.count(annotationManyToOne.targetEntity(), elem);
 | 
															final QueryOptions options) -> {
 | 
				
			||||||
							if (count == 0) {
 | 
														final Object elem = field.get(data);
 | 
				
			||||||
								throw new InputException(baseName + fieldName,
 | 
														if (elem == null) {
 | 
				
			||||||
										"Foreign element does not exist in the DB:" + elem);
 | 
															return;
 | 
				
			||||||
							}
 | 
														}
 | 
				
			||||||
						});
 | 
														final long count = DataAccess.count(annotationManyToOne.targetEntity(), elem);
 | 
				
			||||||
 | 
														if (count == 0) {
 | 
				
			||||||
 | 
															throw new InputException(baseName + fieldName,
 | 
				
			||||||
 | 
																	"Foreign element does not exist in the DB:" + elem);
 | 
				
			||||||
 | 
														}
 | 
				
			||||||
 | 
													});
 | 
				
			||||||
					}
 | 
										}
 | 
				
			||||||
				} else if (type == Boolean.class || type == boolean.class) {
 | 
									} else if (type == Boolean.class || type == boolean.class) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -196,59 +253,83 @@ public class CheckJPA<T> implements CheckFunctionInterface {
 | 
				
			|||||||
					final Long maxValueRoot = AnnotationTools.getConstraintsMax(field);
 | 
										final Long maxValueRoot = AnnotationTools.getConstraintsMax(field);
 | 
				
			||||||
					if (maxValueRoot != null) {
 | 
										if (maxValueRoot != null) {
 | 
				
			||||||
						final float maxValue = maxValueRoot.floatValue();
 | 
											final float maxValue = maxValueRoot.floatValue();
 | 
				
			||||||
						add(fieldName, (final String baseName, final T data, final QueryOptions options) -> {
 | 
											add(fieldName,
 | 
				
			||||||
							final Object elem = field.get(data);
 | 
													(
 | 
				
			||||||
							if (elem == null) {
 | 
															final String baseName,
 | 
				
			||||||
								return;
 | 
															final T data,
 | 
				
			||||||
							}
 | 
															final List<String> modifiedValue,
 | 
				
			||||||
							final Float elemTyped = (Float) elem;
 | 
															final QueryOptions options) -> {
 | 
				
			||||||
							if (elemTyped > maxValue) {
 | 
														final Object elem = field.get(data);
 | 
				
			||||||
								throw new InputException(baseName + fieldName, "Value too height max: " + maxValue);
 | 
														if (elem == null) {
 | 
				
			||||||
							}
 | 
															return;
 | 
				
			||||||
						});
 | 
														}
 | 
				
			||||||
 | 
														final Float elemTyped = (Float) elem;
 | 
				
			||||||
 | 
														if (elemTyped > maxValue) {
 | 
				
			||||||
 | 
															throw new InputException(baseName + fieldName,
 | 
				
			||||||
 | 
																	"Value too height max: " + maxValue);
 | 
				
			||||||
 | 
														}
 | 
				
			||||||
 | 
													});
 | 
				
			||||||
					}
 | 
										}
 | 
				
			||||||
					final Long minValueRoot = AnnotationTools.getConstraintsMin(field);
 | 
										final Long minValueRoot = AnnotationTools.getConstraintsMin(field);
 | 
				
			||||||
					if (minValueRoot != null) {
 | 
										if (minValueRoot != null) {
 | 
				
			||||||
						final float minValue = minValueRoot.floatValue();
 | 
											final float minValue = minValueRoot.floatValue();
 | 
				
			||||||
						add(fieldName, (final String baseName, final T data, final QueryOptions options) -> {
 | 
											add(fieldName,
 | 
				
			||||||
							final Object elem = field.get(data);
 | 
													(
 | 
				
			||||||
							if (elem == null) {
 | 
															final String baseName,
 | 
				
			||||||
								return;
 | 
															final T data,
 | 
				
			||||||
							}
 | 
															final List<String> modifiedValue,
 | 
				
			||||||
							final Float elemTyped = (Float) elem;
 | 
															final QueryOptions options) -> {
 | 
				
			||||||
							if (elemTyped < minValue) {
 | 
														final Object elem = field.get(data);
 | 
				
			||||||
								throw new InputException(baseName + fieldName, "Value too Low min: " + minValue);
 | 
														if (elem == null) {
 | 
				
			||||||
							}
 | 
															return;
 | 
				
			||||||
						});
 | 
														}
 | 
				
			||||||
 | 
														final Float elemTyped = (Float) elem;
 | 
				
			||||||
 | 
														if (elemTyped < minValue) {
 | 
				
			||||||
 | 
															throw new InputException(baseName + fieldName,
 | 
				
			||||||
 | 
																	"Value too Low min: " + minValue);
 | 
				
			||||||
 | 
														}
 | 
				
			||||||
 | 
													});
 | 
				
			||||||
					}
 | 
										}
 | 
				
			||||||
				} else if (type == Double.class || type == double.class) {
 | 
									} else if (type == Double.class || type == double.class) {
 | 
				
			||||||
					final Long maxValueRoot = AnnotationTools.getConstraintsMax(field);
 | 
										final Long maxValueRoot = AnnotationTools.getConstraintsMax(field);
 | 
				
			||||||
					if (maxValueRoot != null) {
 | 
										if (maxValueRoot != null) {
 | 
				
			||||||
						final double maxValue = maxValueRoot.doubleValue();
 | 
											final double maxValue = maxValueRoot.doubleValue();
 | 
				
			||||||
						add(fieldName, (final String baseName, final T data, final QueryOptions options) -> {
 | 
											add(fieldName,
 | 
				
			||||||
							final Object elem = field.get(data);
 | 
													(
 | 
				
			||||||
							if (elem == null) {
 | 
															final String baseName,
 | 
				
			||||||
								return;
 | 
															final T data,
 | 
				
			||||||
							}
 | 
															final List<String> modifiedValue,
 | 
				
			||||||
							final Double elemTyped = (Double) elem;
 | 
															final QueryOptions options) -> {
 | 
				
			||||||
							if (elemTyped > maxValue) {
 | 
														final Object elem = field.get(data);
 | 
				
			||||||
								throw new InputException(baseName + fieldName, "Value too height max: " + maxValue);
 | 
														if (elem == null) {
 | 
				
			||||||
							}
 | 
															return;
 | 
				
			||||||
						});
 | 
														}
 | 
				
			||||||
 | 
														final Double elemTyped = (Double) elem;
 | 
				
			||||||
 | 
														if (elemTyped > maxValue) {
 | 
				
			||||||
 | 
															throw new InputException(baseName + fieldName,
 | 
				
			||||||
 | 
																	"Value too height max: " + maxValue);
 | 
				
			||||||
 | 
														}
 | 
				
			||||||
 | 
													});
 | 
				
			||||||
					}
 | 
										}
 | 
				
			||||||
					final Long minValueRoot = AnnotationTools.getConstraintsMin(field);
 | 
										final Long minValueRoot = AnnotationTools.getConstraintsMin(field);
 | 
				
			||||||
					if (minValueRoot != null) {
 | 
										if (minValueRoot != null) {
 | 
				
			||||||
						final double minValue = minValueRoot.doubleValue();
 | 
											final double minValue = minValueRoot.doubleValue();
 | 
				
			||||||
						add(fieldName, (final String baseName, final T data, final QueryOptions options) -> {
 | 
											add(fieldName,
 | 
				
			||||||
							final Object elem = field.get(data);
 | 
													(
 | 
				
			||||||
							if (elem == null) {
 | 
															final String baseName,
 | 
				
			||||||
								return;
 | 
															final T data,
 | 
				
			||||||
							}
 | 
															final List<String> modifiedValue,
 | 
				
			||||||
							final Double elemTyped = (Double) elem;
 | 
															final QueryOptions options) -> {
 | 
				
			||||||
							if (elemTyped < minValue) {
 | 
														final Object elem = field.get(data);
 | 
				
			||||||
								throw new InputException(baseName + fieldName, "Value too Low min: " + minValue);
 | 
														if (elem == null) {
 | 
				
			||||||
							}
 | 
															return;
 | 
				
			||||||
						});
 | 
														}
 | 
				
			||||||
 | 
														final Double elemTyped = (Double) elem;
 | 
				
			||||||
 | 
														if (elemTyped < minValue) {
 | 
				
			||||||
 | 
															throw new InputException(baseName + fieldName,
 | 
				
			||||||
 | 
																	"Value too Low min: " + minValue);
 | 
				
			||||||
 | 
														}
 | 
				
			||||||
 | 
													});
 | 
				
			||||||
					}
 | 
										}
 | 
				
			||||||
				} else if (type == Date.class || type == Timestamp.class) {
 | 
									} else if (type == Date.class || type == Timestamp.class) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -259,51 +340,87 @@ public class CheckJPA<T> implements CheckFunctionInterface {
 | 
				
			|||||||
				} else if (type == String.class) {
 | 
									} else if (type == String.class) {
 | 
				
			||||||
					final int maxSizeString = AnnotationTools.getLimitSize(field);
 | 
										final int maxSizeString = AnnotationTools.getLimitSize(field);
 | 
				
			||||||
					if (maxSizeString > 0) {
 | 
										if (maxSizeString > 0) {
 | 
				
			||||||
						add(fieldName, (final String baseName, final T data, final QueryOptions options) -> {
 | 
											add(fieldName,
 | 
				
			||||||
							final Object elem = field.get(data);
 | 
													(
 | 
				
			||||||
							if (elem == null) {
 | 
															final String baseName,
 | 
				
			||||||
								return;
 | 
															final T data,
 | 
				
			||||||
							}
 | 
															final List<String> modifiedValue,
 | 
				
			||||||
							final String elemTyped = (String) elem;
 | 
															final QueryOptions options) -> {
 | 
				
			||||||
							if (elemTyped.length() > maxSizeString) {
 | 
														final Object elem = field.get(data);
 | 
				
			||||||
								throw new InputException(baseName + fieldName,
 | 
														if (elem == null) {
 | 
				
			||||||
										"Too long size must be <= " + maxSizeString);
 | 
															return;
 | 
				
			||||||
							}
 | 
														}
 | 
				
			||||||
						});
 | 
														final String elemTyped = (String) elem;
 | 
				
			||||||
 | 
														if (elemTyped.length() > maxSizeString) {
 | 
				
			||||||
 | 
															throw new InputException(baseName + fieldName,
 | 
				
			||||||
 | 
																	"Too long size must be <= " + maxSizeString);
 | 
				
			||||||
 | 
														}
 | 
				
			||||||
 | 
													});
 | 
				
			||||||
					}
 | 
										}
 | 
				
			||||||
					final Size limitSize = AnnotationTools.getConstraintsSize(field);
 | 
										final Size limitSize = AnnotationTools.getConstraintsSize(field);
 | 
				
			||||||
					if (limitSize != null) {
 | 
										if (limitSize != null) {
 | 
				
			||||||
						add(fieldName, (final String baseName, final T data, final QueryOptions options) -> {
 | 
											add(fieldName,
 | 
				
			||||||
							final Object elem = field.get(data);
 | 
													(
 | 
				
			||||||
							if (elem == null) {
 | 
															final String baseName,
 | 
				
			||||||
								return;
 | 
															final T data,
 | 
				
			||||||
							}
 | 
															final List<String> modifiedValue,
 | 
				
			||||||
							final String elemTyped = (String) elem;
 | 
															final QueryOptions options) -> {
 | 
				
			||||||
							if (elemTyped.length() > limitSize.max()) {
 | 
														final Object elem = field.get(data);
 | 
				
			||||||
								throw new InputException(baseName + fieldName,
 | 
														if (elem == null) {
 | 
				
			||||||
										"Too long size (constraints) must be <= " + limitSize.max());
 | 
															return;
 | 
				
			||||||
							}
 | 
														}
 | 
				
			||||||
							if (elemTyped.length() < limitSize.min()) {
 | 
														final String elemTyped = (String) elem;
 | 
				
			||||||
								throw new InputException(baseName + fieldName,
 | 
														if (elemTyped.length() > limitSize.max()) {
 | 
				
			||||||
										"Too small size (constraints) must be >= " + limitSize.min());
 | 
															throw new InputException(baseName + fieldName,
 | 
				
			||||||
							}
 | 
																	"Too long size (constraints) must be <= " + limitSize.max());
 | 
				
			||||||
						});
 | 
														}
 | 
				
			||||||
 | 
														if (elemTyped.length() < limitSize.min()) {
 | 
				
			||||||
 | 
															throw new InputException(baseName + fieldName,
 | 
				
			||||||
 | 
																	"Too small size (constraints) must be >= " + limitSize.min());
 | 
				
			||||||
 | 
														}
 | 
				
			||||||
 | 
													});
 | 
				
			||||||
					}
 | 
										}
 | 
				
			||||||
					final String patternString = AnnotationTools.getConstraintsPattern(field);
 | 
										final String patternString = AnnotationTools.getConstraintsPattern(field);
 | 
				
			||||||
					if (patternString != null) {
 | 
										if (patternString != null) {
 | 
				
			||||||
						final Pattern pattern = Pattern.compile(patternString);
 | 
											final Pattern pattern = Pattern.compile(patternString);
 | 
				
			||||||
						add(fieldName, (final String baseName, final T data, final QueryOptions options) -> {
 | 
											add(fieldName,
 | 
				
			||||||
							final Object elem = field.get(data);
 | 
													(
 | 
				
			||||||
							if (elem == null) {
 | 
															final String baseName,
 | 
				
			||||||
								return;
 | 
															final T data,
 | 
				
			||||||
							}
 | 
															final List<String> modifiedValue,
 | 
				
			||||||
							final String elemTyped = (String) elem;
 | 
															final QueryOptions options) -> {
 | 
				
			||||||
							if (!pattern.matcher(elemTyped).find()) {
 | 
														final Object elem = field.get(data);
 | 
				
			||||||
								throw new InputException(baseName + fieldName,
 | 
														if (elem == null) {
 | 
				
			||||||
										"does not match the required pattern (constraints) must be '" + patternString
 | 
															return;
 | 
				
			||||||
												+ "'");
 | 
														}
 | 
				
			||||||
							}
 | 
														final String elemTyped = (String) elem;
 | 
				
			||||||
						});
 | 
														if (!pattern.matcher(elemTyped).find()) {
 | 
				
			||||||
 | 
															throw new InputException(baseName + fieldName,
 | 
				
			||||||
 | 
																	"does not match the required pattern (constraints) must be '"
 | 
				
			||||||
 | 
																			+ patternString + "'");
 | 
				
			||||||
 | 
														}
 | 
				
			||||||
 | 
													});
 | 
				
			||||||
 | 
										}
 | 
				
			||||||
 | 
										if (AnnotationTools.getConstraintsEmail(field)) {
 | 
				
			||||||
 | 
											final String emailPattern = "^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$";
 | 
				
			||||||
 | 
											final Pattern pattern = Pattern.compile(emailPattern);
 | 
				
			||||||
 | 
											add(fieldName,
 | 
				
			||||||
 | 
													(
 | 
				
			||||||
 | 
															final String baseName,
 | 
				
			||||||
 | 
															final T data,
 | 
				
			||||||
 | 
															final List<String> modifiedValue,
 | 
				
			||||||
 | 
															final QueryOptions options) -> {
 | 
				
			||||||
 | 
														final Object elem = field.get(data);
 | 
				
			||||||
 | 
														if (elem == null) {
 | 
				
			||||||
 | 
															return;
 | 
				
			||||||
 | 
														}
 | 
				
			||||||
 | 
														final String elemTyped = (String) elem;
 | 
				
			||||||
 | 
														if (!pattern.matcher(elemTyped).find()) {
 | 
				
			||||||
 | 
															throw new InputException(baseName + fieldName,
 | 
				
			||||||
 | 
																	"does not match the required pattern[email] (constraints) must be '"
 | 
				
			||||||
 | 
																			+ emailPattern + "'");
 | 
				
			||||||
 | 
														}
 | 
				
			||||||
 | 
													});
 | 
				
			||||||
					}
 | 
										}
 | 
				
			||||||
				} else if (type == JsonValue.class) {
 | 
									} else if (type == JsonValue.class) {
 | 
				
			||||||
					final DataJson jsonAnnotation = AnnotationTools.getDataJson(field);
 | 
										final DataJson jsonAnnotation = AnnotationTools.getDataJson(field);
 | 
				
			||||||
@@ -311,9 +428,14 @@ public class CheckJPA<T> implements CheckFunctionInterface {
 | 
				
			|||||||
						// Here if we have an error it crash at start and no new instance after creation...
 | 
											// Here if we have an error it crash at start and no new instance after creation...
 | 
				
			||||||
						final CheckFunctionInterface instance = jsonAnnotation.checker().getDeclaredConstructor()
 | 
											final CheckFunctionInterface instance = jsonAnnotation.checker().getDeclaredConstructor()
 | 
				
			||||||
								.newInstance();
 | 
													.newInstance();
 | 
				
			||||||
						add(fieldName, (final String baseName, final T data, final QueryOptions options) -> {
 | 
											add(fieldName,
 | 
				
			||||||
							instance.checkAll(baseName + fieldName + ".", field.get(data), options);
 | 
													(
 | 
				
			||||||
						});
 | 
															final String baseName,
 | 
				
			||||||
 | 
															final T data,
 | 
				
			||||||
 | 
															final List<String> modifiedValue,
 | 
				
			||||||
 | 
															final QueryOptions options) -> {
 | 
				
			||||||
 | 
														instance.checkAll(baseName + fieldName + ".", field.get(data), options);
 | 
				
			||||||
 | 
													});
 | 
				
			||||||
					}
 | 
										}
 | 
				
			||||||
				} else if (type.isEnum()) {
 | 
									} else if (type.isEnum()) {
 | 
				
			||||||
					// nothing to do.
 | 
										// nothing to do.
 | 
				
			||||||
@@ -321,21 +443,26 @@ public class CheckJPA<T> implements CheckFunctionInterface {
 | 
				
			|||||||
				// keep this is last ==> take more time...
 | 
									// keep this is last ==> take more time...
 | 
				
			||||||
				if (AnnotationTools.isUnique(field)) {
 | 
									if (AnnotationTools.isUnique(field)) {
 | 
				
			||||||
					// Create the request ...
 | 
										// Create the request ...
 | 
				
			||||||
					add(fieldName, (final String baseName, final T data, final QueryOptions options) -> {
 | 
										add(fieldName,
 | 
				
			||||||
						final List<ConditionChecker> condCheckers = options.get(ConditionChecker.class);
 | 
												(
 | 
				
			||||||
						Object other = null;
 | 
														final String baseName,
 | 
				
			||||||
						if (condCheckers.isEmpty()) {
 | 
														final T data,
 | 
				
			||||||
							other = DataAccess.getWhere(this.clazz,
 | 
														final List<String> modifiedValue,
 | 
				
			||||||
									new Condition(new QueryCondition(fieldName, "==", field.get(data))));
 | 
														final QueryOptions options) -> {
 | 
				
			||||||
						} else {
 | 
													final List<ConditionChecker> condCheckers = options.get(ConditionChecker.class);
 | 
				
			||||||
							other = DataAccess.getWhere(this.clazz,
 | 
													Object other = null;
 | 
				
			||||||
									new Condition(new QueryCondition(fieldName, "==", field.get(data))),
 | 
													if (condCheckers.isEmpty()) {
 | 
				
			||||||
									condCheckers.get(0).toCondition());
 | 
														other = DataAccess.getWhere(this.clazz,
 | 
				
			||||||
						}
 | 
																new Condition(new QueryCondition(fieldName, "==", field.get(data))));
 | 
				
			||||||
						if (other != null) {
 | 
													} else {
 | 
				
			||||||
							throw new InputException(baseName + fieldName, "Name already exist in the DB");
 | 
														other = DataAccess.getWhere(this.clazz,
 | 
				
			||||||
						}
 | 
																new Condition(new QueryCondition(fieldName, "==", field.get(data))),
 | 
				
			||||||
					});
 | 
																condCheckers.get(0).toCondition());
 | 
				
			||||||
 | 
													}
 | 
				
			||||||
 | 
													if (other != null) {
 | 
				
			||||||
 | 
														throw new InputException(baseName + fieldName, "Name already exist in the DB");
 | 
				
			||||||
 | 
													}
 | 
				
			||||||
 | 
												});
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
@@ -349,7 +476,7 @@ public class CheckJPA<T> implements CheckFunctionInterface {
 | 
				
			|||||||
	public void check(
 | 
						public void check(
 | 
				
			||||||
			final String baseName,
 | 
								final String baseName,
 | 
				
			||||||
			final Object data,
 | 
								final Object data,
 | 
				
			||||||
			final List<String> filterValue,
 | 
								final List<String> modifiedValue,
 | 
				
			||||||
			final QueryOptions options) throws Exception {
 | 
								final QueryOptions options) throws Exception {
 | 
				
			||||||
		if (this.checking == null) {
 | 
							if (this.checking == null) {
 | 
				
			||||||
			initialize();
 | 
								initialize();
 | 
				
			||||||
@@ -359,19 +486,20 @@ public class CheckJPA<T> implements CheckFunctionInterface {
 | 
				
			|||||||
		}
 | 
							}
 | 
				
			||||||
		@SuppressWarnings("unchecked")
 | 
							@SuppressWarnings("unchecked")
 | 
				
			||||||
		final T dataCasted = (T) data;
 | 
							final T dataCasted = (T) data;
 | 
				
			||||||
		for (final String filter : filterValue) {
 | 
							for (final String filter : modifiedValue) {
 | 
				
			||||||
			final List<CheckInterface<T>> actions = this.checking.get(filter);
 | 
								final List<CheckInterface<T>> actions = this.checking.get(filter);
 | 
				
			||||||
			if (actions == null) {
 | 
								if (actions == null) {
 | 
				
			||||||
				continue;
 | 
									continue;
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			for (final CheckInterface<T> action : actions) {
 | 
								for (final CheckInterface<T> action : actions) {
 | 
				
			||||||
				action.check(baseName, dataCasted, options);
 | 
									action.check(baseName, dataCasted, modifiedValue, options);
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		checkTyped(dataCasted, filterValue, options);
 | 
							checkTyped(dataCasted, modifiedValue, options);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	public void checkTyped(final T data, final List<String> filterValue, final QueryOptions options) throws Exception {
 | 
						public void checkTyped(final T data, final List<String> modifiedValue, final QueryOptions options)
 | 
				
			||||||
 | 
								throws Exception {
 | 
				
			||||||
		// nothing to do ...
 | 
							// nothing to do ...
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -12,6 +12,7 @@ import java.util.Map.Entry;
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
import org.kar.archidata.annotation.security.PermitTokenInURI;
 | 
					import org.kar.archidata.annotation.security.PermitTokenInURI;
 | 
				
			||||||
import org.kar.archidata.catcher.RestErrorResponse;
 | 
					import org.kar.archidata.catcher.RestErrorResponse;
 | 
				
			||||||
 | 
					import org.kar.archidata.exception.SystemException;
 | 
				
			||||||
import org.kar.archidata.model.UserByToken;
 | 
					import org.kar.archidata.model.UserByToken;
 | 
				
			||||||
import org.kar.archidata.tools.JWTWrapper;
 | 
					import org.kar.archidata.tools.JWTWrapper;
 | 
				
			||||||
import org.slf4j.Logger;
 | 
					import org.slf4j.Logger;
 | 
				
			||||||
@@ -23,6 +24,7 @@ import jakarta.annotation.Priority;
 | 
				
			|||||||
import jakarta.annotation.security.DenyAll;
 | 
					import jakarta.annotation.security.DenyAll;
 | 
				
			||||||
import jakarta.annotation.security.PermitAll;
 | 
					import jakarta.annotation.security.PermitAll;
 | 
				
			||||||
import jakarta.annotation.security.RolesAllowed;
 | 
					import jakarta.annotation.security.RolesAllowed;
 | 
				
			||||||
 | 
					import jakarta.ws.rs.Path;
 | 
				
			||||||
import jakarta.ws.rs.Priorities;
 | 
					import jakarta.ws.rs.Priorities;
 | 
				
			||||||
import jakarta.ws.rs.container.ContainerRequestContext;
 | 
					import jakarta.ws.rs.container.ContainerRequestContext;
 | 
				
			||||||
import jakarta.ws.rs.container.ContainerRequestFilter;
 | 
					import jakarta.ws.rs.container.ContainerRequestFilter;
 | 
				
			||||||
@@ -42,18 +44,40 @@ public class AuthenticationFilter implements ContainerRequestFilter {
 | 
				
			|||||||
	@Context
 | 
						@Context
 | 
				
			||||||
	private ResourceInfo resourceInfo;
 | 
						private ResourceInfo resourceInfo;
 | 
				
			||||||
	protected final String applicationName;
 | 
						protected final String applicationName;
 | 
				
			||||||
 | 
						protected final String issuer;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	public static final String AUTHENTICATION_SCHEME = "Bearer";
 | 
						public static final String AUTHENTICATION_SCHEME = "Bearer";
 | 
				
			||||||
	public static final String APIKEY = "ApiKey";
 | 
						public static final String APIKEY = "ApiKey";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	public AuthenticationFilter(final String applicationName) {
 | 
						public AuthenticationFilter(final String applicationName) {
 | 
				
			||||||
		this.applicationName = applicationName;
 | 
							this.applicationName = applicationName;
 | 
				
			||||||
 | 
							this.issuer = "KarAuth";
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						public AuthenticationFilter(final String applicationName, final String issuer) {
 | 
				
			||||||
 | 
							this.applicationName = applicationName;
 | 
				
			||||||
 | 
							this.issuer = issuer;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						public String getRequestedPath(final ContainerRequestContext requestContext) {
 | 
				
			||||||
 | 
							final Class<?> resourceClass = this.resourceInfo.getResourceClass();
 | 
				
			||||||
 | 
							final Method resourceMethod = this.resourceInfo.getResourceMethod();
 | 
				
			||||||
 | 
							final String classPath = resourceClass.isAnnotationPresent(Path.class)
 | 
				
			||||||
 | 
									? resourceClass.getAnnotation(Path.class).value()
 | 
				
			||||||
 | 
									: "";
 | 
				
			||||||
 | 
							final String methodPath = resourceMethod.isAnnotationPresent(Path.class)
 | 
				
			||||||
 | 
									? resourceMethod.getAnnotation(Path.class).value()
 | 
				
			||||||
 | 
									: "";
 | 
				
			||||||
 | 
							final String fullPath = (classPath.startsWith("/") ? "" : "/") + classPath
 | 
				
			||||||
 | 
									+ (methodPath.startsWith("/") ? "" : "/") + methodPath;
 | 
				
			||||||
 | 
							return fullPath;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	@Override
 | 
						@Override
 | 
				
			||||||
	public void filter(final ContainerRequestContext requestContext) throws IOException {
 | 
						public void filter(final ContainerRequestContext requestContext) throws IOException {
 | 
				
			||||||
		/* logger.debug("-----------------------------------------------------"); logger.debug("----          Check if have authorization        ----");
 | 
							/* logger.debug("-----------------------------------------------------"); logger.debug("----          Check if have authorization        ----");
 | 
				
			||||||
		 * logger.debug("-----------------------------------------------------"); logger.debug("   for:{}", requestContext.getUriInfo().getPath()); */
 | 
							 * logger.debug("-----------------------------------------------------"); logger.debug("   for:{}", requestContext.getUriInfo().getPath()); */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		final Method method = this.resourceInfo.getResourceMethod();
 | 
							final Method method = this.resourceInfo.getResourceMethod();
 | 
				
			||||||
		// Access denied for all
 | 
							// Access denied for all
 | 
				
			||||||
		if (method.isAnnotationPresent(DenyAll.class)) {
 | 
							if (method.isAnnotationPresent(DenyAll.class)) {
 | 
				
			||||||
@@ -140,12 +164,13 @@ public class AuthenticationFilter implements ContainerRequestFilter {
 | 
				
			|||||||
		final List<String> roles = Arrays.asList(rolesAnnotation.value());
 | 
							final List<String> roles = Arrays.asList(rolesAnnotation.value());
 | 
				
			||||||
		// check if the user have the right:
 | 
							// check if the user have the right:
 | 
				
			||||||
		boolean haveRight = false;
 | 
							boolean haveRight = false;
 | 
				
			||||||
		for (final String role : roles) {
 | 
							try {
 | 
				
			||||||
			if (userContext.isUserInRole(role)) {
 | 
								haveRight = checkRight(requestContext, userContext, roles);
 | 
				
			||||||
				haveRight = true;
 | 
							} catch (final SystemException e) {
 | 
				
			||||||
				break;
 | 
								// TODO Auto-generated catch block
 | 
				
			||||||
			}
 | 
								e.printStackTrace();
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// Is user valid?
 | 
							// Is user valid?
 | 
				
			||||||
		if (!haveRight) {
 | 
							if (!haveRight) {
 | 
				
			||||||
			LOGGER.error("REJECTED not enought right : {} require: {}", requestContext.getUriInfo().getPath(), roles);
 | 
								LOGGER.error("REJECTED not enought right : {} require: {}", requestContext.getUriInfo().getPath(), roles);
 | 
				
			||||||
@@ -157,6 +182,18 @@ public class AuthenticationFilter implements ContainerRequestFilter {
 | 
				
			|||||||
		// logger.debug("Get local user : {} / {}", user, userByToken);
 | 
							// logger.debug("Get local user : {} / {}", user, userByToken);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						protected boolean checkRight(
 | 
				
			||||||
 | 
								final ContainerRequestContext requestContext,
 | 
				
			||||||
 | 
								final MySecurityContext userContext,
 | 
				
			||||||
 | 
								final List<String> roles) throws SystemException {
 | 
				
			||||||
 | 
							for (final String role : roles) {
 | 
				
			||||||
 | 
								if (userContext.isUserInRole(this.applicationName + "/" + role)) {
 | 
				
			||||||
 | 
									return true;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							return false;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	private boolean isTokenBasedAuthentication(final String authorizationHeader) {
 | 
						private boolean isTokenBasedAuthentication(final String authorizationHeader) {
 | 
				
			||||||
		// Check if the Authorization header is valid
 | 
							// Check if the Authorization header is valid
 | 
				
			||||||
		// It must not be null and must be prefixed with "Bearer" plus a whitespace
 | 
							// It must not be null and must be prefixed with "Bearer" plus a whitespace
 | 
				
			||||||
@@ -193,7 +230,7 @@ public class AuthenticationFilter implements ContainerRequestFilter {
 | 
				
			|||||||
	// must be override to be good implementation
 | 
						// must be override to be good implementation
 | 
				
			||||||
	protected UserByToken validateJwtToken(final String authorization) throws Exception {
 | 
						protected UserByToken validateJwtToken(final String authorization) throws Exception {
 | 
				
			||||||
		// logger.debug(" validate token : " + authorization);
 | 
							// logger.debug(" validate token : " + authorization);
 | 
				
			||||||
		final JWTClaimsSet ret = JWTWrapper.validateToken(authorization, "KarAuth", null);
 | 
							final JWTClaimsSet ret = JWTWrapper.validateToken(authorization, this.issuer, null);
 | 
				
			||||||
		// check the token is valid !!! (signed and coherent issuer...
 | 
							// check the token is valid !!! (signed and coherent issuer...
 | 
				
			||||||
		if (ret == null) {
 | 
							if (ret == null) {
 | 
				
			||||||
			LOGGER.error("The token is not valid: '{}'", authorization);
 | 
								LOGGER.error("The token is not valid: '{}'", authorization);
 | 
				
			||||||
@@ -208,13 +245,16 @@ public class AuthenticationFilter implements ContainerRequestFilter {
 | 
				
			|||||||
		user.type = UserByToken.TYPE_USER;
 | 
							user.type = UserByToken.TYPE_USER;
 | 
				
			||||||
		final Object rowRight = ret.getClaim("right");
 | 
							final Object rowRight = ret.getClaim("right");
 | 
				
			||||||
		if (rowRight != null) {
 | 
							if (rowRight != null) {
 | 
				
			||||||
			final Map<String, Map<String, Object>> rights = (Map<String, Map<String, Object>>) ret.getClaim("right");
 | 
								LOGGER.info("Detect right in Authentication Filter: {}", rowRight);
 | 
				
			||||||
 | 
								user.right = (Map<String, Map<String, Object>>) ret.getClaim("right");
 | 
				
			||||||
 | 
								/*
 | 
				
			||||||
			if (rights.containsKey(this.applicationName)) {
 | 
								if (rights.containsKey(this.applicationName)) {
 | 
				
			||||||
				user.right = rights.get(this.applicationName);
 | 
									user.right = rights.get(this.applicationName);
 | 
				
			||||||
			} else {
 | 
								} else {
 | 
				
			||||||
				LOGGER.error("Connect with no right for this application='{}' full Right='{}'", this.applicationName,
 | 
									LOGGER.error("Connect with no right for this application='{}' full Right='{}'", this.applicationName,
 | 
				
			||||||
						rights);
 | 
											rights);
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
								*/
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		// logger.debug("request user: '{}' right: '{}' row='{}'", userUID, user.right, rowRight);
 | 
							// logger.debug("request user: '{}' right: '{}' row='{}'", userUID, user.right, rowRight);
 | 
				
			||||||
		return user;
 | 
							return user;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,13 +1,17 @@
 | 
				
			|||||||
package org.kar.archidata.filter;
 | 
					package org.kar.archidata.filter;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import java.security.Principal;
 | 
					import java.security.Principal;
 | 
				
			||||||
 | 
					import java.util.Set;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import org.kar.archidata.model.UserByToken;
 | 
					import org.kar.archidata.model.UserByToken;
 | 
				
			||||||
 | 
					import org.slf4j.Logger;
 | 
				
			||||||
 | 
					import org.slf4j.LoggerFactory;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import jakarta.ws.rs.core.SecurityContext;
 | 
					import jakarta.ws.rs.core.SecurityContext;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// https://simplapi.wordpress.com/2015/09/19/jersey-jax-rs-securitycontext-in-action/
 | 
					// https://simplapi.wordpress.com/2015/09/19/jersey-jax-rs-securitycontext-in-action/
 | 
				
			||||||
class MySecurityContext implements SecurityContext {
 | 
					public class MySecurityContext implements SecurityContext {
 | 
				
			||||||
 | 
						private static final Logger LOGGER = LoggerFactory.getLogger(MySecurityContext.class);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	private final GenericContext contextPrincipale;
 | 
						private final GenericContext contextPrincipale;
 | 
				
			||||||
	private final String sheme;
 | 
						private final String sheme;
 | 
				
			||||||
@@ -22,17 +26,128 @@ class MySecurityContext implements SecurityContext {
 | 
				
			|||||||
		return this.contextPrincipale;
 | 
							return this.contextPrincipale;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	@Override
 | 
						public Object getRightOfRoleInGroup(final String group, final String role) {
 | 
				
			||||||
	public boolean isUserInRole(final String role) {
 | 
					 | 
				
			||||||
		if (this.contextPrincipale.userByToken != null) {
 | 
							if (this.contextPrincipale.userByToken != null) {
 | 
				
			||||||
			final Object value = this.contextPrincipale.userByToken.right.get(role);
 | 
								return this.contextPrincipale.userByToken.getRight(group, role);
 | 
				
			||||||
			if (value instanceof final Boolean ret) {
 | 
							}
 | 
				
			||||||
				return ret;
 | 
							return null;
 | 
				
			||||||
			}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						public Set<String> getGroups() {
 | 
				
			||||||
 | 
							if (this.contextPrincipale.userByToken != null) {
 | 
				
			||||||
 | 
								return this.contextPrincipale.userByToken.getGroups();
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							return Set.of();
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						public boolean groupExist(final String group) {
 | 
				
			||||||
 | 
							if (this.contextPrincipale.userByToken != null) {
 | 
				
			||||||
 | 
								return this.contextPrincipale.userByToken.groupExist(group);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		return false;
 | 
							return false;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Not sure the Long type is definitive.
 | 
				
			||||||
 | 
						public Long getUserID() {
 | 
				
			||||||
 | 
							if (this.contextPrincipale.userByToken != null) {
 | 
				
			||||||
 | 
								return this.contextPrincipale.userByToken.id;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							return null;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						public boolean checkRightInGroup(
 | 
				
			||||||
 | 
								final String group,
 | 
				
			||||||
 | 
								final String role,
 | 
				
			||||||
 | 
								final boolean needRead,
 | 
				
			||||||
 | 
								final boolean needWrite) {
 | 
				
			||||||
 | 
							if ("USER".equals(role)) {
 | 
				
			||||||
 | 
								if (groupExist(group)) {
 | 
				
			||||||
 | 
									return true;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								return false;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							// get associated Roles:
 | 
				
			||||||
 | 
							final Object rightPart = getRightOfRoleInGroup(group, role);
 | 
				
			||||||
 | 
							LOGGER.info("detect : {}", rightPart);
 | 
				
			||||||
 | 
							long dataRight = 0;
 | 
				
			||||||
 | 
							if (rightPart instanceof final Long rightPartCasted) {
 | 
				
			||||||
 | 
								dataRight = rightPartCasted;
 | 
				
			||||||
 | 
							} else if (rightPart instanceof final Integer rightPartCasted) {
 | 
				
			||||||
 | 
								dataRight = rightPartCasted;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							if (dataRight == PartRight.READ_WRITE.getValue()) {
 | 
				
			||||||
 | 
								return true;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							if (!needRead && needWrite && dataRight == PartRight.WRITE.getValue()) {
 | 
				
			||||||
 | 
								return true;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							if (needRead && !needWrite && dataRight == PartRight.READ.getValue()) {
 | 
				
			||||||
 | 
								return true;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							return false;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						@Override
 | 
				
			||||||
 | 
						public boolean isUserInRole(final String role) {
 | 
				
			||||||
 | 
							String roleEdit = role;
 | 
				
			||||||
 | 
							boolean needRead = false;
 | 
				
			||||||
 | 
							boolean needWrite = false;
 | 
				
			||||||
 | 
							// Check if the API overwrite the right needed for this API.
 | 
				
			||||||
 | 
							if (roleEdit.contains(":")) {
 | 
				
			||||||
 | 
								if (roleEdit.endsWith(":w")) {
 | 
				
			||||||
 | 
									try {
 | 
				
			||||||
 | 
										roleEdit = roleEdit.substring(0, roleEdit.length() - 2);
 | 
				
			||||||
 | 
									} catch (final IndexOutOfBoundsException ex) {
 | 
				
			||||||
 | 
										LOGGER.error("Fail to extract role of '{}'", role);
 | 
				
			||||||
 | 
										ex.printStackTrace();
 | 
				
			||||||
 | 
										return false;
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
									needWrite = true;
 | 
				
			||||||
 | 
								} else if (roleEdit.endsWith(":r")) {
 | 
				
			||||||
 | 
									try {
 | 
				
			||||||
 | 
										roleEdit = roleEdit.substring(0, roleEdit.length() - 2);
 | 
				
			||||||
 | 
									} catch (final IndexOutOfBoundsException ex) {
 | 
				
			||||||
 | 
										LOGGER.error("Fail to extract role of '{}'", role);
 | 
				
			||||||
 | 
										ex.printStackTrace();
 | 
				
			||||||
 | 
										return false;
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
									needRead = true;
 | 
				
			||||||
 | 
								} else if (roleEdit.endsWith(":rw")) {
 | 
				
			||||||
 | 
									try {
 | 
				
			||||||
 | 
										roleEdit = roleEdit.substring(0, roleEdit.length() - 3);
 | 
				
			||||||
 | 
									} catch (final IndexOutOfBoundsException ex) {
 | 
				
			||||||
 | 
										LOGGER.error("Fail to extract role of '{}'", role);
 | 
				
			||||||
 | 
										ex.printStackTrace();
 | 
				
			||||||
 | 
										return false;
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
									needRead = true;
 | 
				
			||||||
 | 
									needWrite = true;
 | 
				
			||||||
 | 
								} else {
 | 
				
			||||||
 | 
									LOGGER.error("Request check right of an unknow right mode: {} (after ':')", roleEdit);
 | 
				
			||||||
 | 
									return false;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							if (roleEdit.contains("/")) {
 | 
				
			||||||
 | 
								final String[] elements = roleEdit.split("/");
 | 
				
			||||||
 | 
								return checkRightInGroup(elements[0], elements[1], needRead, needWrite);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							// Special case, if the token is valid, it is an USER ...
 | 
				
			||||||
 | 
							if ("USER".equals(roleEdit)) {
 | 
				
			||||||
 | 
								return true;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							return checkRightInGroup("?system?", roleEdit, needRead, needWrite);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						public Object getRole(final String role) {
 | 
				
			||||||
 | 
							LOGGER.info("contextPrincipale={}", this.contextPrincipale);
 | 
				
			||||||
 | 
							if (this.contextPrincipale.userByToken != null) {
 | 
				
			||||||
 | 
								LOGGER.info("contextPrincipale.userByToken={}", this.contextPrincipale.userByToken);
 | 
				
			||||||
 | 
								LOGGER.info("contextPrincipale.userByToken.right={}", this.contextPrincipale.userByToken.right);
 | 
				
			||||||
 | 
								return this.contextPrincipale.userByToken.right.get(role);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							return null;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	@Override
 | 
						@Override
 | 
				
			||||||
	public boolean isSecure() {
 | 
						public boolean isSecure() {
 | 
				
			||||||
		return "https".equalsIgnoreCase(this.sheme);
 | 
							return "https".equalsIgnoreCase(this.sheme);
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										30
									
								
								src/org/kar/archidata/filter/PartRight.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										30
									
								
								src/org/kar/archidata/filter/PartRight.java
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,30 @@
 | 
				
			|||||||
 | 
					package org.kar.archidata.filter;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import com.fasterxml.jackson.annotation.JsonValue;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					public enum PartRight {
 | 
				
			||||||
 | 
						NONE(0), //
 | 
				
			||||||
 | 
						READ(1), //
 | 
				
			||||||
 | 
						WRITE(2), //
 | 
				
			||||||
 | 
						READ_WRITE(3);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						private final int value;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						PartRight(final int value) {
 | 
				
			||||||
 | 
							this.value = value;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						@JsonValue
 | 
				
			||||||
 | 
						public int getValue() {
 | 
				
			||||||
 | 
							return this.value;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						public static PartRight fromValue(final int value) {
 | 
				
			||||||
 | 
							for (final PartRight element : values()) {
 | 
				
			||||||
 | 
								if (element.getValue() == value) {
 | 
				
			||||||
 | 
									return element;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							throw new IllegalArgumentException("PartRight: Unknown value: " + value);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -28,26 +28,29 @@ import io.swagger.v3.oas.annotations.media.Schema;
 | 
				
			|||||||
import jakarta.annotation.Nullable;
 | 
					import jakarta.annotation.Nullable;
 | 
				
			||||||
import jakarta.persistence.Column;
 | 
					import jakarta.persistence.Column;
 | 
				
			||||||
import jakarta.persistence.Table;
 | 
					import jakarta.persistence.Table;
 | 
				
			||||||
 | 
					import jakarta.validation.constraints.NotNull;
 | 
				
			||||||
 | 
					import jakarta.validation.constraints.Pattern;
 | 
				
			||||||
 | 
					import jakarta.validation.constraints.Size;
 | 
				
			||||||
import jakarta.ws.rs.DefaultValue;
 | 
					import jakarta.ws.rs.DefaultValue;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@Table(name = "user")
 | 
					@Table(name = "user")
 | 
				
			||||||
@DataIfNotExists
 | 
					@DataIfNotExists
 | 
				
			||||||
@JsonInclude(JsonInclude.Include.NON_NULL)
 | 
					@JsonInclude(JsonInclude.Include.NON_NULL)
 | 
				
			||||||
public class User extends GenericDataSoftDelete {
 | 
					public class User extends GenericDataSoftDelete {
 | 
				
			||||||
 | 
						@NotNull
 | 
				
			||||||
	@Column(length = 128)
 | 
						@Column(length = 128)
 | 
				
			||||||
 | 
						@Size(min = 3, max = 128)
 | 
				
			||||||
 | 
						@Pattern(regexp = "^[a-zA-Z0-9-_ \\.]+$")
 | 
				
			||||||
	public String login = null;
 | 
						public String login = null;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd'T'HH:mm:ss.SSSXXX")
 | 
						@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd'T'HH:mm:ss.SSSXXX")
 | 
				
			||||||
	public Timestamp lastConnection = null;
 | 
						public Timestamp lastConnection = null;
 | 
				
			||||||
	@DefaultValue("'0'")
 | 
					
 | 
				
			||||||
	@Column(nullable = false)
 | 
					 | 
				
			||||||
	public boolean admin = false;
 | 
					 | 
				
			||||||
	@DefaultValue("'0'")
 | 
						@DefaultValue("'0'")
 | 
				
			||||||
	@Column(nullable = false)
 | 
						@Column(nullable = false)
 | 
				
			||||||
	public boolean blocked = false;
 | 
						public boolean blocked = false;
 | 
				
			||||||
	@DefaultValue("'0'")
 | 
						@Column(length = 512)
 | 
				
			||||||
	@Column(nullable = false)
 | 
						public String blockedReason;
 | 
				
			||||||
	public boolean removed = false;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	@Schema(description = "List of Id of the specific covers")
 | 
						@Schema(description = "List of Id of the specific covers")
 | 
				
			||||||
	@DataJson(targetEntity = Data.class)
 | 
						@DataJson(targetEntity = Data.class)
 | 
				
			||||||
@@ -56,7 +59,8 @@ public class User extends GenericDataSoftDelete {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	@Override
 | 
						@Override
 | 
				
			||||||
	public String toString() {
 | 
						public String toString() {
 | 
				
			||||||
		return "User [login=" + this.login + ", last=" + this.lastConnection + ", admin=" + this.admin + "]";
 | 
							return "User [login=" + this.login + ", last=" + this.lastConnection + ", blocked=" + this.blocked
 | 
				
			||||||
 | 
									+ ", blockedReason=" + this.blockedReason + "]";
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -2,6 +2,7 @@ package org.kar.archidata.model;
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
import java.util.HashMap;
 | 
					import java.util.HashMap;
 | 
				
			||||||
import java.util.Map;
 | 
					import java.util.Map;
 | 
				
			||||||
 | 
					import java.util.Set;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
public class UserByToken {
 | 
					public class UserByToken {
 | 
				
			||||||
	public static final int TYPE_USER = -1;
 | 
						public static final int TYPE_USER = -1;
 | 
				
			||||||
@@ -13,13 +14,35 @@ public class UserByToken {
 | 
				
			|||||||
	public Long parentId = null; // FOr application, this is the id of the application, and of user token, this is the USERID
 | 
						public Long parentId = null; // FOr application, this is the id of the application, and of user token, this is the USERID
 | 
				
			||||||
	public String name = null;
 | 
						public String name = null;
 | 
				
			||||||
	// Right map
 | 
						// Right map
 | 
				
			||||||
	public Map<String, Object> right = new HashMap<>();
 | 
						public Map<String, Map<String, Object>> right = new HashMap<>();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	public boolean hasRight(final String key, final Object value) {
 | 
						public Set<String> getGroups() {
 | 
				
			||||||
		if (!this.right.containsKey(key)) {
 | 
							return this.right.keySet();
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						public boolean groupExist(final String group) {
 | 
				
			||||||
 | 
							if (!this.right.containsKey(group)) {
 | 
				
			||||||
 | 
								return false;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							return this.right.containsKey(group);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						public Object getRight(final String group, final String key) {
 | 
				
			||||||
 | 
							if (!this.right.containsKey(group)) {
 | 
				
			||||||
 | 
								return null;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							final Map<String, Object> rightGroup = this.right.get(group);
 | 
				
			||||||
 | 
							if (!rightGroup.containsKey(key)) {
 | 
				
			||||||
 | 
								return null;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							return rightGroup.get(key);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						public boolean hasRight(final String group, final String key, final Object value) {
 | 
				
			||||||
 | 
							final Object data = getRight(group, key);
 | 
				
			||||||
 | 
							if (data == null) {
 | 
				
			||||||
			return false;
 | 
								return false;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		final Object data = this.right.get(key);
 | 
					 | 
				
			||||||
		if (data instanceof final Boolean elem) {
 | 
							if (data instanceof final Boolean elem) {
 | 
				
			||||||
			if (value instanceof final Boolean castVal) {
 | 
								if (value instanceof final Boolean castVal) {
 | 
				
			||||||
				if (elem.equals(castVal)) {
 | 
									if (elem.equals(castVal)) {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -121,7 +121,7 @@ public class RESTApi {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	@SuppressWarnings("unchecked")
 | 
						@SuppressWarnings("unchecked")
 | 
				
			||||||
	protected <T, U> T modelSendJson(final String model, final Class<T> clazz, final String urlOffset, String body)
 | 
						public <T, U> T modelSendJson(final String model, final Class<T> clazz, final String urlOffset, String body)
 | 
				
			||||||
			throws RESTErrorResponseExeption, IOException, InterruptedException {
 | 
								throws RESTErrorResponseExeption, IOException, InterruptedException {
 | 
				
			||||||
		final HttpClient client = HttpClient.newHttpClient();
 | 
							final HttpClient client = HttpClient.newHttpClient();
 | 
				
			||||||
		// client.property(HttpUrlConnectorProvider.SET_METHOD_WORKAROUND, true);
 | 
							// client.property(HttpUrlConnectorProvider.SET_METHOD_WORKAROUND, true);
 | 
				
			||||||
@@ -166,7 +166,7 @@ public class RESTApi {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	@SuppressWarnings("unchecked")
 | 
						@SuppressWarnings("unchecked")
 | 
				
			||||||
	protected <T> T modelSendMap(
 | 
						public <T> T modelSendMap(
 | 
				
			||||||
			final String model,
 | 
								final String model,
 | 
				
			||||||
			final Class<T> clazz,
 | 
								final Class<T> clazz,
 | 
				
			||||||
			final String urlOffset,
 | 
								final String urlOffset,
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1 +1 @@
 | 
				
			|||||||
0.16.0
 | 
					0.19.0
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user