package restx.security; import com.google.common.base.Optional; import com.google.common.collect.ImmutableMap; import restx.common.UUIDGenerator; import restx.http.HttpStatus; import restx.Status; import restx.WebException; import restx.annotations.DELETE; import restx.annotations.GET; import restx.annotations.POST; import restx.annotations.RestxResource; import restx.factory.Component; import java.util.Map; @Component @RestxResource(priority = 10000) public class SessionResource { private final BasicPrincipalAuthenticator authenticator; private final UUIDGenerator uuidGenerator; public SessionResource(BasicPrincipalAuthenticator authenticator, UUIDGenerator uuidGenerator) { this.authenticator = authenticator; this.uuidGenerator = uuidGenerator; } @PermitAll @POST("/sessions") public Session authenticate(Map session) { RestxSession.current().clearPrincipal(); RestxSession.current().define(String.class, Session.SESSION_DEF_KEY, null); Map<String, ?> principal = getPrincipal(session); if (principal == null) { throw new WebException(HttpStatus.UNAUTHORIZED); } String name = (String) principal.get("name"); String passwordHash = (String) principal.get("passwordHash"); Optional<? extends RestxPrincipal> principalOptional = authenticator.authenticate( name, passwordHash, ImmutableMap.copyOf(principal)); if (principalOptional.isPresent()) { String sessionKey = uuidGenerator.doGenerate(); RestxSession.current().authenticateAs(principalOptional.get()); RestxSession.current().define(String.class, Session.SESSION_DEF_KEY, sessionKey); return new Session(sessionKey, principalOptional.get()); } else { throw new WebException(HttpStatus.UNAUTHORIZED); } } @SuppressWarnings("unchecked") protected Map<String, ?> getPrincipal(Map session) { return (Map<String, ?>) session.get("principal"); } @GET("/sessions/current") public Session currentSession() { String sessionKey = RestxSession.current().get(String.class, Session.SESSION_DEF_KEY).get(); RestxPrincipal principal = RestxSession.current().getPrincipal().get(); return new Session(sessionKey, principal); } @PermitAll @DELETE("/sessions/{sessionKey}") public Status logout(String sessionKey) { RestxSession.current().clearPrincipal(); RestxSession.current().define(String.class, Session.SESSION_DEF_KEY, null); return Status.of("logout"); } }