From ea777ec13e662bde3731a929ee32d6c4e4d1d4dd Mon Sep 17 00:00:00 2001 From: Tobias Klika Date: Wed, 20 May 2020 16:09:56 +0200 Subject: [PATCH] store and get current app id (draft) --- zero.Core/Api/AppIdService.cs | 39 ++++++++++++++++++ zero.Core/Api/BackofficeStore.cs | 7 +++- zero.Core/Api/SetupApi.cs | 2 +- zero.Core/Constants.cs | 2 + zero.Core/Entities/User/User.cs | 8 ++++ zero.Core/Extensions/HttpContextExtensions.cs | 41 +++++++++++++++++++ zero.Core/Identity/Permissions.cs | 2 +- zero.Web/ZeroClaimsPrinicipalFactory.cs | 18 ++++++++ 8 files changed, 115 insertions(+), 4 deletions(-) create mode 100644 zero.Core/Api/AppIdService.cs create mode 100644 zero.Core/Extensions/HttpContextExtensions.cs diff --git a/zero.Core/Api/AppIdService.cs b/zero.Core/Api/AppIdService.cs new file mode 100644 index 00000000..709ada74 --- /dev/null +++ b/zero.Core/Api/AppIdService.cs @@ -0,0 +1,39 @@ +//using Microsoft.AspNetCore.Http; +//using Microsoft.AspNetCore.Identity; +//using System; +//using System.Collections.Generic; +//using System.Linq; +//using System.Security.Claims; +//using System.Text; +//using zero.Core.Entities; + +//namespace zero.Core.Api +//{ +// public class AppIdService +// { +// protected UserManager UserManager { get; private set; } + +// protected IHttpContextAccessor HttpContextAccessor { get; set; } + +// protected ClaimsPrincipal Principal => HttpContextAccessor.HttpContext?.User; + + +// public AppIdService(UserManager userManager, IHttpContextAccessor httpContextAccessor) +// { +// UserManager = userManager; +// HttpContextAccessor = httpContextAccessor; +// } + + +// /// +// public string[] GetAllowedAppIds() +// { +// return Principal.Claims +// .Where(claim => claim.Type == Constants.Auth.Claims.Permission && (prefix == null || claim.Value.StartsWith(prefix))) +// .Select(claim => Permission.FromClaim(claim, prefix)) +// .ToList(); + +// //return GetPermissions(Permissions.Applications).Where(x => x.CanRead).Select(x => x.NormalizedKey).ToArray(); +// } +// } +//} diff --git a/zero.Core/Api/BackofficeStore.cs b/zero.Core/Api/BackofficeStore.cs index f8a0d950..9f6ee1dc 100644 --- a/zero.Core/Api/BackofficeStore.cs +++ b/zero.Core/Api/BackofficeStore.cs @@ -1,11 +1,13 @@ using FluentValidation; using FluentValidation.Results; +using Microsoft.AspNetCore.Http; using Raven.Client.Documents; using Raven.Client.Documents.Linq; using Raven.Client.Documents.Session; using System; using System.Collections.Generic; using System.Linq; +using System.Security.Claims; using System.Threading.Tasks; using zero.Core.Attributes; using zero.Core.Entities; @@ -237,9 +239,10 @@ namespace zero.Core.Api public class AppAwareBackofficeStore : BackofficeStore, IAppAwareBackofficeStore { - public AppAwareBackofficeStore(IDocumentStore raven, IMediaUpload media) : base(raven, media) + public AppAwareBackofficeStore(IDocumentStore raven, IMediaUpload media, IHttpContextAccessor httpContextAccessor) : base(raven, media) { - AppId = "zero.applications.1-A"; // TODO + Claim appIdClaim = httpContextAccessor.HttpContext?.User.Claims.FirstOrDefault(x => x.Type == Constants.Auth.Claims.CurrentAppId); + AppId = appIdClaim.Value; } } } diff --git a/zero.Core/Api/SetupApi.cs b/zero.Core/Api/SetupApi.cs index 16f2712f..9f238421 100644 --- a/zero.Core/Api/SetupApi.cs +++ b/zero.Core/Api/SetupApi.cs @@ -249,7 +249,7 @@ namespace zero.Core.Api IsActive = true, Claims = new List() { - new UserClaim(type, Permissions.Applications, PermissionsValue.Write), + //new UserClaim(type, Permissions.Applications, PermissionsValue.Write), new UserClaim(type, Permissions.Sections.Dashboard, PermissionsValue.True), new UserClaim(type, Permissions.Sections.Spaces, PermissionsValue.True), new UserClaim(type, Permissions.Sections.Pages, PermissionsValue.True), diff --git a/zero.Core/Constants.cs b/zero.Core/Constants.cs index 6e10304d..9ac63e5d 100644 --- a/zero.Core/Constants.cs +++ b/zero.Core/Constants.cs @@ -23,6 +23,8 @@ public const string Role = "zero.claim.rolealias"; public const string SecurityStamp = "zero.claim.securitystamp"; public const string Permission = "zero.claim.permission"; + public const string DefaultAppId = "zero.claim.defaultAppId"; + public const string CurrentAppId = "zero.claim.currentAppId"; } } diff --git a/zero.Core/Entities/User/User.cs b/zero.Core/Entities/User/User.cs index eea1b3c2..52b6a6d6 100644 --- a/zero.Core/Entities/User/User.cs +++ b/zero.Core/Entities/User/User.cs @@ -8,6 +8,9 @@ namespace zero.Core.Entities /// public string AppId { get; set; } + /// + public string CurrentAppId { get; set; } + /// public bool IsSuper { get; set; } @@ -72,6 +75,11 @@ namespace zero.Core.Entities public interface IUser : IZeroEntity, IAppAwareEntity, IZeroDbConventions { + /// + /// Currently selected app id for the backoffice + /// + public string CurrentAppId { get; set; } + /// /// sudo. /// The user who created the instance. diff --git a/zero.Core/Extensions/HttpContextExtensions.cs b/zero.Core/Extensions/HttpContextExtensions.cs new file mode 100644 index 00000000..06133b3a --- /dev/null +++ b/zero.Core/Extensions/HttpContextExtensions.cs @@ -0,0 +1,41 @@ +//using Microsoft.AspNetCore.Http; +//using Microsoft.AspNetCore.Identity; +//using Raven.Client.Documents; +//using Raven.Client.Documents.Linq; +//using Raven.Client.Documents.Session; +//using System; +//using System.Collections.Generic; +//using System.Linq; +//using System.Security.Claims; +//using System.Threading.Tasks; +//using zero.Core.Entities; +//using zero.Core.Identity; + +//namespace zero.Core.Extensions +//{ +// public static class HttpContextExtensions +// { +// public static string GetCurrentAppId(this HttpContext context) +// { +// ClaimsPrincipal user = context.User; + +// var permissions = user.Claims.Where(x => x.Type == Constants.Auth.Claims.Permission && ); + +// user.HasClaim(Constants.Auth.Claims.Permission, Permissions.Applications + ":" + PermissionsValue.Write) + +// // this is not the final decision, +// // as we need to check permissions too +// string currentAppId = user.CurrentAppId; + +// // set to default app id when nothing selected yet +// if (currentAppId.IsNullOrEmpty()) +// { +// currentAppId = user.AppId; +// } + +// UserManager manager; + +// manager.cla +// } +// } +//} diff --git a/zero.Core/Identity/Permissions.cs b/zero.Core/Identity/Permissions.cs index c40ce291..fba98193 100644 --- a/zero.Core/Identity/Permissions.cs +++ b/zero.Core/Identity/Permissions.cs @@ -6,7 +6,7 @@ /// Ability to switch zero applications and read/write other applications out of the user appId /// If PermissionsValue.Write is set for this permission, the user will be limited to his/her claims in other applications too /// - public const string Applications = "applications"; + public const string Applications = "applications."; public struct Settings diff --git a/zero.Web/ZeroClaimsPrinicipalFactory.cs b/zero.Web/ZeroClaimsPrinicipalFactory.cs index e839b18e..b6b67cd7 100644 --- a/zero.Web/ZeroClaimsPrinicipalFactory.cs +++ b/zero.Web/ZeroClaimsPrinicipalFactory.cs @@ -1,5 +1,7 @@ using Microsoft.AspNetCore.Identity; using Microsoft.Extensions.Options; +using System.Collections.Generic; +using System.Linq; using System.Security.Claims; using System.Threading.Tasks; using zero.Core; @@ -27,6 +29,22 @@ namespace zero.Web identity.AddClaim(new Claim(Constants.Auth.Claims.IsSuper, PermissionsValue.True)); } + // get all allowed app ids + IEnumerable permissions = identity.Claims + .Where(claim => claim.Type == Constants.Auth.Claims.Permission && claim.Value.StartsWith(Permissions.Applications)) + .Select(x => Permission.FromClaim(x, Permissions.Applications)); + + string[] appIds = permissions.Where(x => x.IsTrue).Select(x => x.NormalizedKey).ToArray(); + + string currentAppId = user.CurrentAppId ?? user.AppId; + + if (!user.IsSuper && !appIds.Contains(currentAppId)) + { + currentAppId = user.AppId; + } + + identity.AddClaim(new Claim(Constants.Auth.Claims.CurrentAppId, currentAppId)); + return principal; } }