using System; using System.Collections.Generic; using System.Linq; using System.Web.Mvc; using NHibernate; using NHibernate.Linq; using Sleis.Models; using Sleis.ViewModels; using Sleis.Infrastructure; using Sleis.Service; using Sleis.Utility; using Sleis.Validation; using Sleis.Validation.Attribute; using Sleis.Validation.Spring; using Sleis.Models.ErrorHandling; namespace Sleis.Controllers { [HandleError] public class DocumentController : BaseController { public DocumentService DocumentService { get; set; } public List AgreementQuestions { get; set; } public string AgreementQuestionsErrorMessage { get; set; } public string DocumentSignErrorMessage { get; set; } public string AdditionalLegalTextMessage { get; set; } public override void Init() { base.Init(); ArgumentValidationUtility.ThrowOnNull(DocumentService, "DocumentService"); ArgumentValidationUtility.ThrowOnEmpty(AgreementQuestions, "DocumentService"); ArgumentValidationUtility.ThrowOnNull(AgreementQuestionsErrorMessage, "AgreementQuestionsErrorMessage"); ArgumentValidationUtility.ThrowOnNull(DocumentSignErrorMessage, "DocumentSignErrorMessage"); } [Authorize, AppFacilityRoleValidation(AppUserRoleType.FacilitySubmitter)] public ActionResult Start(int facilityId, int reportId) { if (AppUser.User.ContactSecAnswers.Count < 1) { TempData[Constants.GlobalMessageKey] = new SimpleMessage(AgreementQuestionsErrorMessage, true); return RedirectToAction("Profile", "User"); } DocumentService.Audit(new AppEventModel(EventType.Audit, AppUser.User.Email, "Report Submission Initiated.", Request.UserHostAddress)); SetSelectedFacility(facilityId); FacilityView model = DocumentService.ReportService.GetReportFacility(facilityId, reportId); return View(model); } [Authorize] public ActionResult Make(int facilityId, int reportId, bool print=false) { try { SetSelectedFacility(facilityId); SubmissionDocumentModel doc = DocumentService.Make(facilityId, reportId, AppUser.User); SessionUtility.SetSessionVar(Constants.LastDocumentId, doc.Id); return File(doc.UnsignedContent, doc.ContenType, doc.Name); } catch (Exception ex) { Log.Error("Error while generating report PDF", ex); TempData[Constants.GlobalMessageKey] = new SimpleMessage("The Emissions Inventory Report cannot be generated due to data quality issues. Please click the Validate Report button to view current data quality issues.", true); //initiated through report home, redirect back to there if (print) { return RedirectToAction("Report", "Facility", new { id = reportId, facilityId=facilityId}); } return RedirectToAction("Start", new { facilityId = facilityId, reportId = reportId}); } } [Authorize, AppFacilityRoleValidation(AppUserRoleType.FacilitySubmitter)] public ActionResult Agree(int facilityId, int reportId) { SetSelectedFacility(facilityId); FacilityView facility = DocumentService.ReportService.GetReportFacility(facilityId, reportId); AgreementView model = new AgreementView() { Facility = facility, AgreementQuestions = AgreementQuestions, AdditionalLegalText = AdditionalLegalTextMessage }; return View(model); } [Authorize, AppFacilityRoleValidation(AppUserRoleType.FacilitySubmitter)] public ActionResult Auth(int facilityId, int reportId) { if (AppUser.User.ContactSecAnswers.Count < 1) { TempData[Constants.GlobalMessageKey] = new SimpleMessage(AgreementQuestionsErrorMessage, true); return RedirectToAction("Profile", "User"); } try { List questions = AppUser.User.ContactSecAnswers; SetSelectedFacility(facilityId); FacilityView facility = DocumentService.ReportService.GetReportFacility(facilityId, reportId); SubmissionRequestAuthView model = new SubmissionRequestAuthView() { Facility = facility, Question = questions[new Random().Next(0, questions.Count - 1)].Question, User = AppUser, FacilityId = facility.Facility.Id, ReportId = facility.Report.Id }; return View("Auth", model); } catch (Exception ex) { Log.Error("Error while generating report PDF", ex); TempData[Constants.GlobalMessageKey] = new SimpleMessage("Error while generating document. Please see logs for details", true); return RedirectToAction("Start", new { facilityId = facilityId, reportId = reportId }); } } [Authorize, AppFacilityRoleValidation(AppUserRoleType.FacilitySubmitter)] public ActionResult Sign(SubmissionRequestAuthView model) { //TODO: Does the current user have the necessary rights to sign this document? SetSelectedFacility(model.FacilityId); UserModel authedUser = null; int documentId = SessionUtility.Get(Constants.LastDocumentId); //Check if the document was generated if (documentId < 1) { Log.Error("Document not generated"); TempData[Constants.GlobalMessageKey] = new SimpleMessage("Please generate document first", true); return RedirectToAction("Start", new { facilityId = model.FacilityId, reportId = model.ReportId }); } //Check if they have been certified if (!AppUser.User.IsElectronicSigVerified) { Log.Error("User not electronic sig verified"); TempData[Constants.GlobalMessageKey] = new SimpleMessage(AgreementQuestionsErrorMessage, true); return RedirectToAction("Start", new { facilityId = model.FacilityId, reportId = model.ReportId }); } //Authenticate user try { SimpleAuthModel auth = new SimpleAuthModel(); auth.EmailAddress = AppUser.User.Email; auth.Password = model.Password; authedUser = UserService.AuthUser(auth); } catch (AccountLockedException ex) { throw ex; } catch (Exception ex) { Log.Error("Error authenticating for submission", ex); TempData[Constants.GlobalMessageKey] = new SimpleMessage(DocumentSignErrorMessage, true); return RedirectToAction("Auth", new { facilityId = model.FacilityId, reportId = model.ReportId }); } //Check user security question try { if(!UserService.ValidateUserSecurityQuestionAnswer(authedUser, model.Question, model.Answer)) throw new ApplicationException("Invalid answer"); } catch (AccountLockedException ex) { throw ex; } catch (Exception ex) { Log.Error("Error while compring question to answer", ex); TempData[Constants.GlobalMessageKey] = new SimpleMessage(DocumentSignErrorMessage, true); return RedirectToAction("Auth", new { facilityId = model.FacilityId, reportId = model.ReportId }); } SubmissionDocumentModel signedDocumentModel = null; try { //TODO: Check how many of these are actually needed Dictionary args = new Dictionary(); args.Add("Signed By", AppUser.User.FullName); args.Add("Organization", AppUser.User.Org); args.Add("URL", Request.Url.AbsoluteUri); args.Add("Agent", Request.UserAgent); args.Add("IP", Request.UserHostAddress); args.Add("Time", DateTime.Now.ToString()); for (int i = 0; i < AgreementQuestions.Count; i++) { args.Add(String.Format("Agreement #{0}", i + 1), AgreementQuestions[i]); } signedDocumentModel = DocumentService.Sign(documentId, AppUser.User, args); } catch (Exception ex) { Log.Error("Error while signing report PDF", ex); TempData[Constants.GlobalMessageKey] = new SimpleMessage("Error while signing document. Please see logs for details", true); return RedirectToAction("Auth", new { facilityId = model.FacilityId, reportId = model.ReportId }); } FacilityView facility = DocumentService.ReportService.GetReportFacility(model.FacilityId, model.ReportId); SubmissionRequestAuthView resultModel = new SubmissionRequestAuthView() { Facility = facility, User = AppUser, FacilityId = facility.Facility.Id, ReportId = facility.Report.Id, SignedOn = signedDocumentModel.SignedOn, ConfirmNumber = signedDocumentModel.Number, SignedDocumentId = signedDocumentModel.Id }; return View("End", resultModel); } [Authorize, AppFacilityRoleValidation(AppUserRoleType.AgencySubmitter, AppUserRoleType.FacilityAdmin, AppUserRoleType.FacilityEditor)] public ActionResult View(int documentId) { //TODO: Somehow check if the user invoking this should be able to see this document SubmissionDocumentModel doc = DocumentService.View(documentId); return File(doc.SubmissionCor.SignedContent, doc.ContenType, doc.Name); } } }