Author: matthieu
Date: Fri Dec 11 10:06:00 2015
New Revision: 1719308

URL: http://svn.apache.org/viewvc?rev=1719308&view=rev
Log:
JAMES-1644 Introduce ContinuationToken

Added:
    
james/project/trunk/server/protocols/jmap/src/main/java/org/apache/james/jmap/exceptions/
    
james/project/trunk/server/protocols/jmap/src/main/java/org/apache/james/jmap/exceptions/MalformedContinuationTokenException.java
    
james/project/trunk/server/protocols/jmap/src/main/java/org/apache/james/jmap/model/ContinuationToken.java
    
james/project/trunk/server/protocols/jmap/src/test/java/org/apache/james/jmap/model/
    
james/project/trunk/server/protocols/jmap/src/test/java/org/apache/james/jmap/model/ContinuationTokenTest.java
Modified:
    
james/project/trunk/server/protocols/jmap/src/main/java/org/apache/james/jmap/AuthenticationServlet.java
    
james/project/trunk/server/protocols/jmap/src/main/java/org/apache/james/jmap/model/AccessTokenRequest.java
    
james/project/trunk/server/protocols/jmap/src/main/java/org/apache/james/jmap/model/ContinuationTokenResponse.java

Modified: 
james/project/trunk/server/protocols/jmap/src/main/java/org/apache/james/jmap/AuthenticationServlet.java
URL: 
http://svn.apache.org/viewvc/james/project/trunk/server/protocols/jmap/src/main/java/org/apache/james/jmap/AuthenticationServlet.java?rev=1719308&r1=1719307&r2=1719308&view=diff
==============================================================================
--- 
james/project/trunk/server/protocols/jmap/src/main/java/org/apache/james/jmap/AuthenticationServlet.java
 (original)
+++ 
james/project/trunk/server/protocols/jmap/src/main/java/org/apache/james/jmap/AuthenticationServlet.java
 Fri Dec 11 10:06:00 2015
@@ -19,6 +19,7 @@
 package org.apache.james.jmap;
 
 import java.io.IOException;
+import java.time.ZonedDateTime;
 
 import javax.inject.Inject;
 import javax.servlet.ServletException;
@@ -29,6 +30,7 @@ import javax.servlet.http.HttpServletRes
 import org.apache.james.jmap.json.MultipleObjectMapperBuilder;
 import org.apache.james.jmap.model.AccessTokenRequest;
 import org.apache.james.jmap.model.AccessTokenResponse;
+import org.apache.james.jmap.model.ContinuationToken;
 import org.apache.james.jmap.model.ContinuationTokenRequest;
 import org.apache.james.jmap.model.ContinuationTokenResponse;
 import org.apache.james.user.api.UsersRepository;
@@ -106,7 +108,7 @@ public class AuthenticationServlet exten
         ContinuationTokenResponse continuationTokenResponse = 
ContinuationTokenResponse
                 .builder()
                 // TODO Answer a real token
-                .continuationToken("token")
+                .continuationToken(new ContinuationToken("fake", 
ZonedDateTime.now(), "fake"))
                 
.methods(ContinuationTokenResponse.AuthenticationMethod.PASSWORD)
                 .build();
 
@@ -149,4 +151,5 @@ public class AuthenticationServlet exten
         resp.sendError(HttpServletResponse.SC_UNAUTHORIZED);
     }
 
+
 }

Added: 
james/project/trunk/server/protocols/jmap/src/main/java/org/apache/james/jmap/exceptions/MalformedContinuationTokenException.java
URL: 
http://svn.apache.org/viewvc/james/project/trunk/server/protocols/jmap/src/main/java/org/apache/james/jmap/exceptions/MalformedContinuationTokenException.java?rev=1719308&view=auto
==============================================================================
--- 
james/project/trunk/server/protocols/jmap/src/main/java/org/apache/james/jmap/exceptions/MalformedContinuationTokenException.java
 (added)
+++ 
james/project/trunk/server/protocols/jmap/src/main/java/org/apache/james/jmap/exceptions/MalformedContinuationTokenException.java
 Fri Dec 11 10:06:00 2015
@@ -0,0 +1,31 @@
+/****************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one   *
+ * or more contributor license agreements.  See the NOTICE file *
+ * distributed with this work for additional information        *
+ * regarding copyright ownership.  The ASF licenses this file   *
+ * to you 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 org.apache.james.jmap.exceptions;
+
+public class MalformedContinuationTokenException extends Exception {
+
+    public MalformedContinuationTokenException(String s) {
+        super(s);
+    }
+
+    public MalformedContinuationTokenException(String s, Throwable throwable) {
+        super(s, throwable);
+    }
+}

Modified: 
james/project/trunk/server/protocols/jmap/src/main/java/org/apache/james/jmap/model/AccessTokenRequest.java
URL: 
http://svn.apache.org/viewvc/james/project/trunk/server/protocols/jmap/src/main/java/org/apache/james/jmap/model/AccessTokenRequest.java?rev=1719308&r1=1719307&r2=1719308&view=diff
==============================================================================
--- 
james/project/trunk/server/protocols/jmap/src/main/java/org/apache/james/jmap/model/AccessTokenRequest.java
 (original)
+++ 
james/project/trunk/server/protocols/jmap/src/main/java/org/apache/james/jmap/model/AccessTokenRequest.java
 Fri Dec 11 10:06:00 2015
@@ -20,6 +20,9 @@ package org.apache.james.jmap.model;
 
 import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
 import com.fasterxml.jackson.databind.annotation.JsonPOJOBuilder;
+import org.apache.james.jmap.exceptions.MalformedContinuationTokenException;
+
+import java.time.DateTimeException;
 
 @JsonDeserialize(builder=AccessTokenRequest.Builder.class)
 public class AccessTokenRequest {
@@ -33,14 +36,14 @@ public class AccessTokenRequest {
     @JsonPOJOBuilder(withPrefix="")
     public static class Builder {
 
-        private String token;
+        private ContinuationToken token;
         private String method;
         private String password;
 
         private Builder() {}
 
-        public Builder token(String token) {
-            this.token = token;
+        public Builder token(String token) throws 
MalformedContinuationTokenException, DateTimeException {
+            this.token = ContinuationToken.fromString(token);
             return this;
         }
 
@@ -59,17 +62,17 @@ public class AccessTokenRequest {
         }
     }
 
-    private final String token;
+    private final ContinuationToken token;
     private final String method;
     private final String password;
 
-    private AccessTokenRequest(String token, String method, String password) {
+    private AccessTokenRequest(ContinuationToken token, String method, String 
password) {
         this.token = token;
         this.method = method;
         this.password = password;
     }
 
-    public String getToken() {
+    public ContinuationToken getToken() {
         return token;
     }
 

Added: 
james/project/trunk/server/protocols/jmap/src/main/java/org/apache/james/jmap/model/ContinuationToken.java
URL: 
http://svn.apache.org/viewvc/james/project/trunk/server/protocols/jmap/src/main/java/org/apache/james/jmap/model/ContinuationToken.java?rev=1719308&view=auto
==============================================================================
--- 
james/project/trunk/server/protocols/jmap/src/main/java/org/apache/james/jmap/model/ContinuationToken.java
 (added)
+++ 
james/project/trunk/server/protocols/jmap/src/main/java/org/apache/james/jmap/model/ContinuationToken.java
 Fri Dec 11 10:06:00 2015
@@ -0,0 +1,122 @@
+/****************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one   *
+ * or more contributor license agreements.  See the NOTICE file *
+ * distributed with this work for additional information        *
+ * regarding copyright ownership.  The ASF licenses this file   *
+ * to you 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 org.apache.james.jmap.model;
+
+import com.google.common.base.Joiner;
+import com.google.common.base.Preconditions;
+import com.google.common.base.Splitter;
+import com.google.common.base.Strings;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Lists;
+import org.apache.james.jmap.exceptions.MalformedContinuationTokenException;
+
+import java.time.DateTimeException;
+import java.time.ZonedDateTime;
+import java.time.format.DateTimeFormatter;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Objects;
+
+public class ContinuationToken {
+
+    public static final String SEPARATOR = "_";
+
+    private final String username;
+    private final ZonedDateTime expirationDate;
+    private final String signature;
+
+    public ContinuationToken(String username, ZonedDateTime expirationDate, 
String signature) {
+        Preconditions.checkNotNull(username);
+        Preconditions.checkNotNull(expirationDate);
+        Preconditions.checkNotNull(signature);
+        this.username = username;
+        this.expirationDate = expirationDate;
+        this.signature = signature;
+    }
+
+    public static ContinuationToken fromString(String serializedToken) throws 
MalformedContinuationTokenException {
+        Preconditions.checkArgument(!Strings.isNullOrEmpty(serializedToken), 
"Serialized continuation token should not be null or empty");
+        ImmutableList<String> tokenParts = 
ImmutableList.copyOf(Splitter.on(SEPARATOR).split(serializedToken));
+        if (tokenParts.size() < 3) {
+            throw new MalformedContinuationTokenException("Token " + 
serializedToken + " does not have enough parts");
+        }
+        Iterator<String> tokenPartsReversedIterator = 
tokenParts.reverse().iterator();
+        String signature = tokenPartsReversedIterator.next();
+        String expirationDateString = tokenPartsReversedIterator.next();
+        String username = retrieveUsername(tokenPartsReversedIterator);
+        try {
+            return new ContinuationToken(username,
+                ZonedDateTime.parse(expirationDateString, 
DateTimeFormatter.ISO_OFFSET_DATE_TIME),
+                signature);
+        } catch(DateTimeException e) {
+            throw new MalformedContinuationTokenException("Token " + 
serializedToken + " as an incorrect date", e);
+        }
+    }
+
+    private static String retrieveUsername(Iterator<String> 
reversedIteratorOnUsernameParts) {
+        List<String> usernamePart = 
ImmutableList.copyOf(Lists.newArrayList(reversedIteratorOnUsernameParts)).reverse();
+        return Joiner.on(SEPARATOR).join(usernamePart);
+    }
+
+    public String getUsername() {
+        return username;
+    }
+
+    public ZonedDateTime getExpirationDate() {
+        return expirationDate;
+    }
+
+    public String getSignature() {
+        return signature;
+    }
+
+    public String serialize() {
+        return username
+            + SEPARATOR
+            + DateTimeFormatter.ISO_OFFSET_DATE_TIME.format(expirationDate)
+            + SEPARATOR
+            + signature;
+    }
+
+    @Override
+    public boolean equals(Object other) {
+        if (other == null || getClass() != other.getClass()) {
+            return false;
+        }
+        ContinuationToken continuationToken = (ContinuationToken) other;
+        return Objects.equals(username, continuationToken.username)
+            && expirationDate.isEqual(continuationToken.expirationDate)
+            && Objects.equals(signature, continuationToken.signature);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(username, expirationDate, signature);
+    }
+
+    @Override
+    public String toString() {
+        return "ContinuationToken{" +
+            "username='" + username + '\'' +
+            ", expirationDate=" + expirationDate +
+            ", signature='" + signature + '\'' +
+            '}';
+    }
+}

Modified: 
james/project/trunk/server/protocols/jmap/src/main/java/org/apache/james/jmap/model/ContinuationTokenResponse.java
URL: 
http://svn.apache.org/viewvc/james/project/trunk/server/protocols/jmap/src/main/java/org/apache/james/jmap/model/ContinuationTokenResponse.java?rev=1719308&r1=1719307&r2=1719308&view=diff
==============================================================================
--- 
james/project/trunk/server/protocols/jmap/src/main/java/org/apache/james/jmap/model/ContinuationTokenResponse.java
 (original)
+++ 
james/project/trunk/server/protocols/jmap/src/main/java/org/apache/james/jmap/model/ContinuationTokenResponse.java
 Fri Dec 11 10:06:00 2015
@@ -53,8 +53,8 @@ public class ContinuationTokenResponse {
 
         private Builder() {}
 
-        public Builder continuationToken(String continuationToken) {
-            this.continuationToken = continuationToken;
+        public Builder continuationToken(ContinuationToken continuationToken) {
+            this.continuationToken = continuationToken.serialize();
             return this;
         }
 

Added: 
james/project/trunk/server/protocols/jmap/src/test/java/org/apache/james/jmap/model/ContinuationTokenTest.java
URL: 
http://svn.apache.org/viewvc/james/project/trunk/server/protocols/jmap/src/test/java/org/apache/james/jmap/model/ContinuationTokenTest.java?rev=1719308&view=auto
==============================================================================
--- 
james/project/trunk/server/protocols/jmap/src/test/java/org/apache/james/jmap/model/ContinuationTokenTest.java
 (added)
+++ 
james/project/trunk/server/protocols/jmap/src/test/java/org/apache/james/jmap/model/ContinuationTokenTest.java
 Fri Dec 11 10:06:00 2015
@@ -0,0 +1,97 @@
+/****************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one   *
+ * or more contributor license agreements.  See the NOTICE file *
+ * distributed with this work for additional information        *
+ * regarding copyright ownership.  The ASF licenses this file   *
+ * to you 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 org.apache.james.jmap.model;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+import java.time.ZonedDateTime;
+import java.time.format.DateTimeFormatter;
+
+import org.apache.james.jmap.exceptions.MalformedContinuationTokenException;
+import org.junit.Before;
+import org.junit.Test;
+
+public class ContinuationTokenTest {
+
+    private static final String USER = "user";
+    private static final String EXPIRATION_DATE_STRING = 
"2011-12-03T10:15:30+01:00";
+    public static final String SIGNATURE = "signature";
+
+    private ZonedDateTime expirationDate;
+
+    @Before
+    public void setUp() {
+        expirationDate = ZonedDateTime.parse(EXPIRATION_DATE_STRING, 
DateTimeFormatter.ISO_OFFSET_DATE_TIME);
+    }
+
+    @Test
+    public void continuationTokenShouldBeRetrievedFromString() throws 
Exception {
+        assertThat(ContinuationToken.fromString(USER + 
ContinuationToken.SEPARATOR + EXPIRATION_DATE_STRING + 
ContinuationToken.SEPARATOR + SIGNATURE))
+            .isEqualTo(new ContinuationToken(USER, expirationDate, SIGNATURE));
+    }
+
+    @Test
+    public void usernameShouldBeAllowedToContainSeparator() throws Exception {
+        String username = "user" + ContinuationToken.SEPARATOR + "using" + 
ContinuationToken.SEPARATOR + "separator";
+        assertThat(ContinuationToken.fromString(username + 
ContinuationToken.SEPARATOR + EXPIRATION_DATE_STRING + 
ContinuationToken.SEPARATOR + SIGNATURE))
+            .isEqualTo(new ContinuationToken(username, expirationDate, 
SIGNATURE));
+    }
+
+    @Test(expected = MalformedContinuationTokenException.class)
+    public void continuationTokenThatMissPartsShouldThrow() throws Exception {
+        ContinuationToken.fromString(EXPIRATION_DATE_STRING + 
ContinuationToken.SEPARATOR + SIGNATURE);
+    }
+
+    @Test(expected = MalformedContinuationTokenException.class)
+    public void continuationTokenWithMalformedDatesShouldThrow() throws 
Exception {
+        ContinuationToken.fromString(USER + ContinuationToken.SEPARATOR + 
"2011-25-03T10:15:30+01:00" + ContinuationToken.SEPARATOR + SIGNATURE);
+    }
+
+    @Test(expected = IllegalArgumentException.class)
+    public void nullContinuationTokenShouldThrow() throws Exception {
+        ContinuationToken.fromString(null);
+    }
+
+    @Test(expected = IllegalArgumentException.class)
+    public void emptyContinuationTokenShouldThrow() throws Exception {
+        ContinuationToken.fromString("");
+    }
+
+    @Test
+    public void getAsStringShouldReturnACorrectResult() throws Exception {
+        assertThat(new ContinuationToken(USER, expirationDate, 
SIGNATURE).serialize())
+            .isEqualTo(USER + ContinuationToken.SEPARATOR + 
EXPIRATION_DATE_STRING + ContinuationToken.SEPARATOR + SIGNATURE);
+    }
+
+    @Test(expected = NullPointerException.class)
+    public void newContinuationTokenWithNullUsernameShouldThrow() {
+        new ContinuationToken(null, expirationDate, SIGNATURE);
+    }
+
+    @Test(expected = NullPointerException.class)
+    public void newContinuationTokenWithNullExpirationDateShouldThrow() {
+        new ContinuationToken(USER, null, SIGNATURE);
+    }
+
+    @Test(expected = NullPointerException.class)
+    public void newContinuationTokenWithNullSignatureShouldThrow() {
+        new ContinuationToken(USER, expirationDate, null);
+    }
+}



---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to