7 Commits

66 changed files with 396 additions and 1611 deletions

View File

@ -1,5 +0,0 @@
@ECHO OFF
setlocal
set BASEPATH=%~dp0%
cd %BASEPATH%\..
mvn release:clean release:prepare -Dmaven.test.skip=true -Darguments="-Dmaven.test.skip=true -DskipTests"

View File

@ -24,7 +24,7 @@ limitations under the License.
<parent> <parent>
<artifactId>shared</artifactId> <artifactId>shared</artifactId>
<groupId>de.muehlencord</groupId> <groupId>de.muehlencord</groupId>
<version>1.3.0</version> <version>2.0.1-SNAPSHOT</version>
</parent> </parent>
<name>shared-configuration</name> <name>shared-configuration</name>

View File

@ -20,16 +20,58 @@ limitations under the License.
<groupId>de.muehlencord.shared</groupId> <groupId>de.muehlencord.shared</groupId>
<artifactId>shared-db</artifactId> <artifactId>shared-db</artifactId>
<packaging>ejb</packaging> <packaging>jar</packaging>
<parent> <parent>
<artifactId>shared</artifactId> <artifactId>shared</artifactId>
<groupId>de.muehlencord</groupId> <groupId>de.muehlencord</groupId>
<version>1.3.0</version> <version>2.0.1-SNAPSHOT</version>
</parent> </parent>
<name>shared-db</name> <name>shared-db</name>
<dependencies> <dependencies>
<dependency>
<groupId>org.hibernate.orm</groupId>
<artifactId>hibernate-core</artifactId>
</dependency>
<!-- CDI and annotations -->
<dependency>
<groupId>jakarta.inject</groupId>
<artifactId>jakarta.inject-api</artifactId>
</dependency>
<dependency>
<groupId>jakarta.interceptor</groupId>
<artifactId>jakarta.interceptor-api</artifactId>
</dependency>
<dependency>
<groupId>jakarta.validation</groupId>
<artifactId>jakarta.validation-api</artifactId>
</dependency>
<!-- Logging -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
</dependency>
<!-- Testing -->
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<scope>test</scope>
</dependency>
<!-- Dev Tools -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<scope>provided</scope>
</dependency>
<!-- unsorted -->
<dependency> <dependency>
<groupId>org.apache.commons</groupId> <groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId> <artifactId>commons-lang3</artifactId>
@ -47,50 +89,7 @@ limitations under the License.
<groupId>com.fasterxml.jackson.datatype</groupId> <groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-jsr310</artifactId> <artifactId>jackson-datatype-jsr310</artifactId>
</dependency> </dependency>
<!-- Testing -->
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<scope>test</scope>
</dependency>
<!-- Logging -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-jdk14</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>javax</groupId>
<artifactId>javaee-web-api</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<!-- Dev Tools -->
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<scope>provided</scope>
</dependency>
</dependencies> </dependencies>
<build>
<plugins>
<!-- create EJB version 3.1 -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-ejb-plugin</artifactId>
<configuration>
<ejbVersion>3.1</ejbVersion>
<excludes>
<exclude>**/persistence.xml</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</build>
</project> </project>

View File

@ -15,22 +15,20 @@
*/ */
package de.muehlencord.shared.db; package de.muehlencord.shared.db;
import jakarta.persistence.EntityGraph;
import jakarta.persistence.Query;
import jakarta.persistence.TypedQuery;
import jakarta.persistence.criteria.CriteriaBuilder;
import jakarta.persistence.criteria.CriteriaQuery;
import jakarta.persistence.criteria.Order;
import jakarta.persistence.criteria.Predicate;
import jakarta.persistence.criteria.Root;
import java.io.Serializable; import java.io.Serializable;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import javax.ejb.Lock;
import javax.ejb.LockType;
import javax.persistence.EntityGraph;
import javax.persistence.Query;
import javax.persistence.TypedQuery;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Order;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
/** /**
* *
@ -52,7 +50,6 @@ public abstract class AbstractController<T extends Serializable> extends CommonA
* @param id the primary key of the entity to search for. * @param id the primary key of the entity to search for.
* @return the found entity instance or null if the entity does not exist * @return the found entity instance or null if the entity does not exist
*/ */
@Lock(LockType.READ)
public T find(Object id) { public T find(Object id) {
return em.find(entityClass, id); return em.find(entityClass, id);
} }
@ -66,7 +63,6 @@ public abstract class AbstractController<T extends Serializable> extends CommonA
* Typically this is the name of the 1:n set or list. * Typically this is the name of the 1:n set or list.
* @return the found entity instance or null if the entity does not exist * @return the found entity instance or null if the entity does not exist
*/ */
@Lock(LockType.READ)
public T find(Object id, String... subGraphItems) { public T find(Object id, String... subGraphItems) {
EntityGraph<T> graph = this.em.createEntityGraph(entityClass); EntityGraph<T> graph = this.em.createEntityGraph(entityClass);
for (String subGraphItem : subGraphItems) { for (String subGraphItem : subGraphItems) {
@ -79,7 +75,6 @@ public abstract class AbstractController<T extends Serializable> extends CommonA
return em.find(entityClass, id, hints); return em.find(entityClass, id, hints);
} }
@Lock(LockType.READ)
public List<T> find(String queryName, Map<String, Object> parameterMap) { public List<T> find(String queryName, Map<String, Object> parameterMap) {
Query query = em.createNamedQuery(queryName); Query query = em.createNamedQuery(queryName);
parameterMap.entrySet().forEach(entry -> query.setParameter(entry.getKey(), entry.getValue())); parameterMap.entrySet().forEach(entry -> query.setParameter(entry.getKey(), entry.getValue()));
@ -91,7 +86,6 @@ public abstract class AbstractController<T extends Serializable> extends CommonA
* *
* @return a list of all entities. * @return a list of all entities.
*/ */
@Lock(LockType.READ)
public List<T> findAll() throws ControllerException { public List<T> findAll() throws ControllerException {
return findAll(new ArrayList<>()); return findAll(new ArrayList<>());
} }
@ -102,7 +96,6 @@ public abstract class AbstractController<T extends Serializable> extends CommonA
* @param orderFields the list of field names to order the result by. * @param orderFields the list of field names to order the result by.
* @return a list of all entities. * @return a list of all entities.
*/ */
@Lock(LockType.READ)
public List<T> findAll(String... orderFields) throws ControllerException { public List<T> findAll(String... orderFields) throws ControllerException {
return findAll(Arrays.asList(orderFields)); return findAll(Arrays.asList(orderFields));
} }
@ -112,7 +105,6 @@ public abstract class AbstractController<T extends Serializable> extends CommonA
* @param orderFields the list of field names to order the result by. * @param orderFields the list of field names to order the result by.
* @return a list of all entities. * @return a list of all entities.
*/ */
@Lock(LockType.READ)
public List<T> findAll(List<String> orderFields) throws ControllerException { public List<T> findAll(List<String> orderFields) throws ControllerException {
return findAll(entityClass, orderFields); return findAll(entityClass, orderFields);
} }
@ -125,7 +117,6 @@ public abstract class AbstractController<T extends Serializable> extends CommonA
* @param orderFields the fields to order the result by. * @param orderFields the fields to order the result by.
* @return a list of found entities. * @return a list of found entities.
*/ */
@Lock(LockType.READ)
public List<T> find(Map<String, Object> filters, List<String> orderFields) { public List<T> find(Map<String, Object> filters, List<String> orderFields) {
final CriteriaBuilder cb = em.getCriteriaBuilder(); final CriteriaBuilder cb = em.getCriteriaBuilder();
final CriteriaQuery<T> criteria = cb.createQuery(entityClass); final CriteriaQuery<T> criteria = cb.createQuery(entityClass);

View File

@ -19,10 +19,11 @@ import static java.lang.annotation.ElementType.FIELD;
import static java.lang.annotation.ElementType.METHOD; import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.ElementType.PARAMETER; import static java.lang.annotation.ElementType.PARAMETER;
import static java.lang.annotation.ElementType.TYPE; import static java.lang.annotation.ElementType.TYPE;
import java.lang.annotation.Retention;
import static java.lang.annotation.RetentionPolicy.RUNTIME; import static java.lang.annotation.RetentionPolicy.RUNTIME;
import jakarta.inject.Qualifier;
import java.lang.annotation.Retention;
import java.lang.annotation.Target; import java.lang.annotation.Target;
import javax.inject.Qualifier;
/** /**
* *

View File

@ -15,14 +15,15 @@
*/ */
package de.muehlencord.shared.db; package de.muehlencord.shared.db;
import javax.annotation.Priority; import static jakarta.transaction.Transactional.TxType.REQUIRED;
import javax.inject.Inject;
import javax.interceptor.AroundInvoke; import jakarta.annotation.Priority;
import javax.interceptor.Interceptor; import jakarta.inject.Inject;
import javax.interceptor.InvocationContext; import jakarta.interceptor.AroundInvoke;
import javax.persistence.EntityManager; import jakarta.interceptor.Interceptor;
import javax.transaction.Transactional; import jakarta.interceptor.InvocationContext;
import static javax.transaction.Transactional.TxType.REQUIRED; import jakarta.persistence.EntityManager;
import jakarta.transaction.Transactional;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;

View File

@ -19,13 +19,13 @@ import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fasterxml.jackson.databind.annotation.JsonSerialize; import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer; import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer; import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
import jakarta.persistence.Basic;
import jakarta.persistence.Column;
import jakarta.persistence.Embeddable;
import jakarta.validation.constraints.NotNull;
import java.io.Serializable; import java.io.Serializable;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.time.ZoneOffset; import java.time.ZoneOffset;
import javax.persistence.Basic;
import javax.persistence.Column;
import javax.persistence.Embeddable;
import javax.validation.constraints.NotNull;
import lombok.Getter; import lombok.Getter;
import lombok.Setter; import lombok.Setter;

View File

@ -16,9 +16,20 @@
package de.muehlencord.shared.db; package de.muehlencord.shared.db;
import de.muehlencord.shared.util.DateUtil; import de.muehlencord.shared.util.DateUtil;
import jakarta.inject.Inject;
import jakarta.persistence.EntityGraph;
import jakarta.persistence.EntityManager;
import jakarta.persistence.TypedQuery;
import jakarta.persistence.criteria.CriteriaBuilder;
import jakarta.persistence.criteria.CriteriaQuery;
import jakarta.persistence.criteria.Order;
import jakarta.persistence.criteria.Path;
import jakarta.persistence.criteria.Predicate;
import jakarta.persistence.criteria.Root;
import jakarta.transaction.Transactional;
import jakarta.transaction.Transactional.TxType;
import java.io.Serializable; import java.io.Serializable;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.ZoneOffset; import java.time.ZoneOffset;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
@ -28,21 +39,6 @@ import java.util.List;
import java.util.Locale; import java.util.Locale;
import java.util.Map; import java.util.Map;
import java.util.UUID; import java.util.UUID;
import javax.ejb.Lock;
import javax.ejb.LockType;
import javax.ejb.TransactionAttribute;
import javax.ejb.TransactionAttributeType;
import javax.inject.Inject;
import javax.persistence.EntityGraph;
import javax.persistence.EntityManager;
import javax.persistence.TypedQuery;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Order;
import javax.persistence.criteria.Path;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import javax.transaction.Transactional;
import org.apache.commons.lang3.ArrayUtils; import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
@ -64,7 +60,6 @@ public abstract class CommonAbstractController {
this.em = em; this.em = em;
} }
@Lock(LockType.READ)
public <T extends Serializable> T find(Class<T> clazz, Object id) { public <T extends Serializable> T find(Class<T> clazz, Object id) {
return em.find(clazz, id); return em.find(clazz, id);
} }
@ -79,7 +74,6 @@ public abstract class CommonAbstractController {
return graph; return graph;
} }
@Lock(LockType.READ)
public <T extends Serializable> T find(Class<T> clazz, Object id, String... subGraphItems) { public <T extends Serializable> T find(Class<T> clazz, Object id, String... subGraphItems) {
EntityGraph graph = getEntityGraph(clazz, subGraphItems); EntityGraph graph = getEntityGraph(clazz, subGraphItems);
Map hints = new HashMap<>(); Map hints = new HashMap<>();
@ -89,12 +83,10 @@ public abstract class CommonAbstractController {
return entity; return entity;
} }
@Lock(LockType.READ)
public <T extends Serializable> List<T> find(Class<T> clazz, Map<String, Object> filters, List<String> orderFields, String... subGraphItems) { public <T extends Serializable> List<T> find(Class<T> clazz, Map<String, Object> filters, List<String> orderFields, String... subGraphItems) {
return find(clazz, filters, orderFields, 0, 0, subGraphItems); return find(clazz, filters, orderFields, 0, 0, subGraphItems);
} }
@Lock(LockType.READ)
public <T extends Serializable> List<T> find(Class<T> clazz, Map<String, Object> filters, List<String> orderFields, int limit, int offset, String... subGraphItems) { public <T extends Serializable> List<T> find(Class<T> clazz, Map<String, Object> filters, List<String> orderFields, int limit, int offset, String... subGraphItems) {
final CriteriaBuilder cb = em.getCriteriaBuilder(); final CriteriaBuilder cb = em.getCriteriaBuilder();
final CriteriaQuery<T> criteria = cb.createQuery(clazz); final CriteriaQuery<T> criteria = cb.createQuery(clazz);
@ -118,12 +110,10 @@ public abstract class CommonAbstractController {
return query.getResultList(); return query.getResultList();
} }
@Lock(LockType.READ)
public <T extends Serializable> List<T> find(Class<T> clazz, List<SearchFilter> filters, List<String> orderFields, String... subGraphItems) throws ControllerException { public <T extends Serializable> List<T> find(Class<T> clazz, List<SearchFilter> filters, List<String> orderFields, String... subGraphItems) throws ControllerException {
return find(clazz, filters, orderFields, 0, 0); return find(clazz, filters, orderFields, 0, 0);
} }
@Lock(LockType.READ)
public <T extends Serializable> List<T> find(Class<T> clazz, List<SearchFilter> filters, List<String> orderFields, int limit, int offset, String... subGraphItems) throws ControllerException { public <T extends Serializable> List<T> find(Class<T> clazz, List<SearchFilter> filters, List<String> orderFields, int limit, int offset, String... subGraphItems) throws ControllerException {
final CriteriaBuilder cb = em.getCriteriaBuilder(); final CriteriaBuilder cb = em.getCriteriaBuilder();
final CriteriaQuery<T> criteria = cb.createQuery(clazz); final CriteriaQuery<T> criteria = cb.createQuery(clazz);
@ -157,7 +147,6 @@ public abstract class CommonAbstractController {
* @return a list of all entities found * @return a list of all entities found
* @throws ControllerException if the search cannot be executed. * @throws ControllerException if the search cannot be executed.
*/ */
@Lock(LockType.READ)
public <T extends Serializable> List<T> findAll(Class<T> entityClass) throws ControllerException { public <T extends Serializable> List<T> findAll(Class<T> entityClass) throws ControllerException {
return findAll(entityClass, new ArrayList<>()); return findAll(entityClass, new ArrayList<>());
} }
@ -170,7 +159,6 @@ public abstract class CommonAbstractController {
* @return a list of all entities found * @return a list of all entities found
* @throws ControllerException if the search cannot be executed. * @throws ControllerException if the search cannot be executed.
*/ */
@Lock(LockType.READ)
public <T extends Serializable> List<T> findAll(Class<T> entityClass, String... orderFields) throws ControllerException { public <T extends Serializable> List<T> findAll(Class<T> entityClass, String... orderFields) throws ControllerException {
return findAll(entityClass, Arrays.asList(orderFields)); return findAll(entityClass, Arrays.asList(orderFields));
} }
@ -183,7 +171,6 @@ public abstract class CommonAbstractController {
* @return a list of all entities found * @return a list of all entities found
* @throws ControllerException if the search cannot be executed. * @throws ControllerException if the search cannot be executed.
*/ */
@Lock(LockType.READ)
public <T extends Serializable> List<T> findAll(Class<T> entityClass, List<String> orderFields) throws ControllerException { public <T extends Serializable> List<T> findAll(Class<T> entityClass, List<String> orderFields) throws ControllerException {
final CriteriaBuilder cb = em.getCriteriaBuilder(); final CriteriaBuilder cb = em.getCriteriaBuilder();
final CriteriaQuery<T> criteria = cb.createQuery(entityClass); final CriteriaQuery<T> criteria = cb.createQuery(entityClass);
@ -239,9 +226,7 @@ public abstract class CommonAbstractController {
* @return the entity after it has been written to the database. * @return the entity after it has been written to the database.
* @throws ControllerException if the the creation or update of the entity fails. * @throws ControllerException if the the creation or update of the entity fails.
*/ */
@TransactionAttribute(TransactionAttributeType.REQUIRED) @Transactional(TxType.REQUIRED)
@Transactional
@Lock(LockType.WRITE)
public <T extends IdentifiableEntity> T createOrUpdate(T entity, String createdBy) throws ControllerException { public <T extends IdentifiableEntity> T createOrUpdate(T entity, String createdBy) throws ControllerException {
if (entity.getId() == null) { if (entity.getId() == null) {
create(entity, createdBy); create(entity, createdBy);
@ -260,9 +245,7 @@ public abstract class CommonAbstractController {
* @return the entity after it has been written to the database. * @return the entity after it has been written to the database.
* @throws ControllerException if the the creation fails * @throws ControllerException if the the creation fails
*/ */
@TransactionAttribute(TransactionAttributeType.REQUIRED) @Transactional(TxType.REQUIRED)
@Transactional
@Lock(LockType.WRITE)
public <T> T create(T entity, String createdBy) throws ControllerException { public <T> T create(T entity, String createdBy) throws ControllerException {
if (Auditable.class.isAssignableFrom(entity.getClass())) { if (Auditable.class.isAssignableFrom(entity.getClass())) {
Audit audit = ((Auditable) entity).getAudit(); Audit audit = ((Auditable) entity).getAudit();
@ -324,9 +307,7 @@ public abstract class CommonAbstractController {
* @return the entity after it has been written to the database. * @return the entity after it has been written to the database.
* @throws ControllerException if the the updates fails * @throws ControllerException if the the updates fails
*/ */
@TransactionAttribute(TransactionAttributeType.REQUIRED) @Transactional(TxType.REQUIRED)
@Transactional
@Lock(LockType.WRITE)
public <T extends Serializable> T update(T entity, String updatedBy) throws ControllerException { public <T extends Serializable> T update(T entity, String updatedBy) throws ControllerException {
T currentEntity = executeUpdate(entity, updatedBy); T currentEntity = executeUpdate(entity, updatedBy);
if (EndDateable.class.isAssignableFrom(entity.getClass())) { if (EndDateable.class.isAssignableFrom(entity.getClass())) {
@ -348,9 +329,7 @@ public abstract class CommonAbstractController {
* @param deletedBy the username to apply write into the audit history * @param deletedBy the username to apply write into the audit history
* @throws ControllerException if the deletion fails. * @throws ControllerException if the deletion fails.
*/ */
@TransactionAttribute(TransactionAttributeType.REQUIRED) @Transactional(TxType.REQUIRED)
@Transactional
@Lock(LockType.WRITE)
public <T extends Serializable> void delete(T entity, String deletedBy) throws ControllerException { public <T extends Serializable> void delete(T entity, String deletedBy) throws ControllerException {
// if the entity is endDateable just set the validToDate to now intead of executing the deletion // if the entity is endDateable just set the validToDate to now intead of executing the deletion
if (EndDateable.class.isAssignableFrom(entity.getClass())) { if (EndDateable.class.isAssignableFrom(entity.getClass())) {

View File

@ -15,17 +15,19 @@
*/ */
package de.muehlencord.shared.db; package de.muehlencord.shared.db;
import javax.ejb.ApplicationException;
import lombok.Getter;
/** /**
* Generic exception if an exception inside a Controller class occurs * Generic exception if an exception inside a Controller class occurs
* *
* @author Joern Muehlencord (joern@muehlencord.de) * @author Joern Muehlencord (joern@muehlencord.de)
*/ */
@ApplicationException(rollback = true) @Getter
public class ControllerException extends Exception { public class ControllerException extends Exception {
private static final long serialVersionUID = 5190280225284514859L; private static final long serialVersionUID = 5190280225284514859L;
public static final int INTERNAL_ERROR = 0; public static final int INTERNAL_ERROR = 0;
public static final int CAUSE_ALREADY_EXISTS = 1; public static final int CAUSE_ALREADY_EXISTS = 1;
public static final int CAUSE_NOT_FOUND = 2; public static final int CAUSE_NOT_FOUND = 2;
@ -60,12 +62,4 @@ public class ControllerException extends Exception {
this.causeCode = causeCode; this.causeCode = causeCode;
} }
/**
* returns the cause code
*
* @return the cause code
*/
public int getCauseCode() {
return causeCode;
}
} }

View File

@ -16,14 +16,15 @@
package de.muehlencord.shared.db; package de.muehlencord.shared.db;
import de.muehlencord.shared.util.DateUtil; import de.muehlencord.shared.util.DateUtil;
import jakarta.persistence.Id;
import java.beans.IntrospectionException; import java.beans.IntrospectionException;
import java.beans.PropertyDescriptor; import java.beans.PropertyDescriptor;
import java.io.Serializable; import java.io.Serializable;
import java.lang.annotation.Annotation; import java.lang.annotation.Annotation;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException; import java.lang.reflect.InvocationTargetException;
import javax.persistence.Id;
import org.apache.commons.lang3.SerializationUtils; import org.apache.commons.lang3.SerializationUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
/** /**
@ -32,7 +33,7 @@ import org.slf4j.LoggerFactory;
*/ */
public class EntityUtil { public class EntityUtil {
private static final org.slf4j.Logger LOGGER = LoggerFactory.getLogger(EntityUtil.class); private static final Logger logger = LoggerFactory.getLogger(EntityUtil.class);
public static Field getIdField(Class<?> entity) { public static Field getIdField(Class<?> entity) {
if (entity == null) { if (entity == null) {
@ -63,8 +64,8 @@ public class EntityUtil {
if (field == null) { if (field == null) {
return entity; return entity;
} }
if (LOGGER.isDebugEnabled()) { if (logger.isDebugEnabled()) {
LOGGER.debug("id column of {} is {}", entity.getClass().getSimpleName(), field.getName()); logger.debug("id column of {} is {}", entity.getClass().getSimpleName(), field.getName());
} }
try { try {

View File

@ -1,11 +1,11 @@
package de.muehlencord.shared.db; package de.muehlencord.shared.db;
import jakarta.persistence.Basic;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.MappedSuperclass;
import java.io.Serializable; import java.io.Serializable;
import javax.persistence.Basic;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.MappedSuperclass;
@MappedSuperclass @MappedSuperclass
public abstract class NumericallyIdentifiedEntity implements Serializable { public abstract class NumericallyIdentifiedEntity implements Serializable {

View File

@ -1,29 +0,0 @@
/*
* Copyright 2019 Joern Muehlencord (joern@muehlencord.de).
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package de.muehlencord.shared.db;
import javax.ejb.Stateless;
/**
*
* @author Joern Muehlencord (joern@muehlencord.de)
*/
@Stateless
public class StandardController extends CommonAbstractController {
}

View File

@ -15,14 +15,14 @@
*/ */
package de.muehlencord.shared.db; package de.muehlencord.shared.db;
import jakarta.persistence.Basic;
import jakarta.persistence.Column;
import jakarta.persistence.Embeddable;
import jakarta.persistence.Temporal;
import jakarta.persistence.TemporalType;
import jakarta.validation.constraints.NotNull;
import java.io.Serializable; import java.io.Serializable;
import java.util.Date; import java.util.Date;
import javax.persistence.Basic;
import javax.persistence.Column;
import javax.persistence.Embeddable;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import javax.validation.constraints.NotNull;
/** /**
* *

View File

@ -15,16 +15,16 @@
*/ */
package de.muehlencord.shared.db; package de.muehlencord.shared.db;
import jakarta.persistence.Basic;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.Id;
import jakarta.persistence.NamedQueries;
import jakarta.persistence.NamedQuery;
import jakarta.persistence.Table;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Size;
import java.io.Serializable; import java.io.Serializable;
import javax.persistence.Basic;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.Table;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
/** /**
* *

View File

@ -15,21 +15,21 @@
*/ */
package de.muehlencord.shared.db; package de.muehlencord.shared.db;
import jakarta.persistence.Basic;
import jakarta.persistence.Column;
import jakarta.persistence.Embedded;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.Id;
import jakarta.persistence.NamedQueries;
import jakarta.persistence.NamedQuery;
import jakarta.persistence.Table;
import jakarta.validation.constraints.Max;
import jakarta.validation.constraints.Min;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Size;
import java.io.Serializable; import java.io.Serializable;
import java.util.UUID; import java.util.UUID;
import javax.persistence.Basic;
import javax.persistence.Column;
import javax.persistence.Embedded;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.Table;
import javax.validation.constraints.Max;
import javax.validation.constraints.Min;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
/** /**
* *

View File

@ -16,62 +16,68 @@ limitations under the License.
--> -->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<parent> <parent>
<artifactId>shared</artifactId> <artifactId>shared</artifactId>
<groupId>de.muehlencord</groupId> <groupId>de.muehlencord</groupId>
<version>1.3.0</version> <version>2.0.1-SNAPSHOT</version>
</parent> </parent>
<groupId>de.muehlencord.shared</groupId> <groupId>de.muehlencord.shared</groupId>
<artifactId>shared-jeeutil</artifactId> <artifactId>shared-jeeutil</artifactId>
<packaging>ejb</packaging> <packaging>jar</packaging>
<name>shared-jeeutil</name> <name>shared-jeeutil</name>
<dependencies> <dependencies>
<dependency> <!-- Faces Support -->
<groupId>io.fusionauth</groupId> <dependency>
<artifactId>fusionauth-jwt</artifactId> <groupId>org.glassfish</groupId>
</dependency> <artifactId>jakarta.faces</artifactId>
<dependency> </dependency>
<groupId>javax</groupId> <dependency>
<artifactId>javaee-api</artifactId> <groupId>org.primefaces</groupId>
<scope>provided</scope> <artifactId>primefaces</artifactId>
</dependency> <type>jar</type>
<dependency> <scope>provided</scope>
<groupId>org.slf4j</groupId> </dependency>
<artifactId>slf4j-api</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.primefaces</groupId>
<artifactId>primefaces</artifactId>
<type>jar</type>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-web</artifactId>
<scope>provided</scope>
</dependency>
</dependencies>
<build> <!-- jakarta api -->
<plugins> <dependency>
<plugin> <groupId>jakarta.ws.rs</groupId>
<groupId>org.apache.maven.plugins</groupId> <artifactId>jakarta.ws.rs-api</artifactId>
<artifactId>maven-ejb-plugin</artifactId> <scope>provided</scope>
<configuration> </dependency>
<ejbVersion>3.1</ejbVersion> <dependency>
</configuration> <groupId>jakarta.validation</groupId>
</plugin> <artifactId>jakarta.validation-api</artifactId>
</plugins> </dependency>
</build> <dependency>
<groupId>jakarta.interceptor</groupId>
<artifactId>jakarta.interceptor-api</artifactId>
</dependency>
<!-- Logging -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
</dependency>
<!-- unsorted -->
<dependency>
<groupId>io.fusionauth</groupId>
<artifactId>fusionauth-jwt</artifactId>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<scope>provided</scope>
</dependency>
</dependencies>
</project> </project>

View File

@ -15,8 +15,8 @@
*/ */
package de.muehlencord.shared.jeeutil; package de.muehlencord.shared.jeeutil;
import javax.faces.application.FacesMessage; import jakarta.faces.application.FacesMessage;
import javax.faces.application.FacesMessage.Severity; import jakarta.faces.application.FacesMessage.Severity;
/** /**
* *

View File

@ -15,9 +15,9 @@
*/ */
package de.muehlencord.shared.jeeutil; package de.muehlencord.shared.jeeutil;
import jakarta.faces.application.FacesMessage;
import jakarta.faces.context.FacesContext;
import java.util.List; import java.util.List;
import javax.faces.application.FacesMessage;
import javax.faces.context.FacesContext;
/** /**
* Helper class for java faces application. * Helper class for java faces application.

View File

@ -15,8 +15,8 @@
*/ */
package de.muehlencord.shared.jeeutil; package de.muehlencord.shared.jeeutil;
import jakarta.faces.application.FacesMessage;
import java.io.Serializable; import java.io.Serializable;
import javax.faces.application.FacesMessage;
/** /**
* *

View File

@ -1,87 +0,0 @@
/*
* Copyright 2019 Joern Muehlencord (joern@muehlencord.de).
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package de.muehlencord.shared.jeeutil.jwt;
import io.fusionauth.jwt.Verifier;
import io.fusionauth.jwt.domain.JWT;
import io.fusionauth.jwt.hmac.HMACVerifier;
import java.time.ZonedDateTime;
/**
* @author Joern Muehlencord (joern@muehlencord.de)
*/
public class JWTDecoder {
private boolean parsedSuccessfully;
private JWT jwt = null;
public JWTDecoder(String password, String issuer, String jwtString) throws JWTException {
if ((password == null) || (issuer == null) || (jwtString == null)) {
throw new JWTException("password, issuer and jwt must not be null");
}
Verifier verifier = HMACVerifier.newVerifier(password);
jwt = JWT.getDecoder().decode(jwtString, verifier);
parsedSuccessfully = jwt != null && jwt.issuer.equals(issuer);
}
public String getIssuer() {
if (jwt == null) {
return null;
} else {
return jwt.issuer;
}
}
public ZonedDateTime getIssuedAt() {
if (jwt == null) {
return null;
} else {
return jwt.issuedAt;
}
}
public String getSubject() {
if (jwt == null) {
return null;
} else {
return jwt.subject;
}
}
public String getUniqueId() {
if (jwt == null) {
return null;
} else {
return jwt.uniqueId;
}
}
public ZonedDateTime getExpiration() {
if (jwt == null) {
return null;
} else {
return jwt.expiration;
}
}
public boolean isValid() {
if ((jwt == null) || (jwt.isExpired())) {
return false;
} else {
return this.parsedSuccessfully;
}
}
}

View File

@ -1,46 +0,0 @@
/*
* Copyright 2019 Joern Muehlencord (joern@muehlencord.de).
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package de.muehlencord.shared.jeeutil.jwt;
import io.fusionauth.jwt.Signer;
import io.fusionauth.jwt.domain.JWT;
import io.fusionauth.jwt.hmac.HMACSigner;
import java.time.ZonedDateTime;
/**
*
* @author Joern Muehlencord (joern@muehlencord.de)
*/
public abstract class JWTEncoder {
public static String encode(String password, String issuer, ZonedDateTime issuedAt, String subject, String uniqueId, short expirationInMinutes ) throws JWTException {
if ((password == null) || (issuer == null)) {
throw new JWTException("password and issuer must not be null");
}
Signer signer = HMACSigner.newSHA256Signer(password);
// Signer signer = RSASigner.newSHA256Signer(new String(Files.readAllBytes(Paths.get("private_key.pem"))));
JWT jwt = new JWT().setIssuer(issuer) // FIXME - make configurable
.setIssuedAt(issuedAt)
.setSubject(subject)
.setUniqueId(uniqueId)
.setExpiration(issuedAt.plusMinutes(expirationInMinutes));
return JWT.getEncoder().encode(jwt, signer);
}
}

View File

@ -1,49 +0,0 @@
/*
* Copyright 2019 Joern Muehlencord (joern@muehlencord.de).
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package de.muehlencord.shared.jeeutil.jwt;
/**
*
* @author Joern Muehlencord (joern@muehlencord.de)
*/
public class JWTException extends Exception {
private static final long serialVersionUID = 423992803027530544L;
/**
* Creates a new instance of <code>JWTException</code> without detail message.
*/
public JWTException() {
}
/**
* Constructs an instance of <code>JWTException</code> with the specified detail message.
* @param msg the detail message.
*/
public JWTException(String msg) {
super(msg);
}
/**
* Constructs an instance of <code>JWTException</code> with the specified detail message and root cause.
* @param msg the detail message.
* @param th the root cause
*/
public JWTException(String msg, Throwable th) {
super(msg,th);
}
}

View File

@ -1,35 +0,0 @@
/*
* Copyright 2019 Joern Muehlencord (joern@muehlencord.de).
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package de.muehlencord.shared.jeeutil.jwt;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletResponse;
import org.apache.shiro.web.filter.authc.AuthenticationFilter;
/**
*
* @author Joern Muehlencord (joern@muehlencord.de)
*/
public class JWTGuard extends AuthenticationFilter {
@Override
protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws Exception {
HttpServletResponse httpResponse = (HttpServletResponse) response;
httpResponse.sendError(HttpServletResponse.SC_UNAUTHORIZED);
return false;
}
}

View File

@ -15,7 +15,7 @@
*/ */
package de.muehlencord.shared.jeeutil.restexfw; package de.muehlencord.shared.jeeutil.restexfw;
import javax.ws.rs.core.Response; import jakarta.ws.rs.core.Response;
/** /**
* *

View File

@ -15,6 +15,7 @@
*/ */
package de.muehlencord.shared.jeeutil.restexfw; package de.muehlencord.shared.jeeutil.restexfw;
import jakarta.ws.rs.core.Response;
import jakarta.xml.bind.annotation.XmlAccessType; import jakarta.xml.bind.annotation.XmlAccessType;
import jakarta.xml.bind.annotation.XmlAccessorType; import jakarta.xml.bind.annotation.XmlAccessorType;
import jakarta.xml.bind.annotation.XmlRootElement; import jakarta.xml.bind.annotation.XmlRootElement;
@ -22,7 +23,6 @@ import jakarta.xml.bind.annotation.XmlType;
import jakarta.xml.bind.annotation.adapters.XmlJavaTypeAdapter; import jakarta.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
import java.util.Locale; import java.util.Locale;
import java.util.ResourceBundle; import java.util.ResourceBundle;
import javax.ws.rs.core.Response;
/** /**
* *

View File

@ -16,9 +16,9 @@
package de.muehlencord.shared.jeeutil.restexfw; package de.muehlencord.shared.jeeutil.restexfw;
import jakarta.ws.rs.core.Response;
import jakarta.ws.rs.core.Response.ResponseBuilder;
import java.util.Locale; import java.util.Locale;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.ResponseBuilder;
/** /**
* *

View File

@ -15,12 +15,12 @@
*/ */
package de.muehlencord.shared.jeeutil.restexfw; package de.muehlencord.shared.jeeutil.restexfw;
import jakarta.inject.Inject;
import jakarta.interceptor.AroundInvoke;
import jakarta.interceptor.InvocationContext;
import jakarta.validation.ConstraintViolationException;
import jakarta.ws.rs.core.Response;
import java.util.Locale; import java.util.Locale;
import javax.inject.Inject;
import javax.interceptor.AroundInvoke;
import javax.interceptor.InvocationContext;
import javax.validation.ConstraintViolationException;
import javax.ws.rs.core.Response;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;

View File

@ -15,10 +15,10 @@
*/ */
package de.muehlencord.shared.jeeutil.restexfw; package de.muehlencord.shared.jeeutil.restexfw;
import javax.ws.rs.BadRequestException; import jakarta.ws.rs.BadRequestException;
import javax.ws.rs.core.Response; import jakarta.ws.rs.core.Response;
import javax.ws.rs.ext.ExceptionMapper; import jakarta.ws.rs.ext.ExceptionMapper;
import javax.ws.rs.ext.Provider; import jakarta.ws.rs.ext.Provider;
/** /**
* *

View File

@ -15,12 +15,12 @@
*/ */
package de.muehlencord.shared.jeeutil.restexfw; package de.muehlencord.shared.jeeutil.restexfw;
import jakarta.validation.ConstraintViolation;
import jakarta.validation.Path;
import jakarta.xml.bind.annotation.XmlAccessType; import jakarta.xml.bind.annotation.XmlAccessType;
import jakarta.xml.bind.annotation.XmlAccessorType; import jakarta.xml.bind.annotation.XmlAccessorType;
import jakarta.xml.bind.annotation.XmlRootElement; import jakarta.xml.bind.annotation.XmlRootElement;
import java.util.Iterator; import java.util.Iterator;
import javax.validation.ConstraintViolation;
import javax.validation.Path;
/** /**
* *

View File

@ -15,19 +15,19 @@
*/ */
package de.muehlencord.shared.jeeutil.restexfw; package de.muehlencord.shared.jeeutil.restexfw;
import jakarta.validation.ConstraintViolation;
import jakarta.validation.ConstraintViolationException;
import jakarta.ws.rs.core.Context;
import jakarta.ws.rs.core.GenericEntity;
import jakarta.ws.rs.core.MediaType;
import jakarta.ws.rs.core.Request;
import jakarta.ws.rs.core.Response;
import jakarta.ws.rs.core.Variant;
import jakarta.ws.rs.ext.ExceptionMapper;
import jakarta.ws.rs.ext.Provider;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Set; import java.util.Set;
import javax.validation.ConstraintViolation;
import javax.validation.ConstraintViolationException;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.GenericEntity;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Request;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.Variant;
import javax.ws.rs.ext.ExceptionMapper;
import javax.ws.rs.ext.Provider;
/** /**
* *

View File

@ -15,10 +15,10 @@
*/ */
package de.muehlencord.shared.jeeutil.restexfw; package de.muehlencord.shared.jeeutil.restexfw;
import javax.ws.rs.ForbiddenException; import jakarta.ws.rs.ForbiddenException;
import javax.ws.rs.core.Response; import jakarta.ws.rs.core.Response;
import javax.ws.rs.ext.ExceptionMapper; import jakarta.ws.rs.ext.ExceptionMapper;
import javax.ws.rs.ext.Provider; import jakarta.ws.rs.ext.Provider;
/** /**
* *

View File

@ -15,10 +15,10 @@
*/ */
package de.muehlencord.shared.jeeutil.restexfw; package de.muehlencord.shared.jeeutil.restexfw;
import javax.ws.rs.NotAcceptableException; import jakarta.ws.rs.NotAcceptableException;
import javax.ws.rs.core.Response; import jakarta.ws.rs.core.Response;
import javax.ws.rs.ext.ExceptionMapper; import jakarta.ws.rs.ext.ExceptionMapper;
import javax.ws.rs.ext.Provider; import jakarta.ws.rs.ext.Provider;
/** /**
* *

View File

@ -15,10 +15,10 @@
*/ */
package de.muehlencord.shared.jeeutil.restexfw; package de.muehlencord.shared.jeeutil.restexfw;
import javax.ws.rs.NotAllowedException; import jakarta.ws.rs.NotAllowedException;
import javax.ws.rs.core.Response; import jakarta.ws.rs.core.Response;
import javax.ws.rs.ext.ExceptionMapper; import jakarta.ws.rs.ext.ExceptionMapper;
import javax.ws.rs.ext.Provider; import jakarta.ws.rs.ext.Provider;
/** /**
* *

View File

@ -15,10 +15,10 @@
*/ */
package de.muehlencord.shared.jeeutil.restexfw; package de.muehlencord.shared.jeeutil.restexfw;
import javax.ws.rs.NotAuthorizedException; import jakarta.ws.rs.NotAuthorizedException;
import javax.ws.rs.core.Response; import jakarta.ws.rs.core.Response;
import javax.ws.rs.ext.ExceptionMapper; import jakarta.ws.rs.ext.ExceptionMapper;
import javax.ws.rs.ext.Provider; import jakarta.ws.rs.ext.Provider;
/** /**
* *

View File

@ -15,10 +15,10 @@
*/ */
package de.muehlencord.shared.jeeutil.restexfw; package de.muehlencord.shared.jeeutil.restexfw;
import javax.ws.rs.NotFoundException; import jakarta.ws.rs.NotFoundException;
import javax.ws.rs.core.Response; import jakarta.ws.rs.core.Response;
import javax.ws.rs.ext.ExceptionMapper; import jakarta.ws.rs.ext.ExceptionMapper;
import javax.ws.rs.ext.Provider; import jakarta.ws.rs.ext.Provider;
/** /**
* *

View File

@ -15,10 +15,10 @@
*/ */
package de.muehlencord.shared.jeeutil.restexfw; package de.muehlencord.shared.jeeutil.restexfw;
import javax.ws.rs.NotSupportedException; import jakarta.ws.rs.NotSupportedException;
import javax.ws.rs.core.Response; import jakarta.ws.rs.core.Response;
import javax.ws.rs.ext.ExceptionMapper; import jakarta.ws.rs.ext.ExceptionMapper;
import javax.ws.rs.ext.Provider; import jakarta.ws.rs.ext.Provider;
/** /**
* *

View File

@ -15,9 +15,9 @@
*/ */
package de.muehlencord.shared.jeeutil.restexfw; package de.muehlencord.shared.jeeutil.restexfw;
import jakarta.ws.rs.core.Response;
import jakarta.ws.rs.core.Response.Status;
import jakarta.xml.bind.annotation.adapters.XmlAdapter; import jakarta.xml.bind.annotation.adapters.XmlAdapter;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.Status;
/** /**
* @author Joern Muehlencord (joern@muehlencord.de) * @author Joern Muehlencord (joern@muehlencord.de)

View File

@ -15,12 +15,12 @@
*/ */
package de.muehlencord.shared.jeeutil.restexfw; package de.muehlencord.shared.jeeutil.restexfw;
import jakarta.validation.ConstraintViolation;
import jakarta.validation.ConstraintViolationException;
import jakarta.validation.Validation;
import jakarta.validation.Validator;
import jakarta.validation.ValidatorFactory;
import java.util.Set; import java.util.Set;
import javax.validation.ConstraintViolation;
import javax.validation.ConstraintViolationException;
import javax.validation.Validation;
import javax.validation.Validator;
import javax.validation.ValidatorFactory;
/** /**
* *

View File

@ -15,16 +15,16 @@
*/ */
package de.muehlencord.shared.jeeutil.validator; package de.muehlencord.shared.jeeutil.validator;
import java.lang.annotation.Documented;
import static java.lang.annotation.ElementType.ANNOTATION_TYPE; import static java.lang.annotation.ElementType.ANNOTATION_TYPE;
import static java.lang.annotation.ElementType.FIELD; import static java.lang.annotation.ElementType.FIELD;
import static java.lang.annotation.ElementType.METHOD; import static java.lang.annotation.ElementType.METHOD;
import java.lang.annotation.Retention;
import static java.lang.annotation.RetentionPolicy.RUNTIME; import static java.lang.annotation.RetentionPolicy.RUNTIME;
import jakarta.validation.Constraint;
import jakarta.validation.Payload;
import java.lang.annotation.Documented;
import java.lang.annotation.Retention;
import java.lang.annotation.Target; import java.lang.annotation.Target;
import javax.validation.Constraint;
import javax.validation.Payload;
import org.primefaces.validate.bean.ClientConstraint;
/** /**
* *
@ -33,7 +33,8 @@ import org.primefaces.validate.bean.ClientConstraint;
@Target({METHOD, FIELD, ANNOTATION_TYPE}) @Target({METHOD, FIELD, ANNOTATION_TYPE})
@Retention(RUNTIME) @Retention(RUNTIME)
@Constraint(validatedBy = EmailConstraintValidator.class) @Constraint(validatedBy = EmailConstraintValidator.class)
@ClientConstraint(resolvedBy = EmailClientValidationConstraint.class) // FIXME - broken ClientValidationConstraint from Primefaces 13 still uses javax.xx
//@ClientConstraint(resolvedBy = EmailClientValidationConstraint.class)
@Documented @Documented
public @interface Email { public @interface Email {

View File

@ -15,21 +15,20 @@
*/ */
package de.muehlencord.shared.jeeutil.validator; package de.muehlencord.shared.jeeutil.validator;
import jakarta.validation.metadata.ConstraintDescriptor;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import javax.validation.metadata.ConstraintDescriptor;
import org.primefaces.validate.bean.ClientValidationConstraint;
/** /**
* * FIXME - broken ClientValidationConstraint from Primefaces 13 still uses javax.xx
* @author Joern Muehlencord (joern@muehlencord.de) * @author Joern Muehlencord (joern@muehlencord.de)
*/ */
public class EmailClientValidationConstraint implements ClientValidationConstraint { public class EmailClientValidationConstraint { // {implements ClientValidationConstraint {
public static final String MESSAGE_METADATA = "data-p-email-msg"; public static final String MESSAGE_METADATA = "data-p-email-msg";
@Override // @Override
public Map<String, Object> getMetadata(ConstraintDescriptor constraintDescriptor) { public Map<String, Object> getMetadata(ConstraintDescriptor<?> constraintDescriptor) {
Map<String, Object> metadata = new HashMap<>(); Map<String, Object> metadata = new HashMap<>();
Map<?, ?> attrs = constraintDescriptor.getAttributes(); Map<?, ?> attrs = constraintDescriptor.getAttributes();
Object message = attrs.get("message"); Object message = attrs.get("message");
@ -40,7 +39,7 @@ public class EmailClientValidationConstraint implements ClientValidationConstrai
return metadata; return metadata;
} }
@Override // @Override
public String getValidatorId() { public String getValidatorId() {
return Email.class.getSimpleName(); return Email.class.getSimpleName();
} }

View File

@ -15,9 +15,9 @@
*/ */
package de.muehlencord.shared.jeeutil.validator; package de.muehlencord.shared.jeeutil.validator;
import jakarta.validation.ConstraintValidator;
import jakarta.validation.ConstraintValidatorContext;
import java.util.regex.Pattern; import java.util.regex.Pattern;
import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
/** /**
* *

View File

@ -15,14 +15,14 @@
*/ */
package de.muehlencord.shared.jeeutil.validator; package de.muehlencord.shared.jeeutil.validator;
import jakarta.faces.application.FacesMessage;
import jakarta.faces.component.UIComponent;
import jakarta.faces.context.FacesContext;
import jakarta.faces.validator.FacesValidator;
import jakarta.faces.validator.Validator;
import jakarta.faces.validator.ValidatorException;
import java.util.regex.Matcher; import java.util.regex.Matcher;
import java.util.regex.Pattern; import java.util.regex.Pattern;
import javax.faces.application.FacesMessage;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.validator.FacesValidator;
import javax.faces.validator.Validator;
import javax.faces.validator.ValidatorException;
/** /**
* *

View File

@ -1,34 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
Copyright 2019 Joern Muehlencord (joern@muehlencord.de).
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<project-shared-configuration>
<!--
This file contains additional configuration written by modules in the NetBeans IDE.
The configuration is intended to be shared among all the users of project and
therefore it is assumed to be part of version control checkout.
Without this configuration present, some functionality in the IDE may be limited or fail altogether.
-->
<properties xmlns="http://www.netbeans.org/ns/maven-properties-data/1">
<!--
Properties that influence various parts of the IDE, especially code formatting and the like.
You can copy and paste the single properties, into the pom.xml file and the IDE will pick them up.
That way multiple projects can share the same settings (useful for formatting rules for example).
Any value defined here will override the pom.xml file value but is only applicable to the current project.
-->
<netbeans.compile.on.save>all</netbeans.compile.on.save>
</properties>
</project-shared-configuration>

View File

@ -16,29 +16,36 @@ limitations under the License.
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<artifactId>shared-network</artifactId> <artifactId>shared-network</artifactId>
<build> <groupId>de.muehlencord.shared</groupId>
<finalName>${project.artifactId}</finalName> <modelVersion>4.0.0</modelVersion>
</build> <name>shared-network</name>
<packaging>jar</packaging>
<parent>
<artifactId>shared</artifactId>
<groupId>de.muehlencord</groupId>
<version>2.0.1-SNAPSHOT</version>
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<url>http://maven.apache.org</url>
<version>2.0.1-SNAPSHOT</version>
<dependencies> <dependencies>
<dependency>
<artifactId>junit-jupiter-engine</artifactId>
<groupId>org.junit.jupiter</groupId>
<scope>test</scope>
</dependency>
<dependency> <dependency>
<artifactId>slf4j-api</artifactId> <artifactId>slf4j-api</artifactId>
<groupId>org.slf4j</groupId> <groupId>org.slf4j</groupId>
<scope>provided</scope> <scope>provided</scope>
</dependency> </dependency>
<dependency>
<artifactId>slf4j-jdk14</artifactId>
<groupId>org.slf4j</groupId>
<scope>test</scope>
</dependency>
<dependency> <dependency>
<artifactId>shared-util</artifactId> <artifactId>shared-util</artifactId>
<groupId>de.muehlencord.shared</groupId> <groupId>de.muehlencord.shared</groupId>
<type>jar</type>
</dependency> </dependency>
<dependency> <dependency>
@ -60,25 +67,22 @@ limitations under the License.
<artifactId>jaxws-api</artifactId> <artifactId>jaxws-api</artifactId>
<groupId>javax.xml.ws</groupId> <groupId>javax.xml.ws</groupId>
<scope>test</scope> <scope>test</scope>
<version>2.3.1</version> </dependency>
<!-- Test -->
<dependency>
<artifactId>junit-jupiter-engine</artifactId>
<groupId>org.junit.jupiter</groupId>
<scope>test</scope>
</dependency>
<dependency>
<artifactId>slf4j-jdk14</artifactId>
<groupId>org.slf4j</groupId>
<scope>test</scope>
</dependency> </dependency>
</dependencies> </dependencies>
<groupId>de.muehlencord.shared</groupId>
<modelVersion>4.0.0</modelVersion>
<name>shared-network</name>
<packaging>jar</packaging> <build>
<finalName>${project.artifactId}</finalName>
<parent> </build>
<artifactId>shared</artifactId>
<groupId>de.muehlencord</groupId>
<version>1.3.0</version>
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<url>http://maven.apache.org</url>
<version>1.3.0</version>
</project> </project>

View File

@ -47,9 +47,9 @@ limitations under the License.
<parent> <parent>
<artifactId>shared</artifactId> <artifactId>shared</artifactId>
<groupId>de.muehlencord</groupId> <groupId>de.muehlencord</groupId>
<version>1.3.0</version> <version>2.0.1-SNAPSHOT</version>
</parent> </parent>
<version>1.3.0</version> <version>2.0.1-SNAPSHOT</version>
</project> </project>

173
pom.xml
View File

@ -18,8 +18,9 @@ limitations under the License.
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<groupId>de.muehlencord</groupId>
<artifactId>shared</artifactId> <artifactId>shared</artifactId>
<version>1.3.0</version> <version>2.0.1-SNAPSHOT</version>
<name>shared</name> <name>shared</name>
<packaging>pom</packaging> <packaging>pom</packaging>
@ -28,7 +29,6 @@ limitations under the License.
<module>network</module> <module>network</module>
<module>util</module> <module>util</module>
<module>jeeutil</module> <module>jeeutil</module>
<module>shiro-faces</module>
<module>poi-util</module> <module>poi-util</module>
<module>db</module> <module>db</module>
</modules> </modules>
@ -51,21 +51,28 @@ limitations under the License.
<scm> <scm>
<connection>scm:git:git@jomu.timelord.de:jomu/shared.git</connection> <connection>scm:git:git@jomu.timelord.de:jomu/shared.git</connection>
<developerConnection>scm:git:git@jomu.timelord.de:jomu/shared.git</developerConnection> <developerConnection>scm:git:git@jomu.timelord.de:jomu/shared.git</developerConnection>
<tag>v1.3.0</tag> <tag>HEAD</tag>
<url>https://jomu.timelord.de/git/jomu/shared/</url> <url>https://jomu.timelord.de/git/jomu/shared/</url>
</scm> </scm>
<repositories>
<repository>
<id>gitea</id>
<url>https://jomu.timelord.de/git/api/packages/jomu/maven</url>
</repository>
</repositories>
<distributionManagement> <distributionManagement>
<repository> <repository>
<id>ossrh</id> <id>jomu-gitea</id>
<url>https://oss.sonatype.org/service/local/staging/deploy/maven2/</url> <url>https://jomu.timelord.de/git/api/packages/jomu/maven</url>
</repository> </repository>
<snapshotRepository> <snapshotRepository>
<id>ossrh</id> <id>jomu-gitea</id>
<url>https://oss.sonatype.org/content/repositories/snapshots</url> <url>https://jomu.timelord.de/git/api/packages/jomu/maven</url>
</snapshotRepository> </snapshotRepository>
</distributionManagement> </distributionManagement>
<groupId>de.muehlencord</groupId>
<issueManagement> <issueManagement>
<system>Gitea</system> <system>Gitea</system>
@ -80,32 +87,39 @@ limitations under the License.
<maven.compiler.release>17</maven.compiler.release> <maven.compiler.release>17</maven.compiler.release>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<slf4j.version>2.0.6</slf4j.version> <slf4j.version>2.0.9</slf4j.version>
<jackson.version>2.14.2</jackson.version> <jackson.version>2.16.0</jackson.version>
<shiro.version>1.11.0</shiro.version> <lombok.version>1.18.30</lombok.version>
<lombok.version>1.18.26</lombok.version> <junit.version>5.10.1</junit.version>
<junit.version>5.9.2</junit.version>
<primefaces.version>12.0.0</primefaces.version> <poi.version>5.2.5</poi.version>
<adminfaces-template.version>1.6.1</adminfaces-template.version> <commons-net.version>3.10.0</commons-net.version>
<omnifaces.version>4.0.1</omnifaces.version> <commons-lang.version>3.14.0</commons-lang.version>
<poi.version>5.2.3</poi.version>
<commons-net.version>3.9.0</commons-net.version>
<gson.version>2.10.1</gson.version> <gson.version>2.10.1</gson.version>
<fusionauth.version>5.2.2</fusionauth.version> <fusionauth.version>5.3.1</fusionauth.version>
<bouncycastle.version>1.70</bouncycastle.version> <bouncycastle.version>1.70</bouncycastle.version>
<hibernate.version>6.1.7.Final</hibernate.version> <hibernate.version>6.2.15.Final</hibernate.version>
<com-sun-mail.version>1.6.2</com-sun-mail.version>
<jakarta-faces.version>4.0.5</jakarta-faces.version>
<joinfaces.version>5.1.6</joinfaces.version>
<jakarta.interceptor-api.version>2.1.0</jakarta.interceptor-api.version>
<jakarta-inject-api.version>2.0.1</jakarta-inject-api.version>
<jaxws-api.version>2.3.1</jaxws-api.version>
</properties> </properties>
<dependencyManagement> <dependencyManagement>
<dependencies> <dependencies>
<dependency> <dependency>
<artifactId>shared-db</artifactId> <groupId>org.joinfaces</groupId>
<groupId>de.muehlencord.shared</groupId> <artifactId>joinfaces-dependencies</artifactId>
<type>ejb</type> <version>${joinfaces.version}</version>
<version>${project.version}</version> <type>pom</type>
<scope>import</scope>
</dependency> </dependency>
<dependency> <dependency>
<artifactId>shared-shiro-faces</artifactId> <artifactId>shared-db</artifactId>
<groupId>de.muehlencord.shared</groupId> <groupId>de.muehlencord.shared</groupId>
<version>${project.version}</version> <version>${project.version}</version>
</dependency> </dependency>
@ -119,11 +133,8 @@ limitations under the License.
<groupId>de.muehlencord.shared</groupId> <groupId>de.muehlencord.shared</groupId>
<version>${project.version}</version> <version>${project.version}</version>
</dependency> </dependency>
<dependency>
<artifactId>commons-codec</artifactId> <!-- Apache Commons -->
<groupId>commons-codec</groupId>
<version>1.15</version>
</dependency>
<dependency> <dependency>
<artifactId>commons-net</artifactId> <artifactId>commons-net</artifactId>
<groupId>commons-net</groupId> <groupId>commons-net</groupId>
@ -132,13 +143,10 @@ limitations under the License.
<dependency> <dependency>
<artifactId>commons-lang3</artifactId> <artifactId>commons-lang3</artifactId>
<groupId>org.apache.commons</groupId> <groupId>org.apache.commons</groupId>
<version>3.12.0</version> <version>${commons-lang.version}</version>
</dependency>
<dependency>
<artifactId>commons-io</artifactId>
<groupId>commons-io</groupId>
<version>2.11.0</version>
</dependency> </dependency>
<!-- logging -->
<dependency> <dependency>
<artifactId>slf4j-api</artifactId> <artifactId>slf4j-api</artifactId>
<groupId>org.slf4j</groupId> <groupId>org.slf4j</groupId>
@ -155,16 +163,36 @@ limitations under the License.
<version>${slf4j.version}</version> <version>${slf4j.version}</version>
</dependency> </dependency>
<!-- mail -->
<dependency> <dependency>
<artifactId>javax.mail</artifactId> <artifactId>javax.mail</artifactId>
<groupId>com.sun.mail</groupId> <groupId>com.sun.mail</groupId>
<version>1.6.2</version> <version>${com-sun-mail.version}</version>
</dependency> </dependency>
<dependency> <dependency>
<artifactId>ews-java-api</artifactId> <artifactId>ews-java-api</artifactId>
<groupId>com.microsoft.ews-java-api</groupId> <groupId>com.microsoft.ews-java-api</groupId>
<version>2.0</version> <version>2.0</version>
</dependency> </dependency>
<!-- Faces -->
<dependency>
<groupId>org.glassfish</groupId>
<artifactId>jakarta.faces</artifactId>
<version>${jakarta-faces.version}</version>
</dependency>
<dependency>
<groupId>jakarta.interceptor</groupId>
<artifactId>jakarta.interceptor-api</artifactId>
<version>${jakarta.interceptor-api.version}</version>
</dependency>
<dependency>
<groupId>jakarta.inject</groupId>
<artifactId>jakarta.inject-api</artifactId>
<version>${jakarta-inject-api.version}</version>
</dependency>
<!-- mixed tools -->
<dependency> <dependency>
<artifactId>gson</artifactId> <artifactId>gson</artifactId>
<groupId>com.google.code.gson</groupId> <groupId>com.google.code.gson</groupId>
@ -188,26 +216,11 @@ limitations under the License.
<version>${jackson.version}</version> <version>${jackson.version}</version>
</dependency> </dependency>
<dependency> <dependency>
<artifactId>shiro-core</artifactId> <artifactId>jaxws-api</artifactId>
<groupId>org.apache.shiro</groupId> <groupId>javax.xml.ws</groupId>
<version>${shiro.version}</version> <version>${jaxws-api.version}</version>
</dependency>
<dependency>
<artifactId>shiro-web</artifactId>
<groupId>org.apache.shiro</groupId>
<version>${shiro.version}</version>
</dependency>
<dependency>
<artifactId>javaee-api</artifactId>
<groupId>javax</groupId>
<version>8.0.1</version>
</dependency>
<dependency>
<artifactId>javaee-web-api</artifactId>
<groupId>javax</groupId>
<scope>provided</scope>
<version>8.0.1</version>
</dependency> </dependency>
<dependency> <dependency>
<artifactId>scrypt</artifactId> <artifactId>scrypt</artifactId>
<groupId>com.lambdaworks</groupId> <groupId>com.lambdaworks</groupId>
@ -225,21 +238,6 @@ limitations under the License.
<type>jar</type> <type>jar</type>
<version>${hibernate.version}</version> <version>${hibernate.version}</version>
</dependency> </dependency>
<dependency>
<artifactId>primefaces</artifactId>
<groupId>org.primefaces</groupId>
<version>${primefaces.version}</version>
</dependency>
<dependency>
<artifactId>admin-template</artifactId>
<groupId>com.github.adminfaces</groupId>
<version>${adminfaces-template.version}</version>
</dependency>
<dependency>
<artifactId>omnifaces</artifactId>
<groupId>org.omnifaces</groupId>
<version>${omnifaces.version}</version>
</dependency>
<dependency> <dependency>
<artifactId>poi-ooxml</artifactId> <artifactId>poi-ooxml</artifactId>
<groupId>org.apache.poi</groupId> <groupId>org.apache.poi</groupId>
@ -274,17 +272,17 @@ limitations under the License.
<build> <build>
<plugins> <plugins>
<!-- deploy artifacts to maven repository --> <!-- deploy artifacts to maven repository -->
<plugin> <!-- <plugin>-->
<artifactId>nexus-staging-maven-plugin</artifactId> <!-- <artifactId>nexus-staging-maven-plugin</artifactId>-->
<configuration> <!-- <configuration>-->
<autoReleaseAfterClose>true</autoReleaseAfterClose> <!-- <autoReleaseAfterClose>true</autoReleaseAfterClose>-->
<nexusUrl>https://oss.sonatype.org/</nexusUrl> <!-- <nexusUrl>https://oss.sonatype.org/</nexusUrl>-->
<serverId>ossrh</serverId> <!-- <serverId>ossrh</serverId>-->
</configuration> <!-- </configuration>-->
<extensions>true</extensions> <!-- <extensions>true</extensions>-->
<groupId>org.sonatype.plugins</groupId> <!-- <groupId>org.sonatype.plugins</groupId>-->
<version>1.6.8</version> <!-- <version>1.6.8</version>-->
</plugin> <!-- </plugin>-->
<!-- ensure sources are build so they are also uploaded --> <!-- ensure sources are build so they are also uploaded -->
<plugin> <plugin>
@ -404,10 +402,11 @@ limitations under the License.
<plugins> <plugins>
<plugin> <plugin>
<artifactId>maven-compiler-plugin</artifactId>
<groupId>org.apache.maven.plugins</groupId> <groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
</plugin> </plugin>
<plugin> <plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-release-plugin</artifactId> <artifactId>maven-release-plugin</artifactId>
<configuration> <configuration>
<tagNameFormat>v@{project.version}</tagNameFormat> <tagNameFormat>v@{project.version}</tagNameFormat>
@ -415,8 +414,14 @@ limitations under the License.
<version>2.5.3</version> <version>2.5.3</version>
</plugin> </plugin>
<plugin> <plugin>
<artifactId>maven-surefire-plugin</artifactId>
<groupId>org.apache.maven.plugins</groupId> <groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>3.6.1</version>
</plugin> </plugin>
</plugins> </plugins>
</build> </build>

View File

@ -1,45 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
Copyright 2019 Joern Muehlencord (joern@muehlencord.de).
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>de.muehlencord.shared</groupId>
<artifactId>shared-shiro-faces</artifactId>
<packaging>jar</packaging>
<parent>
<groupId>de.muehlencord</groupId>
<artifactId>shared</artifactId>
<version>1.3.0</version>
</parent>
<name>shared-shiro-faces</name>
<dependencies>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-web</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax</groupId>
<artifactId>javaee-api</artifactId>
<scope>provided</scope>
</dependency>
</dependencies>
</project>

View File

@ -1,50 +0,0 @@
/*
* Copyright 2019 Joern Muehlencord (joern@muehlencord.de).
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package de.muehlencord.shirofaces.filter;
import java.io.IOException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import org.apache.shiro.web.filter.authc.PassThruAuthenticationFilter;
/**
* found at http://balusc.omnifaces.org/2013/01/apache-shiro-is-it-ready-for-java-ee-6.html#MakeShiroJSFAjaxAware)
* source by BalusC, adjusted to PassThruAuthenticationFilter by Joern Muehlencord
* @author BalusC
* @author Joern Muehlencord (joern@muehlencord.de)
*/
public class FacesAjaxAwarePassThruAuthenticationFilter extends PassThruAuthenticationFilter {
private static final String FACES_REDIRECT_XML = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
+ "<partial-response><redirect url=\"%s\"></redirect></partial-response>";
@Override
protected void redirectToLogin(ServletRequest req, ServletResponse res) throws IOException {
HttpServletRequest request = (HttpServletRequest) req;
if ("partial/ajax".equals(request.getHeader("Faces-Request"))) {
res.setContentType("text/xml");
res.setCharacterEncoding("UTF-8");
res.getWriter().printf(FACES_REDIRECT_XML, request.getContextPath() + getLoginUrl());
}
else {
super.redirectToLogin(req, res);
}
}
}

View File

@ -1,51 +0,0 @@
/*
* Copyright 2019 Joern Muehlencord (joern@muehlencord.de).
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package de.muehlencord.shirofaces.tags;
import javax.el.ValueExpression;
import javax.faces.view.facelets.FaceletContext;
import javax.faces.view.facelets.TagAttribute;
import javax.faces.view.facelets.TagConfig;
/**
*
* @author Joern Muehlencord (joern@muehlencord.de)
*/
public abstract class AbstractAccessControlTag extends AbstractTag {
protected TagAttribute attribute;
protected AbstractAccessControlTag(TagConfig config) {
super(config);
}
protected String getAttributeValue(FaceletContext ctx, TagAttribute attr) {
String value;
if (attr.isLiteral()) {
value = attr.getValue(ctx);
} else {
ValueExpression expression = attr.getValueExpression(ctx, String.class);
value = (String) expression.getValue(ctx);
}
return value;
}
protected boolean isPermitted(String permission) {
return getSubject() != null && getSubject().isPermitted(permission);
}
}

View File

@ -1,59 +0,0 @@
/*
* Copyright 2019 Joern Muehlencord (joern@muehlencord.de).
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package de.muehlencord.shirofaces.tags;
import java.io.IOException;
import javax.faces.component.UIComponent;
import javax.faces.view.facelets.FaceletContext;
import javax.faces.view.facelets.TagConfig;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* @author Joern Muehlencord (joern@muehlencord.de)
*/
public abstract class AbstractAuthenticationTag extends AbstractTag {
private static final Logger logger = LoggerFactory.getLogger(AbstractAuthenticationTag.class);
protected AbstractAuthenticationTag(TagConfig config) {
super(config);
}
protected abstract boolean isAuthenticated();
protected boolean applyTagHandler() {
if (isAuthenticated()) {
if (logger.isTraceEnabled()) {
logger.trace("Authentication verified, tag will be evaluated");
}
return true;
} else {
if (logger.isTraceEnabled()) {
logger.trace("Authentifaction verification failed, tag will not be evaluated");
}
return false;
}
}
@Override
public void apply(FaceletContext fc, UIComponent uic) throws IOException {
if (applyTagHandler()) {
this.nextHandler.apply(fc, uic);
}
}
}

View File

@ -1,51 +0,0 @@
/*
* Copyright 2019 Joern Muehlencord (joern@muehlencord.de).
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package de.muehlencord.shirofaces.tags;
import java.io.IOException;
import javax.faces.component.UIComponent;
import javax.faces.view.facelets.FaceletContext;
import javax.faces.view.facelets.TagConfig;
/**
*
* @author Joern Muehlencord (joern@muehlencord.de)
*/
public abstract class AbstractPermissionTag extends AbstractAccessControlTag {
protected AbstractPermissionTag(TagConfig config) {
super(config);
this.attribute = this.getRequiredAttribute("name");
}
protected abstract boolean hasPermission(String permission);
@Override
protected boolean isPermitted(String permission) {
return getSubject() != null && getSubject().isPermitted(permission);
}
@Override
public void apply(FaceletContext fc, UIComponent uic) throws IOException {
String permissionName = getAttributeValue(fc, attribute);
if (hasPermission(permissionName)) {
this.nextHandler.apply(fc, uic);
}
}
}

View File

@ -1,43 +0,0 @@
/*
* Copyright 2019 Joern Muehlencord (joern@muehlencord.de).
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package de.muehlencord.shirofaces.tags;
import java.io.IOException;
import javax.faces.component.UIComponent;
import javax.faces.view.facelets.FaceletContext;
import javax.faces.view.facelets.TagConfig;
/**
*
* @author Joern Muehlencord (joern@muehlencord.de)
*/
public abstract class AbstractRoleTag extends AbstractAccessControlTag {
protected AbstractRoleTag(TagConfig config) {
super(config);
this.attribute = this.getRequiredAttribute("name");
}
protected abstract boolean hasRole(String role);
public void apply(FaceletContext fc, UIComponent uic) throws IOException {
String roleName = getAttributeValue(fc, attribute);
if (hasRole(roleName)) {
this.nextHandler.apply(fc, uic);
}
}
}

View File

@ -1,37 +0,0 @@
/*
* Copyright 2019 Joern Muehlencord (joern@muehlencord.de).
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package de.muehlencord.shirofaces.tags;
import javax.faces.view.facelets.TagConfig;
import javax.faces.view.facelets.TagHandler;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.subject.Subject;
/**
*
* @author Joern Muehlencord (joern@muehlencord.de)
*/
public abstract class AbstractTag extends TagHandler {
protected AbstractTag(TagConfig config) {
super(config);
}
protected Subject getSubject() {
return SecurityUtils.getSubject();
}
}

View File

@ -1,35 +0,0 @@
/*
* Copyright 2019 Joern Muehlencord (joern@muehlencord.de).
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package de.muehlencord.shirofaces.tags;
import javax.faces.view.facelets.TagConfig;
/**
*
* @author Joern Muehlencord (joern@muehlencord.de)
*/
public class AuthenticatedTag extends AbstractAuthenticationTag {
public AuthenticatedTag(TagConfig config) {
super(config);
}
@Override
protected boolean isAuthenticated() {
return getSubject() != null && getSubject().isAuthenticated();
}
}

View File

@ -1,39 +0,0 @@
/*
* Copyright 2019 Joern Muehlencord (joern@muehlencord.de).
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package de.muehlencord.shirofaces.tags;
import javax.faces.view.facelets.TagConfig;
/**
*
* @author Joern Muehlencord (joern@muehlencord.de)
*/
public class GuestTag extends AbstractAuthenticationTag {
public GuestTag(TagConfig config) {
super(config);
}
@Override
protected boolean isAuthenticated() {
return getSubject() == null || getSubject().getPrincipal() == null;
}
}

View File

@ -1,45 +0,0 @@
/*
* Copyright 2019 Joern Muehlencord (joern@muehlencord.de).
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package de.muehlencord.shirofaces.tags;
import java.util.Arrays;
import java.util.List;
import javax.faces.view.facelets.TagConfig;
import org.apache.shiro.subject.Subject;
/**
*
* @author Joern Muehlencord (joern@muehlencord.de)
*/
public class HasAnyPermissionTag extends AbstractPermissionTag {
private final static String PERMISSIONS_DELIMETER = ",";
public HasAnyPermissionTag(TagConfig config) {
super(config);
}
@Override
protected boolean hasPermission(String permissions) {
Subject subject = getSubject();
if (subject != null) {
List<String> permissionsList = Arrays.asList(permissions.split(PERMISSIONS_DELIMETER));
return permissionsList.stream().anyMatch(permission -> subject.isPermitted(permission));
} else return false;
}
}

View File

@ -1,46 +0,0 @@
/*
* Copyright 2019 Joern Muehlencord (joern@muehlencord.de).
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package de.muehlencord.shirofaces.tags;
import java.util.Arrays;
import java.util.List;
import javax.faces.view.facelets.TagConfig;
import org.apache.shiro.subject.Subject;
/**
*
* @author Joern Muehlencord (joern@muehlencord.de)
*/
public class HasAnyRolesTag extends AbstractRoleTag {
private final static String ROLE_NAMES_DELIMETER = ",";
public HasAnyRolesTag(TagConfig config) {
super(config);
}
@Override
protected boolean hasRole(String roleNames) {
Subject subject = getSubject();
if (subject != null) {
List<String> roleList = Arrays.asList(roleNames.split(ROLE_NAMES_DELIMETER));
return roleList.stream().anyMatch(role -> subject.hasRole(role.trim()));
}
return false;
}
}

View File

@ -1,37 +0,0 @@
/*
* Copyright 2019 Joern Muehlencord (joern@muehlencord.de).
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package de.muehlencord.shirofaces.tags;
import javax.faces.view.facelets.TagConfig;
/**
*
* @author Joern Muehlencord (joern@muehlencord.de)
*/
public class HasPermissionTag extends AbstractPermissionTag {
public HasPermissionTag(TagConfig config) {
super(config);
}
@Override
protected boolean hasPermission(String permission) {
return isPermitted(permission);
}
}

View File

@ -1,38 +0,0 @@
/*
* Copyright 2019 Joern Muehlencord (joern@muehlencord.de).
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package de.muehlencord.shirofaces.tags;
import javax.faces.view.facelets.TagConfig;
/**
*
* @author Joern Muehlencord (joern@muehlencord.de)
*/
public class HasRoleTag extends AbstractRoleTag {
public HasRoleTag(TagConfig config) {
super(config);
}
@Override
protected boolean hasRole(String role) {
return getSubject() != null && getSubject().hasRole(role);
}
}

View File

@ -1,36 +0,0 @@
/*
* Copyright 2019 Joern Muehlencord (joern@muehlencord.de).
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package de.muehlencord.shirofaces.tags;
import javax.faces.view.facelets.TagConfig;
/**
*
* @author Joern Muehlencord (joern@muehlencord.de)
*/
public class LacksPermissionTag extends AbstractPermissionTag {
public LacksPermissionTag(TagConfig config) {
super(config);
}
@Override
protected boolean hasPermission(String permission) {
return !isPermitted(permission);
}
}

View File

@ -1,37 +0,0 @@
/*
* Copyright 2019 Joern Muehlencord (joern@muehlencord.de).
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package de.muehlencord.shirofaces.tags;
import javax.faces.view.facelets.TagConfig;
/**
*
* @author Joern Muehlencord (joern@muehlencord.de)
*/
public class LacksRoleTag extends AbstractRoleTag {
public LacksRoleTag(TagConfig config) {
super(config);
}
@Override
protected boolean hasRole(String role) {
return getSubject() != null && getSubject().hasRole(role);
}
}

View File

@ -1,36 +0,0 @@
/*
* Copyright 2019 Joern Muehlencord (joern@muehlencord.de).
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package de.muehlencord.shirofaces.tags;
import javax.faces.view.facelets.TagConfig;
/**
*
* @author Joern Muehlencord (joern@muehlencord.de)
*/
public class NotAuthenticatedTag extends AbstractAuthenticationTag {
public NotAuthenticatedTag(TagConfig config) {
super(config);
}
@Override
protected boolean isAuthenticated() {
return getSubject() == null || !getSubject().isAuthenticated();
}
}

View File

@ -1,35 +0,0 @@
/*
* Copyright 2019 Joern Muehlencord (joern@muehlencord.de).
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package de.muehlencord.shirofaces.tags;
import javax.faces.view.facelets.TagConfig;
/**
*
* @author Joern Muehlencord (joern@muehlencord.de)
*/
public class UserTag extends AbstractAuthenticationTag {
public UserTag(TagConfig config) {
super(config);
}
@Override
protected boolean isAuthenticated() {
return getSubject() != null && getSubject().getPrincipal() != null;
}
}

View File

@ -1,57 +0,0 @@
/*
* Copyright 2019 Joern Muehlencord (joern@muehlencord.de).
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package de.muehlencord.shirofaces.tags.unsupported;
import de.muehlencord.shirofaces.tags.AbstractTag;
import java.io.IOException;
import javax.faces.component.UIComponent;
import javax.faces.view.facelets.FaceletContext;
import javax.faces.view.facelets.TagConfig;
/**
* <div>
* Tag used to print out the String value of a user's default principal, or a
* specific principal as specified by the tag's attributes.
* </div>
*
* <div>
* If no attributes are specified, the tag prints out the <b>toString()</b>
* value of the user's default principal. If the <b>type</b> attribute is
* specified, the tag looks for a principal with the given type. If the
* <b>property</b> attribute is specified, the tag prints the string value of
* the specified property of the principal. If no principal is found or the user
* is not authenticated, the tag displays nothing unless a <b>defaultValue</b>
* is specified.
* </div>
*
* @author Joern Muehlencord (joern@muehlencord.de)
*/
public class PrincipalTag extends AbstractTag {
/**
* creates a new principal tag
*
* @param config the configuration to use
*/
public PrincipalTag(TagConfig config) {
super(config);
}
@Override
public void apply(FaceletContext fc, UIComponent uic) throws IOException {
throw new UnsupportedOperationException("PrincipalTag Not supported yet.");
}
}

View File

@ -1,134 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
Copyright 2019 Joern Muehlencord (joern@muehlencord.de).
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<facelet-taglib version="2.2"
xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-facelettaglibrary_2_2.xsd">
<namespace>http://shiro.apache.org/tags</namespace>
<tags>
<tag>
<tag-name>authenticated</tag-name>
<handler-class>de.muehlencord.shirofaces.tags.AuthenticatedTag</handler-class>
<description>Displays body content only if the current user has successfully authenticated
_during their current session_. It is more restrictive than the 'user' tag.
It is logically opposite to the 'notAuthenticated' tag.
</description>
</tag>
<tag>
<tag-name>guest</tag-name>
<handler-class>de.muehlencord.shirofaces.tags.GuestTag</handler-class>
<description>Displays body content only if the current Subject IS NOT known to the system, either
because they have not logged in or they have no corresponding 'RememberMe' identity. It is logically
opposite to the 'user' tag.
</description>
</tag>
<tag>
<tag-name>hasAnyPermission</tag-name>
<handler-class>de.muehlencord.shirofaces.tags.HasAnyPermissionTag</handler-class>
<description>Displays body content only if the current user has one of the specified permissions from a comma-separated list of permissions.</description>
<attribute>
<description>comma-separated list of permissions to check for</description>
<name>name</name>
<required>true</required>
</attribute>
</tag>
<tag>
<tag-name>hasAnyRoles</tag-name>
<handler-class>de.muehlencord.shirofaces.tags.HasAnyRolesTag</handler-class>
<description>Displays body content only if the current user has one of the specified roles from a comma-separated list of role names.</description>
<attribute>
<description>comma-separated list of roles to check for</description>
<name>name</name>
<required>true</required>
</attribute>
</tag>
<tag>
<tag-name>hasPermission</tag-name>
<handler-class>de.muehlencord.shirofaces.tags.HasPermissionTag</handler-class>
<description>Displays body content only if the current user the given permission.</description>
<attribute>
<description>the permission to check for</description>
<name>name</name>
<required>true</required>
</attribute>
</tag>
<tag>
<tag-name>hasRole</tag-name>
<handler-class>de.muehlencord.shirofaces.tags.HasRoleTag</handler-class>
<description>Displays body content only if the current user has the given role.</description>
<attribute>
<description>the role to check for</description>
<name>name</name>
<required>true</required>
</attribute>
</tag>
<tag>
<tag-name>lacksPermission</tag-name>
<handler-class>de.muehlencord.shirofaces.tags.LacksPermissionTag</handler-class>
<description>Displays body content only if the current user has NOT the given permission.</description>
<attribute>
<description>the permission to check for</description>
<name>name</name>
<required>true</required>
</attribute>
</tag>
<tag>
<tag-name>lacksRole</tag-name>
<handler-class>de.muehlencord.shirofaces.tags.LacksRoleTag</handler-class>
<description>Displays body content only if the current user has NOT the given role.</description>
<attribute>
<description>the role to check for</description>
<name>name</name>
<required>true</required>
</attribute>
</tag>
<tag>
<tag-name>notAuthenticated</tag-name>
<handler-class>de.muehlencord.shirofaces.tags.NotAuthenticatedTag</handler-class>
<description>Displays body content only if the current user has NOT succesfully authenticated
_during their current session_. It is logically opposite to the 'authenticated' tag.
</description>
</tag>
<tag>
<tag-name>user</tag-name>
<handler-class>de.muehlencord.shirofaces.tags.UserTag</handler-class>
<description>Displays body content only if the current Subject has a known identity, either
from a previous login or from 'RememberMe' services. Note that this is semantically different
from the 'authenticated' tag, which is more restrictive. It is logically
opposite to the 'guest' tag.
</description>
</tag>
</tags>
</facelet-taglib>

View File

@ -26,7 +26,7 @@ limitations under the License.
<parent> <parent>
<artifactId>shared</artifactId> <artifactId>shared</artifactId>
<groupId>de.muehlencord</groupId> <groupId>de.muehlencord</groupId>
<version>1.3.0</version> <version>2.0.1-SNAPSHOT</version>
</parent> </parent>