public async Task <IActionResult> GetNew(string dataType, int count = 1) { // Validate IRdDataStorage rdDataStorage; try { rdDataStorage = await dataRouter.GetSourceSystemAsync(dataType); } catch (KeyNotFoundException e) { return(BadRequest(e.Message)); } // Authorize var loggedInUsername = UsernameNormalizer.Normalize(HttpContext.User.Identity.Name); var resourceDescription = new SubmitDataResourceDescription(dataType); var authorizationResult = await authorizationModule.AuthorizeAsync(resourceDescription, loggedInUsername); if (!authorizationResult.IsAuthorized) { return(StatusCode((int)HttpStatusCode.Unauthorized, "Not authorized")); } // Provide var idReservationResult = await rdDataStorage.GetIdsAsync(dataType, loggedInUsername, count); if (idReservationResult.Any(reservationResult => !reservationResult.IsReserved)) { return(StatusCode((int)HttpStatusCode.InternalServerError, "Failed to reserve ID")); } if (idReservationResult.Any(x => x.IsNewCollection)) { newCollectionTasks.PerformTasks(dataType, authorizationResult.User); } return(new ContentResult { ContentType = "text/plain", Content = string.Join("\n", idReservationResult.Select(x => x.Id)), StatusCode = (int)HttpStatusCode.OK }); }
public async Task <IActionResult> TransferSubmissionData([FromQuery] string dataType, [FromQuery] string submissionId) { if (submissionId == null) { return(BadRequest("Invalid submissionId")); } // Authorize var loggedInUsername = UsernameNormalizer.Normalize(HttpContext.User.Identity.Name); var resourceDescription = new SubmitDataResourceDescription(dataType); var authorizationResult = await authorizationModule.AuthorizeAsync(resourceDescription, loggedInUsername); if (!authorizationResult.IsAuthorized) { return(StatusCode((int)HttpStatusCode.Unauthorized, "Not authorized")); } IRdDataStorage rdDataStorage; try { rdDataStorage = await dataRouter.GetSourceSystemAsync(dataType); } catch (KeyNotFoundException) { return(BadRequest($"No data storage backend for data type '{dataType}'")); } if (!(rdDataStorage is IBinaryRdDataStorage binaryRdDataStorage)) { return(BadRequest($"Transfer of data for data type '{dataType}' is not supported")); } if (!await binaryRdDataStorage.ExistsAsync(dataType, submissionId)) { return(NotFound()); } apiEventLogger.Log(LogLevel.Info, $"User '{authorizationResult.User.UserName}' has injected binary payload into '{dataType}' with ID '{submissionId}'"); await binaryRdDataStorage.InjectDataAsync(dataType, submissionId, Request.Body); return(Ok()); }
public async Task <IActionResult> Reserve(string dataType, string id) { // Validate IRdDataStorage rdDataStorage; try { rdDataStorage = await dataRouter.GetSourceSystemAsync(dataType); } catch (KeyNotFoundException e) { return(BadRequest(e.Message)); } if (!rdDataStorage.IsValidId(id)) { return(BadRequest($"The ID '{id}' for object of type '{dataType}' is not valid")); } // Authorize var loggedInUsername = UsernameNormalizer.Normalize(HttpContext.User.Identity.Name); var resourceDescription = new SubmitDataResourceDescription(dataType); var authorizationResult = await authorizationModule.AuthorizeAsync(resourceDescription, loggedInUsername); if (!authorizationResult.IsAuthorized) { return(StatusCode((int)HttpStatusCode.Unauthorized, "Not authorized")); } // Provide var idReservationResult = await rdDataStorage.ReserveIdAsync(dataType, id, loggedInUsername); if (!idReservationResult.IsReserved) { return(StatusCode((int)HttpStatusCode.Forbidden, "Failed to reserve ID")); } if (idReservationResult.IsNewCollection) { newCollectionTasks.PerformTasks(dataType, authorizationResult.User); } return(Ok()); }
public async Task <IActionResult> Submit([FromBody] SubmitDataBody body) { if (!NamingConventions.IsValidDataType(body.DataType)) { return(BadRequest($"Data type '{body.DataType}' is not a valid name for a collection")); } if (body.Data == null) { return(BadRequest("No data submitted")); } // Authorize var loggedInUsername = UsernameNormalizer.Normalize(HttpContext.User.Identity.Name); var resourceDescription = new SubmitDataResourceDescription(body.DataType); var authorizationResult = await authorizationModule.AuthorizeAsync(resourceDescription, loggedInUsername); if (!authorizationResult.IsAuthorized) { return(StatusCode((int)HttpStatusCode.Unauthorized, "Not authorized")); } IRdDataStorage rdDataStorage; try { rdDataStorage = await dataRouter.GetSourceSystemAsync(body.DataType); } catch (KeyNotFoundException) { return(BadRequest($"No data storage backend for data type '{body.DataType}'")); } // Validate var suggestedId = await idPolicy.DetermineIdAsync(body, loggedInUsername, rdDataStorage); if (!rdDataStorage.IsValidId(suggestedId.Id)) { return(BadRequest($"The ID '{suggestedId.Id}' for object of type '{body.DataType}' is not valid")); } if (body.Overwrite) { if (string.IsNullOrEmpty(suggestedId.Id)) { return(BadRequest("Overwriting of existing data is requested, but no ID is provided.")); } } var validators = await validatorManager.GetApprovedValidators(body.DataType); foreach (var validator in validators) { try { var validationResult = validator.Validate(body.Data.ToString()); if (!validationResult.IsValid) { return(new ContentResult { ContentType = Conventions.JsonContentType, Content = JsonConvert.SerializeObject(validationResult), StatusCode = (int)HttpStatusCode.BadRequest }); } } catch (Exception e) { apiEventLogger.Log(LogLevel.Error, e.ToString()); return(StatusCode((int)HttpStatusCode.InternalServerError, e.Message)); } } var existingData = await GetExistingMetadataAsync(rdDataStorage, body.DataType, suggestedId.Id); if (body.Overwrite) { if (!await IsAllowedToOverwriteDataAsync(body.DataType, existingData, authorizationResult.User)) { return(StatusCode((int)HttpStatusCode.Unauthorized, "Data from other users cannot be overwritten, unless you're an admin")); } } else if (existingData != null && !suggestedId.HasBeenReserved) { return(Conflict($"Document of type '{body.DataType}' with ID '{suggestedId.Id}' already exists")); } // Provide var apiVersion = ApiVersion.Current; var data = DataEncoder.Encode(JsonConvert.SerializeObject(body.Data)); var utcNow = DateTime.UtcNow; var dataContainer = new GenericDataContainer( suggestedId.Id, existingData?.OriginalSubmitter ?? authorizationResult.User.UserName, existingData?.CreatedTimeUtc ?? utcNow, authorizationResult.User.UserName, utcNow, apiVersion, data); try { var storeResult = await rdDataStorage.StoreAsync(body.DataType, dataContainer, body.Overwrite || suggestedId.HasBeenReserved); apiEventLogger.Log(LogLevel.Info, $"User '{authorizationResult.User.UserName}' has submitted data of type '{body.DataType}' with ID '{suggestedId.Id}'"); await subscriptionManager.NotifyDataChangedAsync(body.DataType, suggestedId.Id, storeResult.ModificationType); if (storeResult.IsNewCollection) { newCollectionTasks.PerformTasks(body.DataType, authorizationResult.User); } return(new ContentResult { ContentType = "text/plain", Content = storeResult.Id, StatusCode = (int)HttpStatusCode.OK }); } catch (DocumentAlreadyExistsException) { return(Conflict($"Document of type '{body.DataType}' with ID '{suggestedId.Id}' already exists")); } catch (Exception e) { apiEventLogger.Log(LogLevel.Error, e.ToString()); return(StatusCode((int)HttpStatusCode.InternalServerError, e.Message)); } }