package org.karmaexchange.auth; import static org.karmaexchange.util.OfyService.ofy; import java.util.Date; import java.util.UUID; import javax.annotation.Nullable; import javax.servlet.http.Cookie; import javax.servlet.http.HttpServletRequest; import javax.ws.rs.core.NewCookie; import lombok.Data; import lombok.NoArgsConstructor; import org.apache.commons.lang3.time.DateUtils; import org.karmaexchange.dao.User; import org.karmaexchange.resources.msg.ErrorResponseMsg; import org.karmaexchange.resources.msg.ErrorResponseMsg.ErrorInfo; import org.karmaexchange.util.ServletUtil; import com.googlecode.objectify.Key; import com.googlecode.objectify.annotation.Cache; import com.googlecode.objectify.annotation.Entity; import com.googlecode.objectify.annotation.Id; import com.googlecode.objectify.annotation.Index; @Entity @Cache @Data @NoArgsConstructor public class Session { private static final int SESSION_EXPIRATION_HOURS = 24; private static final String SESSION_COOKIE_NAME = "session"; // maxAge: 0 - means expire the cookie public static final NewCookie LOGOUT_COOKIE = new NewCookie(SESSION_COOKIE_NAME, "", "/", null, null, 0, false); @Id private String id; @Index private Date expiresOn; private Key<User> userKey; public Session(Key<User> userKey) { id = UUID.randomUUID().toString(); expiresOn = DateUtils.addHours(new Date(), SESSION_EXPIRATION_HOURS); this.userKey = userKey; } public NewCookie getCookie() { // TODO(avaliani): In the future see which version of Jersey supports http only cookies. // maxAge: -1 - means session / browser lifetime cookie return new NewCookie(SESSION_COOKIE_NAME, id, "/", null, null, -1, false); } /** * @return the current session. If the session has expired a {@link WebApplicationException} * is thrown with error type {@link ErrorInfo#Type.SESSION_EXPIRED}. */ @Nullable public static Session getCurrentSession(HttpServletRequest req) { Key<Session> sessionKey = getCurrentSessionKey(req); if (sessionKey != null) { Session session = ofy().load().key(sessionKey).now(); if ((session == null) || session.isExpired()) { throw ErrorResponseMsg.createException("Session has expired", ErrorInfo.Type.SESSION_EXPIRED); } return session; } return null; } /** * @return a key to the current session. */ @Nullable public static Key<Session> getCurrentSessionKey(HttpServletRequest req) { Cookie cookie = ServletUtil.getCookie(req, SESSION_COOKIE_NAME); if (cookie != null) { return getKey(cookie); } return null; } private static Key<Session> getKey(Cookie sessionCookie) { return Key.create(Session.class, sessionCookie.getValue()); } private boolean isExpired() { return new Date().after(expiresOn); } }