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