Ejemplo n.º 1
0
        public static string RelativeLink(MethodInfo method, params object[] args)
        {
            APIEndpoint endpoint = find(method);
            var         path     = endpoint.GetFormattablePath();

            return(string.Format(path, args));
        }
Ejemplo n.º 2
0
        static void buildEndpoints()
        {
            Endpoints = new Dictionary <string, List <APIEndpoint> >();
            var q = from t in Assembly.GetExecutingAssembly().GetTypes()
                    where t.IsClass && t.IsSubclassOf(typeof(APIBase))
                    select t;

            foreach (var module in q)
            {
                var mod = new APIModule();
                mod.Name    = module.GetCustomAttribute <NameAttribute>()?.Text ?? module.Name;
                mod.Summary = module.GetCustomAttribute <SummaryAttribute>()?.Text ?? null;
                mod.Type    = module;
                foreach (var prec in module.GetCustomAttributes <APIPrecondition>())
                {
                    mod.Preconditions.Add(prec);
                }
                var methods = module.GetMethods(BindingFlags.Public | BindingFlags.Instance);
                foreach (var func in methods)
                {
                    var method = func.GetCustomAttribute <MethodAttribute>();
                    var path   = func.GetCustomAttribute <PathAttribute>();
                    if (method == null || path == null)
                    {
                        continue;
                    }
                    var name   = func.GetCustomAttribute <NameAttribute>();
                    var api    = new APIEndpoint(method.Method.Method, path);
                    var regexs = func.GetCustomAttributes <RegexAttribute>();
                    foreach (var keypair in regexs)
                    {
                        api.Regexs[keypair.Name] = keypair.Regex;
                    }
                    api.Name     = name?.Text ?? func.Name;
                    api.Summary  = func.GetCustomAttribute <SummaryAttribute>()?.Text ?? null;
                    api.Function = func;
                    api.Module   = mod;
                    mod.Endpoints.Add(api);
                    var prec = api.Function.GetCustomAttributes <APIPrecondition>().ToList();
                    api.Preconditions = prec.ToArray();
                    if (Endpoints.ContainsKey(api.Method))
                    {
                        Endpoints[api.Method].Add(api);
                    }
                    else
                    {
                        Endpoints.Add(api.Method, new List <APIEndpoint>()
                        {
                            api
                        });
                    }
                }
                Modules.Add(mod);
            }
            foreach (var keypair in Endpoints)
            {
                Program.LogMsg($"Loaded {keypair.Value.Count} {keypair.Key} endpoints", source: "API", sev: LogSeverity.Debug);
            }
        }
Ejemplo n.º 3
0
 public static T Get <T>(APIEndpoint command) where T : APIPrecondition
 {
     foreach (var p in command.Preconditions)
     {
         if (p is T)
         {
             return(p as T);
         }
     }
     return(null);
 }
Ejemplo n.º 4
0
 public ErrorItem(APIEndpoint e, string r)
 {
     endpoint = e;
     reason   = r;
 }
Ejemplo n.º 5
0
        ParseResult kowalski_analysis(APIEndpoint cmd, Match rgxMatch)
        {
            context.Endpoint = cmd; // temporary for PathRegex
            int weight        = 0;
            var cnt           = System.Activator.CreateInstance(cmd.Module.Type, context);
            var commandBase   = (APIBase)cnt;
            var preconditions = new List <APIPrecondition>();
            var final         = new ParseResult(cmd);

            final.CommandBase = commandBase;

            var ORS      = new Dictionary <string, List <PreconditionResult> >();
            var ANDS     = new Dictionary <string, List <PreconditionResult> >();
            var building = new List <APIPrecondition>();

            building.AddRange(cmd.Preconditions);
            Type parent = commandBase.GetType();

            do
            {
                var attrs = parent.GetCustomAttributes <APIPrecondition>();
                building.AddRange(attrs);
                parent = parent.BaseType;
            } while (parent != null);
            building.Reverse();
            foreach (var nextThing in building)
            {
                var previousThing = preconditions.FirstOrDefault(x => x.TypeId == nextThing.TypeId);
                if (previousThing != null)
                {
                    if (!previousThing.CanChildOverride(nextThing))
                    {
                        continue;
                    }
                    preconditions.Remove(previousThing);
                }
                preconditions.Add(nextThing);
            }
            foreach (var pred in preconditions)
            {
                if (string.IsNullOrWhiteSpace(pred.OR))
                {
                    ANDS.TryAdd(pred.AND, new List <PreconditionResult>());
                }
                else
                {
                    ORS.TryAdd(pred.OR, new List <PreconditionResult>());
                    if (!string.IsNullOrWhiteSpace(pred.AND))
                    {
                        ANDS.TryAdd(pred.AND, new List <PreconditionResult>());
                    }
                }
            }

            bool requireExcessQueryMatch = true;

            foreach (var pred in preconditions)
            {
                if (pred is RequireNoExcessQuery rqp)
                {
                    requireExcessQueryMatch = rqp.Required;
                }
                PreconditionResult result = null;
                try
                {
                    result = pred.Check(context);
                }
                catch (HaltExecutionException e)
                {
                    final.WithException(e);
                    result = PreconditionResult.FromError(e.ToString());
                }
                if (ORS.TryGetValue(pred.OR, out var orls))
                {
                    orls.Add(result);
                }
                if ((string.IsNullOrWhiteSpace(pred.AND) && string.IsNullOrWhiteSpace(pred.OR)) ||
                    !string.IsNullOrWhiteSpace(pred.AND))
                {
                    if (ANDS.TryGetValue(pred.AND, out var andls))
                    {
                        andls.Add(result);
                    }
                }
            }

            foreach (var or in ORS.Keys)
            {
                var ls         = ORS[or];
                var anySuccess = ls.FirstOrDefault(x => x.IsSuccess);
                if (anySuccess == null)
                {
                    return(final.WithError($"{string.Join(",", ls.Where(x => !x.IsSuccess).Select(x => x.ErrorReason))}"));
                }
            }

            weight += 5;

            foreach (var and in ANDS.Keys)
            {
                var ls         = ANDS[and];
                var anyFailure = ls.FirstOrDefault(x => x.IsSuccess == false);
                if (anyFailure != null)
                {
                    return(final.WithError($"{string.Join(",", ls.Where(x => !x.IsSuccess).Select(x => x.ErrorReason))}"));
                }
            }

            weight += 5;

            var serverName = (RequireServerName)preconditions.Last(x => x is RequireServerName);

            if (serverName.Domain == context.Host)
            {
                weight += 5;
            }

            var args       = new List <object>();
            var paramaters = cmd.Function.GetParameters();

            foreach (var param in paramaters)
            {
                string value = null;
                if (cmd.Regexs.TryGetValue(param.Name, out var pattern))
                {
                    var match = rgxMatch.Groups[param.Name];
                    value = match.Value;
                }
                else
                {
                    value = context.GetQuery(param.Name);
                }
                if (value == null && param.IsOptional == false)
                {
                    return(final.WithError($"No argument specified for required item {param.Name}"));
                }
                if (value == null)
                {
                    args.Add(param.DefaultValue);
                    continue;
                }
                if (param.ParameterType == typeof(string))
                {
                    args.Add(Uri.UnescapeDataString(value));
                }
                else
                {
                    var typeResult = Program.AttemptParseInput(value, param.ParameterType);
                    if (typeResult.IsSuccess)
                    {
                        args.Add(typeResult.BestMatch);
                    }
                    else
                    {
                        return(final.WithError($"Could not parse value for {param.Name} as {param.ParameterType.Name}: {typeResult.ErrorReason}"));
                    }
                }
            }
            weight += args.Count;
            foreach (var key in context.GetAllKeys())
            {
                var para = paramaters.FirstOrDefault(x => x.Name == key);
                if (para == null && requireExcessQueryMatch)
                {
                    return(final.WithError($"Unknown argument specified: {key}"));
                }
            }
            weight         += 50;
            final.Arguments = args;
            return(final);
        }
Ejemplo n.º 6
0
 public ParseResult(APIEndpoint cmd)
 {
     Exceptions = new List <HaltExecutionException>();
     Command    = cmd;
 }