/* * Copyright (C) 2014 Divide.io * * Licensed 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 io.divide.server.endpoints; import io.divide.dao.ServerDAO; import io.divide.server.auth.SecManager; import io.divide.server.auth.UserContext; import io.divide.server.dao.DAOManager; import io.divide.server.dao.Session; import io.divide.shared.server.AuthServerLogic; import io.divide.shared.transitory.Credentials; import io.divide.shared.transitory.TransientObject; import org.apache.commons.lang3.exception.ExceptionUtils; import javax.annotation.PostConstruct; import javax.ws.rs.*; import javax.ws.rs.container.ContainerRequestContext; import javax.ws.rs.core.Context; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; import java.util.Calendar; import java.util.Map; import java.util.TimeZone; import java.util.logging.Logger; import static io.divide.server.utils.ResponseUtils.*; import static javax.ws.rs.core.Response.Status; @Path("/auth") public final class AuthenticationEndpoint{ Logger logger = Logger.getLogger(AuthenticationEndpoint.class.getName()); @Context DAOManager dao; @Context SecManager keyManager; private static Calendar c = Calendar.getInstance(TimeZone.getDefault()); AuthServerLogic<TransientObject> authServerLogic; @PostConstruct public void init(){ authServerLogic = new AuthServerLogic<TransientObject>(dao,keyManager); } /* * Saves user credentials */ @POST @Consumes(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON) public Response userSignUp(@Context ContainerRequestContext context, Credentials credentials) { try{ Credentials toSave = authServerLogic.userSignUp(credentials); context.setSecurityContext(new UserContext(context.getUriInfo(),toSave)); logger.info("SignUp Successful. Returning: " + toSave); return ok(toSave); } catch (ServerDAO.DAOException e) { logger.severe(ExceptionUtils.getStackTrace(e)); return fromDAOExpection(e); } catch (Exception e) { logger.severe(ExceptionUtils.getStackTrace(e)); return Response.serverError().build(); } } /** * Checks username/password against that stored in DB, if same return * token, if token expired create new. * @param credentials * @return authentication token */ @PUT @Consumes(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON) public Response userSignIn(@Context ContainerRequestContext context, Credentials credentials) { try{ Credentials dbCreds = authServerLogic.userSignIn(credentials); context.setSecurityContext(new UserContext(context.getUriInfo(),dbCreds)); logger.info("Login Successful. Returning: " + dbCreds); return ok(dbCreds); }catch (ServerDAO.DAOException e) { logger.severe(ExceptionUtils.getStackTrace(e)); return fromDAOExpection(e); } catch (Exception e) { logger.severe(ExceptionUtils.getStackTrace(e)); return Response.serverError().build(); } } @GET @Path("/key") @Produces(MediaType.APPLICATION_JSON) public Response getPublicKey() { try{ return Response .ok() .entity(authServerLogic.getPublicKey()) .build(); } catch (Exception e) { logger.severe(ExceptionUtils.getStackTrace(e)); return Response.serverError().build(); } } /** * Validate a user account * @param token */ @GET @Path("/validate/{token}") @Produces(MediaType.APPLICATION_JSON) public Response validateAccount(@PathParam("token") String token) { try{ if (authServerLogic.validateAccount(token)) { return Response.ok().build(); } else { return Response.status(Status.NOT_FOUND).build(); } }catch (ServerDAO.DAOException e) { return fromDAOExpection(e); } } @GET @Path("/from/{token}") @Produces(MediaType.APPLICATION_JSON) public Response getUserFromToken(@Context ContainerRequestContext context, @PathParam("token") String token) { try{ logger.warning("getUserFromToken"); Credentials user = authServerLogic.getUserFromAuthToken(token); context.setSecurityContext(new UserContext(context.getUriInfo(),user)); return Response.ok(user).build(); }catch (ServerDAO.DAOException e) { e.printStackTrace(); logger.severe(ExceptionUtils.getStackTrace(e)); return fromDAOExpection(e); } } @GET @Path("/recover/{token}") @Produces(MediaType.APPLICATION_JSON) public Response recoverFromOneTimeToken(@Context ContainerRequestContext context, @PathParam("token") String token) { try{ Credentials user = authServerLogic.getUserFromRecoveryToken(token); context.setSecurityContext(new UserContext(context.getUriInfo(),user)); return Response.ok(user).build(); }catch (ServerDAO.DAOException e) { e.printStackTrace(); logger.severe(ExceptionUtils.getStackTrace(e)); return fromDAOExpection(e); } } // @POST // @Path("/reset") // @Consumes(MediaType.APPLICATION_JSON) // @Produces(MediaType.APPLICATION_JSON) // public Response resetAccount(EncryptedEntity encrypted) { // try{ // String email = encrypted.getPlainText(getKeys().getPrivate()); // Query q = new QueryBuilder().select(null).from(Credentials.class).where("emailAddress", OPERAND.EQ, email).limit(1).build(); // // TransientObject to = (TransientObject) ObjectUtils.get1stOrNull(dao.query(q)); // if (to != null) { // ServerCredentials creds = new ServerCredentials(to); // creds.setValidation(getNewAuthToken()); // dao.save(creds); // // EmailMessage emailMessage = new EmailMessage( // "someEmail", // email, // "Tactics Password Reset", // "some link " + creds.getAuthToken()); // // sendEmail(emailMessage); // // return Response // .ok() // .build(); // } else { // return Response // .status(Status.NOT_FOUND) // .build(); // } // } catch (NoSuchAlgorithmException e) { // return Response.serverError().build(); // } catch (DAO.DAOException e) { // return fromDAOExpection(e); // } catch (MessagingException e) { // return errorResponse(e); // } catch (UnsupportedEncodingException e) { // return errorResponse(e); // } // } @POST @Path("/user/data/{userId}") @Consumes(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON) public Response recieveUserData(@Context Session session, @PathParam("userId") String userId, Map<String,?> data) { try{ authServerLogic.recieveUserData(userId,data); return Response.ok().build(); } catch (ServerDAO.DAOException e) { logger.severe(ExceptionUtils.getStackTrace(e)); return fromDAOExpection(e); } } @PUT @Path("/user/data/{userId}") @Produces(MediaType.APPLICATION_JSON) public Response sendUserData(@Context Session session, @PathParam("userId") String userId) { try{ return Response.ok(authServerLogic.sendUserData(userId)).build(); // ok(getUserById(dao,userId).getUserData()); }catch (Exception e) { return errorResponse(e); } } // public void sendEmail(EmailMessage emailMessage) throws MessagingException, UnsupportedEncodingException { // // Properties props = new Properties(); // Session session = Session.getDefaultInstance(props, null); // // Message msg = new MimeMessage(session); // msg.setFrom(new InternetAddress(emailMessage.getFrom(), "")); // msg.addRecipient(Message.RecipientType.TO, new InternetAddress(emailMessage.getTo(), "")); // msg.setSubject(emailMessage.getSubject()); // msg.setText(emailMessage.getBody()); // Transport.send(msg); // // } // // public static class EmailMessage { // private String from; // private String to; // private String subject; // private String body; // // public EmailMessage(String from, String to, String subject, String body) throws MessagingException { // setFrom(from); // setTo(to); // setSubject(subject); // setBody(body); // } // // public String getFrom() { // return from; // } // // public void setFrom(String from) throws MessagingException { // if (!validEmail(from)) throw new MessagingException("Invalid email address!"); // this.from = from; // } // // public String getTo() { // return to; // } // // public void setTo(String to) throws MessagingException { // if (!validEmail(to)) throw new MessagingException("Invalid email address!"); // this.to = to; // } // // public String getSubject() { // return subject; // } // // public void setSubject(String subject) { // this.subject = subject; // } // // public String getBody() { // return body; // } // // public void setBody(String body) { // this.body = body; // } // // private boolean validEmail(String email) { // // editing to make requirements listed // // return email.matches("[A-Z0-9._%+-]+@[A-Z0-9.-]+\\.[A-Z]{2,4}"); // return email.matches("[A-Z0-9._%+-][A-Z0-9._%+-]+@[A-Z0-9.-]+\\.[A-Z]{3}"); // } // } }