/// <summary> /// Call for page with associated FirmaPage /// </summary> protected FirmaViewData(Person currentPerson, Models.FirmaPage firmaPage) { FirmaPage = firmaPage; CurrentPerson = currentPerson; FirmaHomeUrl = SitkaRoute <HomeController> .BuildUrlFromExpression(c => c.Index()); LogInUrl = FirmaHelpers.GenerateLogInUrlWithReturnUrl(); LogOutUrl = FirmaHelpers.GenerateLogOutUrlWithReturnUrl(); RequestSupportUrl = SitkaRoute <HelpController> .BuildUrlFromExpression(c => c.Support()); MakeFirmaMenu(currentPerson); FullProjectListUrl = SitkaRoute <ProjectController> .BuildUrlFromExpression(c => c.Index()); ProjectSearchUrl = SitkaRoute <ProjectController> .BuildUrlFromExpression(c => c.Search(UrlTemplate.Parameter1String)); ProjectFindUrl = SitkaRoute <ProjectController> .BuildUrlFromExpression(c => c.Find(string.Empty)); var currentPersonCanManage = new FirmaPageManageFeature().HasPermission(currentPerson, firmaPage).HasPermission; ViewPageContentViewData = firmaPage != null ? new ViewPageContentViewData(firmaPage, currentPersonCanManage) : null; CustomFooterViewData = new ViewPageContentViewData(Models.FirmaPage.GetFirmaPageByPageType(FirmaPageType.CustomFooter), currentPersonCanManage); TenantName = MultiTenantHelpers.GetTenantName(); TenantDisplayName = MultiTenantHelpers.GetTenantDisplayName(); TenantBannerLogoUrl = MultiTenantHelpers.GetTenantBannerLogoUrl(); }
public static List <string> ValidateImpl(string explanation, List <int> expectedYears, List <IFundingSourceExpenditure> projectFundingSourceExpenditures) { var errors = new List <string>(); // Need to get FundingSources by IDs because we may have unsaved projectFundingSourceExpenditures that won't have a reference to the entity var fundingSourcesIDs = projectFundingSourceExpenditures.Select(x => x.FundingSourceID).Distinct().ToList(); var fundingSources = HttpRequestStorage.DatabaseEntities.FundingSources.Where(x => fundingSourcesIDs.Contains(x.FundingSourceID)); var missingFundingSourceYears = new Dictionary <ProjectFirmaModels.Models.FundingSource, IEnumerable <int> >(); foreach (var fundingSource in fundingSources) { var currentFundingSource = fundingSource; var missingYears = expectedYears .GetMissingYears(projectFundingSourceExpenditures .Where(x => x.FundingSourceID == currentFundingSource.FundingSourceID) .Select(x => x.CalendarYear)).ToList(); if (missingYears.Any()) { missingFundingSourceYears.Add(currentFundingSource, missingYears); } } foreach (var fundingSource in missingFundingSourceYears) { var yearsForErrorDisplay = string.Join(", ", FirmaHelpers.CalculateYearRanges(fundingSource.Value)); errors.Add($"Missing Expenditures for {FieldDefinitionEnum.FundingSource.ToType().GetFieldDefinitionLabel()} '{fundingSource.Key.GetDisplayName()}' for the following years: {string.Join(", ", yearsForErrorDisplay)}. If there are no expenditures to report, save the form with zeros."); } return(errors); }
protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext) { var redirectToLogin = new RedirectResult(FirmaHelpers.GenerateLogInUrlWithReturnUrl()); if (!filterContext.HttpContext.User.Identity.IsAuthenticated) { filterContext.Result = redirectToLogin; return; } throw new SitkaRecordNotAuthorizedException($"You are not authorized for feature \"{FeatureName}\". Log out and log in as a different user or request additional permissions."); }
/// <summary> /// Call for page with associated FirmaPage /// </summary> protected FirmaViewData(FirmaSession currentFirmaSession, ProjectFirmaModels.Models.FirmaPage firmaPage) { FirmaPage = firmaPage; //CurrentPerson = currentPerson; CurrentFirmaSession = currentFirmaSession; FirmaHomeUrl = SitkaRoute <HomeController> .BuildUrlFromExpression(c => c.Index()); LogInUrl = FirmaHelpers.GenerateLogInUrl(); LogOutUrl = FirmaHelpers.GenerateLogOutUrlWithReturnUrl(); CurrentUrl = HttpContext.Current.Request.Url; ForgotPasswordUrl = FirmaHelpers.GenerateForgotPasswordUrlWithReturnUrl(CurrentUrl.AbsoluteUri); RegisterAccountUrl = FirmaHelpers.GenerateCreateAccountWithReturnUrl(CurrentUrl.AbsoluteUri); QaUrl = MultiTenantHelpers.GetRelativeUrlForEnvironment(CurrentUrl, FirmaEnvironmentType.Qa); LocalUrl = MultiTenantHelpers.GetRelativeUrlForEnvironment(CurrentUrl, FirmaEnvironmentType.Local); ProdUrl = MultiTenantHelpers.GetRelativeUrlForEnvironment(CurrentUrl, FirmaEnvironmentType.Prod); TenantSimples = MultiTenantHelpers.GetAllTenantSimples().Where(ts => ts.ShowTenantInSwitcherDropdown).ToList(); RequestSupportUrl = SitkaRoute <HelpController> .BuildUrlFromExpression(c => c.Support()); MakeFirmaMenu(currentFirmaSession); FullProjectListUrl = SitkaRoute <ProjectController> .BuildUrlFromExpression(c => c.Index()); ProjectSearchUrl = SitkaRoute <ProjectController> .BuildUrlFromExpression(c => c.Search(UrlTemplate.Parameter1String)); ProjectFindUrl = SitkaRoute <ProjectController> .BuildUrlFromExpression(c => c.Find(string.Empty)); var currentPersonCanManage = new FirmaPageManageFeature().HasPermission(currentFirmaSession, firmaPage).HasPermission; ViewPageContentViewData = firmaPage != null ? new ViewPageContentViewData(firmaPage, currentPersonCanManage) : null; CustomFooterViewData = new CustomFooterViewData(FirmaPageTypeEnum.CustomFooter.GetFirmaPage(), currentPersonCanManage, this.CurrentFirmaSession); TenantName = MultiTenantHelpers.GetTenantName(); TenantShortDisplayName = MultiTenantHelpers.GetTenantShortDisplayName(); TenantBannerLogoUrl = MultiTenantHelpers.GetTenantBannerLogoUrl(); TenantToolDisplayName = MultiTenantHelpers.GetToolDisplayName(); ShowTenantDropdown = // Tenant dropdown can be globally disabled if necessary. (Reclamation needs this, and so might other hard-ish forks.) FirmaWebConfiguration.TenantDropdownEnabled && (FirmaWebConfiguration.FirmaEnvironment.FirmaEnvironmentType == FirmaEnvironmentType.Local || CurrentFirmaSession.IsSitkaAdministrator()); ShowEnvironmentLabel = FirmaWebConfiguration.FirmaEnvironment.FirmaEnvironmentType != FirmaEnvironmentType.Prod; ShowEnvironmentDropdown = FirmaWebConfiguration.FirmaEnvironment.FirmaEnvironmentType == FirmaEnvironmentType.Local || CurrentFirmaSession.IsSitkaAdministrator(); FirmaIncludesViewData = new FirmaIncludesViewData(); }
private static void SendExistingKeystoneUserCreatedMessage(Person person, Person currentPerson) { var toolDisplayName = MultiTenantHelpers.GetToolDisplayName(); var subject = $"Invitation to {toolDisplayName}"; var message = $@" <div style='font-size: 12px; font-family: Arial'> Welcome {person.FirstName}, <p> You have been invited by a colleague, {currentPerson.GetFullNameFirstLast()}, to check out <a href=""{SitkaRoute<HomeController>.BuildAbsoluteUrlHttpsFromExpression(x => x.Index())}\"">{toolDisplayName}</a>. </p> <p> Because you have logged into other systems that use the same log in service (Keystone) that {toolDisplayName} uses, you already have an account, but it needs to be activated for {toolDisplayName}. </p> <p> When you have a moment, please activate your account by logging in: </p> <strong>Log in here:</strong> <a href=""{FirmaHelpers.GenerateAbsoluteLogInUrl()}"">{toolDisplayName}</a><br /> <strong>Your user name is:</strong> {person.LoginName}<br /> <p> If you don't remember your password, you will be able to reset it from the link above. </p> <p> Sincerely,<br /> The {toolDisplayName} team<br/><br/><img src=""cid:tool-logo"" width=""160"" /> </p>"; var mailMessage = new MailMessage { From = new MailAddress(FirmaWebConfiguration.DoNotReplyEmail), Subject = subject, Body = message, IsBodyHtml = true }; var tenantAttribute = MultiTenantHelpers.GetTenantAttributeFromCache(); var toolLogo = tenantAttribute.TenantSquareLogoFileResourceInfo ?? tenantAttribute.TenantBannerLogoFileResourceInfo; var htmlView = AlternateView.CreateAlternateViewFromString(message, null, "text/html"); htmlView.LinkedResources.Add( new LinkedResource(new MemoryStream(toolLogo.FileResourceData.Data), "img/jpeg") { ContentId = "tool-logo" }); mailMessage.AlternateViews.Add(htmlView); mailMessage.ReplyToList.Add(currentPerson.Email); mailMessage.To.Add(person.Email); SitkaSmtpClient.Send(mailMessage); }
public IEnumerable <ValidationResult> Validate(ValidationContext validationContext) { var editContactViewModel = (EditContactViewModel)validationContext.ObjectInstance; var thePersonBeingEdited = HttpRequestStorage.DatabaseEntities.People.SingleOrDefault(p => p.PersonID == editContactViewModel.PersonID); if (Phone != null) { Regex strip = new Regex(@"[()\-\s]"); // don't worry about whitespace characters or "phone-number" characters var phoneNumberToTest = strip.Replace(Phone, ""); if (phoneNumberToTest.Length != 10 || //number of digits in an american phone number !phoneNumberToTest.All(char.IsDigit)) // phone numbers must be digits { yield return(new SitkaValidationResult <EditContactViewModel, string>("Phone Number was invalid.", m => m.Phone)); } } bool emailProvided = Email != null; if (emailProvided && !FirmaHelpers.IsValidEmail(Email)) { yield return(new SitkaValidationResult <EditContactViewModel, string>("Email Address was invalid.", m => m.Email)); } // If Person record is being created, or email is being changed, make sure someone does not already have the given email address bool existingUserHasGivenEmailAddressAlready = HttpRequestStorage.DatabaseEntities.People.Any(p => p.Email == Email); bool personIsBeingCreated = thePersonBeingEdited == null; // Create case if (emailProvided && personIsBeingCreated && existingUserHasGivenEmailAddressAlready) { yield return(new SitkaValidationResult <EditContactViewModel, string>($"Email Address \"{Email}\" already in use.", m => m.Email)); } // Edit case if (!personIsBeingCreated) { bool personsEmailIsChanging = thePersonBeingEdited.Email != Email; if (emailProvided && personsEmailIsChanging && existingUserHasGivenEmailAddressAlready) { yield return(new SitkaValidationResult <EditContactViewModel, string>($"Email Address \"{Email}\" already in use.", m => m.Email)); } } }
private static void SendExistingKeystoneUserCreatedMessage(Person person, Person currentPerson) { var toolDisplayName = MultiTenantHelpers.GetToolDisplayName(); var subject = $"Invitation to {toolDisplayName}"; var message = $@" <div style='font-size: 12px; font-family: Arial'> Welcome {person.FirstName}, <p> You have been invited by a colleague, {currentPerson.GetFullNameFirstLast()}, to check out <a href=""{SitkaRoute<HomeController>.BuildAbsoluteUrlHttpsFromExpression(x => x.Index())}\"">{toolDisplayName}</a>. </p> <p> Because you have logged into other systems that use the same log in service (Keystone) that {toolDisplayName} uses, you already have an account, but it needs to be activated for {toolDisplayName}. </p> <p> When you have a moment, please activate your account by logging in: </p> <strong>Log in here:</strong> <a href=""{FirmaHelpers.GenerateAbsoluteLogInUrl()}"">{toolDisplayName}</a><br /> <strong>Your user name is:</strong> {person.LoginName}<br /> <p> If you don't remember your password, you will be able to reset it from the link above. </p> <p> Sincerely,<br /> The {toolDisplayName} team </p>"; var mailMessage = new MailMessage { From = new MailAddress(FirmaWebConfiguration.DoNotReplyEmail), Subject = subject, Body = message, IsBodyHtml = true }; mailMessage.ReplyToList.Add(currentPerson.Email); mailMessage.To.Add(person.Email); SitkaSmtpClient.Send(mailMessage); }
public static List <string> ValidateImpl(List <ProjectExemptReportingYearSimple> projectExemptReportingYearSimples, string explanation, List <int> expectedYears, List <IGrantAllocationExpenditure> projectGrantAllocationExpenditures) { var errors = new List <string>(); var grantAllocationsIDs = projectGrantAllocationExpenditures.Select(x => x.GrantAllocationID).Distinct().ToList(); var grantAllocations = HttpRequestStorage.DatabaseEntities.GrantAllocations.Where(x => grantAllocationsIDs.Contains(x.GrantAllocationID)); // validation 1: ensure that we have expenditure values from ProjectUpdate start year to min(endyear, currentyear) if (projectExemptReportingYearSimples.Any(x => x.IsExempt) && string.IsNullOrWhiteSpace(explanation)) { errors.Add(FirmaValidationMessages.ExplanationNecessaryForProjectExemptYears); } if (!projectExemptReportingYearSimples.Any(x => x.IsExempt) && !string.IsNullOrWhiteSpace(explanation)) { errors.Add(FirmaValidationMessages.ExplanationNotNecessaryForProjectExemptYears); } var exemptReportingYears = projectExemptReportingYearSimples.Where(y => y.IsExempt).Select(y => y.CalendarYear).ToList(); var everyYearIsExempt = exemptReportingYears.Count == expectedYears.Count; if (!everyYearIsExempt) { if (grantAllocations.Any()) { var missingGrantAllocationYears = new Dictionary <Models.GrantAllocation, IEnumerable <int> >(); foreach (var currentGrantAllocation in grantAllocations) { //Added check for 0 to prevent a user from submitting a 0 value with no comment var yearsWithValues = projectGrantAllocationExpenditures .Where(x => x.GrantAllocationID == currentGrantAllocation.GrantAllocationID && x.ExpenditureAmount > 0) .Select(x => x.CalendarYear); var missingYears = expectedYears .GetMissingYears(yearsWithValues).ToList() .Where(year => !exemptReportingYears.Contains(year)).ToList(); if (missingYears.Any()) { missingGrantAllocationYears.Add(currentGrantAllocation, missingYears); } } foreach (var grantAllocation in missingGrantAllocationYears) { var yearsForErrorDisplay = string.Join(", ", FirmaHelpers.CalculateYearRanges(grantAllocation.Value)); errors.Add($"Missing Expenditures for {Models.FieldDefinition.GrantAllocation.GetFieldDefinitionLabel()} '{grantAllocation.Key.DisplayName}' for the following years: {string.Join(", ", yearsForErrorDisplay)}"); } } } // reported expenditures in exempt years - Added check for 0 to prevent a user from submitting a 0 value with no comment var yearsWithExpenditures = projectGrantAllocationExpenditures.Where(x => x.ExpenditureAmount > 0).GroupBy(x => x.GrantAllocationID); foreach (var grantAllocation in yearsWithExpenditures) { var exemptYearsWithReportedValues = grantAllocation .Where(x => exemptReportingYears.Contains(x.CalendarYear)).Select(x => x.CalendarYear) .ToList(); if (exemptYearsWithReportedValues.Any()) { var grantAllocationName = grantAllocations.SingleOrDefault(x => x.GrantAllocationID == grantAllocation.Key)?.GrantAllocationName; var yearsForErrorDisplay = string.Join(", ", FirmaHelpers.CalculateYearRanges(exemptYearsWithReportedValues)); errors.Add($"Grant Allocation {grantAllocationName} has reported values for the exempt years: {yearsForErrorDisplay}"); } } return(errors); }
public static List <string> ValidateExpendituresByCostType(this ProjectUpdateBatch projectUpdateBatch) { if (!projectUpdateBatch.AreProjectBasicsValid()) { return(new List <string> { FirmaValidationMessages.UpdateSectionIsDependentUponBasicsSection }); } if (projectUpdateBatch.ProjectUpdate.ProjectStage.RequiresReportedExpenditures() || projectUpdateBatch.ProjectUpdate.ProjectStage == ProjectStage.Completed) { // validation 1: ensure that we have expenditure values from ProjectUpdate start year to min(endyear, currentyear) var yearsExpected = projectUpdateBatch.ProjectUpdate.GetProjectUpdatePlanningDesignStartToCompletionYearRange(); List <IFundingSourceExpenditure> projectFundingSourceExpenditures = new List <IFundingSourceExpenditure>(projectUpdateBatch.ProjectFundingSourceExpenditureUpdates); var errors = new List <string>(); // Need to get FundingSources by IDs because we may have unsaved projectFundingSourceExpenditures that won't have a reference to the entity var fundingSourcesIDs = projectFundingSourceExpenditures.Select(x => x.FundingSourceID).Distinct().ToList(); var fundingSources = HttpRequestStorage.DatabaseEntities.FundingSources.Where(x => fundingSourcesIDs.Contains(x.FundingSourceID)); if (!projectFundingSourceExpenditures.Any()) { if (string.IsNullOrWhiteSpace(projectUpdateBatch.ExpendituresNote)) { errors.Add(FirmaValidationMessages.ExplanationNecessaryForProjectExemptYears); } } else { if (!fundingSources.Any()) { var yearsForErrorDisplay = string.Join(", ", FirmaHelpers.CalculateYearRanges(yearsExpected)); errors.Add($"Missing Expenditures for {string.Join(", ", yearsForErrorDisplay)}"); } else { var missingFundingSourceYears = new Dictionary <ProjectFirmaModels.Models.FundingSource, IEnumerable <int> >(); foreach (var fundingSource in fundingSources) { var currentFundingSource = fundingSource; var missingYears = yearsExpected .GetMissingYears(projectFundingSourceExpenditures .Where(x => x.FundingSourceID == currentFundingSource.FundingSourceID) .Select(x => x.CalendarYear)).ToList(); if (missingYears.Any()) { missingFundingSourceYears.Add(currentFundingSource, missingYears); } } foreach (var fundingSource in missingFundingSourceYears) { var yearsForErrorDisplay = string.Join(", ", FirmaHelpers.CalculateYearRanges(fundingSource.Value)); errors.Add( $"Missing Expenditures for {FieldDefinitionEnum.FundingSource.ToType().GetFieldDefinitionLabel()} '{fundingSource.Key.GetDisplayName()}' for the following years: {string.Join(", ", yearsForErrorDisplay)}"); } } } return(errors); } return(new List <string>()); }