public async Task UpdateAsync(string providerName, string providerKey, IEnumerable <PermissionUpdateRequestModel> requestModels) { foreach (PermissionUpdateRequestModel requestModel in requestModels) { var permission = _permissionDefinitionManager.Get(requestModel.Name); if (permission.AllowedProviders.Any() && !permission.AllowedProviders.Contains(providerName)) { throw new ApplicationException($"The permission named {permission.Name} has not compatible with the provider named {providerName}"); } if (!permission.IsEnabled) { throw new ApplicationException($"The permission named {permission.Name} is disabled"); } PermissionGrant permissionGrant = await _permissionGrantRepository.FindAsync(requestModel.Name, providerName, providerKey); if (requestModel.IsGranted && permissionGrant is null) { await _permissionGrantRepository.InsertAsync(new PermissionGrant { Name = requestModel.Name, ProviderName = providerName, ProviderKey = providerKey, CreateTime = DateTimeOffset.UtcNow }); } if (!requestModel.IsGranted && permissionGrant is not null) { await _permissionGrantRepository.DeleteAsync(permissionGrant); } } await _uow.SaveChangesAsync(); }
/// <summary> /// Check if a user may do something - and throw an error if the permission is not given /// </summary> /// <param name="contentType"></param> /// <param name="grant"></param> /// <param name="autoAllowAdmin"></param> /// <param name="specificItem"></param> private void PerformSecurityCheck(string contentType, PermissionGrant grant, bool autoAllowAdmin = false, IEntity specificItem = null) { // Check if we can find this content-type var ctc = new ContentTypeController(); ctc.SetAppIdAndUser(App.AppId); var cache = DataSource.GetCache(null, App.AppId); var ct = cache.GetContentType(contentType); if (ct == null) { ThrowHttpError(HttpStatusCode.NotFound, "Could not find Content Type '" + contentType + "'.", "content-types"); } // Check if the content-type has a GUID as name - only these can have permission assignments Guid ctGuid; var staticNameIsGuid = Guid.TryParse(ct.StaticName, out ctGuid); if (!staticNameIsGuid) { ThrowHttpError(HttpStatusCode.Unauthorized, "Content Type '" + contentType + "' is not a standard Content Type - no permissions possible."); } // Check permissions in 2sxc - or check if the user has admin-right (in which case he's always granted access for these types of content) var permissionChecker = new PermissionController(App.ZoneId, App.AppId, ctGuid, specificItem, Dnn.Module); var allowed = permissionChecker.UserMay(grant); var isAdmin = autoAllowAdmin && DotNetNuke.Security.Permissions.ModulePermissionController.CanAdminModule(Dnn.Module); if (!(allowed || isAdmin)) { ThrowHttpError(HttpStatusCode.Unauthorized, "Request not allowed. User needs permissions to " + grant + " for Content Type '" + contentType + "'.", "permissions"); } }
public virtual async Task UpdateAsync(string providerName, string providerKey, UpdatePermissionsDto input) { await CheckProviderPolicy(providerName); var permissions = await PermissionGrantRepository.GetListAsync(providerName, providerKey); foreach (var permission in input.Permissions) { var editPermission = permissions.FirstOrDefault(p => p.Name.Equals(permission.Name)); if (editPermission == null) { if (permission.IsGranted) { var permissionGrant = new PermissionGrant(GuidGenerator.Create(), permission.Name, providerName, providerKey, CurrentTenant.Id); await PermissionGrantRepository.InsertAsync(permissionGrant); } } else { if (!permission.IsGranted) { await PermissionGrantRepository.DeleteAsync(editPermission.Id); } } } }
public static IEnumerable <object[]> Rejected() { yield return(new object[] { PermissionGrant.From(Identities.Andre) .To(Identities.DanielB) .ForResources(Resources.Farm.Identifier) .WithActions(ResourceActions.Iam.Owner) .ForSources(DataProviders.Fonterra.Identifier) .WithSchema(Schemas.MilkPickup) }); yield return(new object[] { PermissionGrant.From(Identities.Andre) .To(Identities.Admin) .ForResources(Resources.Farm.Identifier) .WithActions(ResourceActions.Iam.Owner) .ForSources(DataProviders.OpenCountry.Identifier) .WithSchema(Schemas.MilkPickup) }); yield return(new object[] { PermissionGrant.From(Identities.Admin) .To(Identities.DanielB) .ForResources(Resources.HerdTwo.Identifier) .WithActions(ResourceActions.Data.Read) .WithSchema(Schemas.MilkPickup) }); }
public void Add(PermissionGrant grant) { var principal = this.context.Principals.FirstOrDefault(p => p.CanonicalName == grant.Principal.ToString()); var schema = this.context.Schemas.FirstOrDefault(s => s.CanonicalName == grant.Schema.ToString()); var actionsFromRequest = grant.Actions.Select(a => a.ToString()); var actions = this.context.Actions.Where(a => actionsFromRequest.Contains(a.CanonicalName)).ToList(); var resourcesFromRequest = grant.Resource.Select(r => r.ToString()); var resources = this.context.Resources.Where(r => resourcesFromRequest.Contains(r.CanonicalName)).ToList(); var toAdd = new Persistance.Models.PermissionGrant() { Principal = principal, Schema = schema }; var actionsToAdd = actions.Select(a => new Persistance.Models.PermissionGrantResourceAction() { Action = a, Grant = toAdd }); var resourcesToAdd = resources.Select(r => new Persistance.Models.PermissionGrantResource() { Resource = r, Grant = toAdd }); this.context.Add(toAdd); this.context.AddRange(actionsToAdd); this.context.AddRange(resourcesToAdd); this.context.SaveChanges(); }
public bool IsGrantValid(PermissionGrant grant) { if (grant.Tag == null || !grant.Tag.Any()) { return(true); } var parents = this.principalStorage.FindParents(grant.Principal).Select(p => p.Identifier); var policies = this.storage.GetPoliciesForSchema(grant.Schema).ToList(); foreach (var tag in grant.Tag) { var rules = policies .Where(p => p.Provider == tag) .SelectMany(p => p.Rule.Where(r => r.Principal == grant.Principal || parents.Contains(r.Principal))); var denied = rules.Any(r => r.Deny); if (denied) { return(false); } } return(true); }
public void GrantRejected(PermissionGrant grant) { // Act var result = this.manager.Add(grant); // Assert result.Should().BeFalse(); }
public void PolicyDeniesGrant(PermissionGrant grant) { // Act var valid = this.applicator.IsGrantValid(grant); // Assert valid.Should().BeFalse(); }
public void GrantAllowed(PermissionGrant grant) { // Act var result = this.manager.Add(grant); // Assert result.Should().BeTrue(); }
public void PolicyAllowsGrant(PermissionGrant grant) { // Act var valid = this.applicator.IsGrantValid(grant); // Assert valid.Should().BeTrue(); }
public IActionResult Post(PermissionGrant grant) { var valid = this.manager.Add(grant); if (!valid) { return(BadRequest("Provided grant is invalid")); } return(Ok(grant)); }
public void Remove(PermissionGrant grant) { var found = this.context.PermissionGrants.FirstOrDefault(g => g.PermissionGrantId == grant.Id); if (found == null) { return; } this.context.Remove(found); this.context.SaveChanges(); }
public async Task <PermissionListResponseModel> GetAsync([NotNull] string providerName, [NotNull] string providerKey) { var result = new PermissionListResponseModel { EntityDisplayName = providerKey, Groups = new List <PermissionGroupModel>() }; foreach (var group in _permissionDefinitionManager.GetGroups()) { PermissionGroupModel permissionGroupModel = new() { DisplayName = _localizer[group.Name] ?? group.Name, Name = group.Name, Permissions = new List <PermissionGrantModel>() }; foreach (PermissionDefinition?permission in group.GetPermissionsWithChildren()) { if (permission.IsEnabled && (!permission.AllowedProviders.Any() || permission.AllowedProviders.Contains(providerName))) { PermissionGrantModel permissionGrantModel = new() { Name = permission.Name, DisplayName = _localizer[permission.DisplayName ?? permission.Name] ?? permission.Name, ParentName = permission.Parent?.Name !, AllowedProviders = permission.AllowedProviders }; if (permission.AllowedProviders.Any() && !permission.AllowedProviders.Contains(providerName)) { throw new ApplicationException($"The permission named {permission.Name} has not compatible with the provider named {providerName}"); } if (!permission.IsEnabled) { throw new ApplicationException($"The permission named {permission.Name} is disabled"); } PermissionGrant permissionGrant = await _permissionGrantRepository.FindAsync(permission.Name, providerName, providerKey); permissionGrantModel.IsGranted = permissionGrant != null; permissionGroupModel.Permissions.Add(permissionGrantModel); } } if (permissionGroupModel.Permissions.Any()) { result.Groups.Add(permissionGroupModel); } } return(result); }
public virtual async Task <PermissionGrant> UpdateProviderKeyAsync(PermissionGrant permissionGrant, string providerKey) { using (CurrentTenant.Change(permissionGrant.TenantId)) { //Invalidating the cache for the old key await Cache.RemoveAsync( PermissionGrantCacheItem.CalculateCacheKey( permissionGrant.Name, permissionGrant.ProviderName, permissionGrant.ProviderKey ) ); } permissionGrant.ProviderKey = providerKey; return(await PermissionGrantRepository.UpdateAsync(permissionGrant)); }
private bool ValidateGrantAuthority(PermissionGrant grant) { if (grant.Grantor == Principal.Platform) { return(true); } var allActions = this.resources.AllActions().ToList(); var ownerAction = allActions.FirstOrDefault(ra => ra == "iam:owner"); var delegatedAction = allActions.FirstOrDefault(ra => ra == "iam:delegated"); if (ownerAction == default(ResourceAction) && delegatedAction == default(ResourceAction)) { return(false); } foreach (var resource in grant.Resource) { var result = this.validator.Validate(new PermissionValidationRequest() { Schema = grant.Schema, Principal = grant.Grantor, Action = ownerAction, Resource = resource }); // this is the case for no grants, thus no permissions if (result.DeniedResources.Count == 0 && result.AllowedResources.Count == 0) { return(false); } if (result.DeniedResources.Contains(resource)) { return(false); } } return(true); }
public static IEnumerable <object[]> Allowed() { yield return(new object[] { PermissionGrant.From(Identities.Admin) .To(Identities.Andre) .ForResources(Resources.Herd.Identifier) .WithActions(ResourceActions.Data.Read) .WithSchema(Schemas.MilkPickup) }); yield return(new object[] { PermissionGrant.From(Identities.Admin) .To(Identities.DanielB) .ForResources(Resources.Herd.Identifier) .WithActions(ResourceActions.Data.Read) .WithSchema(Schemas.MilkPickup) }); yield return(new object[] { PermissionGrant.From(Identities.Platform) .To(Identities.DanielB) .ForResources(Resources.Farm.Identifier) .WithActions(ResourceActions.Iam.Owner) .WithSchema(Schemas.MilkPickup) }); yield return(new object[] { PermissionGrant.From(Identities.Andre) .To(Identities.Admin) .ForResources(Resources.HerdTwo.Identifier) .WithActions(ResourceActions.Data.Read) .WithSchema(Schemas.MilkPickup) }); }
public bool Add(PermissionGrant grant) { if (!grant.IsValid) { return(false); } var allowedByPolicy = this.applicator.IsGrantValid(grant); if (!allowedByPolicy) { return(false); } if (!ValidateGrantAuthority(grant)) { return(false); } this.storage.Add(grant); return(true); }
/// <summary> /// Check if a user may do something - and throw an error if the permission is not given /// </summary> /// <param name="contentType"></param> /// <param name="grant"></param> /// <param name="autoAllowAdmin"></param> /// <param name="specificItem"></param> /// <param name="useContext"></param> /// <param name="appId"></param> internal void PerformSecurityCheck(string contentType, PermissionGrant grant, bool autoAllowAdmin = false, IEntity specificItem = null, bool useContext = true, int?appId = null) { Log.Add($"security check for type:{contentType}, grant:{grant}, autoAdmin:{autoAllowAdmin}, useContext:{useContext}, app:{appId}, item:{specificItem?.EntityId}"); // make sure we have the right appId, zoneId and module-context var contextMod = useContext ? Dnn.Module : null; var zoneId = useContext ? App?.ZoneId : null; // App is null, when accessing admin-ui from un-initialized module if (useContext) { appId = App?.AppId ?? appId; } if (!useContext) { autoAllowAdmin = false; // auto-check not possible when not using context } if (!appId.HasValue) { throw new Exception("app id doesn't have value, and apparently didn't get it from context either"); } // Check if we can find this content-type var ctc = new ContentTypeController(); ctc.SetAppIdAndUser(appId.Value); var cache = DataSource.GetCache(zoneId, appId); var ct = cache.GetContentType(contentType); if (ct == null) { ThrowHttpError(HttpStatusCode.NotFound, "Could not find Content Type '" + contentType + "'.", "content-types"); return; } // Check if the content-type has a GUID as name - only these can have permission assignments // only check permissions on type if the type has a GUID as static-id var staticNameIsGuid = Guid.TryParse(ct.StaticName, out var ctGuid); // Check permissions in 2sxc - or check if the user has admin-right (in which case he's always granted access for these types of content) if (staticNameIsGuid && new DnnPermissionController(ct, specificItem, Log, contextMod) .UserMay(grant)) { return; } // if initial test couldn't be done (non-guid) or failed, test for admin-specifically if (autoAllowAdmin && DotNetNuke.Security.Permissions.ModulePermissionController.CanAdminModule(contextMod)) { return; } // if the cause was not-admin and not testable, report better error if (!staticNameIsGuid) { ThrowHttpError(HttpStatusCode.Unauthorized, "Content Type '" + contentType + "' is not a standard Content Type - no permissions possible."); } // final case: simply not allowed ThrowHttpError(HttpStatusCode.Unauthorized, "Request not allowed. User needs permissions to " + grant + " for Content Type '" + contentType + "'.", "permissions"); }
public bool UserMay(PermissionGrant action) => DoesPermissionsListAllow((Char)action);
/// <summary> /// Check if a user may do something - and throw an error if the permission is not given /// </summary> /// <param name="contentType"></param> /// <param name="grant"></param> private void PerformSecurityCheck(string contentType, PermissionGrant grant, bool autoAllowAdmin = false) { // Check if we can find this content-type var ct = new Eav.WebApi.ContentTypeController().GetSingle(App.AppId, contentType, null); if(ct == null) ThrowHttpError(HttpStatusCode.NotFound, "Could not find Content Type '" + contentType + "'.", "content-types"); // Check if the content-type has a GUID as name - only these can have permission assignments Guid ctGuid; var staticNameIsGuid = Guid.TryParse(ct.StaticName, out ctGuid); if(!staticNameIsGuid) ThrowHttpError(HttpStatusCode.Unauthorized, "Content Type '" + contentType + "' is not a standard Content Type - no permissions possible."); // Check permissions in 2sxc - or check if the user has admin-right (in which case he's always granted access for these types of content) var permissionChecker = new PermissionController(App.ZoneId, App.AppId, ctGuid, Dnn.Module); var allowed = permissionChecker.UserMay(grant); var isAdmin = autoAllowAdmin && DotNetNuke.Security.Permissions.ModulePermissionController.CanAdminModule(Dnn.Module); if(!(allowed || isAdmin)) ThrowHttpError(HttpStatusCode.Unauthorized, "Request not allowed. User needs permissions to " + grant + " for Content Type '" + contentType + "'.", "permissions"); }
public void Remove(PermissionGrant grant) => this.grants.Remove(grant);
public void Add(PermissionGrant grant) => this.grants.Add(grant);
public bool UserMay(PermissionGrant action) { return DoesPermissionsListAllow((Char)action); }
public bool UserMay(PermissionGrant action) { return(DoesPermissionsListAllow((Char)action)); }