private async Task <ActionResult <EntitiesResponse <ResponsibilityCenter> > > Activate([FromBody] List <int> ids, bool returnEntities, string expand, bool isActive)
        {
            // Parse parameters
            var expandExp = ExpandExpression.Parse(expand);
            var idsArray  = ids.ToArray();

            // Check user permissions
            await CheckActionPermissions("IsActive", idsArray);

            // Execute and return
            using var trx = ControllerUtilities.CreateTransaction();
            await _repo.ResponsibilityCenters__Activate(ids, isActive);

            if (returnEntities)
            {
                var response = await GetByIdListAsync(idsArray, expandExp);

                trx.Complete();
                return(Ok(response));
            }
            else
            {
                trx.Complete();
                return(Ok());
            }
        }
Example #2
0
        public async Task <ActionResult <EntitiesResponse <Document> > > Assign([FromBody] List <int> ids, [FromQuery] AssignArguments args)
        {
            return(await ControllerUtilities.InvokeActionImpl(async() =>
            {
                // Parse parameters
                var selectExp = SelectExpression.Parse(args.Select);
                var expandExp = ExpandExpression.Parse(args.Expand);
                var idsArray = ids.ToArray();

                // TODO: Check user permissions
                // await CheckActionPermissions("IsActive", idsArray);

                // Execute and return
                using var trx = ControllerUtilities.CreateTransaction();
                // TODO: Validate assign

                await _repo.Documents__Assign(ids, args.AssigneeId, args.Comment);

                if (args.ReturnEntities ?? false)
                {
                    var response = await GetByIdListAsync(idsArray, expandExp, selectExp);

                    trx.Complete();
                    return Ok(response);
                }
                else
                {
                    trx.Complete();
                    return Ok();
                }
            }
                                                              , _logger));
        }
Example #3
0
        /// <summary>
        /// Saves the entities (Insert or Update) into the database after authorization and validation.
        /// </summary>
        /// <returns>Optionally returns the same entities in their persisted READ form.</returns>
        protected virtual async Task <EntitiesResponse <TEntity> > SaveImplAsync(List <TEntityForSave> entities, SaveArguments args)
        {
            try
            {
                // Parse arguments
                var expand         = ExpandExpression.Parse(args?.Expand);
                var returnEntities = args?.ReturnEntities ?? false;

                // Trim all strings as a preprocessing step
                entities.ForEach(e => TrimStringProperties(e));

                // This implements field level security
                entities = await ApplyUpdatePermissionsMask(entities);

                // Start a transaction scope for save since it causes data modifications
                using var trx = ControllerUtilities.CreateTransaction(null, GetSaveTransactionOptions());

                // Optional preprocessing
                await SavePreprocessAsync(entities);

                // Validate
                // Basic validation that applies to all entities
                ControllerUtilities.ValidateUniqueIds(entities, ModelState, _localizer);

                // Actual Validation
                await SaveValidateAsync(entities);

                if (!ModelState.IsValid)
                {
                    throw new UnprocessableEntityException(ModelState);
                }

                // Save and retrieve Ids
                var ids = await SaveExecuteAsync(entities, expand, returnEntities);

                // Use the Ids to retrieve the items
                EntitiesResponse <TEntity> result = null;
                if (returnEntities && ids != null)
                {
                    result = await GetByIdListAsync(ids.ToArray(), expand);
                }

                await PostProcess(result);

                // Commit and return
                await OnSaveCompleted();

                trx.Complete();
                return(result);
            }
            catch (Exception ex)
            {
                await OnSaveError(ex);

                throw ex;
            }
        }
Example #4
0
        /// <summary>
        /// Returns a single entity as per the ID and specifications in the get request
        /// </summary>
        protected virtual async Task <EntitiesResponse <TEntity> > GetChildrenOfAsync(GetChildrenArguments <TKey> args)
        {
            // Parse the parameters
            var expand  = ExpandExpression.Parse(args.Expand);
            var select  = SelectExpression.Parse(args.Select);
            var filter  = FilterExpression.Parse(args.Filter);
            var orderby = OrderByExpression.Parse("Node");
            var ids     = args.I ?? new List <TKey>();

            return(await GetByCustomQuery(q => q.FilterByParentIds(ids, args.Roots).Filter(filter), expand, select, orderby));
        }
Example #5
0
        public async Task <ActionResult <EntitiesResponse <Document> > > SignLines([FromBody] List <int> ids, [FromQuery] SignArguments args)
        {
            return(await ControllerUtilities.InvokeActionImpl(async() =>
            {
                // Parse parameters
                var selectExp = SelectExpression.Parse(args.Select);
                var expandExp = ExpandExpression.Parse(args.Expand);
                var idsArray = ids.ToArray();

                // TODO: Check user permissions
                // await CheckActionPermissions("IsActive", idsArray);

                // Execute and return
                using var trx = ControllerUtilities.CreateTransaction();
                // TODO: Validate sign

                var documentIds = await _repo.Lines__Sign(
                    ids,
                    args.ToState,
                    args.ReasonId,
                    args.ReasonDetails,
                    args.OnBehalfOfUserId,
                    args.RoleId,
                    args.SignedAt ?? DateTimeOffset.Now);

                if (args.ReturnEntities ?? false)
                {
                    var response = await GetByIdListAsync(documentIds.ToArray(), expandExp, selectExp);

                    trx.Complete();
                    return Ok(response);
                }
                else
                {
                    trx.Complete();
                    return Ok();
                }
            }
                                                              , _logger));
        }
Example #6
0
        // Endpoint implementations

        /// <summary>
        /// Returns the entities as per the specifications in the get request
        /// </summary>
        protected virtual async Task <GetResponse <TEntity> > GetImplAsync(GetArguments args, Query <TEntity> queryOverride = null)
        {
            // Parse the parameters
            var filter  = FilterExpression.Parse(args.Filter);
            var orderby = OrderByExpression.Parse(args.OrderBy);
            var expand  = ExpandExpression.Parse(args.Expand);
            var select  = SelectExpression.Parse(args.Select);

            // Prepare the query
            var query = queryOverride ?? GetRepository().Query <TEntity>();

            // Retrieve the user permissions for the current view
            var permissions = await UserPermissions(Constants.Read);

            // Filter out permissions with masks that would be violated by the filter or order by arguments
            var defaultMask = GetDefaultMask() ?? new MaskTree();

            permissions = FilterViolatedPermissionsForFlatQuery(permissions, defaultMask, filter, orderby);

            // Apply read permissions
            var permissionsFilter = GetReadPermissionsCriteria(permissions);

            query = query.Filter(permissionsFilter);

            // Search
            query = Search(query, args, permissions);

            // Filter
            query = query.Filter(filter);

            // Before ordering or paging, retrieve the total count
            int totalCount = await query.CountAsync();

            // OrderBy
            query = OrderBy(query, orderby);

            // Apply the paging (Protect against DOS attacks by enforcing a maximum page size)
            var top  = args.Top;
            var skip = args.Skip;

            top   = Math.Min(top, MaximumPageSize());
            query = query.Skip(skip).Top(top);

            // Apply the expand, which has the general format 'Expand=A,B/C,D'
            var expandedQuery = query.Expand(expand);

            // Apply the select, which has the general format 'Select=A,B/C,D'
            expandedQuery = expandedQuery.Select(select);

            // Load the data in memory
            var result = await expandedQuery.ToListAsync();

            // Apply the permission masks (setting restricted fields to null) and adjust the metadata accordingly
            await ApplyReadPermissionsMask(result, query, permissions, defaultMask);

            // Flatten and Trim
            var relatedEntities = FlattenAndTrim(result, expand);

            // Prepare the result in a response object
            return(new GetResponse <TEntity>
            {
                Skip = skip,
                Top = result.Count(),
                OrderBy = args.OrderBy,
                TotalCount = totalCount,

                Result = result,
                RelatedEntities = relatedEntities,
                CollectionName = GetCollectionName(typeof(TEntity))
            });
        }
Example #7
0
        /// <summary>
        /// Returns a single entity as per the ID and specifications in the get request
        /// </summary>
        protected virtual async Task <GetByIdResponse <TEntity> > GetByIdImplAsync(TKey id, [FromQuery] GetByIdArguments args)
        {
            // Parse the parameters
            var expand = ExpandExpression.Parse(args?.Expand);
            var select = SelectExpression.Parse(args?.Select);

            // Prepare the odata query
            var repo  = GetRepository();
            var query = repo.Query <TEntity>();

            // Add the filter by Id
            query = query.FilterByIds(id);

            // Check that the entity exists
            int count = await query.CountAsync();

            if (count == 0)
            {
                throw new NotFoundException <TKey>(id);
            }

            // Apply read permissions
            var permissions = await UserPermissions(Constants.Read);

            var permissionsFilter = GetReadPermissionsCriteria(permissions);

            query = query.Filter(permissionsFilter);

            // Apply the expand, which has the general format 'Expand=A,B/C,D'
            var expandedQuery = query.Expand(expand);

            // Apply the select, which has the general format 'Select=A,B/C,D'
            expandedQuery = expandedQuery.Select(select);

            // Load
            var result = await expandedQuery.FirstOrDefaultAsync();

            if (result == null)
            {
                // We already checked for not found earlier,
                // This can only mean lack of permissions
                throw new ForbiddenException();
            }

            // Apply the permission masks (setting restricted fields to null) and adjust the metadata accordingly
            var singleton = new List <TEntity> {
                result
            };

            await ApplyReadPermissionsMask(singleton, query, permissions, GetDefaultMask());

            // Flatten and Trim
            var relatedEntities = FlattenAndTrim(singleton, expand);

            // Return
            return(new GetByIdResponse <TEntity>
            {
                Result = result,
                CollectionName = GetCollectionName(typeof(TEntity)),
                RelatedEntities = relatedEntities
            });
        }