private IMongoQueryable <DbGeoTask> ApplyPagination( IMongoQueryable <DbGeoTask> query, DbGetGeoTaskListRequest request) { if (request.Offset > 0) { query = query.Skip(request.Offset); } if (request.Limit > 0) { query = query.Take(request.Limit); } return(query); }
public static Dictionary <string, object> ToDictionary (this DbGetGeoTaskListRequest from) { return(new Dictionary <string, object> { { nameof(from.Archived), from.Archived }, { nameof(from.Contains), from.Contains }, { nameof(from.Limit), from.Limit }, { nameof(from.MaxTimeToDeadLine), from.MaxTimeToDeadLine }, { nameof(from.Offset), from.Offset }, { nameof(from.TaskStatusMask), from.TaskStatusMask }, { nameof(from.Actors), String.Join(',', from.Actors.Select(x => $"{x.Key}: {x.Value}")) }, { nameof(from.ProjectIds), String.Join(',', from.ProjectIds) }, { nameof(from.GeoIds), String.Join(',', from.GeoIds) }, }); }
public DbGetGeoTaskListRequestSecurityBuilder (DbGetGeoTaskListRequest filter, Actor currentActor, ActorRole projectActorRole = null) { if (filter is null) { throw new System.ArgumentNullException(nameof(filter)); } if (currentActor is null) { throw new System.ArgumentNullException(nameof(currentActor)); } Filter = filter; Actor = currentActor; ProjectActorRole = projectActorRole; }
public async Task <ListResponse <GeoTask> > Handle (DbGetGeoTaskListRequest request, CancellationToken cancellationToken) { try { Logger.LogInformation(LogEvent.DatabaseRequest, "Request={Request}.", request.ToDictionary()); var validation = new DbGetGeoTaskListRequestValidator() .Validate(request); if (!validation.IsValid) { Logger.LogWarning (LogEvent.DatabaseRequestArgumentError, "Database request validation" + " error. Error={Error}.", validation.Errors); return(ErrorResult("Database request validation error")); } var db = DbContext.Db; var query = BuildQuery(request); var totalCount = await query.CountAsync() .ConfigureAwait(false); if (totalCount == 0) { return(new ListResponse <GeoTask>(new List <GeoTask>(), totalCount)); } query = ApplyPagination(query, request); var dbGeoTaskList = await query .ToListAsync() .ConfigureAwait(false); if (dbGeoTaskList is null) { Logger.LogWarning (LogEvent.DatabaseEmptyResponse, "Database GeoTasks null response."); return(ErrorResult("Database GeoTasks null response.")); } var actorIdsSet = new HashSet <string>(); dbGeoTaskList.ForEach (x => { x.AssistentActorsIds .ForEach(x => actorIdsSet.Add(x)); actorIdsSet.Add(x.CreatedById); actorIdsSet.Add(x.ResponsibleActorId); x.ObserverActorsIds .ForEach(x => actorIdsSet.Add(x)); } ); var actorListResponse = await Mediator .Send(new DbListRequest <Actor>(actorIdsSet)) .ConfigureAwait(false); if (!actorListResponse.Success) { Logger.LogWarning (LogEvent.DatabaseEmptyResponse, "Database Actors null response."); return(ErrorResult("Database Actors null response.")); } var actors = actorListResponse.Entities.ToDictionary(x => x.Id); var result = new ListResponse <GeoTask> { Success = true, TotalCount = totalCount }; dbGeoTaskList.ForEach(x => result.Entities.Add(x.ToGeoTask(actors))); return(result); } catch (Exception e) { Logger.LogWarning(LogEvent.DatabaseExceptionError, e, "Database exception error. Error={Error}.", e.Message); return(ErrorResult("Database exception error")); } }
private IMongoQueryable <DbGeoTask> BuildQuery ( DbGetGeoTaskListRequest request ) { var query = DbContext.Db.GetCollection <DbGeoTask> (Defaults.TaskCollectionName) .AsQueryable(); if (!string.IsNullOrWhiteSpace(request.Contains)) { query = query.WhereText(request.Contains); } if (request.Archived.HasValue) { query = query.Where(x => x.IsArchived == request.Archived); } if (request.ProjectIds.Count > 0) { query = query.Where(x => request.ProjectIds.Contains(x.ProjectId)); } if (request.Actors.Count > 0) { foreach (var actorPair in request.Actors) { if (actorPair.Value == 0 || actorPair.Value .Contains(ActorGeoTaskRole.Assistant)) { query = query.Where(x => x.AssistentActorsIds.Any(x => x == actorPair.Key)); } if (actorPair.Value == 0 || actorPair.Value.Contains(ActorGeoTaskRole.Creator)) { query = query.Where(x => x.CreatedById == actorPair.Key); } if (actorPair.Value == 0 || actorPair.Value.Contains(ActorGeoTaskRole.Observer)) { query = query.Where(x => x.ObserverActorsIds.Any(x => x == actorPair.Key)); } if (actorPair.Value == 0 || actorPair.Value .Contains(ActorGeoTaskRole.Responsible)) { query = query.Where(x => x.ResponsibleActorId == actorPair.Key); } } } if (request.TaskStatusMask != 0) { var statuses = new HashSet <GeoTaskStatus>(); var checkList = EnumerationClass.GetAll <GeoTaskStatus>(); foreach (var item in checkList) { if (request.TaskStatusMask.Contains(item)) { statuses.Add(item); } } query = query.Where(x => statuses.Contains(x.Status)); } if (request.MaxTimeToDeadLine.HasValue) { var deadlineTime = DateTime.UtcNow + request.MaxTimeToDeadLine.Value; query = query.Where(x => x.PlanFinishAt.HasValue && deadlineTime >= x.PlanFinishAt); } if (request.GeoIds.Count > 0) { query = query.Where(x => x.GeosIds.Any(z => request.GeoIds.Contains(z))); } return(query); }
public async Task <ListResponse <GeoTask> > Handle (GeoTaskListQuery request, CancellationToken cancellationToken) { Logger.LogInformation(AppLogEvent.HandleRequest, "Handle get task collection {request}", request.ToDictionary()); if (request is null) { Logger.LogWarning(AppLogEvent.HandleArgumentError, "Handle get task collection request with empty request"); return(ErrorResponse("Request empty argument")); } try { // Validate request var validator = new GeoTaskListQueryValidator(); var validationResult = await validator.ValidateAsync(request) .ConfigureAwait(false); if (!validationResult.IsValid) { Logger.LogError("Query validation error. " + "Request={Request}. Error={Error}.", request.ToDictionary(), validationResult.Errors.Select(x => x.ErrorMessage)); return(ErrorResponse (validationResult.Errors.Select(x => x.ErrorMessage))); } // Build filter var defaultLimit = Configuration.GetValue (Defaults.ConfigurationApiDefaultLimitParameterName, Defaults.ConfigurationApiDefaultLimitDefaultValue); var maxLimit = Configuration.GetValue (Defaults.ConfigurationApiMaxLimitParameterName, Defaults.ConfigurationApiMaxLimitDefaultValue); var filter = new DbGetGeoTaskListRequest { Offset = request.Offset, Limit = request.Limit == 0 ? defaultLimit : Math.Min(request.Limit, maxLimit), Archived = request.Archived, Contains = request.СontainsKeyWords, MaxTimeToDeadLine = request.MaxTimeToDeadLine, TaskStatusMask = request.TaskStatusMask, }; if (!String.IsNullOrWhiteSpace(request.ActorId)) { filter.Actors[request.ActorId] = request.ActorRoleMask; } if (!string.IsNullOrWhiteSpace(request.ProjectId)) { filter.ProjectIds.Add(request.ProjectId); } filter.GeoIds.AddRange(request.GeoIds); // Get Actor for current user by user name var currentActorResponse = await Mediator .Send(new DbGetActorByNameRequest (request.CurrentPrincipal?.Identity?.Name)) .ConfigureAwait(false); Actor currentActor = null; if (currentActorResponse.Success) { currentActor = currentActorResponse.Entity; } else { Logger.LogWarning(AppLogEvent.HandleArgumentError, "Not found current actor"); return(ErrorResponse("Not found current actor")); } ActorRole projectActorRole = null; if (!string.IsNullOrWhiteSpace(request.ProjectId)) { projectActorRole = await GetProjectRoleAsync (request.ProjectId, currentActor?.Id) .ConfigureAwait(false); } // Apply security filter var securizator = new DbGetGeoTaskListRequestSecurityBuilder (filter, currentActor, projectActorRole); var securedFilter = securizator.Build(); return(await Mediator.Send(securedFilter) .ConfigureAwait(false)); } catch (Exception e) { Logger.LogError(AppLogEvent.HandleErrorResponse, e, "Call repository exception"); return(ErrorResponse("Not found")); } }