/// <summary> /// Validates the specified <paramref name="rule" /> as an asynchronous operation. /// </summary> /// <param name="manager">The <see cref="SecurityManager" /> that can be used to retrieve user properties.</param> /// <param name="objectType">The type of the shared object to be found.</param> /// <param name="objectId">The primary key of the shared object to be found.</param> /// <param name="rule">The rule to validate.</param> /// <param name="cancellationToken">The <see cref="CancellationToken" /> used to propagate notifications that the operation should be canceled.</param> /// <returns> /// The <see cref="Task" /> that represents the asynchronous operation, containing the <see cref="ValidationResult" /> of the validation operation. /// </returns> protected virtual Task <ValidationResult> ValidateAnyoneAsync(SecurityManager manager, AccessObjectType objectType, int objectId, AccessRuleItem rule, CancellationToken cancellationToken) { if (rule.Permission != AccessPermission.CanView) { return(ValidationResultTask.Failed(string.Format(CultureInfo.CurrentCulture, SecurityResources.AccessPermissionNotSupported))); } if (rule.Visibility == AccessVisibility.Unknown) { return(ValidationResultTask.Failed(string.Format(CultureInfo.CurrentCulture, SecurityResources.AnyoneVisibilityRequired))); } return(ValidationResultTask.Success); }
/// <summary> /// Validates the specified <paramref name="rule" /> as an asynchronous operation. /// </summary> /// <param name="manager">The <see cref="SecurityManager" /> that can be used to retrieve user properties.</param> /// <param name="objectType">The type of the shared object to be found.</param> /// <param name="objectId">The primary key of the shared object to be found.</param> /// <param name="rule">The rule to validate.</param> /// <param name="cancellationToken">The <see cref="CancellationToken" /> used to propagate notifications that the operation should be canceled.</param> /// <returns> /// The <see cref="Task" /> that represents the asynchronous operation, containing the <see cref="ValidationResult" /> of the validation operation. /// </returns> protected virtual Task <ValidationResult> ValidateUserAsync(SecurityManager manager, AccessObjectType objectType, int objectId, AccessRuleItem rule, CancellationToken cancellationToken) { if (rule.Permission == AccessPermission.Unknown) { return(ValidationResultTask.Failed(string.Format(CultureInfo.CurrentCulture, SecurityResources.UserPermissionRequired))); } if (rule.Visibility != AccessVisibility.Unknown) { return(ValidationResultTask.Failed(string.Format(CultureInfo.CurrentCulture, SecurityResources.AccessVisibilityNotSupported))); } return(AtLeastOneOwnerRequired(manager, objectType, objectId, rule, cancellationToken)); }
/// <summary> /// Checks whether at least one owner exists on the specified <paramref name="objectType" />. /// </summary> /// <param name="manager">The <see cref="SecurityManager" /> that can be used to retrieve user properties.</param> /// <param name="objectType">The type of the shared object to be found.</param> /// <param name="objectId">The primary key of the shared object to be found.</param> /// <param name="rule">The rule to validate.</param> /// <param name="cancellationToken">The <see cref="CancellationToken" /> used to propagate notifications that the operation should be canceled.</param> /// <returns> /// The <see cref="Task" /> that represents the asynchronous operation, containing the <see cref="ValidationResult" /> of the validation operation. /// </returns> protected async Task <ValidationResult> AtLeastOneOwnerRequired(SecurityManager manager, AccessObjectType objectType, int objectId, AccessRuleItem rule, CancellationToken cancellationToken) { Debug.Assert(manager != null); Debug.Assert(rule != null); if (rule.Anyone || rule.Permission == AccessPermission.IsOwner) { // No need to check access rules if this operation does not have an effect on owner rights. return(ValidationResult.Success); } var owners = await manager.GetOwnersAsync(objectType, objectId, cancellationToken); if (owners.Data.Count(ace => ace.User.Id != rule.User.Id) == 0) { return(ValidationResult.Failed(string.Format(CultureInfo.CurrentCulture, SecurityResources.OwnerRequired))); } return(ValidationResult.Success); }
/// <summary> /// Validates the specified <paramref name="rule" /> as an asynchronous operation. /// </summary> /// <param name="manager">The <see cref="SecurityManager" /> that can be used to retrieve user properties.</param> /// <param name="objectType">The type of the shared object to be found.</param> /// <param name="objectId">The primary key of the shared object to be found.</param> /// <param name="rule">The rule to validate.</param> /// <param name="cancellationToken">The <see cref="CancellationToken" /> used to propagate notifications that the operation should be canceled.</param> /// <returns> /// The <see cref="Task" /> that represents the asynchronous operation, containing the <see cref="ValidationResult" /> of the validation operation. /// </returns> /// <exception cref="System.ArgumentNullException"></exception> public virtual async Task <ValidationResult> ValidateAsync(SecurityManager manager, AccessObjectType objectType, int objectId, AccessRuleItem rule, CancellationToken cancellationToken) { if (manager == null) { throw new ArgumentNullException(nameof(manager)); } if (rule == null) { return(ValidationResult.Failed(string.Format(CultureInfo.CurrentCulture, SecurityResources.UserPermissionRequired))); } if (rule.Anyone) { return(await ValidateAnyoneAsync(manager, objectType, objectId, rule, cancellationToken)); } return(await ValidateUserAsync(manager, objectType, objectId, rule, cancellationToken)); }
/// <summary> /// Validates access rule. Called by other <see cref="SecurityManager" /> methods. /// </summary> /// <param name="rule">The rule to validate.</param> /// <param name="cancellationToken">A token to observe while waiting for the task to complete.</param> /// <returns> /// A task that represents the asynchronous operation. /// </returns> private Task <ValidationResult> ValidateAccessRuleAsync(AccessObjectType objectType, int objectId, AccessRuleItem rule, CancellationToken cancellationToken) { return((Validator == null) ? Task.FromResult(ValidationResult.Success) : Validator.ValidateAsync(this, objectType, objectId, rule, cancellationToken)); }
/// <summary> /// Deletes a list of <see cref="AccessRuleItem" />s from the specified <paramref name="item" />. /// </summary> /// <param name="item">The shared to be unshared.</param> /// <param name="rule">The ACEs (Access Control Entries) to delete.</param> /// <param name="cancellationToken">A token to observe while waiting for the task to complete.</param> /// <returns> /// A task that represents the asynchronous operation. /// </returns> public virtual async Task <ValidationResult> RemoveAccessRuleAsync(AccessObjectType objectType, int objectId, AccessRuleItem rule, CancellationToken cancellationToken) { ThrowIfDisposed(); if (rule == null) { throw new ArgumentNullException(nameof(rule)); } // At least one specific user is required as owner of the specified object. if (!rule.Anyone && rule.Permission == AccessPermission.IsOwner) { var owners = await Store.GetAccessRulesAsync(objectType, objectId, cancellationToken); if (owners.Data.Count(o => !o.Anyone && o.Permission == AccessPermission.IsOwner) < 2) { return(ValidationResult.Failed(string.Format(CultureInfo.CurrentCulture, SecurityResources.OwnerRequired))); } } return(await Store.RemoveAccessRuleAsync(objectType, objectId, rule, cancellationToken)); }
/// <summary> /// Deletes a list of <see cref="AccessRuleItem" />s from the specified <paramref name="item" />. /// </summary> /// <param name="item">The shared to be unshared.</param> /// <param name="rule">The ACEs (Access Control Entries) to delete.</param> /// <param name="cancellationToken">A token to observe while waiting for the task to complete.</param> /// <returns> /// A task that represents the asynchronous operation. /// </returns> public virtual Task <ValidationResult> RemoveAccessRuleAsync(SharedResourceItem item, AccessRuleItem rule, CancellationToken cancellationToken) { ThrowIfDisposed(); if (item == null) { throw new ArgumentNullException(nameof(item)); } return(RemoveAccessRuleAsync(item.ObjectType, item.Id, rule, cancellationToken)); }
/// <summary> /// Inserts a list of <see cref="AccessRuleItem" />s to the specified <paramref name="item" />. /// </summary> /// <param name="objectType">The type of the shared object to be found.</param> /// <param name="objectId">The primary key of the shared object to be found.</param> /// <param name="rule">The ACEs (Access Control Entries) to set.</param> /// <param name="cancellationToken">A token to observe while waiting for the task to complete.</param> /// <returns> /// A task that represents the asynchronous operation. /// </returns> /// <exception cref="System.ArgumentNullException"></exception> public virtual async Task <ValidationResult> SetAccessRuleAsync(AccessObjectType objectType, int objectId, AccessRuleItem rule, CancellationToken cancellationToken) { ThrowIfDisposed(); if (rule == null) { throw new ArgumentNullException(nameof(rule)); } AccessRuleItem oldRule; if (rule.Anyone) { oldRule = await Store.GetAccessRuleAsync(objectType, objectId, cancellationToken); } else { oldRule = await Store.GetAccessRuleByUserAsync(objectType, objectId, rule.User.Id, cancellationToken); } if (oldRule == null) { return(await AddAccessRuleAsync(objectType, objectId, rule, cancellationToken)); } var validationResult = await ValidateAccessRuleAsync(objectType, objectId, rule, cancellationToken); if (!validationResult.Succeeded) { return(validationResult); } return(await Store.ReplaceAccessRuleAsync(objectType, objectId, oldRule, rule, cancellationToken)); }
/// <summary> /// Inserts a <see cref="AccessRuleItem" /> to the specified <paramref name="item" />. /// </summary> /// <param name="objectType">The type of the shared object to be found.</param> /// <param name="objectId">The primary key of the shared object to be found.</param> /// <param name="rule">The ACEs (Access Control Entries) to set.</param> /// <param name="cancellationToken">A token to observe while waiting for the task to complete.</param> /// <returns> /// A task that represents the asynchronous operation. /// </returns> /// <exception cref="System.ArgumentNullException"></exception> public virtual async Task <ValidationResult> AddAccessRuleAsync(AccessObjectType objectType, int objectId, AccessRuleItem rule, CancellationToken cancellationToken) { ThrowIfDisposed(); if (rule == null) { throw new ArgumentNullException(nameof(rule)); } var validationResult = await ValidateAccessRuleAsync(objectType, objectId, rule, cancellationToken); if (!validationResult.Succeeded) { return(validationResult); } return(await Store.AddAccessRuleAsync(objectType, objectId, rule, cancellationToken)); }