public async Task <IHttpActionResult> PostAsync(AccessObjectType objectType, int objectId, [FromBody] CreateAccessRuleDto model, CancellationToken cancellationToken)
        {
            if (model == null || !ModelState.IsValid)
            {
                return(BadRequest());
            }
            await ApiSecurity.AuthorizeAsync(objectType, objectId, AccessPermission.IsOwner, cancellationToken);

            ValidationResult validationResult;

            if (model.Anyone)
            {
                validationResult = await _securityManager.SetAccessRuleAsync(objectType, objectId, new AccessRuleItem { Permission = model.Permission, Visibility = model.Visibility }, cancellationToken);
            }
            else
            {
                var user = await _userManager.FindByEmailAsync(model.Email, cancellationToken);

                if (user == null)
                {
                    ModelState.AddModelError("", string.Format(SecurityApiResources.UserNotFound, model.Email));
                    return(BadRequest());
                }
                validationResult = await _securityManager.SetAccessRuleAsync(objectType, objectId, new AccessRuleItem { User = user, Permission = model.Permission, Visibility = model.Visibility }, cancellationToken);
            }
            if (!validationResult.Succeeded)
            {
                return(this.ValidationContent(validationResult));
            }
            return(Ok(model));
        }
Ejemplo n.º 2
0
        /// <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));
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Checks whether the specified user has the specified <paramref name="requiredPermission" /> for the specified object.
        /// </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="userEmail">The user email.</param>
        /// <param name="requiredPermission">The required permission.</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 <SecurityResult> CheckAccessAsync(AccessObjectType objectType, int objectId, string userEmail, AccessPermission requiredPermission, CancellationToken cancellationToken)
        {
            ThrowIfDisposed();
            var user = await UserManager.FindByEmailAsync(userEmail, cancellationToken);

            return(await CheckAccessAsync(objectType, objectId, user?.Id, requiredPermission, cancellationToken));
        }
Ejemplo n.º 4
0
        /// <summary>
        /// Finds a collection of Access Control Entries (ACEs) with the given values.
        /// </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="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 <ListResult <AccessRuleItem> > GetOwnersAsync(AccessObjectType objectType, int objectId, CancellationToken cancellationToken)
        {
            ThrowIfDisposed();
            var rules = await Store.GetAccessRulesAsync(objectType, objectId, cancellationToken);

            return(ListResult.Create(rules.Data.Where(ace => !ace.Anyone && ace.Permission == AccessPermission.IsOwner)));
        }
Ejemplo n.º 5
0
 /// <summary>
 /// Finds a collection of Access Control Entries (ACEs) with the given values.
 /// </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="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 <ListResult <AccessRuleItem> > GetAccessRulesAsync(AccessObjectType objectType, int objectId, CancellationToken cancellationToken)
 {
     cancellationToken.ThrowIfCancellationRequested();
     ThrowIfDisposed();
     return(await
            (
                from ace in AccessRules
                where ace.ObjectType == objectType && ace.ObjectId == objectId
                orderby ace.User.Email.Name
                select new AccessRuleItem
     {
         Permission = ace.Permission,
         Visibility = ace.Visibility,
         User = ace.User == null ? null : new AccountItem
         {
             Id = ace.User.Id,
             Email = ace.User.Email,
             FirstName = ace.User.FirstName,
             LastName = ace.User.LastName,
             Gender = ace.User.Gender,
             Birthday = ace.User.Birthday
         }
     }
            ).ToListResultAsync(cancellationToken));
 }
Ejemplo n.º 6
0
        /// <summary>
        /// Checks whether the specified user has the specified <paramref name="requiredPermission" /> for the specified object.
        /// </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="userId">The primary key of the user.</param>
        /// <param name="requiredPermission">The required permission.</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 <SecurityResult> CheckAccessAsync(AccessObjectType objectType, int objectId, int?userId, AccessPermission requiredPermission, CancellationToken cancellationToken)
        {
            ThrowIfDisposed();

            var acl = await Store.GetAccessRulesAsync(objectType, objectId, cancellationToken);

            if (acl.Data.IsEmpty)
            {
                return(SecurityResult.AccessDenied);
            }

            var anyone = acl.Data.FirstOrDefault(rule => rule.Anyone);

            if (userId == null && (anyone == null || anyone.Permission < requiredPermission || anyone.Visibility == AccessVisibility.Private))
            {
                return(SecurityResult.AccessDenied);
            }

            var userOrAnyone = acl.Data.FirstOrDefault(rule => rule.User?.Id == userId) ?? anyone;

            if (userOrAnyone == null || userOrAnyone.Permission < requiredPermission)
            {
                return(SecurityResult.AccessDenied);
            }

            return(new SecurityResult(true, anyone?.Visibility ?? AccessVisibility.Unknown));
        }
        public async Task <IHttpActionResult> DeleteAsync(AccessObjectType objectType, int objectId, [FromBody] string email, CancellationToken cancellationToken)
        {
            await ApiSecurity.AuthorizeAsync(objectType, objectId, AccessPermission.IsOwner, cancellationToken);

            AccessRuleItem trustee;

            if (email == null)
            {
                trustee = await _securityManager.GetAccessRuleAsync(objectType, objectId, cancellationToken);
            }
            else
            {
                trustee = await _securityManager.GetAccessRuleByUserEmailAsync(objectType, objectId, email, cancellationToken);
            }
            if (trustee == null)
            {
                ModelState.AddModelError("", string.Format(SecurityApiResources.UserNotFound, email ?? "Anyone"));
                return(BadRequest());
            }

            var validationResult = await _securityManager.RemoveAccessRuleAsync(objectType, objectId, trustee, cancellationToken);

            if (!validationResult.Succeeded)
            {
                return(this.ValidationContent(validationResult));
            }
            return(StatusCode(HttpStatusCode.NoContent));
        }
Ejemplo n.º 8
0
        /// <summary>
        /// Replaces the given <paramref name="rule" /> on the specified object with the <paramref name="newTrustee" />.
        /// </summary>
        /// <param name="objectType">The type of the shared object to be found.</param>
        /// <param name="objectId">The primary key for the shared object to be found.</param>
        /// <param name="rule">The ACE (Access Control Entry) to replace.</param>
        /// <param name="newTrustee">The new ACE (Access Control Entry) 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>
        public virtual async Task <ValidationResult> ReplaceAccessRuleAsync(AccessObjectType objectType, int objectId, AccessRuleItem rule, AccessRuleItem newTrustee, CancellationToken cancellationToken)
        {
            cancellationToken.ThrowIfCancellationRequested();
            ThrowIfDisposed();
            if (rule == null)
            {
                throw new ArgumentNullException(nameof(rule));
            }
            if (newTrustee == null)
            {
                throw new ArgumentNullException(nameof(newTrustee));
            }

            var userId    = rule.User?.Id;
            var aceEntity = await AccessRules.SingleOrDefaultAsync(p => p.ObjectType == objectType && p.ObjectId == objectId && p.UserId == userId, cancellationToken);

            if (aceEntity == null)
            {
                throw new InvalidOperationException("ACE does not exist.");
            }
            aceEntity.Permission = newTrustee.Permission;
            aceEntity.Visibility = newTrustee.Visibility;
            await SaveChangesAsync(cancellationToken);

            return(ValidationResult.Success);
        }
Ejemplo n.º 9
0
        /// <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 inserted.</param>
        /// <param name="objectId">The primary key for the shared object to be inserted.</param>
        /// <param name="rule">The ACEs (Access Control Entries) to insert.</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> AddAccessRuleAsync(AccessObjectType objectType, int objectId, AccessRuleItem rule, CancellationToken cancellationToken)
        {
            cancellationToken.ThrowIfCancellationRequested();
            ThrowIfDisposed();
            if (rule == null)
            {
                throw new ArgumentNullException(nameof(rule));
            }

            if (await AccessRules.Where(objectType, objectId, rule.User?.Id).AnyAsync(cancellationToken))
            {
                return(ValidationResult.Failed("Duplicated ACE entry."));
            }
            AccessRules.Add(new SecurityAccessRule
            {
                ObjectType = objectType,
                ObjectId   = objectId,
                UserId     = rule.User?.Id,
                Permission = rule.Permission,
                Visibility = rule.Visibility
            });
            await SaveChangesAsync(cancellationToken);

            return(ValidationResult.Success);
        }
Ejemplo n.º 10
0
        /// <summary>
        /// Throws a <see cref="HttpResponseException" /> at run time if the security requirement is not met.
        /// </summary>
        /// <param name="objectType">The type of the object to protect.</param>
        /// <param name="objectId">The primary key for the object to protect.</param>
        /// <param name="requiredPermission">The required permission.</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 static async Task AuthorizeAsync(AccessObjectType objectType, int objectId, AccessPermission requiredPermission, CancellationToken cancellationToken)
        {
            if (objectType == AccessObjectType.Unknown)
            {
                throw new HttpResponseException(HttpStatusCode.Forbidden);
            }
            var securityResult = await Manager.CheckAccessAsync(objectType, objectId, WebSecurity.IsAuthenticated?CurrentUserName : null, requiredPermission, cancellationToken);

            if (!securityResult.AccessGranted)
            {
                throw new HttpResponseException(HttpStatusCode.Forbidden);
            }
        }
Ejemplo n.º 11
0
 /// <summary>
 /// Retrieves the <see cref="AccessRuleItem" /> associated with the key, as an asynchronous operation.
 /// </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="cancellationToken">The <see cref="CancellationToken" /> used to propagate notifications that the operation should be canceled.</param>
 /// <returns>
 /// The <see cref="Task" /> for the asynchronous operation, containing the contact, if any which matched the specified key.
 /// </returns>
 public virtual Task <AccessRuleItem> GetAccessRuleAsync(AccessObjectType objectType, int objectId, CancellationToken cancellationToken)
 {
     cancellationToken.ThrowIfCancellationRequested();
     ThrowIfDisposed();
     return(AccessRules
            .Where(objectType, objectId, null)
            .Select(ace => new AccessRuleItem
     {
         Permission = ace.Permission,
         Visibility = ace.Visibility
     })
            .SingleOrDefaultAsync(cancellationToken));
 }
Ejemplo n.º 12
0
        /// <summary>
        /// Deletes all <see cref="AccessRuleItem" />s from 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 for the shared object to be found.</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> RemoveAccessRulesAsync(AccessObjectType objectType, int objectId, CancellationToken cancellationToken)
        {
            cancellationToken.ThrowIfCancellationRequested();
            ThrowIfDisposed();

            await Context.Database.ExecuteSqlCommandAsync(
                $"{DbSchema.Security}.DeleteAccessRules @ObjectTypeId, @ObjectId",
                cancellationToken,
                DbParameters.Value("ObjectTypeId", objectType),
                DbParameters.Value("ObjectId", objectId));

            return(ValidationResult.Success);
        }
Ejemplo n.º 13
0
        /// <summary>
        /// Retrieves the <see cref="AccessRuleItem" /> associated with the key, as an asynchronous operation.
        /// </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="userEmail">The email address of the user to be found.</param>
        /// <param name="cancellationToken">The <see cref="CancellationToken" /> used to propagate notifications that the operation should be canceled.</param>
        /// <returns>
        /// The <see cref="Task" /> for the asynchronous operation, containing the contact, if any which matched the specified key.
        /// </returns>
        public virtual async Task <AccessRuleItem> GetAccessRuleByUserEmailAsync(AccessObjectType objectType, int objectId, string userEmail, CancellationToken cancellationToken)
        {
            ThrowIfDisposed();

            // If the specified user does not exist, do not try to return a 'Anyone'.
            // This method should be straight and unambiguous.
            var user = await UserManager.FindByEmailAsync(userEmail, cancellationToken);

            if (user == null)
            {
                return(null);
            }
            return(await Store.GetAccessRuleByUserAsync(objectType, objectId, user.Id, cancellationToken));
        }
Ejemplo n.º 14
0
        /// <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));
        }
Ejemplo n.º 15
0
 /// <summary>
 /// Retrieves the <see cref="AccessRuleItem" /> associated with the key, as an asynchronous operation.
 /// </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="userId">The primary key of the user to be found.</param>
 /// <param name="cancellationToken">The <see cref="CancellationToken" /> used to propagate notifications that the operation should be canceled.</param>
 /// <returns>
 /// The <see cref="Task" /> for the asynchronous operation, containing the contact, if any which matched the specified key.
 /// </returns>
 public virtual Task <AccessRuleItem> GetAccessRuleByUserAsync(AccessObjectType objectType, int objectId, int userId, CancellationToken cancellationToken)
 {
     cancellationToken.ThrowIfCancellationRequested();
     ThrowIfDisposed();
     return(AccessRules.Where(objectType, objectId, userId).Select(ace => new AccessRuleItem
     {
         Permission = ace.Permission,
         Visibility = ace.Visibility,
         User = new AccountItem
         {
             Id = ace.User.Id,
             Email = ace.User.Email,
             FirstName = ace.User.FirstName,
             LastName = ace.User.LastName,
             Gender = ace.User.Gender,
             Birthday = ace.User.Birthday
         }
     }).SingleOrDefaultAsync(cancellationToken));
 }
Ejemplo n.º 16
0
        /// <summary>
        /// Deletes a list of <see cref="AccessRuleItem" />s from the specified <paramref name="item" />.
        /// </summary>
        /// <param name="objectType">The type of the shared object to be removed.</param>
        /// <param name="objectId">The primary key for the shared object to be removed.</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)
        {
            cancellationToken.ThrowIfCancellationRequested();
            ThrowIfDisposed();
            if (rule == null)
            {
                throw new ArgumentNullException(nameof(rule));
            }

            var aceEntity = await AccessRules.Where(objectType, objectId, rule.User?.Id).SingleOrDefaultAsync(cancellationToken);

            if (aceEntity == null)
            {
                throw new InvalidOperationException("ACE does not exist.");
            }
            Context.Remove(aceEntity);
            await SaveChangesAsync(cancellationToken);

            return(ValidationResult.Success);
        }
Ejemplo n.º 17
0
        /// <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));
        }
Ejemplo n.º 18
0
 /// <summary>
 /// Filters a sequences of items based on predicates.
 /// </summary>
 public static IQueryable <SecurityAccessRule> Where(this IQueryable <SecurityAccessRule> query, AccessObjectType objectType, int objectId, int?userId)
 {
     return(query.Where(ace => ace.ObjectType == objectType && ace.ObjectId == objectId && ace.UserId == userId));
 }
Ejemplo n.º 19
0
 /// <summary>
 /// Finds a collection of Access Control Entries (ACEs) with the given values.
 /// </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="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 <ListResult <AccessRuleItem> > GetAccessRulesAsync(AccessObjectType objectType, int objectId, CancellationToken cancellationToken)
 {
     ThrowIfDisposed();
     return(Store.GetAccessRulesAsync(objectType, objectId, cancellationToken));
 }
 public async Task <IHttpActionResult> GetAllAsync(AccessObjectType objectType, int objectId, CancellationToken cancellationToken)
 {
     return(Ok(await _securityManager.GetAccessRulesAsync(objectType, objectId, cancellationToken)));
 }
Ejemplo n.º 21
0
 /// <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));
 }
Ejemplo n.º 22
0
 /// <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);
 }
Ejemplo n.º 23
0
 /// <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));
 }
Ejemplo n.º 24
0
        /// <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);
        }
Ejemplo n.º 25
0
 /// <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));
 }
Ejemplo n.º 26
0
 /// <summary>
 /// Deletes all <see cref="AccessRuleItem" />s from 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 for the shared object to be found.</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> RemoveAccessRulesAsync(AccessObjectType objectType, int objectId, CancellationToken cancellationToken)
 {
     ThrowIfDisposed();
     return(Store.RemoveAccessRulesAsync(objectType, objectId, cancellationToken));
 }
Ejemplo n.º 27
0
 /// <summary>
 /// Retrieves the <see cref="AccessRuleItem" /> associated with the key, as an asynchronous operation.
 /// </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="cancellationToken">The <see cref="CancellationToken" /> used to propagate notifications that the operation should be canceled.</param>
 /// <returns>
 /// The <see cref="Task" /> for the asynchronous operation, containing the contact, if any which matched the specified key.
 /// </returns>
 public virtual async Task <AccessRuleItem> GetAccessRuleAsync(AccessObjectType objectType, int objectId, CancellationToken cancellationToken)
 {
     ThrowIfDisposed();
     return(await Store.GetAccessRuleAsync(objectType, objectId, cancellationToken));
 }
Ejemplo n.º 28
0
 /// <summary>
 /// Retrieves the <see cref="AccessRuleItem" /> associated with the key, as an asynchronous operation.
 /// </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="userId">The primary key of the user to be found.</param>
 /// <param name="cancellationToken">The <see cref="CancellationToken" /> used to propagate notifications that the operation should be canceled.</param>
 /// <returns>
 /// The <see cref="Task" /> for the asynchronous operation, containing the contact, if any which matched the specified key.
 /// </returns>
 public virtual Task <AccessRuleItem> GetAccessRuleByUserIdAsync(AccessObjectType objectType, int objectId, int userId, CancellationToken cancellationToken)
 {
     ThrowIfDisposed();
     return(Store.GetAccessRuleByUserAsync(objectType, objectId, userId, cancellationToken));
 }