Beispiel #1
0
        private dynamic DeleteResource(
            IRequest request,
            TRelation relationType,
            IRequest relatedRequest,
            PermissionHandler <TRelation, TUser> permissionHandler)
        {
            var resource = APIUtils.GetResource(dbContext, request) as object;

            if (resource == null)
            {
                return(new NotFoundResult());
            }

            if (!(resource is RootModel))
            {
                return(new BadRequestObjectResult(
                           new APIError {
                    Code = StatusCodes.Status424FailedDependency,
                    Message = "Only api architecture based models can be deleted"
                }
                           ));
            }

            var globalIntraction = dbContext.MagicDbSet(EngineService.MapRelationToType("Global")) as IEnumerable <dynamic>;
            var globalRelation   = Enum.Parse(enumType: typeof(TRelation), value: "Global");

            var isCreator = globalIntraction
                            .Where(predicate: intraction =>
                                   intraction.IntractionType.Equals(globalRelation) &&
                                   intraction.Valid &&
                                   ((intraction.ValidUntil == null || intraction.ValidUntil.HasValue == false) ||
                                    (intraction.ValidUntil.HasValue && System.DateTime.Now.CompareTo(intraction.ValidUntil.Value) < 0)) &&
                                   (intraction.CreatorId.Equals(permissionHandler.getRequesterID()) &&
                                    intraction.FirstModelId.Equals(permissionHandler.getRequesterID()) &&
                                    intraction.SecondModelId.Equals(resource.GetKeyPropertyValue())))
                            .Any();

            if (!isCreator)
            {
                return(new BadRequestObjectResult(
                           new APIError {
                    Code = StatusCodes.Status403Forbidden,
                    Message = "Only object creator (The owner) can delete it"
                }));
            }

            resource.GetType().GetProperty(nameof(RootModel.Deactivated)).SetValue(resource, true);

            dbContext.Entry(resource).Property(nameof(RootModel.Deactivated)).IsModified = true;
            dbContext.SaveChanges();

            EngineService.OnResourceDeleted(dbContext, request, resource);

            return(new OkResult());
        }
Beispiel #2
0
        private dynamic CreateResource(
            IRequest request,
            HttpRequestMethod requestMethod,
            PermissionHandler <TRelation, TUser> permissionHandler,
            string jsonData)
        {
            var jsonResolver = new APIJsonResolver <TRelation, TUser> {
                DbContext         = dbContext,
                PermissionHandler = permissionHandler,
                ModelAction       = ModelAction.Create,
                RequestMethod     = requestMethod,
                IRequest          = request,
                IncludeKey        = false,
                IncludeBindNever  = false,
                EngineService     = EngineService
            };

            var serializerSettings = JsonConvert.DefaultSettings();

            serializerSettings.ContractResolver = jsonResolver;

            var model =
                JsonConvert.DeserializeObject(
                    value: jsonData,
                    type: request.Temp_ResourceType,
                    settings: serializerSettings);

            dbContext.Add(model);
            dbContext.SaveChanges();

            var intraction = new ModelInteraction <TRelation> {
                CreatorId      = permissionHandler.getRequesterID(),
                FirstModelId   = permissionHandler.getRequesterID(),
                SecondModelId  = model.GetKeyPropertyValue(),
                IntractionType = (TRelation)Enum.Parse(typeof(TRelation), "Global"),
                ModelAction    = ModelAction.Create
            };

            dbContext.MagicAddIntraction(intraction, EngineService.MapRelationToType("Global"));
            dbContext.SaveChangesAsync();

            EngineService.OnResourceCreated(dbContext, request, model, intraction);

            return(new OkObjectResult(new {
                GeneratedID = model.GetKeyPropertyValue()
            }));
        }
Beispiel #3
0
        private dynamic PatchResource(
            IRequest request,
            HttpRequestMethod requestMethod,
            PermissionHandler <TRelation, TUser> permissionHandler,
            string jsonData)
        {
            var jsonResolver = new APIJsonResolver <TRelation, TUser> {
                DbContext         = dbContext,
                PermissionHandler = permissionHandler,
                ModelAction       = ModelAction.Create,
                RequestMethod     = requestMethod,
                IRequest          = request,
                EngineService     = EngineService,
                IncludeKey        = true,
                IncludeBindNever  = false
            };

            var serializerSettings = JsonConvert.DefaultSettings();

            serializerSettings.ContractResolver = jsonResolver;

            var model = JsonConvert.DeserializeObject(
                jsonData,
                request.Temp_ResourceType,
                serializerSettings);

            var oldModel = APIUtils.GetResource(dbContext, request);

            if (oldModel == null)
            {
                return(new NotFoundResult());
            }

            if (oldModel is IdentityUser)
            {
                return(new BadRequestObjectResult(new APIError {
                    Message = "User model can not edited by general api, this must be handled using an special AccountController."
                }));
            }

            var modelKey = model.GetType().GetPropertiesWithAttribute(typeof(KeyAttribute)).FirstOrDefault();

            if (modelKey == null)
            {
                return(new ForbidResult());
            }

            if (request.IdentifierName != modelKey.Name)
            {
                var identifierProperty = model.GetType().GetCustomAttributes <IdentifierValidatorAttribute> ()
                                         .Where(attribute => attribute.PropertyName == request.IdentifierName)
                                         .FirstOrDefault();

                if (identifierProperty == null)
                {
                    return(new ForbidResult());
                }

                modelKey.SetValue(model, modelKey.GetValue(oldModel));
            }

            var modelKeyValue     = modelKey.GetValue(model).ToString();
            var isValidIdentifier = modelKeyValue != null && modelKeyValue != request.IdentifierValue;

            if (!isValidIdentifier ||
                !verifyModelRelationChain(model))
            {
                return(BadRequest(new APIError {
                    Message =
                        "Error: Invalid relation in received model, it can be happend when you are not " +
                        "permitted for this action or there are some invalid id(s)."
                }));
            }

            // dbContext.Update (model);
            // ExcludeAttributes (model);

            IncludeAttributes(model);

            var intraction = new ModelInteraction <TRelation> {
                CreatorId     = permissionHandler.getRequesterID(),
                FirstModelId  = permissionHandler.getRequesterID(),
                SecondModelId = modelKeyValue,
                ModelAction   = ModelAction.Update
            };

            dbContext.MagicAddIntraction(intraction, EngineService.MapRelationToType("Global"));
            dbContext.SaveChanges();

            EngineService.OnResourcePatched(dbContext, request, model);

            return(new OkResult());
        }
        private dynamic JoinResourceAsync(
            IRequest request,
            IRequest relatedRequest,
            TRelation relationType,
            PermissionHandler <TRelation, TUser> permissionHandler,
            HttpRequestMethod httpRequestMethod)
        {
            var oneWayRelation = relatedRequest == null || !relatedRequest.filledWithData();

            if (oneWayRelation)
            {
                relatedRequest = request;
            }

            var resourceType =
                oneWayRelation ?
                typeof(TUser) :
                ModelParser.GetResourceType(request.ResourceName);

            var relatedResourceType = ModelParser.GetResourceType(relatedRequest.ResourceName);

            bool firstIdentifierNameIsKey = true;

            if (!oneWayRelation)
            {
                firstIdentifierNameIsKey = resourceType.GetProperties()
                                           .Where(property =>
                                                  property.Name.Equals(request.IdentifierName) &&
                                                  property.IsDefined(typeof(KeyAttribute), true))
                                           .Any();
            }

            bool secondIdentifierNameIsKey = relatedResourceType.GetProperties()
                                             .Where(prop =>
                                                    prop.Name.Equals(relatedRequest.IdentifierName) &&
                                                    prop.IsDefined(typeof(KeyAttribute), true))
                                             .Any();

            if (!firstIdentifierNameIsKey || !secondIdentifierNameIsKey)
            {
                return(BadRequest(new APIError {
                    Message = "To create relation only key identifier is acceptable"
                }));
            }

            // Check whether request is exist or not
            var requestModel = oneWayRelation ?
                               UserManager.FindByIdAsync(permissionHandler.getRequesterID()).Result :
                               APIUtils.GetResource(dbContext, request);

            if (requestModel == null)
            {
                return(NotFound(request));
            }

            // Check if relationType is valid for request
            var resourceCheck =
                permissionHandler.ModelValidation(
                    Request: request,
                    ModelType: resourceType,
                    ModelAction: ModelAction.Relate,
                    RequestMethod: httpRequestMethod,
                    RelationType: relationType);

            if (!(resourceCheck is bool && (bool)resourceCheck))
            {
                return(BadRequest(new APIError {
                    Message = "Request Error: " + resourceCheck
                }));
            }

            // Check whether related request is exist or not
            var relatedRequestModel = APIUtils.GetResource(dbContext, relatedRequest);

            if (relatedRequestModel == null)
            {
                return(NotFound(relatedRequest));
            }

            // Check if relationType is valid for related request
            var relatedSourceCheck =
                permissionHandler.ModelValidation(
                    Request: relatedRequest,
                    ModelType: relatedResourceType,
                    ModelAction: ModelAction.Relate,
                    RequestMethod: httpRequestMethod,
                    RelationType: relationType);

            if (!(relatedSourceCheck is bool && (bool)relatedSourceCheck))
            {
                return(BadRequest(new APIError {
                    Message = "Request Error: " + relatedSourceCheck
                }));
            }

            if (!oneWayRelation)
            {
                // Check if relationType is valid for requesterID
                var userCheck =
                    permissionHandler.ModelValidation(
                        Request: request,
                        ModelType: typeof(TUser),
                        ModelAction: ModelAction.Relate,
                        RequestMethod: httpRequestMethod,
                        RelationType: relationType);
                if (!(userCheck is bool && (bool)userCheck))
                {
                    return(BadRequest(new APIError {
                        Message = "Request Error: " + userCheck
                    }));
                }
            }

            var intractionType = EngineService.MapRelationToType(relationType.ToString());
            var queryable      = dbContext.MagicDbSet(intractionType);

            var FirstModelId  = oneWayRelation ? permissionHandler.getRequesterID() : request.IdentifierValue;
            var SecondModelId = relatedRequest.IdentifierValue;

            var relation =
                (queryable as IEnumerable <dynamic>)
                .Where(intraction =>
                       intraction.Valid &&
                       ((intraction.ValidUntil == null || intraction.ValidUntil.HasValue == false) ||
                        (intraction.ValidUntil.HasValue && DateTime.Now.CompareTo(intraction.ValidUntil.Value) < 0)) &&
                       (intraction.CreatorId.Equals(permissionHandler.getRequesterID()) &&
                        intraction.FirstModelId.Equals(FirstModelId) &&
                        intraction.SecondModelId.Equals(SecondModelId)))
                .Take(1)
                .FirstOrDefault();

            // Create relation
            if (httpRequestMethod == HttpRequestMethod.Post)
            {
                if (relation != null)
                {
                    return(new OkObjectResult(relation));
                }

                relation = new ModelInteraction <TRelation> {
                    CreatorId      = permissionHandler.getRequesterID(),
                    FirstModelId   = FirstModelId,
                    SecondModelId  = SecondModelId,
                    IntractionType = relationType
                };

                MagicExtentions.MagicAddIntraction(queryable, relation, intractionType);

                EngineService.OnRelationCreated(dbContext, request, relatedRequest, relation);
            }
            else if (httpRequestMethod == HttpRequestMethod.Delete)
            {
                if (relation == null)
                {
                    return(new OkResult());
                }

                queryable.Remove(relation);

                relation.Valid       = false;
                relation.ValidUntil  = DateTime.Now;
                relation.Information = "Extinct by " + permissionHandler.getRequesterID();

                dbContext.MagicAddIntraction(relation as object, EngineService.MapRelationToType("Invalid"));
                EngineService.OnRelationDeleted(dbContext, request, relatedRequest, relation);
            }
            else
            {
                return(BadRequest());
            }

            ResolveRelationDependency(
                requestModel,
                permissionHandler.getRequesterID(),
                request,
                relatedRequest,
                relationType,
                httpRequestMethod);

            ResolveRelationDependency(
                relatedRequestModel,
                permissionHandler.getRequesterID(),
                request,
                relatedRequest,
                relationType,
                httpRequestMethod);

            dbContext.SaveChanges();

            return(new OkObjectResult(relation));
        }