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

Tsylia/RegionAdmin #972

Merged
merged 27 commits into from
Jan 30, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
60d536d
Add RegionAdmin model and role. Change OutOfSchoolDbContext.
andriitsylia Jan 6, 2023
29c5262
Add repository.
andriitsylia Jan 6, 2023
2dbd821
Add region admin service and controller in IdentityServer project. Ad…
andriitsylia Jan 8, 2023
e8f5427
Add region admin service and controller in WebApi project.
andriitsylia Jan 8, 2023
c57f717
Seed permissions for region admin.
andriitsylia Jan 9, 2023
9e89a02
CurrentUserService shows if a current user is the region admin.
andriitsylia Jan 9, 2023
ec3d558
Add mapping, automated apply new roles to Db, add new permissions for…
andriitsylia Jan 11, 2023
74b5db2
Add migration.
andriitsylia Jan 11, 2023
75109f3
Updated permissions for tech, ministry, region admins, added migratio…
andriitsylia Jan 12, 2023
afdcd55
Made some tests.
andriitsylia Jan 13, 2023
21eb056
Remove migrations.
andriitsylia Jan 13, 2023
a77f838
Add migration AddRegionAdmin. Fix some issues after rebase.
andriitsylia Jan 13, 2023
f48e8d8
Fix migration.
andriitsylia Jan 13, 2023
ee8ca2b
Fix code smell.
andriitsylia Jan 13, 2023
87d076c
Code smell
andriitsylia Jan 16, 2023
891931a
Code smell. Add WebApi.RegionAdminController tests.
andriitsylia Jan 16, 2023
bfa1754
Add WebApi.RegionAdminService test.
andriitsylia Jan 16, 2023
2b73d31
Add WebApi.RegionAdminService tests.
andriitsylia Jan 16, 2023
ddabdb4
Data, that output corresponds the logined region admin:
andriitsylia Jan 17, 2023
7f19465
Fix mapping for WorkshopFilter.
andriitsylia Jan 24, 2023
cbcaa35
Code smell.
andriitsylia Jan 24, 2023
eb4a882
Fix
andriitsylia Jan 25, 2023
817b5b6
Tests.
andriitsylia Jan 25, 2023
54a0815
Refactored CodeficatorService.GetAllChildrenIdsByParentIdAsync().
andriitsylia Jan 25, 2023
3b75ea7
Fix code smell.
andriitsylia Jan 26, 2023
841d4e4
Remove migration.
andriitsylia Jan 27, 2023
687323e
Fix migrations.
andriitsylia Jan 29, 2023
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
18 changes: 18 additions & 0 deletions OutOfSchool/OutOfSchool.Common/Models/RegionAdminBaseDto.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
using System;
using System.ComponentModel.DataAnnotations;

namespace OutOfSchool.Common.Models;

public class RegionAdminBaseDto : AdminBaseDto
{
[DataType(DataType.DateTime)]
public DateTimeOffset CreatingTime { get; set; }

[Required(ErrorMessage = "InstitutionId is required")]
public Guid InstitutionId { get; set; }

public string UserId { get; set; }

[Required(ErrorMessage = "CATOTTGId is required")]
public long CATOTTGId { get; set; }
}
Original file line number Diff line number Diff line change
Expand Up @@ -146,4 +146,19 @@ public enum Permissions : short
[Display(GroupName = "MinistryAdmin", Name = "Ministry Admins", Description = "Can manage ministry admins")]
MinistryAdmins = 114,
#endregion

#region RegionAdmin Control permissions # 13
[Display(GroupName = "RegionAdmin", Name = "Read", Description = "Can read region admin")]
RegionAdminRead = 120,
[Display(GroupName = "RegionAdmin", Name = "Edit", Description = "Can edit region admin")]
RegionAdminEdit = 121,
[Display(GroupName = "RegionAdmin", Name = "Add new", Description = "Can add a new region admin")]
RegionAdminAddNew = 122,
[Display(GroupName = "RegionAdmin", Name = "Remove", Description = "Can remove region admin")]
RegionAdminRemove = 123,
[Display(GroupName = "RegionAdmin", Name = "Region Admins", Description = "Can manage region admins")]
RegionAdmins = 124,
[Display(GroupName = "RegionAdmin", Name = "Block", Description = "Can block region admin")]
RegionAdminBlock = 125,
#endregion
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ public static class PermissionsSeeder
Permissions.UserRead, Permissions.UserEdit,
Permissions.WorkshopEdit, Permissions.WorkshopRemove, Permissions.WorkshopAddNew,
Permissions.MinistryAdmins, Permissions.MinistryAdminAddNew, Permissions.MinistryAdminRemove, Permissions.MinistryAdminEdit, Permissions.MinistryAdminRead,
Permissions.RegionAdmins, Permissions.RegionAdminAddNew, Permissions.RegionAdminRemove, Permissions.RegionAdminEdit, Permissions.RegionAdminRead, Permissions.RegionAdminBlock,
Permissions.PersonalInfo,
};

Expand Down Expand Up @@ -59,6 +60,7 @@ public static class PermissionsSeeder
Permissions.PersonalInfo,
Permissions.MinistryAdminRead,
Permissions.WorkshopEdit,
Permissions.RegionAdminAddNew, Permissions.RegionAdminRead, Permissions.RegionAdminEdit, Permissions.RegionAdminRemove, Permissions.RegionAdminBlock,
};

private static readonly IEnumerable<Permissions> SeedParentPermissions = new List<Permissions>
Expand All @@ -74,6 +76,21 @@ public static class PermissionsSeeder
Permissions.PersonalInfo,
};

private static readonly IEnumerable<Permissions> SeedRegionAdminPermissions = new List<Permissions>
{
Permissions.ImpersonalDataRead, Permissions.LogDataRead,
Permissions.AddressAddNew, Permissions.AddressEdit, Permissions.AddressRead, Permissions.AddressRemove,
Permissions.ApplicationRead,
Permissions.ProviderRead, Permissions.ProviderRemove, Permissions.ProviderApprove,
Permissions.ParentRead,
Permissions.ChildRead,
Permissions.UserRead, Permissions.UserEdit,
Permissions.TeacherRead,
Permissions.PersonalInfo,
Permissions.RegionAdminRead, Permissions.RegionAdminEdit,
Permissions.WorkshopEdit,
};

public static string SeedPermissions(string role)
{
switch (role.ToLower())
Expand All @@ -93,6 +110,9 @@ public static string SeedPermissions(string role)
case "parent":
return SeedParentPermissions.PackPermissionsIntoString();

case "regionadmin":
return SeedRegionAdminPermissions.PackPermissionsIntoString();

default:
break;
}
Expand Down
1 change: 1 addition & 0 deletions OutOfSchool/OutOfSchool.DataAccess/Enums/Role.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,5 @@ public enum Role
Parent,
TechAdmin,
MinistryAdmin,
RegionAdmin,
}
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,13 @@ public static void Seed(this ModelBuilder builder)
RoleName = Role.MinistryAdmin.ToString(),
PackedPermissions = PermissionsSeeder.SeedPermissions(Role.MinistryAdmin.ToString()),
Description = "ministry admin permissions",
},
new PermissionsForRole
{
Id = 6,
RoleName = Role.RegionAdmin.ToString(),
PackedPermissions = PermissionsSeeder.SeedPermissions(Role.RegionAdmin.ToString()),
Description = "region admin permissions",
}
);

Expand Down
36 changes: 36 additions & 0 deletions OutOfSchool/OutOfSchool.DataAccess/Models/RegionAdmin.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
using System;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using OutOfSchool.Services.Models.SubordinationStructure;

namespace OutOfSchool.Services.Models;

public class RegionAdmin : IKeyedEntity<(string, long)>
{
[Key]
public string UserId { get; set; }

[Required(ErrorMessage = "InstitutionId is required")]
public Guid InstitutionId { get; set; }

public virtual Institution Institution { get; set; }

[ForeignKey("UserId")]
public virtual User User { get; set; }

[Required(ErrorMessage = "CATOTTGId is required")]
public long CATOTTGId { get; set; }

public virtual CATOTTG CATOTTG { get; set; }

[NotMapped]
public (string, long) Id
{
get => (UserId, CATOTTGId);
set
{
UserId = value.Item1;
CATOTTGId = value.Item2;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ private void ApplySoftDelete(ModelBuilder builder)
.ApplySoftDelete<ProviderAdmin>()
.ApplySoftDelete<ProviderSectionItem>()
.ApplySoftDelete<Rating>()
.ApplySoftDelete<RegionAdmin>()
.ApplySoftDelete<SocialGroup>()
.ApplySoftDelete<Teacher>()
.ApplySoftDelete<Workshop>()
Expand Down
3 changes: 3 additions & 0 deletions OutOfSchool/OutOfSchool.DataAccess/OutOfSchoolDbContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ public OutOfSchoolDbContext(DbContextOptions<OutOfSchoolDbContext> options)
public DbSet<AchievementTeacher> AchievementTeachers { get; set; }

public DbSet<Achievement> Achievements { get; set; }

public DbSet<ProviderType> ProviderTypes { get; set; }

public DbSet<StatisticReport> StatisticReports { get; set; }
Expand All @@ -102,6 +103,8 @@ public OutOfSchoolDbContext(DbContextOptions<OutOfSchoolDbContext> options)

public DbSet<FileInDb> FilesInDb { get; set; }

public DbSet<RegionAdmin> RegionAdmins { get; set; }

public async Task<int> CompleteAsync() => await this.SaveChangesAsync();

public int Complete() => this.SaveChanges();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,26 +38,26 @@ public async Task<List<CodeficatorAddressDto>> GetFullAddressesByPartOfName(stri

// TODO: Refactor this query, please
var query = from e in db.CATOTTGs
from p in db.CATOTTGs.Where(x1 => e.ParentId == x1.Id).DefaultIfEmpty()
from pp in db.CATOTTGs.Where(x2 => p.ParentId == x2.Id).DefaultIfEmpty()
from ppp in db.CATOTTGs.Where(x3 => pp.ParentId == x3.Id).DefaultIfEmpty()
from pppp in db.CATOTTGs.Where(x4 => ppp.ParentId == x4.Id).DefaultIfEmpty()
where string.IsNullOrEmpty(namePart)
? EF.Property<bool>(e, "IsTop")
: ((CodeficatorCategory.Level4.Name.Contains(e.Category) && e.Name.StartsWith(namePart)) || (e.Category == CodeficatorCategory.CityDistrict.Name && p.Name.StartsWith(namePart))) && categories.Contains(e.Category)
from p in db.CATOTTGs.Where(x1 => e.ParentId == x1.Id).DefaultIfEmpty()
from pp in db.CATOTTGs.Where(x2 => p.ParentId == x2.Id).DefaultIfEmpty()
from ppp in db.CATOTTGs.Where(x3 => pp.ParentId == x3.Id).DefaultIfEmpty()
from pppp in db.CATOTTGs.Where(x4 => ppp.ParentId == x4.Id).DefaultIfEmpty()
where string.IsNullOrEmpty(namePart)
? EF.Property<bool>(e, "IsTop")
: ((CodeficatorCategory.Level4.Name.Contains(e.Category) && e.Name.StartsWith(namePart)) || (e.Category == CodeficatorCategory.CityDistrict.Name && p.Name.StartsWith(namePart))) && categories.Contains(e.Category)
select new CodeficatorAddressDto
{
Id = e.Id,
Category = e.Category,
Settlement = e.Category == CodeficatorCategory.CityDistrict.Name ? p.Name : e.Name,
Latitude = e.Latitude,
Longitude = e.Longitude,
Order = e.Order,
TerritorialCommunity = e.Category == CodeficatorCategory.CityDistrict.Name ? pp.Name : p.Name,
District = e.Category == CodeficatorCategory.CityDistrict.Name ? ppp.Name : pp.Name,
Region = e.Category == CodeficatorCategory.CityDistrict.Name ? pppp.Name : ppp.Name,
CityDistrict = e.Category == CodeficatorCategory.CityDistrict.Name ? e.Name : null,
};
{
Id = e.Id,
Category = e.Category,
Settlement = e.Category == CodeficatorCategory.CityDistrict.Name ? p.Name : e.Name,
Latitude = e.Latitude,
Longitude = e.Longitude,
Order = e.Order,
TerritorialCommunity = e.Category == CodeficatorCategory.CityDistrict.Name ? pp.Name : p.Name,
District = e.Category == CodeficatorCategory.CityDistrict.Name ? ppp.Name : pp.Name,
Region = e.Category == CodeficatorCategory.CityDistrict.Name ? pppp.Name : ppp.Name,
CityDistrict = e.Category == CodeficatorCategory.CityDistrict.Name ? e.Name : null,
};

query = query.OrderBy(x => x.Order);

Expand All @@ -68,4 +68,11 @@ where string.IsNullOrEmpty(namePart)

return await query.ToListAsync();
}

/// <inheritdoc/>
public async Task<List<long>> GetIdsByParentIds(List<long> parentIds)
{
var query = db.CATOTTGs.Where(c => parentIds.Contains(c.ParentId.Value)).Select(c => c.Id);
return await query.ToListAsync().ConfigureAwait(false);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,4 +24,11 @@ public interface ICodeficatorRepository : IEntityRepository<long, CATOTTG>
/// <param name="categories">Categories for search.</param>
/// <returns>The task result contains a <see cref="List{CodeficatorAddressDto}"/> that contains elements' full addresses.</returns>
public Task<List<CodeficatorAddressDto>> GetFullAddressesByPartOfName(string namePart, string categories = default);

/// <summary>
/// Get the list of CATOTTGs Ids by list of CATOTTGs parentIds.
/// </summary>
/// <param name="parentIds">list of CATOTTGs parentIds</param>
/// <returns>The task result contains a <see cref="List{TResult}"/> that contains the list of CATOTTGs Ids.</returns>
public Task<List<long>> GetIdsByParentIds(List<long> parentIds);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
using System;
using System.Threading.Tasks;

using OutOfSchool.Services.Models;

namespace OutOfSchool.Services.Repository;

public interface IRegionAdminRepository : IEntityRepository<(string, long), RegionAdmin>
{
Task<RegionAdmin> GetByIdAsync(string userId);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
using System;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore;

using OutOfSchool.Services.Models;

namespace OutOfSchool.Services.Repository;

public class RegionAdminRepository : EntityRepository<(string, long), RegionAdmin>, IRegionAdminRepository
{
private readonly OutOfSchoolDbContext db;

public RegionAdminRepository(OutOfSchoolDbContext dbContext)
: base(dbContext)
{
db = dbContext;
}

public async Task<RegionAdmin> GetByIdAsync(string userId)
{
return await db.RegionAdmins
.SingleOrDefaultAsync(ra => ra.UserId == userId);
}
}
Loading