Search in sources :

Example 1 with Session

use of com.macasaet.fernet.example.pb.Example.Session in project fernet-java8 by l0s.

the class ProtocolBuffersExampleIT method createSession.

/**
 * Start a new session.
 *
 * @return a serialised Fernet token with a {@link Session} embedded in the payload
 */
@POST
@Path("/api/sessions")
public String createSession(@Context final HttpServletResponse servletResponse) {
    final String sessionId = UUID.randomUUID().toString();
    final Builder builder = Session.newBuilder();
    builder.setSessionId(sessionId);
    builder.setRenewalCount(0);
    builder.setStartTime(Instant.now().getEpochSecond());
    servletResponse.addHeader("Location", "/api/sessions/" + sessionId);
    final Session session = builder.build();
    // persist session in server-side data store
    final Token token = Token.generate(random, key, session.toByteArray());
    return token.serialise();
}
Also used : Builder(com.macasaet.fernet.example.pb.Example.Session.Builder) Token(com.macasaet.fernet.Token) Session(com.macasaet.fernet.example.pb.Example.Session) Path(javax.ws.rs.Path) POST(javax.ws.rs.POST)

Example 2 with Session

use of com.macasaet.fernet.example.pb.Example.Session in project fernet-java8 by l0s.

the class ProtocolBuffersExampleIT method renew.

/**
 * Renew a session
 *
 * @param sessionId the existing session ID
 * @param tokenString a current valid Fernet token
 * @return a new Fernet token with the updated session state embedded
 */
@PUT
@Path("/api/sessions/{sessionId}/renewal")
public String renew(@PathParam("sessionId") final String sessionId, final String tokenString, @Context final HttpServletResponse servletResponse) {
    final Token inputToken = Token.fromString(tokenString);
    final Session session = inputToken.validateAndDecrypt(key, validator);
    if (!Objects.equals(sessionId, session.getSessionId())) {
        throw new BadRequestException("SessionID mismatch.");
    }
    final Instant lastRenewed = Instant.ofEpochSecond(session.getLastRenewalTime());
    if (session.hasLastRenewalTime() && lastRenewed.isAfter(Instant.now().minus(Duration.ofMinutes(1)))) {
        // prevent denial-of-service
        // if token was renewed less than a minute ago, tell the client to back off
        servletResponse.addHeader("Retry-After", "60");
        // Too Many Requests: https://tools.ietf.org/html/rfc6585#section-4
        throw new WebApplicationException("Try again in a minute", 429);
    }
    // check session validity in server-side data store
    // The token and session are valid, now update the session
    final Builder builder = Session.newBuilder(session);
    builder.setRenewalCount(session.getRenewalCount() + 1);
    builder.setLastRenewalTime(Instant.now().getEpochSecond());
    final Session updatedSession = builder.build();
    // update session in server-side data store
    // store the updated session in a new Fernet token
    final Token retval = Token.generate(random, key, updatedSession.toByteArray());
    return retval.serialise();
}
Also used : WebApplicationException(javax.ws.rs.WebApplicationException) Instant(java.time.Instant) Builder(com.macasaet.fernet.example.pb.Example.Session.Builder) BadRequestException(javax.ws.rs.BadRequestException) Token(com.macasaet.fernet.Token) Session(com.macasaet.fernet.example.pb.Example.Session) Path(javax.ws.rs.Path) PUT(javax.ws.rs.PUT)

Example 3 with Session

use of com.macasaet.fernet.example.pb.Example.Session in project fernet-java8 by l0s.

the class ProtocolBuffersExampleIT method testRenewal.

@Test
public final void testRenewal() {
    // given
    final HttpServletResponse initialResponse = mock(HttpServletResponse.class);
    final String initialToken = createSession(initialResponse);
    verify(initialResponse).addHeader(eq("Location"), locationHeaderCaptor.capture());
    final String location = locationHeaderCaptor.getValue();
    final String sessionId = location.substring(location.lastIndexOf('/') + 1);
    // when
    final HttpServletResponse renewalResponse = mock(HttpServletResponse.class);
    final String subsequentToken = renew(sessionId, initialToken, renewalResponse);
    // then
    final Session result = Token.fromString(subsequentToken).validateAndDecrypt(key, validator);
    assertEquals(1, result.getRenewalCount());
    assertEquals(sessionId, result.getSessionId());
}
Also used : HttpServletResponse(javax.servlet.http.HttpServletResponse) Session(com.macasaet.fernet.example.pb.Example.Session) Test(org.junit.Test)

Aggregations

Session (com.macasaet.fernet.example.pb.Example.Session)3 Token (com.macasaet.fernet.Token)2 Builder (com.macasaet.fernet.example.pb.Example.Session.Builder)2 Path (javax.ws.rs.Path)2 Instant (java.time.Instant)1 HttpServletResponse (javax.servlet.http.HttpServletResponse)1 BadRequestException (javax.ws.rs.BadRequestException)1 POST (javax.ws.rs.POST)1 PUT (javax.ws.rs.PUT)1 WebApplicationException (javax.ws.rs.WebApplicationException)1 Test (org.junit.Test)1