/**
* Copyright (C) 2012 KRM Associates, Inc. healtheme@krminc.com
*
* 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.
*/
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package com.krminc.phr.web.form;
import com.krminc.phr.api.service.util.ServiceUtils;
import com.krminc.phr.core.AppConfig;
import com.krminc.phr.core.UserConfig;
import com.krminc.phr.dao.PersistenceService;
import com.krminc.phr.domain.HealthRecord;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.persistence.EntityManager;
import javax.ws.rs.Consumes;
import javax.ws.rs.FormParam;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.UriInfo;
import com.krminc.phr.domain.User;
import com.krminc.phr.domain.UserPreferences;
import com.sun.jersey.api.core.ResourceContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
/**
*
* @author cmccall
*/
public class SelfFormProcessor {
final Logger logger = LoggerFactory.getLogger(SelfFormProcessor.class);
@Context
protected ResourceContext resourceContext;
@Context
protected UriInfo uriInfo;
@Context
HttpServletRequest req;
public SelfFormProcessor() {
}
/**
* Alter User Password.
* Security on this method is handled at controller level via authorizeFor
* Use asHealthRecord to interpret the path param as a healthRecord Id instead of user ID for contexts where uID unavailable
*
* @return redirect
*/
@Path("{userId}/password/")
@POST
@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
public Response alterUserPassword(
@PathParam("userId") Long userId,
@FormParam("currentPassword") String currentPassword,
@FormParam("newPassword") String newPassword,
@FormParam("newPassword2") String newPassword2,
@FormParam("redirectUri") String redirectUri,
@FormParam("asHealthRecord") Boolean asHR
) {
String status = "unknown";
String hrid = null;
User user = null;
if (!newPassword.equals(newPassword2)) {
//passwords do not match
status = "nomatch";
} else if (!ServiceUtils.isPassword(newPassword)) {
//new password invalid
status = "invalid";
} else {
PersistenceService persistenceSvc = PersistenceService.getInstance();
if (asHR == null) asHR = false;
try {
persistenceSvc.beginTx();
EntityManager em = persistenceSvc.getEntityManager();
if (asHR) {
user = em.find(HealthRecord.class, userId).getUser();
} else {
user = em.find(User.class, userId);
}
if (user == null) throw new Exception("Unable to locate user entity");
if (user.isPatient()) {
if (hrid == null) {
if (asHR) {
hrid = userId.toString();
} else {
hrid = user.getPrimaryHealthRecord().getHealthRecordId().toString();
//hrid = user.getHealthRecords().get(0).getHealthRecordId().toString();
}
}
// patients will pass in their own redirect URL using own HRID generally
if (redirectUri == null || redirectUri.isEmpty()) {
redirectUri = "." + AppConfig.PATH_PATIENT_ROOT + "/" + hrid + "/account";
}
}
if (user.testPassword(currentPassword) == false) {
throw new Exception("Incorrect password");
} else if (user.getUsername().equalsIgnoreCase(newPassword)) {
//error if setting password with username
throw new Exception("Password matches username");
}
user.setPassword(newPassword);
user.setRequiresReset(Boolean.FALSE);
em.merge(user);
persistenceSvc.commitTx();
status = "updated";
} catch (Exception e) {
logger.error("Password Update Failed - " + e.getMessage());
status = "failed";
} finally {
persistenceSvc.close();
}
}
//mirror getFirstLogin() in Main.java here
if ("updated".equals(status) && redirectUri.contains("passwordchange")) {
//password has been updated on first login/forced change
HttpSession session = req.getSession(); //create session if none exists
if (session != null)
session.setAttribute("needsreset", "false");
if (req.isUserInRole(UserConfig.ROLE_PATIENT) || req.isUserInRole(UserConfig.ROLE_CARETAKER)) {
if (hrid != null) {
session.setAttribute("healthRecordId", hrid);
if (req.isUserInRole(UserConfig.ROLE_PATIENT)) {
UserPreferences pref = user.getPrimaryHealthRecord().getPreferences();
boolean showCN;
if (pref != null) {
showCN = (pref.getShowCarenotebook() == true) ? true : false;
} else {
showCN = false;
}
session.setAttribute("showCareNotebook", showCN);
}
} else {
//needs health record id in session to perform data manipulation
if (req.isUserInRole(UserConfig.ROLE_PATIENT)) {
logger.error("Found null healthrecord id for patient.");
status = "failed";
}
}
}
}
return Response.seeOther(uriInfo.getBaseUri().resolve(redirectUri + "?pwStatus=" + status)).build();
}
/**
* Alter User Account Info
* Security on this method is handled at controller level via authorizeFor
*
* @return redirect
*/
@Path("{healthRecordId}/account/")
@POST
@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
public Response alterUserAccount(
@PathParam("healthRecordId") Long healthRecordId,
@FormParam("email") String email,
@FormParam("preferredName") String preferredName
) {
String status = "unknown";
String redirectUri = "." + AppConfig.PATH_PATIENT_ROOT + "/" + healthRecordId + "/account";
if (!ServiceUtils.isEmail(email)) {
status = "badmail";
return Response.seeOther(uriInfo.getBaseUri().resolve(redirectUri + "?acctStatus=" + status)).build();
}
if (!ServiceUtils.hasAlphaCharacters(preferredName)) {
status = "badname";
return Response.seeOther(uriInfo.getBaseUri().resolve(redirectUri + "?acctStatus=" + status)).build();
}
if (email.isEmpty()) {
status = "nomail";
return Response.seeOther(uriInfo.getBaseUri().resolve(redirectUri + "?acctStatus=" + status)).build();
}
PersistenceService persistenceSvc = PersistenceService.getInstance();
try {
persistenceSvc.beginTx();
EntityManager em = persistenceSvc.getEntityManager();
User user = em.find(HealthRecord.class, healthRecordId).getUser();
if (!user.getEmail().equals(email)) {
user.setEmail(email);
}
if (!preferredName.isEmpty() && !user.getPreferredName().equals(preferredName)) {
user.setPreferredName(preferredName);
}
em.merge(user);
persistenceSvc.commitTx();
status = "updated";
return Response.seeOther(uriInfo.getBaseUri().resolve(redirectUri + "?acctStatus=" + status)).build();
} catch (Exception e) {
logger.error("Account Update Failed", e);
status = "failed";
return Response.seeOther(uriInfo.getBaseUri().resolve(redirectUri + "?acctStatus=" + status)).build();
} finally {
persistenceSvc.close();
}
}
/**
* Alter User Preference Info
* Security on this method is handled at controller level via authorizeFor
*
* @return redirect
*/
@Path("{healthRecordId}/preferences/")
@POST
@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
public Response alterHealthRecordPreferences(
@PathParam("healthRecordId") Long healthRecordId,
@FormParam("carenotebook") String careNotebook
) {
String status = "unknown";
String redirectUri = "." + AppConfig.PATH_PATIENT_ROOT + "/" + healthRecordId + "/account";
boolean careNotebookVal = (careNotebook != null ? true : false);
PersistenceService persistenceSvc = PersistenceService.getInstance();
try {
persistenceSvc.beginTx();
EntityManager em = persistenceSvc.getEntityManager();
HealthRecord hr = em.find(HealthRecord.class, healthRecordId);
UserPreferences preferences = hr.getPreferences();
String username = req.getRemoteUser();
boolean updateHRisRequired = false;
if (preferences == null) {
preferences = new UserPreferences(username);
preferences.setShowCarenotebook(careNotebookVal);
hr.setPreferences(preferences);
updateHRisRequired = true;
} else {
preferences.setLastUpdatedUser(username);
preferences.setShowCarenotebook(careNotebookVal);
}
if (updateHRisRequired) em.merge(hr);
em.merge(preferences);
persistenceSvc.commitTx();
status = "updated";
//update session value
req.getSession(Boolean.FALSE).setAttribute("showCareNotebook", careNotebookVal);
return Response.seeOther(uriInfo.getBaseUri().resolve(redirectUri + "?preferenceStatus=" + status)).build();
} catch (Exception e) {
logger.error("Account Preference Update Failed", e);
status = "failed";
return Response.seeOther(uriInfo.getBaseUri().resolve(redirectUri + "?preferenceStatus=" + status)).build();
} finally {
persistenceSvc.close();
}
}
}