api/src/main/java/com/wrixton/doorlock/resources/DoorlockApiAppResource.java
package com.wrixton.doorlock.resources;
import com.codahale.metrics.annotation.Timed;
import com.wrixton.doorlock.DAO.BasicDoorlockUser;
import com.wrixton.doorlock.DAO.DoorlockUser;
import com.wrixton.doorlock.DAO.DoorlockUserLoginCheck;
import com.wrixton.doorlock.DAO.LoginStatus;
import com.wrixton.doorlock.DAO.QueryDAO;
import com.wrixton.doorlock.DAO.Status;
import com.wrixton.doorlock.DAO.UserIDInfo;
import com.wrixton.doorlock.ForgotPasswordRequest;
import com.wrixton.doorlock.LoginRequest;
import com.wrixton.doorlock.OtherUserUpdate;
import com.wrixton.doorlock.RegisterUserRequest;
import com.wrixton.doorlock.ResetPasswordRequest;
import com.wrixton.doorlock.SessionRequest;
import com.wrixton.doorlock.USER_TYPE;
import com.wrixton.doorlock.UpdateCurrentUserRequest;
import com.wrixton.doorlock.UpdateOtherUserRequest;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.lang3.BooleanUtils;
import org.apache.commons.lang3.RandomStringUtils;
import org.json.simple.parser.JSONParser;
import redis.clients.jedis.Jedis;
import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;
import javax.ws.rs.Consumes;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.client.Client;
import javax.ws.rs.client.ClientBuilder;
import javax.ws.rs.client.WebTarget;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import java.io.FileReader;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.logging.Logger;
import static com.wrixton.doorlock.ConfigurationMethods.saltPassword;
@Api(tags = {"Api"})
@Path("/")
@Produces(MediaType.APPLICATION_JSON)
public class DoorlockApiAppResource {
private static final Logger LOG = Logger.getLogger(DoorlockApiAppResource.class.getName());
private final String CONFIG_FILE = "config.json";
private final QueryDAO queriesDAO;
public DoorlockApiAppResource(QueryDAO queriesDAO) {
this.queriesDAO = queriesDAO;
}
@ApiOperation("Index")
@GET
@Timed
@Produces(MediaType.TEXT_HTML)
public Object getIndex(@Context HttpServletRequest request) throws Exception {
Client myClient = ClientBuilder.newClient();
WebTarget target = myClient.target(request.getRequestURL().toString() + "lib/index.htm");
return target.request(MediaType.TEXT_HTML).get();
}
@ApiOperation("Log user in")
@POST
@Timed
@Consumes(MediaType.APPLICATION_JSON)
@Path("/login")
public LoginStatus login(@Valid LoginRequest body, @Context Jedis jedis) {
try {
String sid = body.getSid();
String token = body.getToken();
System.out.println(sid);
DoorlockUserLoginCheck user = queriesDAO.loginUser(body.getUsername(), saltPassword(body.getUsername(), body.getPassword()));
if (user == null) {
return new LoginStatus(null, new Status(false));
}
jedis.hset("loggedInUsers:" + sid, "name", user.getName());
jedis.hset("loggedInUsers:" + sid, "username", user.getUsername());
jedis.hset("loggedInUsers:" + sid, "UserID", "" + user.getUserID());
jedis.hset("loggedInUsers:" + sid, "admin", "" + user.isAdmin());
return new LoginStatus(user, new Status(true));
} catch (Exception e) {
e.printStackTrace();
System.out.println(e.getMessage());
}
return new LoginStatus(null, new Status(false));
}
@ApiOperation("Logout user in")
@POST
@Timed
@Consumes(MediaType.APPLICATION_JSON)
@Path("/logout")
public Status logout(@Valid SessionRequest sid, @Context Jedis jedis) {
jedis.hdel(getRedisKey(sid), "name");
jedis.hdel(getRedisKey(sid), "username");
jedis.hdel(getRedisKey(sid), "UserID");
jedis.hdel(getRedisKey(sid), "admin");
return new Status(true);
}
@ApiOperation("Check if user is logged in")
@POST
@Timed
@Consumes(MediaType.APPLICATION_JSON)
@Path("/IsLoggedIn")
public LoginStatus isLoggedIn(@Valid SessionRequest sid, @Context Jedis jedis) {
DoorlockUserLoginCheck user = null;
Status status = new Status(false);
String id = jedis.hget(getRedisKey(sid), "UserID");
String name = jedis.hget(getRedisKey(sid), "name");
String username = jedis.hget(getRedisKey(sid), "username");
String admin = jedis.hget(getRedisKey(sid), "admin");
if (id != null && name != null && username != null && admin != null) {
user = new DoorlockUserLoginCheck(id, name, username, BooleanUtils.toBoolean(admin));
status = new Status(true);
}
return new LoginStatus(user, status);
}
@ApiOperation("Get user information")
@POST
@Timed
@Consumes(MediaType.APPLICATION_JSON)
@Path("/GetUserInfo")
public DoorlockUser getUserInfo(@Valid SessionRequest sid, @Context Jedis jedis) {
try {
String redisKey = getRedisKey(sid);
String redisRateKey = "rate:" + redisKey;
Long amount = jedis.incr(redisRateKey);
int limit = 10;
jedis.expire(redisRateKey, limit);
if (amount <= limit) {
System.out.println("starting to rate limit");
}
String username = jedis.hget(redisKey, "username");
if (username != null) {
return queriesDAO.getUserInfo(username);
}
} catch (Exception e) {
LOG.severe(e.getLocalizedMessage());
}
return null;
}
@ApiOperation("Get all users")
@POST
@Timed
@Consumes(MediaType.APPLICATION_JSON)
@Path("/GetAllUsers")
public Map<String, List<BasicDoorlockUser>> getAllUsers(@Valid SessionRequest sid, @Context Jedis jedis) {
try {
System.out.println(sid);
boolean isAdmin = isAdmin(sid, jedis);
if (isAdmin) {
String username = jedis.hget(getRedisKey(sid), "username");
return getAllUsers(username);
}
} catch (Exception e) {
e.printStackTrace();
System.out.println(e.getMessage());
}
return new HashMap<>();
}
private boolean isAdmin(@Valid SessionRequest sid, @Context Jedis jedis) {
String admin;
admin = jedis.hget(getRedisKey(sid), "admin");
return BooleanUtils.toBoolean(admin);
}
@ApiOperation("Register new user")
@POST
@Timed
@Consumes(MediaType.APPLICATION_JSON)
@Path("/RegisterUser")
public Status registerUser(@Valid RegisterUserRequest registerUserRequest, @Context Jedis jedis) {
try {
if (isAdmin(registerUserRequest.getSessionRequest(), jedis)) {
queriesDAO.registerUser(registerUserRequest.getName(), registerUserRequest.getUsername(),
saltPassword(registerUserRequest.getUsername(), registerUserRequest.getPassword()),
registerUserRequest.getEmail(), registerUserRequest.getAuthyID(), registerUserRequest.getCardID().trim(),
registerUserRequest.isAdmin());
return new Status(true);
}
} catch (Exception e) {
e.printStackTrace();
}
return new Status(false);
}
@ApiOperation("Update current user")
@POST
@Timed
@Consumes(MediaType.APPLICATION_JSON)
@Path("/UpdateCurrentUser")
public Status updateCurrentUser(@Valid UpdateCurrentUserRequest updateCurrentUserRequest) {
// queriesDAO.updateCurrentUser(updateCurrentUserRequest.get)
return new Status(false);
}
@ApiOperation("Update other user")
@POST
@Timed
@Consumes(MediaType.APPLICATION_JSON)
@Path("/UpdateOtherUser")
public Status updateOtherUser(@Valid UpdateOtherUserRequest updateOtherUserRequest, @Context Jedis jedis) {
SessionRequest sid = updateOtherUserRequest.getSessionRequest();
boolean isAdmin = isAdmin(sid, jedis);
if (!isAdmin) {
return new Status(false);
}
OtherUserUpdate update = updateOtherUserRequest.getOtherUserUpdate();
boolean userIsAdmin = false;
boolean userIsActive = false;
USER_TYPE type = updateOtherUserRequest.getOtherUserUpdate().getType();
switch (type) {
case ADMIN:
userIsAdmin = true;
userIsActive = true;
break;
case ACTIVE:
userIsActive = true;
break;
case INACTIVE:
default:
break;
}
int result = queriesDAO.updateOtherUser(update.getUuid(), userIsAdmin, userIsActive);
if (result != 1) {
LOG.severe("Error with updateOtherUser, updated " + result + " rows with: " + updateOtherUserRequest);
return new Status(false);
}
return new Status(true);
}
@ApiOperation("Submit forgot user forgot password")
@POST
@Timed
@Consumes(MediaType.APPLICATION_JSON)
@Path("/ForgotPassword")
public Status forgotPassword(@Valid ForgotPasswordRequest forgotPasswordRequest) {
UserIDInfo userIdInfoForName = queriesDAO.findUserIdForName(forgotPasswordRequest.getUsername());
if (userIdInfoForName == null) {
return new Status(false);
}
String random = RandomStringUtils.random(128, true, true);
queriesDAO.forgotPassword(userIdInfoForName.getId(), random);
queriesDAO.changeUserStatus(forgotPasswordRequest.getUsername(), false);
// queriesDAO.updateOtherUser(userIdInfoForName.getUuid(), userIdInfoForName.isAdmin(), false);
return new Status(true);
}
@ApiOperation("Reset user password")
@POST
@Timed
@Consumes(MediaType.APPLICATION_JSON)
@Path("/ResetPassword")
public Status resetPassword(@Valid ResetPasswordRequest resetPasswordRequest) {
Long userId = queriesDAO.checkResetUrl(resetPasswordRequest.getResetUrl());
if (userId == null) {
return new Status(false);
}
// queriesDAO.forgotPassword();
queriesDAO.changeUserStatus(resetPasswordRequest.getUsername(), true);
queriesDAO.resetPassword(resetPasswordRequest.getUsername(), resetPasswordRequest.getPassword());
return new Status(true);
}
@ApiOperation("Check lock status")
@POST
@Timed
@Consumes(MediaType.APPLICATION_JSON)
@Path("/LockStatus")
public String lockStatus(@Valid SessionRequest sid, @Context Jedis jedis) {
// String lockStatus = jedis.get("lockStatus");
return "{\"Status\":\"open\",\"isLocked\":\"1\"}";
}
@ApiOperation("Lock the lock")
@POST
@Timed
@Consumes(MediaType.APPLICATION_JSON)
@Path("/Lock")
public String lock(@Valid SessionRequest sid, @Context Jedis jedis) {
// jedis.set("lockStatus", "isLocked");
return "{\"Status\":\"some other status\"}";
}
@ApiOperation("Unlock the lock")
@POST
@Timed
@Consumes(MediaType.APPLICATION_JSON)
@Path("/Unlock")
public String unlock(@Valid SessionRequest sid, @Context Jedis jedis) {
// jedis.set("lockStatus", "isLocked");
return "{\"Status\":\"some status\"}";
}
@ApiOperation("Get config information")
@POST
@Timed
@Consumes(MediaType.APPLICATION_JSON)
@Path("/config")
public Object getConfig(@Valid SessionRequest sid, @Context Jedis jedis) {
String admin = jedis.hget(getRedisKey(sid), "admin");
if (admin == null) {
return null;
}
JSONParser jp = new JSONParser();
try {
return jp.parse(new FileReader(CONFIG_FILE));
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
private String getRedisKey(@Valid SessionRequest sid) {
return "loggedInUsers:" + sid.getSid();
}
private Map<String, List<BasicDoorlockUser>> getAllUsers(String currentUsername) {
Map<String, List<BasicDoorlockUser>> results = new HashMap<>(3);
List<BasicDoorlockUser> allAdmins = queriesDAO.getAllAdmins(currentUsername);
List<BasicDoorlockUser> allActiveUsers = queriesDAO.getAllActiveUsers();
List<BasicDoorlockUser> allInactiveUsers = queriesDAO.getAllInactiveUsers();
results.put("Admins", allAdmins);
results.put("ActiveUsers", allActiveUsers);
results.put("InactiveUsers", allInactiveUsers);
return results;
}
}