package fi.otavanopisto.muikku.plugins.forgotpassword; import javax.ejb.Stateful; import javax.enterprise.context.RequestScoped; import javax.inject.Inject; import javax.ws.rs.GET; import javax.ws.rs.Path; import javax.ws.rs.Produces; import javax.ws.rs.QueryParam; import javax.ws.rs.core.Response; import javax.ws.rs.core.Response.Status; import fi.otavanopisto.muikku.controller.SystemSettingsController; import fi.otavanopisto.muikku.i18n.LocaleController; import fi.otavanopisto.muikku.mail.Mailer; import fi.otavanopisto.muikku.model.base.SchoolDataSource; import fi.otavanopisto.muikku.model.users.UserEntity; import fi.otavanopisto.muikku.plugin.PluginRESTService; import fi.otavanopisto.muikku.plugins.user.UserPendingPasswordChange; import fi.otavanopisto.muikku.plugins.user.UserPendingPasswordChangeDAO; import fi.otavanopisto.muikku.rest.RESTPermitUnimplemented; import fi.otavanopisto.muikku.schooldata.RestCatchSchoolDataExceptions; import fi.otavanopisto.muikku.schooldata.SchoolDataBridgeSessionController; import fi.otavanopisto.muikku.schooldata.SchoolDataBridgeUnauthorizedException; import fi.otavanopisto.muikku.schooldata.UserSchoolDataController; import fi.otavanopisto.muikku.servlet.BaseUrl; import fi.otavanopisto.muikku.session.SessionController; import fi.otavanopisto.muikku.users.UserEntityController; @Path("/forgotpassword") @RequestScoped @Stateful @Produces ("application/json") @RestCatchSchoolDataExceptions public class ForgotPasswordRESTService extends PluginRESTService { private static final long serialVersionUID = -3009238121067011985L; @Inject private LocaleController localeController; @Inject private SessionController sessionController; @Inject private UserSchoolDataController userSchoolDataController; @Inject private UserEntityController userEntityController; @Inject private UserPendingPasswordChangeDAO userPendingPasswordChangeDAO; @Inject private SchoolDataBridgeSessionController schoolDataBridgeSessionController; @Inject private SystemSettingsController systemSettingsController; @Inject private Mailer mailer; @Inject @BaseUrl private String baseUrl; @Path("/reset") @GET @RESTPermitUnimplemented public Response resetPassword(@QueryParam("email") String email) { UserEntity userEntity = userEntityController.findUserEntityByEmailAddress(email); if (userEntity == null) return Response.status(Status.NOT_FOUND).build(); try { UserPendingPasswordChange passwordChange = userPendingPasswordChangeDAO.findByUserEntity(userEntity); schoolDataBridgeSessionController.startSystemSession(); try { String confirmationHash = userSchoolDataController.requestPasswordResetByEmail(userEntity.getDefaultSchoolDataSource(), email); if (passwordChange != null) passwordChange = userPendingPasswordChangeDAO.updateHash(passwordChange, confirmationHash); else passwordChange = userPendingPasswordChangeDAO.create(userEntity, confirmationHash); // TODO Email could be added to the reset link for added security (email+hash rather than just hash) String resetLink = baseUrl + "/forgotpassword/reset?h=" + passwordChange.getConfirmationHash(); String mailSubject = localeController.getText(sessionController.getLocale(), "plugin.forgotpassword.mailSubject"); String mailContent = localeController.getText(sessionController.getLocale(), "plugin.forgotpassword.mailContent", new String[] { resetLink }); // TODO System sender address needs to be configurable mailer.sendMail(systemSettingsController.getSystemEmailSenderAddress(), email, mailSubject, mailContent); } finally { schoolDataBridgeSessionController.endSystemSession(); } return Response.noContent().build(); } catch (SchoolDataBridgeUnauthorizedException e) { return Response.status(Status.FORBIDDEN).build(); } } @Path("/confirm") @GET @RESTPermitUnimplemented public Response confirmResetPassword(ConfirmResetPassword crp) { UserPendingPasswordChange passwordChange = userPendingPasswordChangeDAO.findByConfirmationHash(crp.getResetCode()); UserEntity userEntity = userEntityController.findUserEntityById(passwordChange.getUserEntity()); // TODO: tis a guesstimate of the datasource SchoolDataSource schoolDataSource = userEntity.getDefaultSchoolDataSource(); try { userSchoolDataController.confirmResetPassword(schoolDataSource, crp.getResetCode(), crp.getNewPassword()); return Response.noContent().build(); } catch (SchoolDataBridgeUnauthorizedException e) { return Response.status(Status.FORBIDDEN).build(); } } }