Exemple #1
0
 /// <summary>
 /// Creates a new instance of <see cref="RestRequestArgs"/> with the given verbs, escaped parameters, request, token data, and context.
 /// </summary>
 /// <param name="verbs"></param>
 /// <param name="param"></param>
 /// <param name="request"></param>
 /// <param name="tokenData"></param>
 /// <param name="context"></param>
 public RestRequestArgs(RestVerbs verbs, EscapedParameterCollection param, IRequest request, SecureRest.TokenData tokenData, IHttpContext context)
 {
     Verbs      = verbs;
     Parameters = param;
     Request    = request;
     TokenData  = tokenData;
     Context    = context;
 }
Exemple #2
0
 /// <summary>
 /// Creates a new instance of <see cref="RestRequestArgs"/> with the given verbs, parameters, request, and context.
 /// No token data is used
 /// </summary>
 /// <param name="verbs">Verbs used in the request</param>
 /// <param name="param">Parameters used in the request</param>
 /// <param name="request">The HTTP request</param>
 /// <param name="context">The HTTP context</param>
 public RestRequestArgs(RestVerbs verbs, IParameterCollection param, IRequest request, IHttpContext context)
 {
     Verbs      = verbs;
     Parameters = param;
     Request    = request;
     TokenData  = SecureRest.TokenData.None;
     Context    = context;
 }
Exemple #3
0
        private object DestroyAllTokens(RestVerbs verbs, IParameterCollection parameters, SecureRest.TokenData tokenData)
        {
            Tokens.Clear();

            return(new RestObject()
            {
                Response = "All tokens were successfully destroyed."
            });
        }
Exemple #4
0
        private object NewToken(RestVerbs verbs, IParameterCollection parameters)
        {
            var user = verbs["username"];
            var pass = verbs["password"];

            RestObject response = this.NewTokenInternal(user, pass);

            response["deprecated"] = "This endpoint is depracted and will be removed in the future.";
            return(response);
        }
Exemple #5
0
        protected virtual object ProcessRequest(object sender, RequestEventArgs e)
        {
            try
            {
                var uri = e.Request.Uri.AbsolutePath;
                uri = uri.TrimEnd('/');

                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);
                    if (obj != null)
                    {
                        return(obj);
                    }
                }
            }
            catch (Exception exception)
            {
                return(new Dictionary <string, string>
                {
                    { "status", "500" },
                    { "error", "Internal server error." },
                    { "errormsg", exception.Message },
                    { "stacktrace", exception.StackTrace },
                });
            }
            return(new Dictionary <string, string>
            {
                { "status", "404" },
                { "error", "Specified API endpoint doesn't exist. Refer to the documentation for a list of valid endpoints." }
            });
        }
Exemple #6
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 && TShock.Config.LogRest)
            {
                TShock.Log.ConsoleInfo("Anonymous requested REST endpoint: " + BuildRequestUri(cmd, verbs, parms, false));
            }

            return(result);
        }
Exemple #7
0
        protected virtual object ExecuteCommand(RestCommand cmd, RestVerbs verbs, IParameterCollection parms)
        {
            object result = cmd.Execute(verbs, parms);

            if (cmd.DoLog)
            {
                Log.ConsoleInfo("Anonymous requested REST endpoint: " + BuildRequestUri(cmd, verbs, parms, false));
            }

            return(result);
        }
Exemple #8
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)));
        }
    }
Exemple #9
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 = "未验证. 指定的API端点需要验证TOKEN."
                       }
            }
            ;

            return(callback(new RestRequestArgs(verbs, parameters, request, tokenData, context)));
        }
    }
Exemple #10
0
        object DestroyToken(RestVerbs verbs, IParameterCollection parameters)
        {
            var token = verbs["token"];

            try
            {
                Tokens.Remove(token);
            }
            catch (Exception)
            {
                return(new Dictionary <string, string> {
                    { "status", "400" }, { "error", "The specified token queued for destruction failed to be deleted." }
                });
            }
            return(new Dictionary <string, string> {
                { "status", "200" }, { "response", "Requested token was successfully destroyed." }
            });
        }
Exemple #11
0
        private object NewToken(RestVerbs verbs, IParameterCollection parameters)
        {
            var user = verbs["username"];
            var pass = verbs["password"];

            RestObject obj = null;

            if (Verify != null)
            {
                obj = Verify(user, pass);
            }

            if (obj == null)
            {
                obj = new RestObject("401")
                {
                    Error = "Invalid username/password combination provided. Please re-submit your query with a correct pair."
                }
            }
            ;

            if (obj.Error != null)
            {
                return(obj);
            }

            string hash;
            var    rand      = new Random();
            var    randbytes = new byte[32];

            do
            {
                rand.NextBytes(randbytes);
                hash = randbytes.Aggregate("", (s, b) => s + b.ToString("X2"));
            } while (Tokens.ContainsKey(hash));

            Tokens.Add(hash, user);

            obj["token"]      = hash;
            obj["deprecated"] = "This method will be removed from TShock in 3.6.";
            return(obj);
        }
Exemple #12
0
        private object DestroyToken(RestVerbs verbs, IParameterCollection parameters, SecureRest.TokenData tokenData)
        {
            var token = verbs["token"];

            try
            {
                Tokens.Remove(token);
            }
            catch (Exception)
            {
                return(new RestObject("400")
                {
                    Error = "The specified token queued for destruction failed to be deleted."
                });
            }
            return(new RestObject()
            {
                Response = "Requested token was successfully destroyed."
            });
        }
Exemple #13
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());
        }
Exemple #14
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." }
            });
        }
Exemple #15
0
 public virtual object Execute(RestVerbs verbs, IParameterCollection parameters, IRequest request, IHttpContext context)
 {
     return(callback(new RestRequestArgs(verbs, parameters, request, context)));
 }
Exemple #16
0
        protected override object ExecuteCommand(RestCommand cmd, RestVerbs verbs, IParameterCollection parms, IRequest request)
        {
            if (!cmd.RequiresToken)
            {
                return(base.ExecuteCommand(cmd, verbs, parms, request));
            }

            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."
                       }
            }
            ;

            // TODO: Get rid of this when the old REST permission model is removed.
            if (TShock.Config.RestUseNewPermissionModel)
            {
                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)
                    });
                }
            }

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

            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);
        }
    }
}
Exemple #17
0
 /// <summary>
 /// Creates a new instance of <see cref="RestRequestArgs"/> with the given verbs, parameters, request, and context.
 /// No token data is used
 /// </summary>
 /// <param name="verbs">Verbs used in the request</param>
 /// <param name="param">Parameters used in the request</param>
 /// <param name="request">The HTTP request</param>
 /// <param name="context">The HTTP context</param>
 public RestRequestArgs(RestVerbs verbs, IParameterCollection param, IRequest request, IHttpContext context)
     : this(verbs, param, request, SecureRest.TokenData.None, context)
 {
 }
Exemple #18
0
 /// <summary>
 /// Creates a new instance of <see cref="RestRequestArgs"/> with the given verbs, parameters, request, token data, and context.
 /// </summary>
 /// <param name="verbs">Verbs used in the request</param>
 /// <param name="param">Parameters used in the request</param>
 /// <param name="request">The HTTP request</param>
 /// <param name="tokenData">Token data used in the request</param>
 /// <param name="context">The HTTP context</param>
 public RestRequestArgs(RestVerbs verbs, IParameterCollection param, IRequest request, SecureRest.TokenData tokenData, IHttpContext context)
     : this(verbs, new EscapedParameterCollection(param), request, tokenData, context)
 {
 }
Exemple #19
0
 protected virtual object ExecuteCommand(RestCommand cmd, RestVerbs verbs, IParameterCollection parms)
 {
     return(cmd.Callback(verbs, parms));
 }
Exemple #20
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.Settings.LogRest)
            {
                TShock.Utils.SendLogs(string.Format(
                                          "\"{0}\" requested REST endpoint: {1}", tokenData.Username, this.BuildRequestUri(cmd, verbs, parms, false)),
                                      Color.PaleVioletRed);
            }

            return(result);
        }
    }
}
Exemple #21
0
 public virtual object Execute(RestVerbs verbs, IParameterCollection parameters)
 {
     return(callback(verbs, parameters));
 }