You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cxf.apache.org by se...@apache.org on 2017/03/20 11:10:22 UTC

cxf git commit: [CXF-7264, CXF-7286] JPA change userSubject pk to id and fixing PersistenceException on refreshAccessToken, patch from Adrian Gonzalez applied, This closes #246

Repository: cxf
Updated Branches:
  refs/heads/master 3bbfc22e1 -> 9d64bcedb


[CXF-7264,CXF-7286] JPA change userSubject pk to id and fixing PersistenceException on refreshAccessToken, patch from Adrian Gonzalez applied, This closes #246


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

Branch: refs/heads/master
Commit: 9d64bcedb508732cdc377312f0fb433ee1dc630e
Parents: 3bbfc22
Author: Sergey Beryozkin <sb...@gmail.com>
Authored: Mon Mar 20 11:09:59 2017 +0000
Committer: Sergey Beryozkin <sb...@gmail.com>
Committed: Mon Mar 20 11:09:59 2017 +0000

----------------------------------------------------------------------
 .../rs/security/oauth2/common/UserSubject.java  | 16 ++++++++---
 .../oauth2/grants/code/JPACodeDataProvider.java |  2 +-
 .../provider/AbstractOAuthDataProvider.java     |  6 ++--
 .../oauth2/provider/JPAOAuthDataProvider.java   | 16 ++++++-----
 .../provider/JPAOAuthDataProviderTest.java      | 30 ++++++++++++++++++++
 .../src/test/resources/META-INF/persistence.xml |  2 ++
 6 files changed, 58 insertions(+), 14 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cxf/blob/9d64bced/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/common/UserSubject.java
----------------------------------------------------------------------
diff --git a/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/common/UserSubject.java b/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/common/UserSubject.java
index 7621481..014c5f5 100644
--- a/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/common/UserSubject.java
+++ b/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/common/UserSubject.java
@@ -32,6 +32,9 @@ import javax.persistence.MapKeyColumn;
 import javax.persistence.OrderColumn;
 import javax.xml.bind.annotation.XmlRootElement;
 
+import org.apache.cxf.common.util.Base64UrlUtility;
+import org.apache.cxf.rt.security.crypto.CryptoUtils;
+
 /**
  * Represents a login name which AuthorizationService
  * may capture after the end user approved a given third party request
@@ -49,26 +52,28 @@ public class UserSubject implements Serializable {
     private AuthenticationMethod am;
 
     public UserSubject() {
-
+        this.id = newId();
     }
 
     public UserSubject(String login) {
+        this();
         this.login = login;
     }
 
     public UserSubject(String login, List<String> roles) {
+        this();
         this.login = login;
         this.roles = roles;
     }
 
     public UserSubject(String login, String id) {
         this.login = login;
-        this.id = id;
+        this.id = id != null ? id : newId();
     }
 
     public UserSubject(String login, String id, List<String> roles) {
         this.login = login;
-        this.id = id;
+        this.id = id != null ? id : newId();
         this.roles = roles;
     }
 
@@ -76,7 +81,10 @@ public class UserSubject implements Serializable {
         this(sub.getLogin(), sub.getId(), sub.getRoles());
         this.properties = sub.getProperties();
         this.am = sub.getAuthenticationMethod();
+    }
 
+    private String newId() {
+        return Base64UrlUtility.encode(CryptoUtils.generateSecureRandomBytes(16));
     }
 
     /**
@@ -84,7 +92,6 @@ public class UserSubject implements Serializable {
      *
      * @return the login name
      */
-    @Id
     public String getLogin() {
         return login;
     }
@@ -145,6 +152,7 @@ public class UserSubject implements Serializable {
      *
      * @return the user's id
      */
+    @Id
     public String getId() {
         return this.id;
     }

http://git-wip-us.apache.org/repos/asf/cxf/blob/9d64bced/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/grants/code/JPACodeDataProvider.java
----------------------------------------------------------------------
diff --git a/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/grants/code/JPACodeDataProvider.java b/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/grants/code/JPACodeDataProvider.java
index 84bfb8e..a0b2001 100644
--- a/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/grants/code/JPACodeDataProvider.java
+++ b/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/grants/code/JPACodeDataProvider.java
@@ -50,7 +50,7 @@ public class JPACodeDataProvider extends JPAOAuthDataProvider implements Authori
             @Override
             public Void execute(EntityManager em) {
                 if (grant.getSubject() != null) {
-                    UserSubject sub = em.find(UserSubject.class, grant.getSubject().getLogin());
+                    UserSubject sub = em.find(UserSubject.class, grant.getSubject().getId());
                     if (sub == null) {
                         em.persist(grant.getSubject());
                     } else {

http://git-wip-us.apache.org/repos/asf/cxf/blob/9d64bced/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/provider/AbstractOAuthDataProvider.java
----------------------------------------------------------------------
diff --git a/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/provider/AbstractOAuthDataProvider.java b/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/provider/AbstractOAuthDataProvider.java
index dec7775..4b0509f 100644
--- a/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/provider/AbstractOAuthDataProvider.java
+++ b/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/provider/AbstractOAuthDataProvider.java
@@ -365,14 +365,16 @@ public abstract class AbstractOAuthDataProvider implements OAuthDataProvider, Cl
                                                      RefreshToken oldRefreshToken,
                                                      List<String> restrictedScopes) {
         ServerAccessToken at = createNewAccessToken(client, oldRefreshToken.getSubject());
-        at.setAudiences(oldRefreshToken.getAudiences());
+        at.setAudiences(oldRefreshToken.getAudiences() != null
+                ? new ArrayList<String>(oldRefreshToken.getAudiences()) : null);
         at.setGrantType(oldRefreshToken.getGrantType());
         at.setGrantCode(oldRefreshToken.getGrantCode());
         at.setSubject(oldRefreshToken.getSubject());
         at.setNonce(oldRefreshToken.getNonce());
         at.setClientCodeVerifier(oldRefreshToken.getClientCodeVerifier());
         if (restrictedScopes.isEmpty()) {
-            at.setScopes(oldRefreshToken.getScopes());
+            at.setScopes(oldRefreshToken.getScopes() != null
+                    ? new ArrayList<OAuthPermission>(oldRefreshToken.getScopes()) : null);
         } else {
             List<OAuthPermission> theNewScopes = convertScopeToPermissions(client, restrictedScopes);
             if (oldRefreshToken.getScopes().containsAll(theNewScopes)) {

http://git-wip-us.apache.org/repos/asf/cxf/blob/9d64bced/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/provider/JPAOAuthDataProvider.java
----------------------------------------------------------------------
diff --git a/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/provider/JPAOAuthDataProvider.java b/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/provider/JPAOAuthDataProvider.java
index ce49673..f59b40e 100644
--- a/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/provider/JPAOAuthDataProvider.java
+++ b/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/provider/JPAOAuthDataProvider.java
@@ -105,7 +105,7 @@ public class JPAOAuthDataProvider extends AbstractOAuthDataProvider {
             public Void execute(EntityManager em) {
                 if (client.getResourceOwnerSubject() != null) {
                     UserSubject sub =
-                            em.find(UserSubject.class, client.getResourceOwnerSubject().getLogin());
+                            em.find(UserSubject.class, client.getResourceOwnerSubject().getId());
                     if (sub == null) {
                         em.persist(client.getResourceOwnerSubject());
                     } else {
@@ -263,12 +263,14 @@ public class JPAOAuthDataProvider extends AbstractOAuthDataProvider {
                 }
                 serverToken.setScopes(perms);
 
-                UserSubject sub = em.find(UserSubject.class, serverToken.getSubject().getLogin());
-                if (sub == null) {
-                    em.persist(serverToken.getSubject());
-                } else {
-                    sub = em.merge(serverToken.getSubject());
-                    serverToken.setSubject(sub);
+                if (serverToken.getSubject() != null) {
+                    UserSubject sub = em.find(UserSubject.class, serverToken.getSubject().getId());
+                    if (sub == null) {
+                        em.persist(serverToken.getSubject());
+                    } else {
+                        sub = em.merge(serverToken.getSubject());
+                        serverToken.setSubject(sub);
+                    }
                 }
                 // ensure we have a managed association
                 // (needed for OpenJPA : InvalidStateException: Encountered unmanaged object)

http://git-wip-us.apache.org/repos/asf/cxf/blob/9d64bced/rt/rs/security/oauth-parent/oauth2/src/test/java/org/apache/cxf/rs/security/oauth2/provider/JPAOAuthDataProviderTest.java
----------------------------------------------------------------------
diff --git a/rt/rs/security/oauth-parent/oauth2/src/test/java/org/apache/cxf/rs/security/oauth2/provider/JPAOAuthDataProviderTest.java b/rt/rs/security/oauth-parent/oauth2/src/test/java/org/apache/cxf/rs/security/oauth2/provider/JPAOAuthDataProviderTest.java
index b71a920..cc0cf29 100644
--- a/rt/rs/security/oauth-parent/oauth2/src/test/java/org/apache/cxf/rs/security/oauth2/provider/JPAOAuthDataProviderTest.java
+++ b/rt/rs/security/oauth-parent/oauth2/src/test/java/org/apache/cxf/rs/security/oauth2/provider/JPAOAuthDataProviderTest.java
@@ -199,6 +199,36 @@ public class JPAOAuthDataProviderTest extends Assert {
         assertEquals(0, tokens.size());
     }
 
+    /**
+     * Checks that having multiple token each with its own
+     * userSubject (but having same login) works.
+     */
+    @Test
+    public void testAddGetDeleteMultipleAccessToken() {
+        Client c = addClient("101", "bob");
+
+        AccessTokenRegistration atr = new AccessTokenRegistration();
+        atr.setClient(c);
+        atr.setApprovedScope(Collections.singletonList("a"));
+        atr.setSubject(c.getResourceOwnerSubject());
+        ServerAccessToken at = getProvider().createAccessToken(atr);
+        at = getProvider().getAccessToken(at.getTokenKey());
+
+        AccessTokenRegistration atr2 = new AccessTokenRegistration();
+        atr2.setClient(c);
+        atr2.setApprovedScope(Collections.singletonList("a"));
+        atr2.setSubject(new TestingUserSubject(c.getResourceOwnerSubject().getLogin()));
+        ServerAccessToken at2 = getProvider().createAccessToken(atr2);
+        at2 = getProvider().getAccessToken(at2.getTokenKey());
+
+        assertNotNull(at.getSubject().getId());
+        assertTrue(at.getSubject() instanceof UserSubject);
+        assertNotNull(at2.getSubject().getId());
+        assertTrue(at2.getSubject() instanceof TestingUserSubject);
+        assertEquals(at.getSubject().getLogin(), at2.getSubject().getLogin());
+        assertNotEquals(at.getSubject().getId(), at2.getSubject().getId());
+    }
+
     @Test
     public void testAddGetDeleteRefreshToken() {
         Client c = addClient("101", "bob");

http://git-wip-us.apache.org/repos/asf/cxf/blob/9d64bced/rt/rs/security/oauth-parent/oauth2/src/test/resources/META-INF/persistence.xml
----------------------------------------------------------------------
diff --git a/rt/rs/security/oauth-parent/oauth2/src/test/resources/META-INF/persistence.xml b/rt/rs/security/oauth-parent/oauth2/src/test/resources/META-INF/persistence.xml
index 8d7ad1c..41e7e83 100644
--- a/rt/rs/security/oauth-parent/oauth2/src/test/resources/META-INF/persistence.xml
+++ b/rt/rs/security/oauth-parent/oauth2/src/test/resources/META-INF/persistence.xml
@@ -14,6 +14,7 @@
         <class>org.apache.cxf.rs.security.oauth2.common.AccessToken</class>
         <class>org.apache.cxf.rs.security.oauth2.common.OAuthPermission</class>
         <class>org.apache.cxf.rs.security.oauth2.tokens.refresh.RefreshToken</class>
+        <class>org.apache.cxf.rs.security.oauth2.provider.TestingUserSubject</class>
         <exclude-unlisted-classes>true</exclude-unlisted-classes>
         <shared-cache-mode>ENABLE_SELECTIVE</shared-cache-mode>
         <properties>
@@ -41,6 +42,7 @@
         <class>org.apache.cxf.rs.security.oauth2.common.AccessToken</class>
         <class>org.apache.cxf.rs.security.oauth2.common.OAuthPermission</class>
         <class>org.apache.cxf.rs.security.oauth2.tokens.refresh.RefreshToken</class>
+        <class>org.apache.cxf.rs.security.oauth2.provider.TestingUserSubject</class>
         <exclude-unlisted-classes>true</exclude-unlisted-classes>
         <shared-cache-mode>ENABLE_SELECTIVE</shared-cache-mode>
         <properties>