From d028eb22611025a2a7007f3614e56d7ba210004d Mon Sep 17 00:00:00 2001 From: Edouard DUPIN Date: Sun, 26 Jan 2025 23:38:48 +0100 Subject: [PATCH] Manage correct rights --- .../filter/AuthenticationFilter.java | 3 +- .../archidata/filter/MySecurityContext.java | 16 ++--- src/org/kar/archidata/filter/PartRight.java | 23 +++++++ .../kar/archidata/filter/RightSafeCaster.java | 61 +++++++++++++++++++ src/org/kar/archidata/model/UserByToken.java | 11 ++-- 5 files changed, 97 insertions(+), 17 deletions(-) create mode 100644 src/org/kar/archidata/filter/RightSafeCaster.java diff --git a/src/org/kar/archidata/filter/AuthenticationFilter.java b/src/org/kar/archidata/filter/AuthenticationFilter.java index 8c822b5..5c35d2b 100644 --- a/src/org/kar/archidata/filter/AuthenticationFilter.java +++ b/src/org/kar/archidata/filter/AuthenticationFilter.java @@ -4,7 +4,6 @@ import java.io.IOException; import java.lang.reflect.Method; import java.util.Arrays; import java.util.List; -import java.util.Map; import java.util.Map.Entry; // https://stackoverflow.com/questions/26777083/best-practice-for-rest-token-based-authentication-with-jax-rs-and-jersey // https://stackoverflow.com/questions/26777083/best-practice-for-rest-token-based-authentication-with-jax-rs-and-jersey/45814178#45814178 @@ -246,7 +245,7 @@ public class AuthenticationFilter implements ContainerRequestFilter { final Object rowRight = ret.getClaim("right"); if (rowRight != null) { LOGGER.info("Detect right in Authentication Filter: {}", rowRight); - user.right = (Map>) ret.getClaim("right"); + user.right = RightSafeCaster.safeCastAndTransform(ret.getClaim("right")); /* if (rights.containsKey(this.applicationName)) { user.right = rights.get(this.applicationName); diff --git a/src/org/kar/archidata/filter/MySecurityContext.java b/src/org/kar/archidata/filter/MySecurityContext.java index ee15ecf..086ab25 100644 --- a/src/org/kar/archidata/filter/MySecurityContext.java +++ b/src/org/kar/archidata/filter/MySecurityContext.java @@ -26,7 +26,7 @@ public class MySecurityContext implements SecurityContext { return this.contextPrincipale; } - public Object getRightOfRoleInGroup(final String group, final String role) { + public PartRight getRightOfRoleInGroup(final String group, final String role) { if (this.contextPrincipale.userByToken != null) { return this.contextPrincipale.userByToken.getRight(group, role); } @@ -67,21 +67,15 @@ public class MySecurityContext implements SecurityContext { return false; } // get associated Roles: - final Object rightPart = getRightOfRoleInGroup(group, role); + final PartRight rightPart = getRightOfRoleInGroup(group, role); LOGGER.info("detect : {}", rightPart); - long dataRight = 0; - if (rightPart instanceof final Long rightPartCasted) { - dataRight = rightPartCasted; - } else if (rightPart instanceof final Integer rightPartCasted) { - dataRight = rightPartCasted; - } - if (dataRight == PartRight.READ_WRITE.getValue()) { + if (PartRight.READ_WRITE.equals(rightPart)) { return true; } - if (!needRead && needWrite && dataRight == PartRight.WRITE.getValue()) { + if (!needRead && needWrite && PartRight.WRITE.equals(rightPart)) { return true; } - if (needRead && !needWrite && dataRight == PartRight.READ.getValue()) { + if (needRead && !needWrite && PartRight.READ.equals(rightPart)) { return true; } return false; diff --git a/src/org/kar/archidata/filter/PartRight.java b/src/org/kar/archidata/filter/PartRight.java index d5aa929..0e5948c 100644 --- a/src/org/kar/archidata/filter/PartRight.java +++ b/src/org/kar/archidata/filter/PartRight.java @@ -27,4 +27,27 @@ public enum PartRight { } throw new IllegalArgumentException("PartRight: Unknown value: " + value); } + + public static PartRight fromValue(final long value) { + for (final PartRight element : values()) { + if (element.getValue() == value) { + return element; + } + } + throw new IllegalArgumentException("PartRight: Unknown value: " + value); + } + + public static PartRight fromString(final String value) { + if (value == null) { + throw new IllegalArgumentException("La chaîne ne peut pas être nulle"); + } + + return switch (value.toUpperCase()) { + case "NONE" -> NONE; + case "READ" -> READ; + case "WRITE" -> WRITE; + case "READ_WRITE" -> READ_WRITE; + default -> throw new IllegalArgumentException("Valeur inconnue pour PartRight : " + value); + }; + } } diff --git a/src/org/kar/archidata/filter/RightSafeCaster.java b/src/org/kar/archidata/filter/RightSafeCaster.java new file mode 100644 index 0000000..65bafdc --- /dev/null +++ b/src/org/kar/archidata/filter/RightSafeCaster.java @@ -0,0 +1,61 @@ +package org.kar.archidata.filter; + +import java.util.Map; + +public class RightSafeCaster { + + @SuppressWarnings("unchecked") + public static Map> safeCastAndTransform(final Object obj) { + if (!(obj instanceof Map)) { + throw new IllegalArgumentException("L'objet n'est pas un Map"); + } + + final Map outerMap = (Map) obj; + + // Résultat final après vérification et transformation + final Map> resultMap = new java.util.HashMap<>(); + + for (final Map.Entry outerEntry : outerMap.entrySet()) { + if (!(outerEntry.getKey() instanceof String)) { + throw new IllegalArgumentException("Une clé du Map externe n'est pas de type String"); + } + + if (!(outerEntry.getValue() instanceof Map)) { + throw new IllegalArgumentException("Une valeur du Map externe n'est pas un Map"); + } + + final String outerKey = (String) outerEntry.getKey(); + final Map innerMap = (Map) outerEntry.getValue(); + + final Map transformedInnerMap = new java.util.HashMap<>(); + + for (final Map.Entry innerEntry : innerMap.entrySet()) { + if (!(innerEntry.getKey() instanceof String)) { + throw new IllegalArgumentException("Une clé du Map interne n'est pas de type String"); + } + + final String innerKey = (String) innerEntry.getKey(); + final Object value = innerEntry.getValue(); + + PartRight partRight; + if (value instanceof PartRight) { + partRight = (PartRight) value; + } else if (value instanceof final Integer valueCasted) { + partRight = PartRight.fromValue(valueCasted); + } else if (value instanceof final Long valueCasted) { + partRight = PartRight.fromValue(valueCasted); + } else if (value instanceof final String valueCasted) { + partRight = PartRight.fromString(valueCasted); + } else { + throw new IllegalArgumentException("The Map Value is neither PartRight nor String nor Integer"); + } + + transformedInnerMap.put(innerKey, partRight); + } + + resultMap.put(outerKey, transformedInnerMap); + } + + return resultMap; + } +} diff --git a/src/org/kar/archidata/model/UserByToken.java b/src/org/kar/archidata/model/UserByToken.java index 560d2db..d94f615 100644 --- a/src/org/kar/archidata/model/UserByToken.java +++ b/src/org/kar/archidata/model/UserByToken.java @@ -4,6 +4,8 @@ import java.util.HashMap; import java.util.Map; import java.util.Set; +import org.kar.archidata.filter.PartRight; + public class UserByToken { public static final int TYPE_USER = -1; public static final int TYPE_APPLICATION = -2; @@ -11,10 +13,11 @@ public class UserByToken { public Integer type = null; public Long id = null; - public Long parentId = null; // FOr application, this is the id of the application, and of user token, this is the USERID + // For application, this is the id of the application, and of user token, this is the USERID + public Long parentId = null; public String name = null; // Right map - public Map> right = new HashMap<>(); + public Map> right = new HashMap<>(); public Set getGroups() { return this.right.keySet(); @@ -27,11 +30,11 @@ public class UserByToken { return this.right.containsKey(group); } - public Object getRight(final String group, final String key) { + public PartRight getRight(final String group, final String key) { if (!this.right.containsKey(group)) { return null; } - final Map rightGroup = this.right.get(group); + final Map rightGroup = this.right.get(group); if (!rightGroup.containsKey(key)) { return null; }