Beispiel #1
0
        /// <summary>
        /// Executes a <see cref="RestCommand"/> using the provided verbs, parameters, request, and context objects
        /// </summary>
        /// <param name="cmd">The REST command to execute</param>
        /// <param name="verbs">The REST verbs used in the command</param>
        /// <param name="parms">The REST parameters used in the command</param>
        /// <param name="request">The HTTP request object associated with the command</param>
        /// <param name="context">The HTTP context associated with the command</param>
        /// <returns></returns>
        protected virtual object ExecuteCommand(RestCommand cmd, RestVerbs verbs, IParameterCollection parms, IRequest request, IHttpContext context)
        {
            object result = cmd.Execute(verbs, parms, request, context);

            if (cmd.DoLog && Restful.Instance.Config.LogConnections)
            {
                TShock.Log.ConsoleInfo("Anonymous requested REST endpoint: " + BuildRequestUri(cmd, verbs, parms, false));
            }

            return(result);
        }
Beispiel #2
0
        public object Execute(RestVerbs verbs, IParameterCollection parameters, SecureRest.TokenData tokenData, IRequest request, IHttpContext context)
        {
            if (tokenData.Equals(SecureRest.TokenData.None))
            {
                return new RestObject("401")
                       {
                           Error = "Not authorized. The specified API endpoint requires a token."
                       }
            }
            ;

            return(callback(new RestRequestArgs(verbs, parameters, request, tokenData, context)));
        }
    }
Beispiel #3
0
        /// <summary>
        /// Builds a request URI from the parameters, verbs, and URI template of a <see cref="RestCommand"/>
        /// </summary>
        /// <param name="cmd">The REST command to take the URI template from</param>
        /// <param name="verbs">Verbs used in building the URI string</param>
        /// <param name="parms">Parameters used in building the URI string</param>
        /// <param name="includeToken">Whether or not to include a token in the URI</param>
        /// <returns></returns>
        protected virtual string BuildRequestUri(
            RestCommand cmd, RestVerbs verbs, IParameterCollection parms, bool includeToken = true
            )
        {
            StringBuilder requestBuilder = new StringBuilder(cmd.UriTemplate);
            char          separator      = '?';

            foreach (IParameter paramImpl in parms)
            {
                Parameter param = (paramImpl as Parameter);
                if (param == null || (!includeToken && param.Name.Equals("token", StringComparison.InvariantCultureIgnoreCase)))
                {
                    continue;
                }

                requestBuilder.Append(separator);
                requestBuilder.Append(param.Name);
                requestBuilder.Append('=');
                requestBuilder.Append(param.Value);
                separator = '&';
            }

            return(requestBuilder.ToString());
        }
Beispiel #4
0
        /// <summary>
        /// Attempts to process a request received by the <see cref="HttpListener"/>
        /// </summary>
        /// <param name="sender">Sender of the request</param>
        /// <param name="e">RequestEventArgs received</param>
        /// <returns>A <see cref="RestObject"/> describing the state of the request</returns>
        protected virtual object ProcessRequest(object sender, RequestEventArgs e)
        {
            try
            {
                var uri = e.Request.Uri.AbsolutePath;
                uri = uri.TrimEnd('/');
                string upgrade = null;

                if (redirects.ContainsKey(uri))
                {
                    upgrade = redirects[uri].Item2;
                    uri     = redirects[uri].Item1;
                }

                foreach (var com in commands)
                {
                    var verbs = new RestVerbs();
                    if (com.HasVerbs)
                    {
                        var match = Regex.Match(uri, com.UriVerbMatch);
                        if (!match.Success)
                        {
                            continue;
                        }
                        if ((match.Groups.Count - 1) != com.UriVerbs.Length)
                        {
                            continue;
                        }

                        for (int i = 0; i < com.UriVerbs.Length; i++)
                        {
                            verbs.Add(com.UriVerbs[i], match.Groups[i + 1].Value);
                        }
                    }
                    else if (com.UriTemplate.ToLower() != uri.ToLower())
                    {
                        continue;
                    }

                    var obj = ExecuteCommand(com, verbs, e.Request.Parameters, e.Request, e.Context);
                    if (obj != null)
                    {
                        if (!String.IsNullOrWhiteSpace(upgrade) && obj is RestObject)
                        {
                            if (!(obj as RestObject).ContainsKey("upgrade"))
                            {
                                (obj as RestObject).Add("upgrade", upgrade);
                            }
                        }

                        return(obj);
                    }
                }
            }
            catch (Exception exception)
            {
                return(new RestObject("500")
                {
                    { "error", "Internal server error." },
                    { "errormsg", exception.Message },
                    { "stacktrace", exception.StackTrace },
                });
            }
            return(new RestObject("404")
            {
                { "error", "Specified API endpoint doesn't exist. Refer to the documentation for a list of valid endpoints." }
            });
        }
Beispiel #5
0
 public virtual object Execute(RestVerbs verbs, IParameterCollection parameters, IRequest request, IHttpContext context)
 {
     return(callback(new RestRequestArgs(verbs, parameters, request, context)));
 }
Beispiel #6
0
        protected override object ExecuteCommand(RestCommand cmd, RestVerbs verbs, IParameterCollection parms, IRequest request, IHttpContext context)
        {
            if (!cmd.RequiresToken)
            {
                return(base.ExecuteCommand(cmd, verbs, parms, request, context));
            }

            var token = parms["token"];

            if (token == null)
            {
                return new RestObject("401")
                       {
                           Error = "Not authorized. The specified API endpoint requires a token."
                       }
            }
            ;

            SecureRestCommand secureCmd = (SecureRestCommand)cmd;
            TokenData         tokenData;

            if (!Tokens.TryGetValue(token, out tokenData) && !AppTokens.TryGetValue(token, out tokenData))
            {
                return new RestObject("403")
                       {
                           Error = "Not authorized. The specified API endpoint requires a token, but the provided token was not valid."
                       }
            }
            ;

            Group userGroup = TShock.Groups.GetGroupByName(tokenData.UserGroupName);

            if (userGroup == null)
            {
                Tokens.Remove(token);

                return(new RestObject("403")
                {
                    Error = "Not authorized. The provided token became invalid due to group changes, please create a new token."
                });
            }

            if (secureCmd.Permissions.Length > 0 && secureCmd.Permissions.All(perm => !userGroup.HasPermission(perm)))
            {
                return(new RestObject("403")
                {
                    Error = string.Format("Not authorized. User \"{0}\" has no access to use the specified API endpoint.", tokenData.Username)
                });
            }

            //Main.rand being null can cause issues in command execution.
            //This should solve that
            if (Main.rand == null)
            {
                Main.rand = new Terraria.Utilities.UnifiedRandom();
            }

            object result = secureCmd.Execute(verbs, parms, tokenData, request, context);

            if (cmd.DoLog && TShock.Config.LogRest)
            {
                TShock.Utils.SendLogs(string.Format(
                                          "\"{0}\" requested REST endpoint: {1}", tokenData.Username, this.BuildRequestUri(cmd, verbs, parms, false)),
                                      Color.PaleVioletRed);
            }

            return(result);
        }
    }
}