/// <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; }
/// <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; }
private object DestroyAllTokens(RestVerbs verbs, IParameterCollection parameters, SecureRest.TokenData tokenData) { Tokens.Clear(); return(new RestObject() { Response = "All tokens were successfully destroyed." }); }
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); }
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." } }); }
/// <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); }
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); }
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))); } }
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))); } }
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." } }); }
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); }
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." }); }
/// <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()); }
/// <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." } }); }
public virtual object Execute(RestVerbs verbs, IParameterCollection parameters, IRequest request, IHttpContext context) { return(callback(new RestRequestArgs(verbs, parameters, request, context))); }
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); } } }
/// <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) { }
/// <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) { }
protected virtual object ExecuteCommand(RestCommand cmd, RestVerbs verbs, IParameterCollection parms) { return(cmd.Callback(verbs, parms)); }
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); } } }
public virtual object Execute(RestVerbs verbs, IParameterCollection parameters) { return(callback(verbs, parameters)); }