// Helper methods

        private Task <GetByIdResponse <GlobalSettings> > GetImpl(GetByIdArguments args)
        {
            //M.GlobalSettings mSettings = await _repo.GlobalSettings.FirstOrDefaultAsync();
            //if (mSettings == null)
            //{
            //    // This should never happen
            //    throw new BadRequestException("Settings have not been initialized");
            //}

            //var settings = _mapper.Map<GlobalSettings>(mSettings);
            //var result = new GetByIdResponse<GlobalSettings>
            //{
            //    CollectionName = "Settings",
            //    Result = settings,
            //};

            //if (!string.IsNullOrWhiteSpace(args.Expand))
            //{
            //    Expand(args.Expand, settings, result);
            //}

            // TODO

            return(Task.FromResult(new GetByIdResponse <GlobalSettings>
            {
                CollectionName = "Settings",
                Result = new GlobalSettings {
                    SettingsVersion = Guid.Parse("aafc6590-cadf-45fe-8c4a-045f4d6f73b3")
                }
            }));
        }
        /// <summary>
        /// Returns a <see cref="TEntity"/> as per the Id and the specifications in the <see cref="GetByIdArguments"/>, after verifying the user's permissions
        /// </summary>
        public virtual async Task <(TEntity, Extras)> GetById(TKey id, GetByIdArguments args, CancellationToken cancellation)
        {
            // Parse the parameters
            var expand = ExpressionExpand.Parse(args?.Expand);
            var select = ParseSelect(args?.Select);

            // Load the data
            var data = await GetEntitiesByIds(new List <TKey> {
                id
            }, expand, select, null, cancellation);

            // Check that the entity exists, else return NotFound
            var entity = data.SingleOrDefault();

            if (entity == null)
            {
                throw new NotFoundException <TKey>(id);
            }

            // Load the extras
            var extras = await GetExtras(data, cancellation);

            // Return
            return(entity, extras);
        }
 public async Task <ActionResult <GetByIdResponse <GlobalSettings> > > Get([FromQuery] GetByIdArguments args)
 {
     try
     {
         return(await GetImpl(args));
     }
     catch (BadRequestException ex)
     {
         return(BadRequest(ex.Message));
     }
     catch (Exception ex)
     {
         _logger.LogError($"Error: {ex.Message} {ex.StackTrace}");
         return(BadRequest(ex.Message));
     }
 }
Example #4
0
        // Helper methods

        private async Task <GetEntityResponse <Settings> > GetImpl(GetByIdArguments args)
        {
            var settings = await _repo.Settings
                           .Select(args.Select)
                           .Expand(args.Expand)
                           .OrderBy("PrimaryLanguageId")
                           .FirstOrDefaultAsync();

            if (settings == null)
            {
                // Programmer mistake
                throw new BadRequestException("Settings have not been initialized");
            }

            var result = new GetEntityResponse <Settings>
            {
                Result = settings,
            };

            return(result);
        }
Example #5
0
        public async Task <ActionResult <GetByIdResponse <Settings> > > Get([FromQuery] GetByIdArguments args)
        {
            // Authorized access (Criteria are not supported here)
            var readPermissions = await ControllerUtilities.GetPermissions(_db.AbstractPermissions, PermissionLevel.Read, "settings");

            if (!readPermissions.Any())
            {
                return(StatusCode(403));
            }

            try
            {
                return(await GetImpl(args));
            }
            catch (BadRequestException ex)
            {
                return(BadRequest(ex.Message));
            }
            catch (Exception ex)
            {
                _logger.LogError($"Error: {ex.Message} {ex.StackTrace}");
                return(BadRequest(ex.Message));
            }
        }
Example #6
0
        // Helper methods

        private async Task <GetByIdResponse <Settings> > GetImpl(GetByIdArguments args)
        {
            M.Settings mSettings = await _db.Settings.FirstOrDefaultAsync();

            if (mSettings == null)
            {
                // This should never happen
                throw new BadRequestException("Settings have not been initialized");
            }

            var settings = _mapper.Map <Settings>(mSettings);
            var result   = new GetByIdResponse <Settings>
            {
                CollectionName = "Settings",
                Entity         = settings,
            };

            if (!string.IsNullOrWhiteSpace(args.Expand))
            {
                Expand(args.Expand, settings, result);
            }

            return(result);
        }
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
            });
        }
Example #8
0
 public virtual async Task <ActionResult <GetByIdResponse <TEntity> > > GetById(TKey id, [FromQuery] GetByIdArguments args)
 {
     return(await ControllerUtilities.InvokeActionImpl(async() =>
     {
         var result = await GetByIdImplAsync(id, args);
         return Ok(result);
     }, _logger));
 }
        public virtual async Task <ActionResult <GetByIdResponse <TEntity> > > GetById(TKey id, [FromQuery] GetByIdArguments args, CancellationToken cancellation)
        {
            return(await ControllerUtilities.InvokeActionImpl(async() =>
            {
                // Calculate server time at the very beginning for consistency
                var serverTime = DateTimeOffset.UtcNow;

                // Load the data
                var service = GetFactGetByIdService();
                var(entity, extras) = await service.GetById(id, args, cancellation);

                // Load the extras
                var singleton = new List <TEntity> {
                    entity
                };

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

                // Prepare the result in a response object
                var result = new GetByIdResponse <TEntity>
                {
                    Result = entity,
                    RelatedEntities = relatedEntities,
                    CollectionName = ControllerUtilities.GetCollectionName(typeof(TEntity)),
                    Extras = TransformExtras(extras, cancellation),
                    ServerTime = serverTime,
                };
                return Ok(result);
            }, _logger));
        }
Example #10
0
        public virtual async Task <ActionResult <GetByIdResponse <TEntity> > > GetById(TKey id, [FromQuery] GetByIdArguments args, CancellationToken cancellation)
        {
            // Calculate server time at the very beginning for consistency
            var serverTime = DateTimeOffset.UtcNow;

            // Load the data + extras
            var service = GetFactGetByIdService();
            var result  = await service.GetById(id, args, cancellation);

            var entity = result.Entity;

            // Flatten and Trim
            var singleton = new List <TEntity> {
                entity
            };
            var relatedEntities = Flatten(singleton, cancellation);

            // Prepare the result in a response object
            var response = new GetByIdResponse <TEntity>
            {
                Result          = entity,
                RelatedEntities = relatedEntities,
                CollectionName  = ControllerUtilities.GetCollectionName(typeof(TEntity)),
                Extras          = CreateExtras(result),
                ServerTime      = serverTime,
            };

            return(Ok(response));
        }
        async Task <EntityResult <EntityWithKey> > IFactGetByIdServiceBase.GetById(object id, GetByIdArguments args, CancellationToken cancellation)
        {
            Type target = typeof(TKey);

            if (target == typeof(string))
            {
                id = id?.ToString();
                var result = await GetById((TKey)id, args, cancellation);

                return(new EntityResult <EntityWithKey>(result.Entity));
            }
            else if (target == typeof(int) || target == typeof(int?))
            {
                string stringId = id?.ToString();
                if (int.TryParse(stringId, out int intId))
                {
                    id = intId;
                    var result = await GetById((TKey)id, args, cancellation);

                    return(new EntityResult <EntityWithKey>(result.Entity));
                }
                else
                {
                    throw new ServiceException($"Value '{id}' could not be interpreted as a valid integer");
                }
            }
            else
            {
                throw new InvalidOperationException("Bug: Only integer and string Ids are supported");
            }
        }