Repository: syncope
Updated Branches:
  refs/heads/2_0_X d1e14c106 -> d9105ee8a
  refs/heads/master 3fc8bf3ef -> a5311460f


[SYNCOPE-1088] Storing Spring Security authorities with AccessToken entities 
(not for admin)


Project: http://git-wip-us.apache.org/repos/asf/syncope/repo
Commit: http://git-wip-us.apache.org/repos/asf/syncope/commit/a5311460
Tree: http://git-wip-us.apache.org/repos/asf/syncope/tree/a5311460
Diff: http://git-wip-us.apache.org/repos/asf/syncope/diff/a5311460

Branch: refs/heads/master
Commit: a5311460f81e50852978fa6823905b10d36700c6
Parents: 3fc8bf3
Author: Francesco Chicchiriccò <[email protected]>
Authored: Mon May 22 13:23:46 2017 +0200
Committer: Francesco Chicchiriccò <[email protected]>
Committed: Mon May 22 13:24:01 2017 +0200

----------------------------------------------------------------------
 .../client/console/SyncopeConsoleSession.java   |  4 +-
 .../client/enduser/SyncopeEnduserSession.java   |  2 +-
 .../apache/syncope/core/logic/AnyTypeLogic.java | 16 +---
 .../persistence/api/entity/AccessToken.java     |  4 +
 .../persistence/jpa/entity/JPAAccessToken.java  | 14 +++
 .../core/persistence/jpa/entity/JPADomain.java  |  4 +-
 .../persistence/jpa/entity/user/JPAUser.java    |  8 +-
 .../core/provisioning/api/AuditManager.java     |  2 +-
 .../provisioning/api/EntitlementsHolder.java    | 14 ++-
 .../api/data/AnyTypeDataBinder.java             |  2 +
 .../java/data/AccessTokenDataBinderImpl.java    | 34 ++++++++
 .../java/data/AnyTypeDataBinderImpl.java        | 89 ++++++++++++++++++++
 .../java/data/UserDataBinderImpl.java           |  6 +-
 .../core/spring/security/AuthContextUtils.java  | 18 ++++
 .../core/spring/security/AuthDataAccessor.java  | 25 +++++-
 .../UsernamePasswordAuthenticationProvider.java |  8 +-
 16 files changed, 219 insertions(+), 31 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/syncope/blob/a5311460/client/console/src/main/java/org/apache/syncope/client/console/SyncopeConsoleSession.java
----------------------------------------------------------------------
diff --git 
a/client/console/src/main/java/org/apache/syncope/client/console/SyncopeConsoleSession.java
 
b/client/console/src/main/java/org/apache/syncope/client/console/SyncopeConsoleSession.java
index 2fbefe2..3d3daf8 100644
--- 
a/client/console/src/main/java/org/apache/syncope/client/console/SyncopeConsoleSession.java
+++ 
b/client/console/src/main/java/org/apache/syncope/client/console/SyncopeConsoleSession.java
@@ -143,8 +143,8 @@ public class SyncopeConsoleSession extends 
AuthenticatedWebSession {
 
     private void afterAuthentication() {
         Pair<Map<String, Set<String>>, UserTO> self = client.self();
-        auth = self.getKey();
-        selfTO = self.getValue();
+        auth = self.getLeft();
+        selfTO = self.getRight();
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/syncope/blob/a5311460/client/enduser/src/main/java/org/apache/syncope/client/enduser/SyncopeEnduserSession.java
----------------------------------------------------------------------
diff --git 
a/client/enduser/src/main/java/org/apache/syncope/client/enduser/SyncopeEnduserSession.java
 
b/client/enduser/src/main/java/org/apache/syncope/client/enduser/SyncopeEnduserSession.java
index 8268ef5..cd94d0c 100644
--- 
a/client/enduser/src/main/java/org/apache/syncope/client/enduser/SyncopeEnduserSession.java
+++ 
b/client/enduser/src/main/java/org/apache/syncope/client/enduser/SyncopeEnduserSession.java
@@ -101,7 +101,7 @@ public class SyncopeEnduserSession extends WebSession {
 
     private void afterAuthentication() {
         Pair<Map<String, Set<String>>, UserTO> self = client.self();
-        selfTO = self.getValue();
+        selfTO = self.getRight();
 
         // bind explicitly this session to have a stateful behavior during 
http requests, unless session will
         // expire for every request

http://git-wip-us.apache.org/repos/asf/syncope/blob/a5311460/core/logic/src/main/java/org/apache/syncope/core/logic/AnyTypeLogic.java
----------------------------------------------------------------------
diff --git 
a/core/logic/src/main/java/org/apache/syncope/core/logic/AnyTypeLogic.java 
b/core/logic/src/main/java/org/apache/syncope/core/logic/AnyTypeLogic.java
index 2a5e89b..b21ab45 100644
--- a/core/logic/src/main/java/org/apache/syncope/core/logic/AnyTypeLogic.java
+++ b/core/logic/src/main/java/org/apache/syncope/core/logic/AnyTypeLogic.java
@@ -29,7 +29,6 @@ import org.apache.syncope.common.lib.SyncopeClientException;
 import org.apache.syncope.common.lib.to.AnyTypeTO;
 import org.apache.syncope.common.lib.types.ClientExceptionType;
 import org.apache.syncope.common.lib.types.StandardEntitlement;
-import org.apache.syncope.core.provisioning.api.EntitlementsHolder;
 import org.apache.syncope.core.persistence.api.dao.NotFoundException;
 import org.apache.syncope.core.persistence.api.dao.AnyTypeDAO;
 import org.apache.syncope.core.persistence.api.dao.DuplicateException;
@@ -82,9 +81,7 @@ public class AnyTypeLogic extends 
AbstractTransactionalLogic<AnyTypeTO> {
             throw new DuplicateException(anyTypeTO.getKey());
         }
 
-        AnyTypeTO result = 
binder.getAnyTypeTO(anyTypeDAO.save(binder.create(anyTypeTO)));
-        EntitlementsHolder.getInstance().addFor(result.getKey());
-        return result;
+        return binder.getAnyTypeTO(anyTypeDAO.save(binder.create(anyTypeTO)));
     }
 
     @PreAuthorize("hasRole('" + StandardEntitlement.ANYTYPE_UPDATE + "')")
@@ -95,14 +92,10 @@ public class AnyTypeLogic extends 
AbstractTransactionalLogic<AnyTypeTO> {
             throw new NotFoundException(anyTypeTO.getKey());
         }
 
-        EntitlementsHolder.getInstance().removeFor(anyTypeTO.getKey());
-
         binder.update(anyType, anyTypeTO);
         anyType = anyTypeDAO.save(anyType);
 
-        AnyTypeTO result = binder.getAnyTypeTO(anyType);
-        EntitlementsHolder.getInstance().addFor(result.getKey());
-        return result;
+        return binder.getAnyTypeTO(anyTypeDAO.save(anyType));
     }
 
     @PreAuthorize("hasRole('" + StandardEntitlement.ANYTYPE_DELETE + "')")
@@ -114,16 +107,13 @@ public class AnyTypeLogic extends 
AbstractTransactionalLogic<AnyTypeTO> {
             throw new NotFoundException(key);
         }
 
-        AnyTypeTO deleted = binder.getAnyTypeTO(anyType);
         try {
-            anyTypeDAO.delete(key);
-            EntitlementsHolder.getInstance().removeFor(deleted.getKey());
+            return binder.delete(anyType);
         } catch (IllegalArgumentException e) {
             SyncopeClientException sce = 
SyncopeClientException.build(ClientExceptionType.InvalidAnyType);
             sce.getElements().add(e.getMessage());
             throw sce;
         }
-        return deleted;
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/syncope/blob/a5311460/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/AccessToken.java
----------------------------------------------------------------------
diff --git 
a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/AccessToken.java
 
b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/AccessToken.java
index e08e9e3..ee68d6c 100644
--- 
a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/AccessToken.java
+++ 
b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/AccessToken.java
@@ -33,4 +33,8 @@ public interface AccessToken extends ProvidedKeyEntity {
     String getOwner();
 
     void setOwner(String owner);
+
+    byte[] getAuthorities();
+
+    void setAuthorities(byte[] authorities);
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/a5311460/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAAccessToken.java
----------------------------------------------------------------------
diff --git 
a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAAccessToken.java
 
b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAAccessToken.java
index 05464d6..4ddaed1 100644
--- 
a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAAccessToken.java
+++ 
b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAAccessToken.java
@@ -26,6 +26,7 @@ import javax.persistence.Lob;
 import javax.persistence.Table;
 import javax.persistence.Temporal;
 import javax.persistence.TemporalType;
+import org.apache.commons.lang3.ArrayUtils;
 import org.apache.syncope.core.persistence.api.entity.AccessToken;
 
 @Entity
@@ -46,6 +47,9 @@ public class JPAAccessToken extends AbstractProvidedKeyEntity 
implements AccessT
     @Column(nullable = true)
     private String owner;
 
+    @Lob
+    private byte[] authorities;
+
     @Override
     public String getBody() {
         return body;
@@ -80,4 +84,14 @@ public class JPAAccessToken extends 
AbstractProvidedKeyEntity implements AccessT
         this.owner = owner;
     }
 
+    @Override
+    public byte[] getAuthorities() {
+        return authorities;
+    }
+
+    @Override
+    public void setAuthorities(final byte[] authorities) {
+        this.authorities = ArrayUtils.clone(authorities);
+    }
+
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/a5311460/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPADomain.java
----------------------------------------------------------------------
diff --git 
a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPADomain.java
 
b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPADomain.java
index 5e6a80f..7e0c456 100644
--- 
a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPADomain.java
+++ 
b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPADomain.java
@@ -36,6 +36,8 @@ public class JPADomain extends AbstractProvidedKeyEntity 
implements Domain {
 
     public static final String TABLE = "SyncopeDomain";
 
+    private static final Encryptor ENCRYPTOR = Encryptor.getInstance();
+
     private String adminPwd;
 
     @Enumerated(EnumType.STRING)
@@ -54,7 +56,7 @@ public class JPADomain extends AbstractProvidedKeyEntity 
implements Domain {
     @Override
     public void setPassword(final String password, final CipherAlgorithm 
cipherAlgoritm) {
         try {
-            this.adminPwd = Encryptor.getInstance().encode(password, 
cipherAlgoritm);
+            this.adminPwd = ENCRYPTOR.encode(password, cipherAlgoritm);
             this.adminCipherAlgorithm = cipherAlgoritm;
         } catch (Exception e) {
             LOG.error("Could not encode password", e);

http://git-wip-us.apache.org/repos/asf/syncope/blob/a5311460/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPAUser.java
----------------------------------------------------------------------
diff --git 
a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPAUser.java
 
b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPAUser.java
index ba1544d..0dddb77 100644
--- 
a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPAUser.java
+++ 
b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPAUser.java
@@ -78,6 +78,8 @@ public class JPAUser
 
     public static final String TABLE = "SyncopeUser";
 
+    private static final Encryptor ENCRYPTOR = Encryptor.getInstance();
+
     @Column(nullable = true)
     private String password;
 
@@ -256,7 +258,7 @@ public class JPAUser
         this.clearPassword = password;
 
         try {
-            this.password = Encryptor.getInstance().encode(password, 
cipherAlgoritm);
+            this.password = ENCRYPTOR.encode(password, cipherAlgoritm);
             this.cipherAlgorithm = cipherAlgoritm;
         } catch (Exception e) {
             LOG.error("Could not encode password", e);
@@ -460,8 +462,8 @@ public class JPAUser
                 res = passwordHistory.subList(size >= passwordHistory.size()
                         ? 0
                         : passwordHistory.size() - size, 
passwordHistory.size()).contains(cipherAlgorithm == null
-                                ? password
-                                : Encryptor.getInstance().encode(password, 
cipherAlgorithm));
+                        ? password
+                        : ENCRYPTOR.encode(password, cipherAlgorithm));
             } catch (Exception e) {
                 LOG.error("Error evaluating password history", e);
             }

http://git-wip-us.apache.org/repos/asf/syncope/blob/a5311460/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/AuditManager.java
----------------------------------------------------------------------
diff --git 
a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/AuditManager.java
 
b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/AuditManager.java
index 333d415..64c03e9 100644
--- 
a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/AuditManager.java
+++ 
b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/AuditManager.java
@@ -45,7 +45,7 @@ public interface AuditManager {
      * @param subcategory event subcategory
      * @param event event
      * @param condition result value condition.
-     * @param before object(s) availabile before the event
+     * @param before object(s) available before the event
      * @param output object(s) produced by the event
      * @param input object(s) provided to the event
      */

http://git-wip-us.apache.org/repos/asf/syncope/blob/a5311460/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/EntitlementsHolder.java
----------------------------------------------------------------------
diff --git 
a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/EntitlementsHolder.java
 
b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/EntitlementsHolder.java
index 53a86f5..bb7eab8 100644
--- 
a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/EntitlementsHolder.java
+++ 
b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/EntitlementsHolder.java
@@ -50,16 +50,26 @@ public final class EntitlementsHolder {
         this.values.addAll(values);
     }
 
-    public void addFor(final String anyType) {
+    public Set<String> addFor(final String anyType) {
+        Set<String> added = new HashSet<>();
+
         for (AnyEntitlement operation : AnyEntitlement.values()) {
             this.values.add(operation.getFor(anyType));
+            added.add(operation.getFor(anyType));
         }
+
+        return added;
     }
 
-    public void removeFor(final String anyType) {
+    public Set<String> removeFor(final String anyType) {
+        Set<String> removed = new HashSet<>();
+
         for (AnyEntitlement operation : AnyEntitlement.values()) {
             this.values.remove(operation.getFor(anyType));
+            removed.add(operation.getFor(anyType));
         }
+
+        return removed;
     }
 
     public Set<String> getValues() {

http://git-wip-us.apache.org/repos/asf/syncope/blob/a5311460/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/data/AnyTypeDataBinder.java
----------------------------------------------------------------------
diff --git 
a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/data/AnyTypeDataBinder.java
 
b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/data/AnyTypeDataBinder.java
index c29c2ac..e644121 100644
--- 
a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/data/AnyTypeDataBinder.java
+++ 
b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/data/AnyTypeDataBinder.java
@@ -27,5 +27,7 @@ public interface AnyTypeDataBinder {
 
     void update(AnyType anyType, AnyTypeTO anyTypeTO);
 
+    AnyTypeTO delete(AnyType anyType);
+
     AnyTypeTO getAnyTypeTO(AnyType anyType);
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/a5311460/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AccessTokenDataBinderImpl.java
----------------------------------------------------------------------
diff --git 
a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AccessTokenDataBinderImpl.java
 
b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AccessTokenDataBinderImpl.java
index b278e30..6bca7e0 100644
--- 
a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AccessTokenDataBinderImpl.java
+++ 
b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AccessTokenDataBinderImpl.java
@@ -34,24 +34,37 @@ import 
org.apache.cxf.rs.security.jose.jws.JwsSignatureProvider;
 import org.apache.cxf.rs.security.jose.jwt.JwtClaims;
 import org.apache.cxf.rs.security.jose.jwt.JwtToken;
 import org.apache.syncope.common.lib.to.AccessTokenTO;
+import org.apache.syncope.common.lib.types.CipherAlgorithm;
 import org.apache.syncope.core.persistence.api.dao.AccessTokenDAO;
 import org.apache.syncope.core.persistence.api.dao.ConfDAO;
 import org.apache.syncope.core.persistence.api.entity.AccessToken;
 import org.apache.syncope.core.persistence.api.entity.EntityFactory;
 import org.apache.syncope.core.provisioning.api.data.AccessTokenDataBinder;
+import org.apache.syncope.core.provisioning.api.serialization.POJOHelper;
 import org.apache.syncope.core.spring.BeanUtils;
+import org.apache.syncope.core.spring.security.AuthContextUtils;
+import org.apache.syncope.core.spring.security.Encryptor;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Component;
 
 @Component
 public class AccessTokenDataBinderImpl implements AccessTokenDataBinder {
 
+    private static final Logger LOG = 
LoggerFactory.getLogger(AccessTokenDataBinder.class);
+
+    private static final Encryptor ENCRYPTOR = Encryptor.getInstance();
+
     private static final String[] IGNORE_PROPERTIES = { "owner" };
 
     private static final RandomBasedGenerator UUID_GENERATOR = 
Generators.randomBasedGenerator();
 
     private static final JwsHeaders JWS_HEADERS = new JwsHeaders(JoseType.JWT, 
SignatureAlgorithm.HS512);
 
+    @Resource(name = "adminUser")
+    private String adminUser;
+
     @Resource(name = "jwtIssuer")
     private String jwtIssuer;
 
@@ -118,6 +131,17 @@ public class AccessTokenDataBinderImpl implements 
AccessTokenDataBinder {
             accessToken.setBody(body);
             accessToken.setExpiryTime(created.getRight());
             accessToken.setOwner(subject);
+
+            if (!adminUser.equals(accessToken.getOwner())) {
+                try {
+                    accessToken.setAuthorities(ENCRYPTOR.encode(
+                            
POJOHelper.serialize(AuthContextUtils.getAuthorities()), CipherAlgorithm.AES).
+                            getBytes());
+                } catch (Exception e) {
+                    LOG.error("Could not store authorities", e);
+                }
+            }
+
             accessTokenDAO.save(accessToken);
         }
 
@@ -147,6 +171,16 @@ public class AccessTokenDataBinderImpl implements 
AccessTokenDataBinder {
         accessToken.setBody(body);
         accessToken.setExpiryTime(expiry.getTime());
 
+        if (!adminUser.equals(accessToken.getOwner())) {
+            try {
+                accessToken.setAuthorities(ENCRYPTOR.encode(
+                        
POJOHelper.serialize(AuthContextUtils.getAuthorities()), CipherAlgorithm.AES).
+                        getBytes());
+            } catch (Exception e) {
+                LOG.error("Could not store authorities", e);
+            }
+        }
+
         accessTokenDAO.save(accessToken);
 
         return body;

http://git-wip-us.apache.org/repos/asf/syncope/blob/a5311460/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AnyTypeDataBinderImpl.java
----------------------------------------------------------------------
diff --git 
a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AnyTypeDataBinderImpl.java
 
b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AnyTypeDataBinderImpl.java
index f74efbc..84d9bd9 100644
--- 
a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AnyTypeDataBinderImpl.java
+++ 
b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AnyTypeDataBinderImpl.java
@@ -18,15 +18,31 @@
  */
 package org.apache.syncope.core.provisioning.java.data;
 
+import com.fasterxml.jackson.core.type.TypeReference;
+import java.util.HashSet;
+import java.util.Set;
+import javax.annotation.Resource;
+import org.apache.commons.collections4.CollectionUtils;
+import org.apache.commons.collections4.Predicate;
 import org.apache.syncope.common.lib.SyncopeClientException;
+import org.apache.syncope.common.lib.SyncopeConstants;
 import org.apache.syncope.common.lib.to.AnyTypeTO;
 import org.apache.syncope.common.lib.types.AnyTypeKind;
+import org.apache.syncope.common.lib.types.CipherAlgorithm;
 import org.apache.syncope.common.lib.types.ClientExceptionType;
+import org.apache.syncope.core.persistence.api.dao.AccessTokenDAO;
 import org.apache.syncope.core.persistence.api.dao.AnyTypeClassDAO;
+import org.apache.syncope.core.persistence.api.dao.AnyTypeDAO;
+import org.apache.syncope.core.persistence.api.entity.AccessToken;
 import org.apache.syncope.core.persistence.api.entity.EntityFactory;
 import org.apache.syncope.core.persistence.api.entity.AnyType;
 import org.apache.syncope.core.persistence.api.entity.AnyTypeClass;
+import org.apache.syncope.core.provisioning.api.EntitlementsHolder;
 import org.apache.syncope.core.provisioning.api.data.AnyTypeDataBinder;
+import org.apache.syncope.core.provisioning.api.serialization.POJOHelper;
+import org.apache.syncope.core.spring.security.AuthContextUtils;
+import org.apache.syncope.core.spring.security.Encryptor;
+import org.apache.syncope.core.spring.security.SyncopeGrantedAuthority;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -37,16 +53,52 @@ public class AnyTypeDataBinderImpl implements 
AnyTypeDataBinder {
 
     private static final Logger LOG = 
LoggerFactory.getLogger(AnyTypeDataBinder.class);
 
+    private static final Encryptor ENCRYPTOR = Encryptor.getInstance();
+
+    @Resource(name = "adminUser")
+    private String adminUser;
+
+    @Autowired
+    private AnyTypeDAO anyTypeDAO;
+
     @Autowired
     private AnyTypeClassDAO anyTypeClassDAO;
 
     @Autowired
+    private AccessTokenDAO accessTokenDAO;
+
+    @Autowired
     private EntityFactory entityFactory;
 
     @Override
     public AnyType create(final AnyTypeTO anyTypeTO) {
         AnyType anyType = entityFactory.newEntity(AnyType.class);
         update(anyType, anyTypeTO);
+
+        Set<String> added = 
EntitlementsHolder.getInstance().addFor(anyType.getKey());
+
+        if (!adminUser.equals(AuthContextUtils.getUsername())) {
+            AccessToken accessToken = 
accessTokenDAO.findByOwner(AuthContextUtils.getUsername());
+            try {
+                Set<SyncopeGrantedAuthority> authorities = new 
HashSet<>(POJOHelper.deserialize(
+                        ENCRYPTOR.decode(new 
String(accessToken.getAuthorities()), CipherAlgorithm.AES),
+                        new TypeReference<Set<SyncopeGrantedAuthority>>() {
+                }));
+
+                for (String entitlement : added) {
+                    authorities.add(new SyncopeGrantedAuthority(entitlement, 
SyncopeConstants.ROOT_REALM));
+                }
+
+                accessToken.setAuthorities(ENCRYPTOR.encode(
+                        POJOHelper.serialize(authorities), 
CipherAlgorithm.AES).
+                        getBytes());
+
+                accessTokenDAO.save(accessToken);
+            } catch (Exception e) {
+                LOG.error("Could not fetch or store authorities", e);
+            }
+        }
+
         return anyType;
     }
 
@@ -76,6 +128,43 @@ public class AnyTypeDataBinderImpl implements 
AnyTypeDataBinder {
     }
 
     @Override
+    public AnyTypeTO delete(final AnyType anyType) {
+        AnyTypeTO deleted = getAnyTypeTO(anyType);
+
+        anyTypeDAO.delete(anyType.getKey());
+
+        final Set<String> removed = 
EntitlementsHolder.getInstance().removeFor(deleted.getKey());
+
+        if (!adminUser.equals(AuthContextUtils.getUsername())) {
+            AccessToken accessToken = 
accessTokenDAO.findByOwner(AuthContextUtils.getUsername());
+            try {
+                Set<SyncopeGrantedAuthority> authorities = new 
HashSet<>(POJOHelper.deserialize(
+                        ENCRYPTOR.decode(new 
String(accessToken.getAuthorities()), CipherAlgorithm.AES),
+                        new TypeReference<Set<SyncopeGrantedAuthority>>() {
+                }));
+
+                CollectionUtils.filterInverse(authorities, new 
Predicate<SyncopeGrantedAuthority>() {
+
+                    @Override
+                    public boolean evaluate(final SyncopeGrantedAuthority 
authority) {
+                        return removed.contains(authority.getAuthority());
+                    }
+                });
+
+                accessToken.setAuthorities(ENCRYPTOR.encode(
+                        POJOHelper.serialize(authorities), 
CipherAlgorithm.AES).
+                        getBytes());
+
+                accessTokenDAO.save(accessToken);
+            } catch (Exception e) {
+                LOG.error("Could not fetch or store authorities", e);
+            }
+        }
+
+        return deleted;
+    }
+
+    @Override
     public AnyTypeTO getAnyTypeTO(final AnyType anyType) {
         AnyTypeTO anyTypeTO = new AnyTypeTO();
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/a5311460/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/UserDataBinderImpl.java
----------------------------------------------------------------------
diff --git 
a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/UserDataBinderImpl.java
 
b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/UserDataBinderImpl.java
index 2ba5d85..647e850 100644
--- 
a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/UserDataBinderImpl.java
+++ 
b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/UserDataBinderImpl.java
@@ -89,6 +89,8 @@ public class UserDataBinderImpl extends AbstractAnyDataBinder 
implements UserDat
         "plainAttrs", "derAttrs", "virAttrs", "resources", "securityQuestion", 
"securityAnswer"
     };
 
+    private static final Encryptor ENCRYPTOR = Encryptor.getInstance();
+
     @Autowired
     private RoleDAO roleDAO;
 
@@ -110,8 +112,6 @@ public class UserDataBinderImpl extends 
AbstractAnyDataBinder implements UserDat
     @Resource(name = "anonymousUser")
     private String anonymousUser;
 
-    private final Encryptor encryptor = Encryptor.getInstance();
-
     @Transactional(readOnly = true)
     @Override
     public UserTO returnUserTO(final UserTO userTO) {
@@ -152,7 +152,7 @@ public class UserDataBinderImpl extends 
AbstractAnyDataBinder implements UserDat
     @Transactional(readOnly = true)
     @Override
     public boolean verifyPassword(final User user, final String password) {
-        return encryptor.verify(password, user.getCipherAlgorithm(), 
user.getPassword());
+        return ENCRYPTOR.verify(password, user.getCipherAlgorithm(), 
user.getPassword());
     }
 
     private void setPassword(final User user, final String password, final 
SyncopeClientCompositeException scce) {

http://git-wip-us.apache.org/repos/asf/syncope/blob/a5311460/core/spring/src/main/java/org/apache/syncope/core/spring/security/AuthContextUtils.java
----------------------------------------------------------------------
diff --git 
a/core/spring/src/main/java/org/apache/syncope/core/spring/security/AuthContextUtils.java
 
b/core/spring/src/main/java/org/apache/syncope/core/spring/security/AuthContextUtils.java
index 36e4188..cc0b4fd 100644
--- 
a/core/spring/src/main/java/org/apache/syncope/core/spring/security/AuthContextUtils.java
+++ 
b/core/spring/src/main/java/org/apache/syncope/core/spring/security/AuthContextUtils.java
@@ -19,7 +19,9 @@
 package org.apache.syncope.core.spring.security;
 
 import java.util.ArrayList;
+import java.util.Collections;
 import java.util.HashMap;
+import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
@@ -63,6 +65,22 @@ public final class AuthContextUtils {
         SecurityContextHolder.getContext().setAuthentication(newAuth);
     }
 
+    public static Set<SyncopeGrantedAuthority> getAuthorities() {
+        SecurityContext ctx = SecurityContextHolder.getContext();
+        if (ctx != null && ctx.getAuthentication() != null && 
ctx.getAuthentication().getAuthorities() != null) {
+            Set<SyncopeGrantedAuthority> result = new HashSet<>();
+            for (GrantedAuthority authority : 
ctx.getAuthentication().getAuthorities()) {
+                if (authority instanceof SyncopeGrantedAuthority) {
+                    result.add(SyncopeGrantedAuthority.class.cast(authority));
+                }
+            }
+
+            return result;
+        }
+
+        return Collections.emptySet();
+    }
+
     public static Map<String, Set<String>> getAuthorizations() {
         Map<String, Set<String>> result = null;
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/a5311460/core/spring/src/main/java/org/apache/syncope/core/spring/security/AuthDataAccessor.java
----------------------------------------------------------------------
diff --git 
a/core/spring/src/main/java/org/apache/syncope/core/spring/security/AuthDataAccessor.java
 
b/core/spring/src/main/java/org/apache/syncope/core/spring/security/AuthDataAccessor.java
index b54d756..aba2e50 100644
--- 
a/core/spring/src/main/java/org/apache/syncope/core/spring/security/AuthDataAccessor.java
+++ 
b/core/spring/src/main/java/org/apache/syncope/core/spring/security/AuthDataAccessor.java
@@ -18,6 +18,7 @@
  */
 package org.apache.syncope.core.spring.security;
 
+import com.fasterxml.jackson.core.type.TypeReference;
 import java.util.Arrays;
 import java.util.Collections;
 import java.util.Date;
@@ -38,6 +39,7 @@ import org.apache.commons.lang3.tuple.Pair;
 import org.apache.syncope.common.lib.SyncopeConstants;
 import org.apache.syncope.common.lib.types.AnyTypeKind;
 import org.apache.syncope.common.lib.types.AuditElements;
+import org.apache.syncope.common.lib.types.CipherAlgorithm;
 import org.apache.syncope.common.lib.types.StandardEntitlement;
 import org.apache.syncope.core.persistence.api.dao.AccessTokenDAO;
 import org.apache.syncope.core.persistence.api.dao.AnySearchDAO;
@@ -62,6 +64,7 @@ import org.apache.syncope.core.provisioning.api.AuditManager;
 import org.apache.syncope.core.provisioning.api.ConnectorFactory;
 import org.apache.syncope.core.provisioning.api.EntitlementsHolder;
 import org.apache.syncope.core.provisioning.api.MappingManager;
+import org.apache.syncope.core.provisioning.api.serialization.POJOHelper;
 import org.identityconnectors.framework.common.objects.Uid;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -362,6 +365,7 @@ public class AuthDataAccessor {
         }
 
         Set<SyncopeGrantedAuthority> authorities;
+
         if (adminUser.equals(accessToken.getOwner())) {
             authorities = getAdminAuthorities();
         } else {
@@ -381,7 +385,26 @@ public class AuthDataAccessor {
                 throw new DisabledException("User " + user.getUsername() + " 
not allowed to authenticate");
             }
 
-            authorities = getUserAuthorities(user);
+            if (user.isMustChangePassword()) {
+                authorities = Collections.singleton(
+                        new 
SyncopeGrantedAuthority(StandardEntitlement.MUST_CHANGE_PASSWORD));
+            } else if (accessToken.getAuthorities() == null) {
+                LOG.debug("No authorities found in JWT, calculating...");
+
+                authorities = getUserAuthorities(user);
+            } else {
+                LOG.debug("Authorities found in JWT, fetching...");
+
+                try {
+                    authorities = POJOHelper.deserialize(
+                            ENCRYPTOR.decode(new 
String(accessToken.getAuthorities()), CipherAlgorithm.AES),
+                            new TypeReference<Set<SyncopeGrantedAuthority>>() {
+                    });
+                } catch (Exception e) {
+                    LOG.error("Could not read stored authorities", e);
+                    authorities = Collections.emptySet();
+                }
+            }
         }
 
         return authorities;

http://git-wip-us.apache.org/repos/asf/syncope/blob/a5311460/core/spring/src/main/java/org/apache/syncope/core/spring/security/UsernamePasswordAuthenticationProvider.java
----------------------------------------------------------------------
diff --git 
a/core/spring/src/main/java/org/apache/syncope/core/spring/security/UsernamePasswordAuthenticationProvider.java
 
b/core/spring/src/main/java/org/apache/syncope/core/spring/security/UsernamePasswordAuthenticationProvider.java
index 83a03c3..28cc970 100644
--- 
a/core/spring/src/main/java/org/apache/syncope/core/spring/security/UsernamePasswordAuthenticationProvider.java
+++ 
b/core/spring/src/main/java/org/apache/syncope/core/spring/security/UsernamePasswordAuthenticationProvider.java
@@ -42,6 +42,8 @@ public class UsernamePasswordAuthenticationProvider 
implements AuthenticationPro
 
     protected static final Logger LOG = 
LoggerFactory.getLogger(UsernamePasswordAuthenticationProvider.class);
 
+    protected static final Encryptor ENCRYPTOR = Encryptor.getInstance();
+
     @Autowired
     protected AuthDataAccessor dataAccessor;
 
@@ -63,8 +65,6 @@ public class UsernamePasswordAuthenticationProvider 
implements AuthenticationPro
     @Resource(name = "anonymousKey")
     protected String anonymousKey;
 
-    protected final Encryptor encryptor = Encryptor.getInstance();
-
     /**
      * @param adminPassword the adminPassword to set
      */
@@ -99,7 +99,7 @@ public class UsernamePasswordAuthenticationProvider 
implements AuthenticationPro
         } else if (adminUser.equals(authentication.getName())) {
             username[0] = adminUser;
             if (SyncopeConstants.MASTER_DOMAIN.equals(domainKey)) {
-                authenticated = encryptor.verify(
+                authenticated = ENCRYPTOR.verify(
                         authentication.getCredentials().toString(),
                         CipherAlgorithm.valueOf(adminPasswordAlgorithm),
                         adminPassword);
@@ -112,7 +112,7 @@ public class UsernamePasswordAuthenticationProvider 
implements AuthenticationPro
                     public Boolean exec() {
                         Domain domain = dataAccessor.findDomain(domainToFind);
 
-                        return encryptor.verify(
+                        return ENCRYPTOR.verify(
                                 authentication.getCredentials().toString(),
                                 domain.getAdminCipherAlgorithm(),
                                 domain.getAdminPwd());

Reply via email to