Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

develop -> staging #124

Merged
merged 98 commits into from
Jun 17, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
98 commits
Select commit Hold shift + click to select a range
eda02f2
PC-1083: Adds migration and new model for consortium data. Adds a lis…
Glenn-Clarke May 22, 2024
18d7f12
PC-1083: Indenting cleanup
Glenn-Clarke May 22, 2024
0b872d8
PC-1083: Added missing designer file
Glenn-Clarke May 22, 2024
b60340a
PC-1083: Added notes about how changing custodian codes or consortium…
Glenn-Clarke May 22, 2024
adb3c5a
PC-1083: Added additional information to mapping/migration notes
Glenn-Clarke May 22, 2024
75a78a4
PC-1083: Updated comments for clarity. Adding links to improve commen…
Glenn-Clarke May 23, 2024
6ac5490
PC-1083: Further updates to comments for clarity. Adding more links t…
Glenn-Clarke May 23, 2024
5fd5af1
PC-1083: Update to make comment more readable
Glenn-Clarke May 23, 2024
529a03a
Merge pull request #109 from UKGovernmentBEIS/PC-1083-data-layer-upda…
Glenn-Clarke May 23, 2024
72dace0
PC-1085: add structure for a user to be created with consortiums
samyou-softwire May 28, 2024
dfab47f
PC-1085: add new command to add consortia to an account
samyou-softwire May 28, 2024
5e534ba
PC-1085: add warnings when managing LA access
samyou-softwire May 28, 2024
3cc32da
PC-1085: update database operations
samyou-softwire May 28, 2024
4b8a863
PC-1085: consolidate to less restrictive collections of strings
samyou-softwire May 28, 2024
dc52089
PC-1085: allow consortia to be remove
samyou-softwire May 28, 2024
990da7b
PC-1085: reformat test file
samyou-softwire May 28, 2024
d2db801
PC-1085: add tests for managing of LAs related to consortiums
samyou-softwire May 28, 2024
715e993
PC-1085: add tests for removing consortia
samyou-softwire May 28, 2024
558d456
PC-1085: remove SetupConfirmCustodianCodes
samyou-softwire May 28, 2024
21198cf
PC-1085: add some handling for when the added LA/consortium isn't in DB
samyou-softwire May 28, 2024
f43857f
PC-1085: final naming improvements and code format
samyou-softwire May 29, 2024
39bd576
PC-1084: Updated user to have method to get all administrated custodi…
Glenn-Clarke May 28, 2024
6e218e9
PC-1084: Whitespace cleanup. Helper class is now static.
Glenn-Clarke May 28, 2024
491bfaf
PC-1085: add back braces cut by lint
samyou-softwire May 30, 2024
7f1a563
PC-1085: print consortium name with LA name
samyou-softwire May 30, 2024
a729bba
PC-1085: use AddConsortiaToUser if possible
samyou-softwire May 30, 2024
93f0616
PC-1085: use ==0 over <1
samyou-softwire May 30, 2024
6196d63
PC-1085: patch a few failing tests
samyou-softwire May 30, 2024
a6bf2f7
PC-1084: Renamed and simplified many functions. Updated tests to use …
Glenn-Clarke May 30, 2024
37b15da
PC-1085: use an exception over optional type
samyou-softwire May 30, 2024
cd163da
PC-1085: fix tests as null return for GetLas matters now
samyou-softwire May 30, 2024
49032a5
PC-1085: wrap database calls
samyou-softwire May 30, 2024
b9f33ec
PC-1085: strip the braces again
samyou-softwire May 30, 2024
7366a12
PC-1085: remove boolean logic split
samyou-softwire May 30, 2024
cd22ceb
PC-1085: remove unneeded optional email type
samyou-softwire May 30, 2024
cb2342f
PC-1085: split AdminAction
samyou-softwire May 30, 2024
3514419
PC-1085: remove unnecessary null annotations
samyou-softwire May 30, 2024
ac1e68e
PC-1085: format all touched files
samyou-softwire May 30, 2024
a329b46
PC-1085: use a custom exception over inbuilt
samyou-softwire May 31, 2024
e9c3801
PC-1085: extract UserStatus to its own class
samyou-softwire May 31, 2024
5fc935c
PC-1084: Removed unnecessary ToLists. Removed unused import. Added ne…
Glenn-Clarke May 31, 2024
8d2ee6c
PC-1084: Changed user methods to return enumerables.
Glenn-Clarke May 31, 2024
be520d0
PC-1085: replace any with select -> contains
samyou-softwire May 31, 2024
ce1525a
PC-1085: move error message construction up the chain
samyou-softwire Jun 3, 2024
3a42ad8
Merge pull request #110 from UKGovernmentBEIS/PC-1084-build-consortiu…
Glenn-Clarke Jun 3, 2024
e7172d7
PC-1085: output string directly where possible
samyou-softwire Jun 3, 2024
4f45a80
Merge branch 'PC-1047-create-true-consortium-admin-role' into PC-1085…
samyou-softwire Jun 3, 2024
bec2385
Merge pull request #111 from UKGovernmentBEIS/PC-1085-update-user-man…
samyou-softwire Jun 3, 2024
002422f
PC-1047: fix test issues
samyou-softwire Jun 5, 2024
9da504b
PC-1086: add skeleton for migration methods
samyou-softwire Jun 5, 2024
8a805ab
PC-1047: auto format
samyou-softwire Jun 5, 2024
07c7130
PC-1086: add tests for new command function
samyou-softwire Jun 5, 2024
77c7063
PC-1047: make job run on any pull request
samyou-softwire Jun 5, 2024
c44130f
PC-1047: run on push too
samyou-softwire Jun 5, 2024
da1daea
PC-1086: add function to migrating admins
samyou-softwire Jun 5, 2024
5e06d53
PC-1086: add entrypoint to migration system
samyou-softwire Jun 5, 2024
6411a7a
Merge branch 'PC-1047-fix-failing-tests' into PC-1086-migrate-histori…
samyou-softwire Jun 5, 2024
94aaa4e
PC-1047: add back filter for push runs
samyou-softwire Jun 5, 2024
5e0ec76
PC-1047: remove unneeded variables to fix warnings
samyou-softwire Jun 5, 2024
c55c7ab
Merge branch 'PC-1047-fix-failing-tests' into PC-1086-migrate-histori…
samyou-softwire Jun 5, 2024
6e725bc
PC-1047: specify branches in both cases
samyou-softwire Jun 5, 2024
3eb2e52
PC-1047: quote wildcard
samyou-softwire Jun 5, 2024
5e681d2
PC-1086: code format
samyou-softwire Jun 5, 2024
db11e4d
PC-1086: use a struct to pass test setup info
samyou-softwire Jun 6, 2024
45e3688
PC-1086: increase clarity on migration manifest
samyou-softwire Jun 6, 2024
04cf3ba
PC-1086: improve result messages
samyou-softwire Jun 6, 2024
1d38f0b
PC-1086: code format
samyou-softwire Jun 6, 2024
522c627
Merge pull request #112 from UKGovernmentBEIS/PC-1047-fix-failing-tests
samyou-softwire Jun 7, 2024
5043b82
PC-NONE: Ensure tests run on all PRs
jdgage Jun 7, 2024
f402146
PC-NONE: Ensure label check re-runs when appropriate
jdgage Jun 7, 2024
6c4254c
PC-NONE: Auto-format yaml files
jdgage Jun 7, 2024
00941fc
Merge pull request #118 from UKGovernmentBEIS/github-workflows
jdgage Jun 10, 2024
82929b9
PC-1086: update name of migrate command
samyou-softwire Jun 10, 2024
fb48cc8
PC-1086: update test names too
samyou-softwire Jun 10, 2024
a1a96d9
Merge branch 'PC-1047-create-true-consortium-admin-role' into PC-1086…
samyou-softwire Jun 10, 2024
0eab51e
Merge branch 'develop' into PC-1047-create-true-consortium-admin-role
samyou-softwire Jun 10, 2024
1890950
Merge branch 'PC-1047-create-true-consortium-admin-role' into PC-1086…
samyou-softwire Jun 10, 2024
76c1994
PC-1086: remove check to only remove LAs the user owns
samyou-softwire Jun 10, 2024
bca9a8e
PC-1086: remove hardcoded custodian code values in tests
samyou-softwire Jun 10, 2024
ccd2d9b
PC-1086: clarify amount of LAs in test Consortia
samyou-softwire Jun 11, 2024
32714a5
PC-1086: output when a user won't be updated
samyou-softwire Jun 11, 2024
8556c56
PC-1086: clarify what LAs will be removed from
samyou-softwire Jun 11, 2024
d4c6227
Merge pull request #113 from UKGovernmentBEIS/PC-1086-migrate-histori…
samyou-softwire Jun 12, 2024
6adacde
Merge pull request #119 from UKGovernmentBEIS/PC-1047-create-true-con…
samyou-softwire Jun 12, 2024
4e43a34
PC-1047: fix key error for LAs with no Consortium
samyou-softwire Jun 12, 2024
225bc5a
PC-1047: add a verifying test
samyou-softwire Jun 12, 2024
beab04d
PC-1047: remove unused variables
samyou-softwire Jun 12, 2024
0e0e118
PC-1048: remove incorrect comment
samyou-softwire Jun 12, 2024
1f02a5a
Merge pull request #120 from UKGovernmentBEIS/PC-1047-fix-key-error
samyou-softwire Jun 13, 2024
6e85123
PC-1047: add consortium codes script
samyou-softwire Jun 13, 2024
ae4b5aa
PC-1047: fix add consortia messaging
samyou-softwire Jun 13, 2024
8dd45a6
PC-1047: update tests to new messaging
samyou-softwire Jun 13, 2024
750f4b4
PC-1047: fix sql file comment
samyou-softwire Jun 13, 2024
884fa63
PC-1047: revert authorityType changes to data breach warning
samyou-softwire Jun 13, 2024
c28ed05
Merge pull request #122 from UKGovernmentBEIS/PC-1047-add-consortium-…
samyou-softwire Jun 13, 2024
c2336a2
Merge pull request #123 from UKGovernmentBEIS/PC-1047-fix-add-consort…
samyou-softwire Jun 14, 2024
56d6a69
PC-NONE: Add note about database migrations
jdgage Jun 14, 2024
78d86ee
Merge pull request #125 from UKGovernmentBEIS/note-about-migrations
jdgage Jun 14, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
92 changes: 45 additions & 47 deletions .github/workflows/build-and-run-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,7 @@ name: Run automated tests
on:
pull_request:
branches:
- develop
- staging
- main
- '**'
push:
branches:
- develop
Expand All @@ -16,52 +14,52 @@ jobs:
build-and-run-tests:
runs-on: ubuntu-latest
steps:
- name: Checkout code onto job runner
uses: actions/checkout@v2
- name: Checkout code onto job runner
uses: actions/checkout@v2

- name: Install .Net (6.0)
uses: actions/setup-dotnet@v1
with:
dotnet-version: 6.0.x

- name: Restore .Net dependencies
run: dotnet restore --configfile nuget.config

- name: Install .Net (6.0)
uses: actions/setup-dotnet@v1
with:
dotnet-version: 6.0.x
- name: Build .Net code
run: dotnet build --no-restore

- name: Restore .Net dependencies
run: dotnet restore --configfile nuget.config
- name: Run tests
run: dotnet test --no-restore --logger trx --results-directory "TestResults" --collect:"XPlat Code Coverage" --settings HerPortal.UnitTests/coverlet.runsettings

- name: Build .Net code
run: dotnet build --no-restore
- name: Inline code coverage report and minimum coverage check
uses: irongut/[email protected]
with:
filename: TestResults/*/coverage.cobertura.xml
badge: false
fail_below_min: true
format: text
hide_branch_rate: false
hide_complexity: false
indicators: true
output: console
# Threshold is low as this is a small project and a lot of the code is boilerplate or doesn't make sense to test
# Business logic coverage should be kept at/above 80%
thresholds: '50 80'
# Use always() to always run this step to publish coverage results when there are test failures
if: ${{ always() }}

- name: Run tests
run: dotnet test --no-restore --logger trx --results-directory "TestResults" --collect:"XPlat Code Coverage" --settings HerPortal.UnitTests/coverlet.runsettings
- name: Generate detailed code coverage report
uses: danielpalme/[email protected]
with:
reports: TestResults/*/coverage.cobertura.xml
targetdir: TestResults/CoverageReport
# Use always() to always run this step to publish coverage report when there are test failures
if: ${{ always() }}

- name: Inline code coverage report and minimum coverage check
uses: irongut/[email protected]
with:
filename: TestResults/*/coverage.cobertura.xml
badge: false
fail_below_min: true
format: text
hide_branch_rate: false
hide_complexity: false
indicators: true
output: console
# Threshold is low as this is a small project and a lot of the code is boilerplate or doesn't make sense to test
# Business logic coverage should be kept at/above 80%
thresholds: '50 80'
# Use always() to always run this step to publish coverage results when there are test failures
if: ${{ always() }}

- name: Generate detailed code coverage report
uses: danielpalme/[email protected]
with:
reports: TestResults/*/coverage.cobertura.xml
targetdir: TestResults/CoverageReport
# Use always() to always run this step to publish coverage report when there are test failures
if: ${{ always() }}

- name: Upload dotnet test results
uses: actions/upload-artifact@v3
with:
name: test-results
path: TestResults
# Use always() to always run this step to publish test results when there are test failures
if: ${{ always() }}
- name: Upload dotnet test results
uses: actions/upload-artifact@v3
with:
name: test-results
path: TestResults
# Use always() to always run this step to publish test results when there are test failures
if: ${{ always() }}
11 changes: 8 additions & 3 deletions .github/workflows/main-label-check.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,13 @@ name: main_label_check

on:
pull_request:
types: [opened, edited, labeled, unlabeled]
types:
- opened
- edited
- labeled
- reopened
- synchronize
- unlabeled

jobs:
label_check:
Expand All @@ -13,5 +19,4 @@ jobs:
uses: actions/github-script@v3
with:
script: |
core.setFailed("Label is missing: add a 'production release' label in order to merge to main")

core.setFailed("Label is missing: add a 'production release' label in order to merge to main")
1 change: 0 additions & 1 deletion HerPortal.BusinessLogic/IDataAccessProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,4 @@ public interface IDataAccessProvider
public Task<IEnumerable<User>> GetAllActiveUsersAsync();
public Task<List<CsvFileDownload>> GetCsvFileDownloadDataForUserAsync(int userId);
public Task MarkCsvFileAsDownloadedAsync(string custodianCode, int year, int month, int userId);
public List<string> GetConsortiumCodesForUser(User user);
}
15 changes: 15 additions & 0 deletions HerPortal.BusinessLogic/Models/Consortium.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
namespace HerPortal.BusinessLogic.Models;

/// <summary>
/// This model is not a full model for Consortium Data.
/// It should be considered as a reference to the full data for a Consortium.
/// The full data (including an the Consortium's relationship to LAs) can be found in the HUG2 Public Website codebase
/// <see href="https://github.com/UKGovernmentBEIS/desnz-home-energy-retrofit-beta/blob/develop/HerPublicWebsite.BusinessLogic/Models/LocalAuthorityData.cs"/>
/// </summary>
public class Consortium
{
public int Id { get; set; }
public string ConsortiumCode { get; set; }

public List<User> Users { get; set; }
}
6 changes: 6 additions & 0 deletions HerPortal.BusinessLogic/Models/ConsortiumData.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,13 @@
namespace HerPortal.BusinessLogic.Models;

/// <summary>
/// LA-Consortium mapping data can be found both in <see cref="LocalAuthorityData"/>, and in the HUG2 Public Website codebase's LocalAuthorityData.cs.
/// <seealso href="https://github.com/UKGovernmentBEIS/desnz-home-energy-retrofit-beta/blob/develop/HerPublicWebsite.BusinessLogic/Models/LocalAuthorityData.cs">Link to HUG2 Public Website codebase's LocalAuthorityData.cs</seealso>
/// Note: Mappings in the above files are expected to be consistent between both repos
/// </summary>
public static class ConsortiumData
{
/// If any Custodian/Consortium codes are changed, consider if remapping is required in <see cref="LocalAuthorityData"/>
public static readonly Dictionary<string, string> ConsortiumNamesByConsortiumCode = new()
{
{ "C_0002", "Blackpool" },
Expand Down
7 changes: 7 additions & 0 deletions HerPortal.BusinessLogic/Models/LocalAuthority.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
namespace HerPortal.BusinessLogic.Models;

/// <summary>
/// This model is not a full model for Local Authority Data.
/// It should be considered as a reference to the full data for a Local Authority.
/// Data for LA Relationships to Consortiums can be found in <see cref="LocalAuthorityData"> LocalAuthorityData.cs </see>
/// The full data for LAs (including an LAs relationship to a Consortium) can also be found in the HUG2 Public Website codebase.
/// <seealso href="https://github.com/UKGovernmentBEIS/desnz-home-energy-retrofit-beta/blob/develop/HerPublicWebsite.BusinessLogic/Models/LocalAuthorityData.cs">Link to HUG2 Public Website codebase's LocalAuthorityData.cs</seealso>
/// </summary>
public class LocalAuthority
{
public int Id { get; set; }
Expand Down
20 changes: 18 additions & 2 deletions HerPortal.BusinessLogic/Models/LocalAuthorityData.cs
Original file line number Diff line number Diff line change
@@ -1,9 +1,20 @@
namespace HerPortal.BusinessLogic.Models;

/// <summary>
/// This class does not contain all data for Local Authorities.
/// Full data (including an LAs relationship to a Consortium) can be found in the HUG2 Public Website codebase
/// <see href="https://github.com/UKGovernmentBEIS/desnz-home-energy-retrofit-beta/blob/develop/HerPublicWebsite.BusinessLogic/Models/LocalAuthorityData.cs"> HUG2 Public Website codebase </see>
/// The LA-Consortium mapping contained here must be the same as the LocalAuthorityData.cs file in the
/// public website repository.
/// </summary>
public static class LocalAuthorityData
{
// The mapping from custodian code to name comes from the publicly available "Local custodian codes" download link
// on https://www.ordnancesurvey.co.uk/business-government/tools-support/addressbase-support
/// If Custodian Codes change (through LAs merging etc.) we need to ensure
/// consistency with the HUG2 Public Website data, and consider any remapping that may be required.
/// <see href="https://github.com/UKGovernmentBEIS/desnz-home-energy-retrofit-beta/blob/develop/HerPublicWebsite.BusinessLogic/Models/LocalAuthorityData.cs"> HUG2 Public Website codebase </see>
/// The mapping from custodian code to name comes from the publicly available "Local custodian codes" download link
/// on https://www.ordnancesurvey.co.uk/business-government/tools-support/addressbase-support
/// <see href=" https://www.ordnancesurvey.co.uk/business-government/tools-support/addressbase-support"/>
public static readonly Dictionary<string, string> LocalAuthorityNamesByCustodianCode = new()
{
{ "9052", "Aberdeenshire" },
Expand Down Expand Up @@ -376,6 +387,11 @@ public static class LocalAuthorityData
{ "2741", "York" },
};

/// If Custodian Codes change (through LAs merging etc.) we need to ensure consistency with the
/// HUG2 Public Website data, and we may need to map old codes to new ones for existing users.
/// <see href="https://github.com/UKGovernmentBEIS/desnz-home-energy-retrofit-beta/blob/develop/HerPublicWebsite.BusinessLogic/Models/LocalAuthorityData.cs"> HUG2 Public Website codebase </see>
/// The mappings contained here should be consistent with the mapping in the HUG2 Public Website Repo's LocalAuthorityData.cs
/// <see href="https://github.com/UKGovernmentBEIS/desnz-home-energy-retrofit-beta/blob/develop/HerPublicWebsite.BusinessLogic/Models/LocalAuthorityData.cs"> HUG2 Public Website codebase </see>
public static readonly Dictionary<string, string> LocalAuthorityConsortiumCodeByCustodianCode = new()
{
{ "3805", "C_0031" },
Expand Down
20 changes: 18 additions & 2 deletions HerPortal.BusinessLogic/Models/User.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,22 @@ public class User
public int Id { get; set; }
public string EmailAddress { get; set; }
public bool HasLoggedIn { get; set; }

public List<LocalAuthority> LocalAuthorities { get; set; }
}
public List<Consortium> Consortia { get; set; }

public IEnumerable<string> GetAdministeredCustodianCodes()
{
var consortiumCodes = Consortia.Select(consortium => consortium.ConsortiumCode);
var custodianCodes = LocalAuthorities.Select(la => la.CustodianCode);

return consortiumCodes.SelectMany(consortiumCode =>
ConsortiumData.ConsortiumCustodianCodesIdsByConsortiumCode[consortiumCode])
.Union(custodianCodes);
}

public IEnumerable<string> GetAdministeredConsortiumCodes()
{
return Consortia.Select(c => c.ConsortiumCode);
}
}
67 changes: 37 additions & 30 deletions HerPortal.BusinessLogic/Services/CsvFileService/CsvFileService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -83,17 +83,27 @@ public async Task<IEnumerable<CsvFileData>> GetFileDataForUserAsync(string userE
{
// Make sure that we only return file data for files that the user currently has access to
var user = await dataAccessProvider.GetUserByEmailAsync(userEmailAddress);
var currentCustodianCodes = user.LocalAuthorities.Select(la => la.CustodianCode);
var custodianCodes = user.GetAdministeredCustodianCodes();
var consortiumCodes = user.GetAdministeredConsortiumCodes();

var downloads = await dataAccessProvider.GetCsvFileDownloadDataForUserAsync(user.Id);
var files = new List<CsvFileData>();
var localAuthoritiesFileData = await BuildCsvFileDataForLocalAuthorities(user, custodianCodes);
var consortiaTransformedFileData = TransformFileDataForConsortia(consortiumCodes, localAuthoritiesFileData);
var combinedFileData = localAuthoritiesFileData.Concat(consortiaTransformedFileData);

var consortiumCodes = dataAccessProvider.GetConsortiumCodesForUser(user);
return combinedFileData
.OrderByDescending(f => new DateOnly(f.Year, f.Month, 1))
.ThenByDescending(f => f is ConsortiumCsvFileData)
.ThenBy(f => f.Name);
}

private async Task<List<CsvFileData>> BuildCsvFileDataForLocalAuthorities(User user, IEnumerable<string> currentCustodianCodes)
{
var laFileData = new List<CsvFileData>();
var downloads = await dataAccessProvider.GetCsvFileDownloadDataForUserAsync(user.Id);
foreach (var custodianCode in currentCustodianCodes)
{
var s3Objects = await s3FileReader.GetS3ObjectsByCustodianCodeAsync(custodianCode);
files.AddRange(s3Objects.Select(s3O =>
laFileData.AddRange(s3Objects.Select(s3O =>
{
var data = keyService.GetDataFromS3Key(s3O.Key);
var downloadData = downloads.SingleOrDefault(d =>
Expand All @@ -113,30 +123,28 @@ public async Task<IEnumerable<CsvFileData>> GetFileDataForUserAsync(string userE
));
}

files.AddRange(
files
.Where(file => LocalAuthorityData.LocalAuthorityConsortiumCodeByCustodianCode.ContainsKey(file.Code))
.GroupBy(file => (LocalAuthorityData.LocalAuthorityConsortiumCodeByCustodianCode[file.Code], file.Month,
file.Year))
.Where(grouping => consortiumCodes.Contains(grouping.Key.Item1))
.Select(grouping => new ConsortiumCsvFileData(
grouping.Key.Item1,
grouping.Key.Month,
grouping.Key.Year,
grouping
.Select(fileData => fileData.LastUpdated)
.Max(), // there are csv updates as new as
grouping
.Select(fileData => fileData.LastDownloaded)
.Min() // there are csvs undownloaded for as long as
)
return laFileData;
}

private IEnumerable<CsvFileData> TransformFileDataForConsortia(IEnumerable<string> consortiumCodes, IEnumerable<CsvFileData> laFileData)
{
return laFileData
.Where(fileRow => LocalAuthorityData.LocalAuthorityConsortiumCodeByCustodianCode.ContainsKey(fileRow.Code))
.GroupBy(fileRow => (LocalAuthorityData.LocalAuthorityConsortiumCodeByCustodianCode[fileRow.Code], fileRow.Month,
fileRow.Year))
.Where(grouping => consortiumCodes.Contains(grouping.Key.Item1))
.Select(grouping => new ConsortiumCsvFileData(
grouping.Key.Item1,
grouping.Key.Month,
grouping.Key.Year,
grouping
.Select(fileData => fileData.LastUpdated)
.Max(), // there are csv updates as new as
grouping
.Select(fileData => fileData.LastDownloaded)
.Min() // there are csvs undownloaded for as long as
)
);

return files
.OrderByDescending(f => new DateOnly(f.Year, f.Month, 1))
.ThenByDescending(f => f is ConsortiumCsvFileData)
.ThenBy(f => f.Name);
}

// Page number starts at 1
Expand Down Expand Up @@ -167,7 +175,7 @@ public async Task<Stream> GetLocalAuthorityFileForDownloadAsync(string custodian
{
// Important! First ensure the logged-in user is allowed to access this data
var userData = await dataAccessProvider.GetUserByEmailAsync(userEmailAddress);
if (!userData.LocalAuthorities.Any(la => la.CustodianCode == custodianCode))
if (!userData.GetAdministeredCustodianCodes().Contains(custodianCode))
{
// We don't want to log the User's email address for GDPR reasons, but the ID is fine.
throw new SecurityException(
Expand All @@ -194,9 +202,8 @@ public async Task<Stream> GetConsortiumFileForDownloadAsync(string consortiumCod
{
// Important! First ensure the logged-in user is allowed to access this data
var userData = await dataAccessProvider.GetUserByEmailAsync(userEmailAddress);
var consortiumCodes = dataAccessProvider.GetConsortiumCodesForUser(userData);

if (!consortiumCodes.Contains(consortiumCode))
if (!userData.GetAdministeredConsortiumCodes().Contains(consortiumCode))
{
// We don't want to log the User's email address for GDPR reasons, but the ID is fine.
throw new SecurityException(
Expand Down
5 changes: 0 additions & 5 deletions HerPortal.BusinessLogic/Services/UserService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,4 @@ public async Task MarkUserAsHavingLoggedInAsync(int userId)
{
await dataAccessProvider.MarkUserAsHavingLoggedInAsync(userId);
}

public List<string> GetConsortiumCodesForUser(User user)
{
return dataAccessProvider.GetConsortiumCodesForUser(user);
}
}
13 changes: 1 addition & 12 deletions HerPortal.Data/DataAccessProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ public async Task<User> GetUserByEmailAsync(string emailAddress)
{
var users = await context.Users
.Include(u => u.LocalAuthorities)
.Include(u => u.Consortia)
// In order to compare email addresses case-insensitively, we bring the whole table into memory here
// to perform the comparison in C#, since Entity Framework doesn't allow for the StringComparison
// overload. However, since we don't expect this table to be monstrously huge this is acceptable
Expand Down Expand Up @@ -44,7 +45,6 @@ public async Task<IEnumerable<User>> GetAllActiveUsersAsync()
{
return await context.Users
.Where(u => u.HasLoggedIn)
.Include(u => u.LocalAuthorities)
.ToListAsync();
}

Expand Down Expand Up @@ -102,15 +102,4 @@ public async Task MarkCsvFileAsDownloadedAsync(string custodianCode, int year, i

await context.SaveChangesAsync();
}

public List<string> GetConsortiumCodesForUser(User user)
{
var userLocalAuthorities = user.LocalAuthorities.Select(la => la.CustodianCode);

// user is a consortium manager if they are a manager of all LAs in that consortium
return ConsortiumData.ConsortiumCustodianCodesIdsByConsortiumCode
.Where(pair => pair.Value.All(consortiumLa => userLocalAuthorities.Contains(consortiumLa)))
.Select(pair => pair.Key)
.ToList();
}
}
1 change: 1 addition & 0 deletions HerPortal.Data/HerDbContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ public class HerDbContext : DbContext, IDataProtectionKeyContext
public DbSet<AuditDownload> AuditDownloads { get; set; }
public DbSet<CsvFileDownload> CsvFileDownloads { get; set; }
public DbSet<LocalAuthority> LocalAuthorities { get; set; }
public DbSet<Consortium> Consortia { get; set; }
public DbSet<User> Users { get; set; }

public HerDbContext(DbContextOptions<HerDbContext> options) : base(options)
Expand Down
Loading
Loading