-
Notifications
You must be signed in to change notification settings - Fork 104
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Major refactor before starting part2
- Loading branch information
Showing
25 changed files
with
330 additions
and
168 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
// Copyright (c) 2018 Jon P Smith, GitHub: JonPSmith, web: http://www.thereformedprogrammer.net/ | ||
// Licensed under MIT license. See License.txt in the project root for license information. | ||
|
||
using System.Linq; | ||
using System.Reflection; | ||
using System.Security.Claims; | ||
using System.Threading.Tasks; | ||
using DataLayer.EfCode; | ||
using Microsoft.EntityFrameworkCore; | ||
using PermissionParts; | ||
|
||
namespace RolesToPermission | ||
{ | ||
public class CalcAllowedPermissions | ||
{ | ||
/// <summary> | ||
/// NOTE: This class is used in OnValidatePrincipal so it can't use DI, so I can't inject the DbContext here because that is dynamic. | ||
/// Therefore I can pass in the database options because that is a singleton | ||
/// From that the method can create a valid dbContext to access the database | ||
/// </summary> | ||
private readonly DbContextOptions<ExtraAuthorizeDbContext> _extraAuthDbContextOptions; | ||
|
||
|
||
public CalcAllowedPermissions(DbContextOptions<ExtraAuthorizeDbContext> extraAuthDbContextOptions) | ||
{ | ||
_extraAuthDbContextOptions = extraAuthDbContextOptions; | ||
} | ||
|
||
/// <summary> | ||
/// This is called if the Permissions that a user needs calculating. | ||
/// </summary> | ||
/// <param name="user"></param> | ||
/// <returns></returns> | ||
public async Task<string> CalcPermissionsForUser(ClaimsPrincipal user) | ||
{ | ||
var usersRoles = user.Claims.Where(x => x.Type == ClaimTypes.Role).Select(x => x.Value) | ||
.ToList(); | ||
|
||
using (var dbContext = new ExtraAuthorizeDbContext(_extraAuthDbContextOptions)) | ||
{ | ||
//This gets all the permissions, with a distinct to remove duplicates | ||
var permissionsForUser = await dbContext.RolesToPermissions.Where(x => usersRoles.Contains(x.RoleName)) | ||
.SelectMany(x => x.PermissionsInRole) | ||
.Distinct() | ||
.ToListAsync(); | ||
//we get the modules this user is allows to see | ||
var userModules = | ||
dbContext.ModulesForUsers.Find(user.Claims.SingleOrDefault(x => x.Type == ClaimTypes.NameIdentifier).Value) | ||
?.AllowedPaidForModules ?? PaidForModules.None; | ||
//Now we remove permissions that are linked to modules that the user has no access to | ||
var filteredPermissions = | ||
from permission in permissionsForUser | ||
let moduleAttr = typeof(Permissions).GetMember(permission.ToString())[0] | ||
.GetCustomAttribute<LinkedToModuleAttribute>() | ||
where moduleAttr == null || userModules.HasFlag(moduleAttr.PaidForModule) | ||
select permission; | ||
|
||
return filteredPermissions.PackPermissionsIntoString(); | ||
} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
2 changes: 1 addition & 1 deletion
2
...RolesToPermissions/PermissionConstants.cs → RolesToPermission/PermissionConstants.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
<Project Sdk="Microsoft.NET.Sdk"> | ||
|
||
<PropertyGroup> | ||
<TargetFramework>netcoreapp2.1</TargetFramework> | ||
</PropertyGroup> | ||
|
||
<ItemGroup> | ||
<PackageReference Include="Microsoft.AspNetCore.Authorization" Version="2.1.2" /> | ||
<PackageReference Include="Microsoft.Extensions.Configuration" Version="2.1.1" /> | ||
</ItemGroup> | ||
|
||
<ItemGroup> | ||
<ProjectReference Include="..\DataLayer\DataLayer.csproj" /> | ||
<ProjectReference Include="..\PermissionParts\PermissionParts.csproj" /> | ||
</ItemGroup> | ||
|
||
</Project> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
<Project Sdk="Microsoft.NET.Sdk"> | ||
|
||
<PropertyGroup> | ||
<TargetFramework>netcoreapp2.1</TargetFramework> | ||
</PropertyGroup> | ||
|
||
<ItemGroup> | ||
<PackageReference Include="Microsoft.AspNetCore.Hosting" Version="2.1.1" /> | ||
<PackageReference Include="Microsoft.AspNetCore.Identity" Version="2.1.6" /> | ||
<PackageReference Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" Version="2.1.6" /> | ||
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="2.1.1" /> | ||
<PackageReference Include="Newtonsoft.Json" Version="12.0.1" /> | ||
</ItemGroup> | ||
|
||
<ItemGroup> | ||
<ProjectReference Include="..\DataLayer\DataLayer.csproj" /> | ||
</ItemGroup> | ||
|
||
</Project> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,97 @@ | ||
// Copyright (c) 2018 Jon P Smith, GitHub: JonPSmith, web: http://www.thereformedprogrammer.net/ | ||
// Licensed under MIT license. See License.txt in the project root for license information. | ||
|
||
using System; | ||
using System.Collections.Generic; | ||
using System.IO; | ||
using System.Linq; | ||
using System.Threading.Tasks; | ||
using DataLayer.EfClasses; | ||
using DataLayer.EfCode; | ||
using Microsoft.AspNetCore.Hosting; | ||
using Microsoft.AspNetCore.Identity; | ||
using Microsoft.Extensions.DependencyInjection; | ||
using Newtonsoft.Json; | ||
using PermissionParts; | ||
|
||
namespace StartupCode | ||
{ | ||
public static class StartupExtensions | ||
{ | ||
private const string SeedDataDir = "SeedData"; | ||
private const string UserInfoJsonFilename = "userinfo.json"; | ||
private const string RoleToPermissionsFilename = "rolestopermissions.json"; | ||
|
||
public static async Task AddUsersAndExtraAuthAsync(this IServiceProvider serviceProvider) | ||
{ | ||
using (var scope = serviceProvider.CreateScope()) | ||
{ | ||
|
||
var services = scope.ServiceProvider; | ||
var env = services.GetRequiredService<IHostingEnvironment>(); | ||
var pathToUserData = Path.GetFullPath(Path.Combine(env.WebRootPath, SeedDataDir, UserInfoJsonFilename)); | ||
var userInfo = JsonConvert.DeserializeObject<List<UserInfoJson>>(File.ReadAllText(pathToUserData)); | ||
|
||
var userManager = services.GetRequiredService<UserManager<IdentityUser>>(); | ||
var roleManager = services.GetRequiredService<RoleManager<IdentityRole>>(); | ||
|
||
var users = await Task.WhenAll(userInfo.Select(async x => await AddUserWithRoles(x, userManager, roleManager))); | ||
|
||
var pathToRolePermissionData = Path.GetFullPath(Path.Combine(env.WebRootPath, SeedDataDir, RoleToPermissionsFilename)); | ||
var rolesToPermissions = JsonConvert.DeserializeObject<List<RoleToPermissions>>(File.ReadAllText(pathToRolePermissionData)); | ||
|
||
using (var context = services.GetRequiredService<ExtraAuthorizeDbContext>()) | ||
{ | ||
context.AddRange(rolesToPermissions); | ||
context.AddRange(userInfo.BuildModulesForUsers(users)); | ||
context.SaveChanges(); | ||
} | ||
} | ||
} | ||
|
||
//--------------------------------------------------------------------------- | ||
//private methods | ||
|
||
private static IEnumerable<ModulesForUser> BuildModulesForUsers(this List<UserInfoJson> userInfo, | ||
IdentityUser[] users) | ||
{ | ||
foreach (var userInfoJson in userInfo.Where(x => !string.IsNullOrEmpty(x.ModulesCommaDelimited))) | ||
{ | ||
PaidForModules combinedModules = PaidForModules.None; | ||
foreach (var moduleName in userInfoJson.ModulesCommaDelimited.Split(',').Select(x => x.Trim())) | ||
{ | ||
if (!Enum.TryParse(typeof(PaidForModules), moduleName, true, out var thisModule)) | ||
throw new InvalidOperationException($"The module name {moduleName} in the {UserInfoJsonFilename} isn't a valid module name."); | ||
combinedModules |= (PaidForModules) thisModule; | ||
} | ||
yield return new ModulesForUser(userInfoJson.Email.GetUserIdWithGivenEmail(users), combinedModules); | ||
} | ||
} | ||
|
||
private static string GetUserIdWithGivenEmail(this string email, IdentityUser[] users) | ||
{ | ||
return users.Single(x => x.Email == email).Id; | ||
} | ||
|
||
private static async Task<IdentityUser> AddUserWithRoles(UserInfoJson userInfo, UserManager<IdentityUser> userManager, RoleManager<IdentityRole> roleManager) | ||
{ | ||
var user = new IdentityUser {UserName = userInfo.Email, Email = userInfo.Email}; | ||
var result = await userManager.CreateAsync(user, user.Email); //email is the password | ||
if (!result.Succeeded) | ||
throw new InvalidOperationException($"Tried to add user {user.UserName}, but failed."); | ||
|
||
foreach (var roleName in userInfo.RolesCommaDelimited.Split(',').Select(x => x.Trim())) | ||
{ | ||
var roleExist = await roleManager.RoleExistsAsync(roleName); | ||
if (!roleExist) | ||
{ | ||
//create the roles and seed them to the database: Question 1 | ||
await roleManager.CreateAsync(new IdentityRole(roleName)); | ||
} | ||
await userManager.AddToRoleAsync(user, roleName); | ||
} | ||
|
||
return user; | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
// Copyright (c) 2018 Jon P Smith, GitHub: JonPSmith, web: http://www.thereformedprogrammer.net/ | ||
// Licensed under MIT license. See License.txt in the project root for license information. | ||
|
||
using System.Collections.Generic; | ||
|
||
namespace StartupCode | ||
{ | ||
public class UserInfoJson | ||
{ | ||
/// <summary> | ||
/// User's Email, which is also their password | ||
/// </summary> | ||
public string Email { get; set; } | ||
/// <summary> | ||
/// List of RoleNames, comma delimited | ||
/// </summary> | ||
public string RolesCommaDelimited { get; set; } | ||
/// <summary> | ||
/// List of Module Names, comma delimited | ||
/// </summary> | ||
public string ModulesCommaDelimited { get; set; } | ||
/// <summary> | ||
/// Various Data authorization data | ||
/// </summary> | ||
public Dictionary<string,string> DataInfo { get; set; } | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.