You are viewing a plain text version of this content. The canonical link for it is here.
Posted to oak-commits@jackrabbit.apache.org by an...@apache.org on 2012/10/31 19:12:37 UTC

svn commit: r1404278 - in /jackrabbit/oak/trunk/oak-core/src: main/java/org/apache/jackrabbit/oak/security/authentication/token/TokenProviderImpl.java test/java/org/apache/jackrabbit/oak/security/authentication/token/TokenProviderImplTest.java

Author: angela
Date: Wed Oct 31 18:12:37 2012
New Revision: 1404278

URL: http://svn.apache.org/viewvc?rev=1404278&view=rev
Log:
 OAK-91 - Implement Authentication Support (WIP)

Modified:
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authentication/token/TokenProviderImpl.java
    jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authentication/token/TokenProviderImplTest.java

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authentication/token/TokenProviderImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authentication/token/TokenProviderImpl.java?rev=1404278&r1=1404277&r2=1404278&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authentication/token/TokenProviderImpl.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authentication/token/TokenProviderImpl.java Wed Oct 31 18:12:37 2012
@@ -26,7 +26,9 @@ import java.util.Collections;
 import java.util.Date;
 import java.util.GregorianCalendar;
 import java.util.HashMap;
+import java.util.HashSet;
 import java.util.Map;
+import java.util.Set;
 import javax.annotation.CheckForNull;
 import javax.annotation.Nonnull;
 import javax.jcr.Credentials;
@@ -98,6 +100,13 @@ public class TokenProviderImpl implement
     private static final int DEFAULT_KEY_SIZE = 8;
     private static final char DELIM = '_';
 
+    private static final Set<String> RESERVED_ATTRIBUTES = new HashSet(2);
+    static {
+        RESERVED_ATTRIBUTES.add(TOKEN_ATTRIBUTE);
+        RESERVED_ATTRIBUTES.add(TOKEN_ATTRIBUTE_EXPIRY);
+        RESERVED_ATTRIBUTES.add(TOKEN_ATTRIBUTE_KEY);
+    }
+
     private final Root root;
     private final ConfigurationParameters options;
 
@@ -174,14 +183,13 @@ public class TokenProviderImpl implement
                 tokenNode.setDate(TOKEN_ATTRIBUTE_EXPIRY, expirationTime);
 
                 for (String name : attributes.keySet()) {
-                    if (!TOKEN_ATTRIBUTE.equals(name)) {
+                    if (!RESERVED_ATTRIBUTES.contains(name)) {
                         String attr = attributes.get(name).toString();
                         tokenNode.setString(name, attr);
                     }
                 }
                 root.commit();
 
-
                 return new TokenInfoImpl(tokenNode, token, userId);
             } else {
                 log.debug("Cannot create login token: No corresponding node for User " + userId + '.');
@@ -203,8 +211,8 @@ public class TokenProviderImpl implement
     @Override
     public TokenInfo getTokenInfo(String token) {
         int pos = token.indexOf(DELIM);
-        String tokenPath = (pos == -1) ? token : token.substring(0, pos);
-        Tree tokenTree = root.getTree(tokenPath);
+        String nodeId = (pos == -1) ? token : token.substring(0, pos);
+        Tree tokenTree = identifierManager.getTree(nodeId);
         String userId = getUserId(tokenTree);
         if (tokenTree == null || userId == null) {
             return null;
@@ -343,7 +351,7 @@ public class TokenProviderImpl implement
             for (PropertyState propertyState : tokenNode.getTree().getProperties()) {
                 String name = propertyState.getName();
                 String value = propertyState.getValue(STRING);
-                if (TOKEN_ATTRIBUTE_KEY.equals(name) || TOKEN_ATTRIBUTE_EXPIRY.equals(name)) {
+                if (RESERVED_ATTRIBUTES.contains(name)) {
                     continue;
                 }
                 if (isMandatoryAttribute(name)) {

Modified: jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authentication/token/TokenProviderImplTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authentication/token/TokenProviderImplTest.java?rev=1404278&r1=1404277&r2=1404278&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authentication/token/TokenProviderImplTest.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authentication/token/TokenProviderImplTest.java Wed Oct 31 18:12:37 2012
@@ -16,16 +16,38 @@
  */
 package org.apache.jackrabbit.oak.security.authentication.token;
 
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.UUID;
+import javax.annotation.Nonnull;
+import javax.jcr.Credentials;
 import javax.jcr.GuestCredentials;
 import javax.jcr.SimpleCredentials;
 
 import org.apache.jackrabbit.api.security.authentication.token.TokenCredentials;
+import org.apache.jackrabbit.api.security.user.Authorizable;
+import org.apache.jackrabbit.api.security.user.UserManager;
+import org.apache.jackrabbit.oak.api.PropertyState;
+import org.apache.jackrabbit.oak.api.Root;
+import org.apache.jackrabbit.oak.api.Tree;
+import org.apache.jackrabbit.oak.api.Type;
+import org.apache.jackrabbit.oak.namepath.NamePathMapper;
 import org.apache.jackrabbit.oak.security.AbstractSecurityTest;
 import org.apache.jackrabbit.oak.spi.security.ConfigurationParameters;
+import org.apache.jackrabbit.oak.spi.security.authentication.ImpersonationCredentials;
+import org.apache.jackrabbit.oak.spi.security.authentication.token.TokenInfo;
+import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
 
+import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertTrue;
 
 /**
@@ -33,15 +55,39 @@ import static org.junit.Assert.assertTru
  */
 public class TokenProviderImplTest extends AbstractSecurityTest {
 
+    private Root root;
     private TokenProviderImpl tokenProvider;
 
+    private String userId;
+    private UserManager userManager;
+
     @Before
     public void before() throws Exception {
         super.before();
 
-        tokenProvider = new TokenProviderImpl(admin.getLatestRoot(),
+        root = admin.getLatestRoot();
+        tokenProvider = new TokenProviderImpl(root,
                 ConfigurationParameters.EMPTY,
                 getSecurityProvider().getUserConfiguration());
+
+        userId = "testUser";
+        userManager = getSecurityProvider().getUserConfiguration().getUserManager(root, NamePathMapper.DEFAULT);
+
+        userManager.createUser(userId, "pw");
+        root.commit();
+    }
+
+    @After
+    public void after() throws Exception {
+        try {
+            Authorizable a = userManager.getAuthorizable(userId);
+            if (a != null) {
+                a.remove();
+                root.commit();
+            }
+        } finally {
+            super.after();
+        }
     }
 
 
@@ -68,27 +114,245 @@ public class TokenProviderImplTest exten
     }
 
     @Test
+    public void testCreateTokenFromInvalidCredentials() throws Exception {
+        List<Credentials> invalid = new ArrayList<Credentials>();
+        invalid.add(new GuestCredentials());
+        invalid.add(new TokenCredentials("sometoken"));
+        invalid.add(new ImpersonationCredentials(new GuestCredentials(), null));
+        invalid.add(new SimpleCredentials("unknownUserId", new char[0]));
+
+        for (Credentials creds : invalid) {
+            assertNull(tokenProvider.createToken(creds));
+        }
+    }
+
+    @Test
     public void testCreateTokenFromCredentials() throws Exception {
-        // TODO
+        SimpleCredentials sc = new SimpleCredentials(userId, new char[0]);
+        List<Credentials> valid = new ArrayList<Credentials>();
+        valid.add(sc);
+        valid.add(new ImpersonationCredentials(sc, null));
+
+        for (Credentials creds : valid) {
+            TokenInfo info = tokenProvider.createToken(creds);
+            assertTokenInfo(info, userId);
+        }
+    }
+
+    @Test
+    public void testCreateTokenFromInvalidUserId() throws Exception {
+        TokenInfo info = tokenProvider.createToken("unknownUserId", Collections.<String, Object>emptyMap());
+        assertNull(info);
     }
 
     @Test
     public void testCreateTokenFromUserId() throws Exception {
-        // TODO
+        TokenInfo info = tokenProvider.createToken(userId, Collections.<String, Object>emptyMap());
+        assertTokenInfo(info, userId);
+    }
+
+    @Test
+    public void testCreateTokenWithAttributes() throws Exception {
+        Map<String, String> reserved = new HashMap<String, String>();
+        reserved.put(".token", "value");
+        reserved.put(".token.key", "value");
+        reserved.put(".token.exp", "value");
+
+        Map<String, String> privateAttributes = new HashMap<String, String>();
+        privateAttributes.put(".token_exp", "value");
+        privateAttributes.put(".tokenTest", "value");
+        privateAttributes.put(".token_something", "value");
+
+        Map<String, String> publicAttributes = new HashMap<String, String>();
+        publicAttributes.put("any", "value");
+        publicAttributes.put("another", "value");
+
+        Map<String, String> attributes = new HashMap<String, String>();
+        attributes.putAll(reserved);
+        attributes.putAll(publicAttributes);
+        attributes.putAll(privateAttributes);
+
+        TokenInfo info = tokenProvider.createToken(userId, attributes);
+        assertTokenInfo(info, userId);
+
+        Map<String,String> pubAttr = info.getPublicAttributes();
+        assertEquals(publicAttributes.size(), pubAttr.size());
+        for (String key : publicAttributes.keySet()) {
+            assertTrue(pubAttr.containsKey(key));
+            assertEquals(publicAttributes.get(key), pubAttr.get(key));
+        }
+
+        Map<String,String> privAttr = info.getPrivateAttributes();
+        assertEquals(privateAttributes.size(), privAttr.size());
+        for (String key : privateAttributes.keySet()) {
+            assertTrue(privAttr.containsKey(key));
+            assertEquals(privateAttributes.get(key), privAttr.get(key));
+        }
+
+        for (String key : reserved.keySet()) {
+            assertFalse(privAttr.containsKey(key));
+            assertFalse(pubAttr.containsKey(key));
+        }
+    }
+
+    @Test
+    public void testTokenNode() throws Exception {
+        Map<String, String> reserved = new HashMap<String, String>();
+        reserved.put(".token", "value");
+        reserved.put(".token.key", "value");
+        reserved.put(".token.exp", "value");
+
+        Map<String, String> privateAttributes = new HashMap<String, String>();
+        privateAttributes.put(".token_exp", "value");
+        privateAttributes.put(".tokenTest", "value");
+        privateAttributes.put(".token_something", "value");
+
+        Map<String, String> publicAttributes = new HashMap<String, String>();
+        publicAttributes.put("any", "value");
+        publicAttributes.put("another", "value");
+
+        Map<String, String> attributes = new HashMap<String, String>();
+        attributes.putAll(reserved);
+        attributes.putAll(publicAttributes);
+        attributes.putAll(privateAttributes);
+
+        TokenInfo info = tokenProvider.createToken(userId, attributes);
+
+        Tree userTree = root.getTree(userManager.getAuthorizable(userId).getPath());
+        Tree tokens = userTree.getChild(".tokens");
+        assertNotNull(tokens);
+        assertEquals(1, tokens.getChildrenCount());
+
+        Tree tokenNode = tokens.getChildren().iterator().next();
+        assertNotNull(tokenNode.getProperty(".token.key"));
+        assertNotNull(tokenNode.getProperty(".token.exp"));
+
+        for (String key : reserved.keySet()) {
+            PropertyState p = tokenNode.getProperty(key);
+            if (p != null) {
+                assertFalse(reserved.get(key).equals(p.getValue(Type.STRING)));
+            }
+        }
+
+        for (String key : privateAttributes.keySet()) {
+            assertEquals(privateAttributes.get(key), tokenNode.getProperty(key).getValue(Type.STRING));
+        }
+
+        for (String key : publicAttributes.keySet()) {
+            assertEquals(publicAttributes.get(key), tokenNode.getProperty(key).getValue(Type.STRING));
+        }
+    }
+
+    @Test
+    public void testGetTokenInfoFromInvalidToken() throws Exception {
+        List<String> invalid = new ArrayList<String>();
+        invalid.add("/invalid");
+        invalid.add(UUID.randomUUID().toString());
+
+        for (String token : invalid) {
+            TokenInfo info = tokenProvider.getTokenInfo(token);
+            assertNull(info);
+        }
+
+        try {
+            assertNull(tokenProvider.getTokenInfo("invalidToken"));
+        } catch (Exception e) {
+            // success
+        }
     }
 
     @Test
     public void testGetTokenInfo() throws Exception {
-        // TODO
+        String token = tokenProvider.createToken(userId, Collections.<String, Object>emptyMap()).getToken();
+        TokenInfo info = tokenProvider.getTokenInfo(token);
+        assertTokenInfo(info, userId);
+    }
+
+    @Test
+    public void testRemoveTokenInvalidInfo() throws Exception {
+        assertFalse(tokenProvider.removeToken(new InvalidTokenInfo()));
     }
 
     @Test
     public void testRemoveToken() throws Exception {
-        // TODO
+        TokenInfo info = tokenProvider.createToken(userId, Collections.<String, Object>emptyMap());
+        assertTrue(tokenProvider.removeToken(info));
+    }
+
+    @Test
+    public void testRemoveToken2() throws Exception {
+        TokenInfo info = tokenProvider.createToken(userId, Collections.<String, Object>emptyMap());
+        assertTrue(tokenProvider.removeToken(tokenProvider.getTokenInfo(info.getToken())));
+    }
+
+    @Test
+    public void testRemoveTokenRemovesNode() throws Exception {
+        TokenInfo info = tokenProvider.createToken(userId, Collections.<String, Object>emptyMap());
+
+        Tree userTree = root.getTree(userManager.getAuthorizable(userId).getPath());
+        Tree tokens = userTree.getChild(".tokens");
+        String tokenNodePath = tokens.getChildren().iterator().next().getPath();
+
+        tokenProvider.removeToken(info);
+        assertNull(root.getTree(tokenNodePath));
+    }
+
+    @Test
+    public void testResetTokenExpirationInvalidToken() throws Exception {
+        assertFalse(tokenProvider.resetTokenExpiration(new InvalidTokenInfo(), new Date().getTime()));
     }
 
     @Test
     public void testResetTokenExpiration() throws Exception {
-        // TODO
+        TokenInfo info = tokenProvider.createToken(userId, Collections.<String, Object>emptyMap());
+
+        assertFalse(tokenProvider.resetTokenExpiration(info, new Date().getTime()));
+
+        long loginTime = new Date().getTime() + 3600000;
+        assertFalse(info.isExpired(loginTime));
+        assertTrue(tokenProvider.resetTokenExpiration(info, loginTime));
+
+        long expiredTime = new Date().getTime() + 7200000;
+        assertTrue(info.isExpired(expiredTime));
+        assertTrue(tokenProvider.resetTokenExpiration(info, expiredTime));
+    }
+
+    //--------------------------------------------------------------------------
+    private static void assertTokenInfo(TokenInfo info, String userId) {
+        assertNotNull(info);
+        assertNotNull(info.getToken());
+        assertEquals(userId, info.getUserId());
+        assertFalse(info.isExpired(new Date().getTime()));
+    }
+
+    private final class InvalidTokenInfo implements TokenInfo {
+        @Nonnull
+        @Override
+        public String getUserId() {
+            return "invalid";
+        }
+        @Nonnull
+        @Override
+        public String getToken() {
+            return "invalid";
+        }
+        @Override
+        public boolean isExpired(long loginTime) {
+            return true;
+        }
+        @Override
+        public boolean matches(TokenCredentials tokenCredentials) {
+            return false;
+        }
+        @Nonnull
+        @Override
+        public Map<String, String> getPrivateAttributes() {
+            return null;
+        }
+        @Nonnull
+        @Override
+        public Map<String, String> getPublicAttributes() {
+            return null;
+        }
     }
 }
\ No newline at end of file