Esempio n. 1
0
        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
            });
        }
Esempio n. 2
0
        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());
        }
Esempio n. 3
0
        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());
        }
Esempio n. 4
0
        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));
            }
        }