public static _ApiEntityType ToEntity <TEntity>(this Project from) where TEntity : _ApiEntityType { if (from is null) { return(null); } var to = new _ApiEntityType { Description = from.Description, Id = from.Id, Title = from.Title, CreatedAt = from.CreatedAt, CreatedBy = from.CreatedBy.ToApiActor(), IsArchived = from.IsArchived, IsMap = from.IsMap, MapProvider = from.MapProvider, ShowMap = from.ShowMap }; to.Layers.AddRange(from.Layers); from.MapParameters.ToList().ForEach(x => to.MapParameters.TryAdd(x.Key, x.Value)); from.ProjectActorRoles.ToList().ForEach(x => to.ProjectActorRoles.TryAdd(x.Key, x.Value)); return(to); }
public static Dictionary <string, object> ToDictionary (this _TEntity from) { if (from is null) { return(null); } return(new Dictionary <string, object> { { nameof(from.Id), from.Id }, { nameof(from.Layers), String.Join(',', from.Layers.Select(x => $"{{\"{nameof(x.GeoId)}\"={x.GeoId}," + $"\"{nameof(x.IsHidden)}\"={x.IsHidden}," + $"\"{nameof(x.Order)}\"={x.Order}}}")) }, { nameof(from.Description), from.Description }, { nameof(from.IsArchived), from.IsArchived }, { nameof(from.IsMap), from.IsMap }, { nameof(from.MapParameters), String.Join(',', from.MapParameters.Select(x => $"{{\"{nameof(x.Key)}\"={x.Value.ToString()}}}")) }, { nameof(from.MapProvider), from.MapProvider }, { nameof(from.ProjectActorRoles), String.Join(',', from.ProjectActorRoles.Select(x => $"{{\"{nameof(x.Key)}\"={x.Value}}}")) }, { nameof(from.ShowMap), from.ShowMap }, { nameof(from.Title), from.Title }, { nameof(from.CreatedAt), from.CreatedAt } }); }
private async Task <_TEntity> BuildUpdatedEntity (_TUpdateCommand command, _TEntity oldEntity) { var newEntity = new _TEntity { CreatedAt = oldEntity.CreatedAt, CreatedBy = oldEntity.CreatedBy, Description = command.Description, Id = oldEntity.Id, IsArchived = command.IsArchived, Title = command.Title, IsMap = command.IsMap, MapProvider = command.MapProvider, ShowMap = command.ShowMap }; newEntity.Layers.AddRange(command.Layers); command.MapParameters .ToList() .ForEach(x => newEntity.MapParameters.TryAdd(x.Key, x.Value)); // There is no necessary to check actor Ids when they are the same. if (command.ProjectActorRoles .All(x => oldEntity.ProjectActorRoles.ContainsKey(x.Key))) { command.ProjectActorRoles .ToList() .ForEach(x => newEntity.ProjectActorRoles .TryAdd(x.Key, x.Value)); } else { var checkingActorIds = command.ProjectActorRoles.Keys; var repResponse = await Mediator .Send(new DbListRequest <Actor>(checkingActorIds)) .ConfigureAwait(false); if (repResponse.Success) { var actorIdSet = new HashSet <string> (repResponse.Entities.Select(x => x.Id)); command.ProjectActorRoles .ToList() .ForEach(x => { if (actorIdSet.Contains(x.Key)) { newEntity.ProjectActorRoles.TryAdd(x.Key, x.Value); } }); } } return(await Task.FromResult(newEntity).ConfigureAwait(false)); }
private async Task <ValidationResult> CheckPermissionAsync (_TEntity oldEntity, _TEntity newEntity, Actor currentActor) { var checkModel = new CheckUpdatePermissionModel <_TEntity> { Actor = currentActor, EntityBeforeUpdate = oldEntity, EntityAfterUpdate = newEntity }; var validator = new UpdatePermissionValidator <_TEntity>(); var validatorResult = await validator.ValidateAsync(checkModel) .ConfigureAwait(false); return(validatorResult); }
private async Task <CreateResult> CheckPermission (_TEntity entity, Actor currentActor) { var checkModel = new CheckCreatePermissionModel <_TEntity> { Entity = entity, Actor = currentActor }; var validator = new CreatePermissionValidator <_TEntity>(); var validatorResult = await validator.ValidateAsync(checkModel) .ConfigureAwait(false); if (!validatorResult.IsValid) { return(ErrorResult(validatorResult.Errors .Select(x => x.ErrorMessage))); } return(new CreateResult { Success = true }); }
public async Task <UpdateResult> Handle(_TUpdateCommand command, CancellationToken cancellationToken) { try { Logger.LogInformation(AppLogEvent.HandleRequest, "Handle Project Update Command {Command}", command.ToDictionary()); if (command is null || string.IsNullOrWhiteSpace(command.Id)) { Logger.LogWarning(AppLogEvent.HandleArgumentError, "Project Update Command is empty"); return(ErrorResult("Project Update Command is empty")); } var validator = new ProjectUpdateCommandValidator(); var validationResult = await validator.ValidateAsync(command) .ConfigureAwait(false); if (!validationResult.IsValid) { var validationErrors = validationResult.Errors .Select(x => x.ErrorMessage) .ToList(); Logger.LogWarning(AppLogEvent.HandleArgumentError, "Project Update Command validation error. " + "Command={Command}. Error={Error}.", command.ToDictionary(), validationErrors); return(ErrorResult(validationErrors)); } var oldEntityResponse = await Mediator .Send(new DbGetEntityByIdRequest <_TEntity>(command.Id)) .ConfigureAwait(false); if (!oldEntityResponse.Success) { Logger.LogWarning(AppLogEvent.HandleErrorResponse, "Get entity for update error. Id={Id}. Error={Error}", command.Id, oldEntityResponse.Errors); return(ErrorResult(oldEntityResponse.Errors)); } var oldEntity = oldEntityResponse.Entity; var currentActorResponse = await Mediator .Send(new DbGetActorByNameRequest (command.CurrentPrincipal?.Identity?.Name)) .ConfigureAwait(false); var currentActor = currentActorResponse.Success ? currentActorResponse.Entity : null; _TEntity newEntity = await BuildUpdatedEntity(command, oldEntity) .ConfigureAwait(false); var validatorBeforeSave = new BeforeSaveValidator <_TEntity>(); var validationBeforeSaveResult = await validatorBeforeSave .ValidateAsync(newEntity) .ConfigureAwait(false); if (!validationBeforeSaveResult.IsValid) { Logger.LogWarning(AppLogEvent.RequestValidationError, "Update Project validation error. Entity={Entity}. " + "Error={Error}.", newEntity.ToDictionary(), validationBeforeSaveResult.Errors); return(ErrorResult(validationBeforeSaveResult.Errors .Select(x => x.ErrorMessage))); } var permissionValidateResult = await CheckPermissionAsync (oldEntity, newEntity, currentActor) .ConfigureAwait(false); if (!permissionValidateResult.IsValid) { Logger.LogWarning(AppLogEvent.SecurityNotPassed, "Current actor has no rights to update entity. " + "Actor={Actor}. Entity before update={OldEntity}. " + "Entity after update={NewEntity}. Error={Error}.", currentActor.ToDictionary(), oldEntity.ToDictionary(), newEntity.ToDictionary(), permissionValidateResult.Errors .Select(x => x.ErrorMessage)); return(ErrorResult(permissionValidateResult.Errors .Select(x => x.ErrorMessage))); } var updateResult = await Mediator .Send(new DbUpdateCommand <_TEntity>(newEntity)) .ConfigureAwait(false); return(updateResult); } catch (Exception e) { Logger.LogError(AppLogEvent.HandleErrorResponse, e, "Project update exception"); return(ErrorResult("Project update exception")); } }
public async Task <CreateResult> Handle(_TCreateCommand command, CancellationToken cancellationToken) { Logger.LogInformation(AppLogEvent.HandleRequest, "Handle Project Create Command. Command={Command}", command.ToDictionary()); if (command is null) { Logger.LogWarning(AppLogEvent.HandleArgumentError, "Handle Create Project Command got empty command"); return(ErrorResult("Empty Project Create command")); } try { var validator = new CreateCommandValidator <_TCreateCommand>(); var validationResult = await validator.ValidateAsync(command) .ConfigureAwait(false); if (!validationResult.IsValid) { Logger.LogWarning(AppLogEvent.RequestValidationError, "Validation command error. Command={Command}. " + "Error={Error}.", command.ToDictionary(), validationResult.Errors); return(ErrorResult(validationResult.Errors .Select(x => x.ErrorMessage))); } // Get Actor for current user by user name Actor createdBy = null; var currentUserName = command.CurrentPrincipal? .Identity? .Name; var creatorResponse = await Mediator .Send(new DbGetActorByNameRequest(currentUserName)) .ConfigureAwait(false); if (creatorResponse.Success) { createdBy = creatorResponse.Entity; //TODO Add to all create permission validation CreatedBy not null check } var entity = new _TEntity() { CreatedAt = DateTime.UtcNow, CreatedBy = createdBy, Description = command.Description, IsArchived = command.IsArchived, Title = command.Title, IsMap = command.IsMap, MapProvider = command.MapProvider, ShowMap = command.ShowMap }; entity.Layers.AddRange(command.Layers); command.MapParameters .ToList() .ForEach(x => entity.MapParameters.TryAdd(x.Key, x.Value)); var checkingActors = command.ProjectActorRoles.Keys; if (checkingActors.Count > 0) { var actorIdsFromRepository = await GetActorIds (checkingActors).ConfigureAwait(false); foreach (var item in command.ProjectActorRoles) { if (!String.IsNullOrWhiteSpace(item.Key) && actorIdsFromRepository.Contains(item.Key)) { entity.ProjectActorRoles.Add(item.Key, item.Value); } } } var validatorBeforeSave = new BeforeSaveValidator <_TEntity>(); var validationBeforeSaveResult = await validatorBeforeSave .ValidateAsync(entity).ConfigureAwait(false); if (!validationBeforeSaveResult.IsValid) { Logger.LogWarning(AppLogEvent.RequestNotValid, "Project validation error. Entity={Entity}. " + "Error={Error}.", entity.ToDictionary(), validationBeforeSaveResult.Errors); return(ErrorResult(validationBeforeSaveResult.Errors .Select(x => x.ErrorMessage))); } var checkPermissionResult = await CheckPermission(entity, createdBy).ConfigureAwait(false); if (!checkPermissionResult.Success) { Logger.LogWarning(AppLogEvent.SecurityNotPassed, "Project Create permission error. " + "Entity={Entity}. CurrentActor={CurrentActor}." + " Error={Error}.", entity.ToDictionary(), createdBy?.ToDictionary(), checkPermissionResult.Errors); return(checkPermissionResult); } return(await Mediator.Send (new DbCreateCommand <_TEntity>(entity)) .ConfigureAwait(false)); } catch (Exception e) { Logger.LogError(AppLogEvent.HandleErrorResponse, e, "Call repository exception"); return(ErrorResult("Not found")); } }