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()); } }
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)); }
/// <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; } }
/// <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)); }
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)); }
// 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)) }); }
/// <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 }); }