public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
        {
            var bsonDocument = value as BsonDocument;
            var json         = DataEncoder.DecodeToJson(bsonDocument);

            writer.WriteRawValue(json);
        }
        private BsonDocument MapContainerUsingSelect(GenericDataContainer container, DataApiSqlQuery parsedQuery)
        {
            var containerJObject = JObject.FromObject(container);
            var dataJObject      = JObject.Parse(DataEncoder.DecodeToJson(container.Data));
            var fieldMappings    = parsedQuery.SelectArguments.Split(',').Select(x => x.Trim());
            var bsonDocument     = new BsonDocument();

            foreach (var fieldMapping in fieldMappings)
            {
                var match = Regex.Match(fieldMapping, "^(?<Path>[^\\s]+)(?<Map>\\s+AS\\s+(?<NewName>[^\\s]+))?", RegexOptions.IgnoreCase);
                if (!match.Success)
                {
                    throw new FormatException($"Invalid SELECT statement '{fieldMapping}'");
                }
                var    fieldPath = match.Groups["Path"].Value;
                string newName;
                var    hasMap = match.Groups["Map"].Success;
                if (hasMap)
                {
                    newName = match.Groups["NewName"].Value;
                }
                else
                {
                    newName = fieldPath.Replace('.', '_');
                }
                JToken jToken;
                if (fieldPath.StartsWith("Data."))
                {
                    var token = hasMap ? newName : fieldPath.Substring("Data.".Length);
                    jToken = dataJObject.SelectToken(token);
                }
                else if (fieldPath == "Data")
                {
                    jToken = dataJObject;
                }
                else
                {
                    jToken = containerJObject.SelectToken(fieldPath);
                }
                BsonValue bsonValue;
                if (jToken == null)
                {
                    bsonValue = BsonNull.Value;
                }
                else if (jToken is JValue jValue)
                {
                    bsonValue = BsonValue.Create(jValue.Value);
                }
                else
                {
                    bsonValue = BsonDocument.Parse(jToken.ToString());
                }
                bsonDocument.Add(new BsonElement(newName, bsonValue));
            }
            return(bsonDocument);
        }
        public static string CreateFromDataAndTableSetup(BsonDocument data, SqlTableSetup tableSetup)
        {
            var jObject    = JObject.Parse(DataEncoder.DecodeToJson(data));
            var properties = jObject.Properties().Where(property => property.Name != tableSetup.IdColumnName).ToList();
            var query      = $"INSERT INTO {tableSetup.TableName} ({string.Join(", ", properties.Select(property => property.Name))}) "
                             + $"OUTPUT INSERTED.{tableSetup.IdColumnName} "
                             + $"VALUES ({string.Join(", ", properties.Select(property => $"'{JTokenStringify.Stringify(property.Value)}'"))})";

            return(query);
        }
        public async Task <IActionResult> GetSubmissionMetadata([FromQuery] string dataType, [FromQuery] string id)
        {
            // Validate
            if (dataType == null)
            {
                return(BadRequest("Invalid dataType"));
            }
            if (id == null)
            {
                return(BadRequest("Invalid id"));
            }

            // Authorize
            var loggedInUsername    = UsernameNormalizer.Normalize(HttpContext.User.Identity.Name);
            var resourceDescription = new GetDataResourceDescription(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(await Get(dataType, id));
            }

            if (!await binaryRdDataStorage.ExistsAsync(dataType, id))
            {
                return(NotFound());
            }

            apiEventLogger.Log(LogLevel.Info, $"User '{authorizationResult.User.UserName}' has accessed metadata of type '{dataType}' with ID '{id}'");
            var container = await binaryRdDataStorage.GetMetadataFromId(dataType, id);

            var json = DataEncoder.DecodeToJson(container.Data);

            return(new ContentResult
            {
                ContentType = Conventions.JsonContentType,
                Content = json,
                StatusCode = (int)HttpStatusCode.OK
            });
        }
        public static string CreateFromDataAndTableSetup(BsonDocument data, SqlTableSetup tableSetup, string id)
        {
            var jObject       = JObject.Parse(DataEncoder.DecodeToJson(data));
            var properties    = jObject.Properties().Where(property => property.Name != tableSetup.IdColumnName).ToList();
            var keyValuePairs = string.Join(", ", properties.Where(property => property.Name != tableSetup.IdColumnName)
                                            .ToDictionary(property => property.Name, property => JTokenStringify.Stringify(property.Value))
                                            .Select(kvp => $"{kvp.Key} = '{kvp.Value}'"));
            var query = $"UPDATE {tableSetup.TableName} SET {keyValuePairs} WHERE {tableSetup.IdColumnName} = '{id}'";

            return(query);
        }
        public async Task <IActionResult> Get([FromQuery] string dataType, [FromQuery] string id)
        {
            // Validate
            if (string.IsNullOrEmpty(dataType))
            {
                return(BadRequest("Data type not specified"));
            }
            if (string.IsNullOrEmpty(id))
            {
                return(BadRequest("ID not specified"));
            }

            // Authorize
            var loggedInUsername    = UsernameNormalizer.Normalize(HttpContext.User.Identity.Name);
            var resourceDescription = new GetDataResourceDescription(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 e)
            {
                return(BadRequest(e.Message));
            }

            // Provide
            if (!await rdDataStorage.ExistsAsync(dataType, id))
            {
                return(NotFound());
            }
            apiEventLogger.Log(LogLevel.Info, $"User '{authorizationResult.User.UserName}' has accessed data of type '{dataType}' with ID '{id}'");
            var matchingContainer = await rdDataStorage.GetFromIdAsync(dataType, id);

            var json = DataEncoder.DecodeToJson(matchingContainer.Data);

            return(new ContentResult
            {
                ContentType = Conventions.JsonContentType,
                Content = json,
                StatusCode = (int)HttpStatusCode.OK
            });
        }
Beispiel #7
0
        public static Dictionary <string, string> Traverse(GenericDataContainer container)
        {
            var jObject       = JObject.Parse(DataEncoder.DecodeToJson(container.Data));
            var keyValuePairs = new Dictionary <string, string>
            {
                { "Id", container.Id },
                { "OriginalSubmitter", container.OriginalSubmitter },
                { "CreatedTimeUtc", container.CreatedTimeUtc?.ToString("yyyy-MM-dd HH:mm:ss") },
                { "Submitter", container.Submitter },
                { "SubmissionTimeUtc", container.SubmissionTimeUtc.ToString("yyyy-MM-dd HH:mm:ss") }
            };

            TraverseJObject(jObject, keyValuePairs, "Data");
            return(keyValuePairs);
        }
        public async Task <IActionResult> GetMany([FromQuery] string dataType, [FromQuery] string whereArguments, [FromQuery] string orderByArguments, [FromQuery] uint?limit = null)
        {
            // Validate
            if (string.IsNullOrEmpty(dataType))
            {
                return(BadRequest("Data type not specified"));
            }

            // Authorize
            var loggedInUsername    = UsernameNormalizer.Normalize(HttpContext.User.Identity.Name);
            var resourceDescription = new GetDataResourceDescription(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 e)
            {
                return(BadRequest(e.Message));
            }

            apiEventLogger.Log(LogLevel.Info, $"User '{authorizationResult.User.UserName}' requested objects of type '{dataType}' matching '{whereArguments?.RemoveLineBreaks()}' ordered by '{orderByArguments?.RemoveLineBreaks()}'");
            try
            {
                var getManyResult = rdDataStorage.GetManyAsync(dataType, whereArguments, orderByArguments, limit);
                var stream        = new SearchResultStream(getManyResult.Select(x => DataEncoder.DecodeToJson(x.Data)));
                return(new FileStreamResult(stream, Conventions.JsonContentType));
            }
            catch (FormatException formatException)
            {
                return(BadRequest(formatException.Message));
            }
            catch (Exception e)
            {
                return(StatusCode((int)HttpStatusCode.InternalServerError, e.InnermostException().Message));
            }
        }
        private bool CanAutoApprove(ValidatorDefinition validatorDefinition)
        {
            var validator        = validatorFactory.Create(validatorDefinition);
            var targetCollection = mongoClient.DataDatabase.GetCollection <GenericDataContainer>(validatorDefinition.DataType);

            using var documents = targetCollection.Find(x => true).ToCursor();
            while (documents.MoveNext())
            {
                var batch = documents.Current;
                foreach (var document in batch)
                {
                    if (!validator.Validate(DataEncoder.DecodeToJson(document.Data)).IsValid)
                    {
                        return(false);
                    }
                }
            }
            return(true);
        }
Beispiel #10
0
        public async Task <IActionResult> GetFile([FromQuery] string dataType, [FromQuery] string id, [FromQuery] string shortId)
        {
            if (!string.IsNullOrEmpty(shortId))
            {
                var shortIdDataStorage = await dataRouter.GetSourceSystemAsync(nameof(ShortId));

                var shortIdContainer = await shortIdDataStorage.GetFromIdAsync(nameof(ShortId), shortId);

                if (shortIdContainer == null)
                {
                    return(NotFound());
                }
                var shortIdJson   = DataEncoder.DecodeToJson(shortIdContainer.Data);
                var shortIdObject = JsonConvert.DeserializeObject <ShortId>(shortIdJson);
                dataType = shortIdObject.CollectionName;
                id       = shortIdObject.OriginalId;
            }

            // Validate
            if (string.IsNullOrEmpty(dataType))
            {
                return(BadRequest("Data type not specified"));
            }
            if (string.IsNullOrEmpty(id))
            {
                return(BadRequest("ID not specified"));
            }

            // Authorize
            var loggedInUsername    = UsernameNormalizer.Normalize(HttpContext.User.Identity.Name);
            var resourceDescription = new GetDataResourceDescription(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 e)
            {
                return(BadRequest(e.Message));
            }

            if (!await rdDataStorage.ExistsAsync(dataType, id))
            {
                return(NotFound());
            }

            // Provide
            apiEventLogger.Log(LogLevel.Info, $"User '{authorizationResult.User.UserName}' has accessed binary payload of type '{dataType}' with ID '{id}'");
            if (!(rdDataStorage is IBinaryRdDataStorage binaryRdDataStorage))
            {
                var metadata = await rdDataStorage.GetFromIdAsync(dataType, id);

                var metadataJson = DataEncoder.DecodeToJson(metadata.Data);
                var filename     = GetFilename(dataType, id, metadataJson);
                return(new FileContentResult(Encoding.UTF8.GetBytes(metadataJson), Conventions.JsonContentType)
                {
                    FileDownloadName = filename
                });
            }