Exemple #1
0
        public async Task <ActionResult> GetAsync([FromRoute] string path)
        {
            var allParams      = PartitionByKey(HttpContext.Request.Query.ToDictionary(x => x.Key, x => x.Value), x => x.StartsWith("$"));
            var modifiers      = allParams.Item1;
            var isFlatten      = modifiers.TryGetValue("$flatten").Select(x => bool.Parse(x.First())).IfNone(false);
            var includeErrors  = modifiers.TryGetValue("$includeErrors").Select(x => bool.Parse(x.First())).IfNone(false);
            var ignoreKeyTypes = modifiers.TryGetValue("$ignoreKeyTypes").Select(x => bool.Parse(x.First())).IfNone(false);
            var includePaths   = modifiers.TryGetValue("$include").Select(x => x.ToArray()).IfNone(new string[] {});

            var translateValue = ignoreKeyTypes ? (TranslateValue)TranslateValueToString : (x => x.Value);

            IReadOnlyDictionary <string, JsonValue> contextParams = allParams.Item2.ToDictionary(x => x.Key,
                                                                                                 x => x.Value.Count == 1 ? JsonValue.NewString(x.Value.ToString()) : JsonValue.NewArray(x.Value.Map(t => JsonValue.NewString(t)).ToArray()), StringComparer.OrdinalIgnoreCase);

            var identities = new IdentityHashSet(contextParams.Where(x => !x.Key.Contains(".")).Select(x => new Identity(x.Key, x.Value.AsString())));

            if (!_checkAccess(User, path, identities))
            {
                return(Forbid());
            }
            GetLoadedContextByIdentityType contextProps =
                identityType => key => contextParams.TryGetValue($"{identityType}.{key}");

            var root = ConfigurationPath.New(path);

            var query = GetQuery(root, includePaths);

            var values = await _tweek.GetContextAndCalculate(query, identities, _contextDriver, contextProps);

            var errors = values.Where(x => x.Value.Exception != null).ToDictionary(x => x.Key, x => x.Value.Exception.Message);

            Response.Headers.Add("X-Error-Count", errors.Count.ToString());

            object result = null;

            if (root.IsScan)
            {
                var relativeData = values.Where(x => x.Value.Exception == null).ToDictionary(x => x.Key.ToRelative(root), x => x.Value);
                result = !isFlatten
                    ? TreeResult.From(relativeData, translateValue)
                    : relativeData.ToDictionary(x => x.Key.ToString(), x => translateValue(x.Value));
            }
            else if (values.TryGetValue(root, out var value) && value.Exception == null)
            {
                result = ignoreKeyTypes ? TranslateValueToString(value) : value.Value;
            }

            if (!includeErrors)
            {
                return(Json(result));
            }


            return(Json(new Dictionary <string, object> {
                { "data", result }, { "errors", errors }
            }));
        }
Exemple #2
0
        internal static GetLoadedContextByIdentityType Memoize(GetLoadedContextByIdentityType c)
        {
            var list = new Dictionary <string, GetContextValue>();

            return((t) =>
            {
                if (!list.ContainsKey(t))
                {
                    list[t] = Core.Context.ContextHelpers.Memoize(c(t));
                }
                return list[t];
            });
        }
Exemple #3
0
        public static GetRuleValue GetRulesEvaluator(IdentityHashSet identities, GetLoadedContextByIdentityType contextByIdentity, GetRule getRule)
        {
            var identityTypes  = identities.Select(x => x.Type).ToArray();
            var flattenContext = ContextHelpers.FlattenLoadedContext(contextByIdentity);

            GetRuleValue    getRuleValue     = null;
            GetContextValue recursiveContext = key =>
            {
                if (key.StartsWith("@@key:"))
                {
                    key = key.Replace("@@key:", "keys.");
                }
                if (!key.StartsWith("keys."))
                {
                    return(Option <JsonValue> .None);
                }
                var path = new ConfigurationPath(key.Split('.')[1]);
                return(getRuleValue(path).Map(x => x.Value));
            };

            var context = ContextHelpers.Merge(flattenContext, recursiveContext);

            getRuleValue = Memoize(path =>
            {
                try
                {
                    foreach (var identity in identityTypes)
                    {
                        var fixedResult = ContextHelpers.GetFixedConfigurationContext(context, identity)(path);
                        if (fixedResult.IsSome)
                        {
                            return(fixedResult);
                        }
                    }

                    return(getRule(path).Bind(x => x.GetValue(context)));
                }
                catch (Exception e)
                {
                    return(ConfigurationValue.Error(e));
                }
            });
            return(getRuleValue);
        }
        public async Task <ActionResult> GetAsync([FromRoute] string path)
        {
            var allParams      = PartitionByKey(HttpContext.Request.Query.ToDictionary(x => x.Key, x => x.Value), x => x.StartsWith("$"));
            var modifiers      = allParams.Item1;
            var isFlatten      = modifiers.TryGetValue("$flatten").Select(x => bool.Parse(x.First())).IfNone(false);
            var ignoreKeyTypes = modifiers.TryGetValue("$ignoreKeyTypes").Select(x => bool.Parse(x.First())).IfNone(false);
            var includePaths   = modifiers.TryGetValue("$include").Select(x => x.ToArray()).IfNone(new string[] {});

            var translateValue = ignoreKeyTypes ? (TranslateValue)TranslateValueToString : (x => x.Value);

            IReadOnlyDictionary <string, JsonValue> contextParams = allParams.Item2.ToDictionary(x => x.Key,
                                                                                                 x => JsonValue.NewString(x.Value.ToString()), StringComparer.OrdinalIgnoreCase);

            var identities = new IdentityHashSet(contextParams.Where(x => !x.Key.Contains(".")).Select(x => new Identity(x.Key, x.Value.AsString())));

            if (!_checkAccess(User, path, identities))
            {
                return(Forbid());
            }
            GetLoadedContextByIdentityType contextProps =
                identityType => key => contextParams.TryGetValue($"{identityType}.{key}");

            var root = ConfigurationPath.New(path);

            var query = GetQuery(root, includePaths);

            var data = await _tweek.GetContextAndCalculate(query, identities, _contextDriver, contextProps);

            if (root.IsScan)
            {
                var relativeData = data.ToDictionary(x => x.Key.ToRelative(root), x => x.Value);
                return(Json(!isFlatten ? (TreeResult.From(relativeData, translateValue)) : relativeData.ToDictionary(x => x.Key.ToString(), x => translateValue(x.Value))));
            }

            return(data.Select(x => ignoreKeyTypes ? (object)x.Value.Value.AsString() : x.Value.Value)
                   .FirstOrNone()
                   .Match(x => Json(x), () => Json(null)));
        }
Exemple #5
0
        public static GetLoadedContextByIdentityType AddSystemContext(GetLoadedContextByIdentityType context)
        {
            var timeUtc = Option <JsonValue> .Some(JsonValue.NewString(DateTime.UtcNow.ToString("u")));

            return(Fallback(context, type =>
            {
                if (type.Equals("system", StringComparison.CurrentCultureIgnoreCase))
                {
                    return (key =>
                    {
                        switch (key)
                        {
                        case "time_utc":
                            return timeUtc;

                        default:
                            return Option <JsonValue> .None;
                        }
                    });
                }

                return (key => Option <JsonValue> .None);
            }));
        }
Exemple #6
0
 public static Dictionary <ConfigurationPath, ConfigurationValue> Calculate(this ITweek tweek,
                                                                            ConfigurationPath pathQuery,
                                                                            HashSet <Identity> identities, GetLoadedContextByIdentityType context, ConfigurationPath[] includeFixedPaths = null)
 {
     return(tweek.Calculate(new[] { pathQuery }, identities, context, includeFixedPaths));
 }
Exemple #7
0
        public static async Task <Dictionary <ConfigurationPath, ConfigurationValue> > GetContextAndCalculate(this ITweek tweek,
                                                                                                              ICollection <ConfigurationPath> pathQuery,
                                                                                                              HashSet <Identity> identities,
                                                                                                              IContextReader contextDriver,
                                                                                                              GetLoadedContextByIdentityType externalContext = null)
        {
            var allContextData = (await Task.WhenAll(identities
                                                     .Select(async identity => new
            {
                Identity = identity,
                Context = new Dictionary <string, JsonValue>(await contextDriver.GetContext(identity), StringComparer.OrdinalIgnoreCase)
            })))
                                 .ToDictionary(x => x.Identity, x => x.Context);

            externalContext = externalContext ?? ContextHelpers.EmptyContextByIdentityType;

            var loadedContexts = ContextHelpers.GetContextRetrieverByType(ContextHelpers.LoadContexts(allContextData), identities);
            var context        = ContextHelpers.AddSystemContext(ContextHelpers.Fallback(externalContext, loadedContexts));
            var contextPaths   = pathQuery.Any(x => x.IsScan) ? allContextData.Values.SelectMany(x => x.Keys)
                                 .Where(x => x.Contains("@fixed:"))
                                 .Select(x => x.Split(':')[1])
                                 .Select(ConfigurationPath.New).ToArray() : null;


            return(tweek.Calculate(pathQuery, identities, context, contextPaths));
        }
Exemple #8
0
 public static Task <Dictionary <ConfigurationPath, ConfigurationValue> > GetContextAndCalculate(this ITweek tweek,
                                                                                                 ConfigurationPath pathQuery,
                                                                                                 HashSet <Identity> identities,
                                                                                                 IContextReader contextDriver,
                                                                                                 GetLoadedContextByIdentityType externalContext = null)
 {
     return(tweek.GetContextAndCalculate(new[] { pathQuery }, identities, contextDriver, externalContext));
 }
Exemple #9
0
 internal static GetContextValue FlattenLoadedContext(GetLoadedContextByIdentityType getLoadedContext)
 {
     return(fullKey =>
            SplitFullKey(fullKey).Bind(fk => getLoadedContext(fk.IdentityType)(fk.Key)));
 }