Added URI-unescaping for inputs into REST requests
This commit is contained in:
parent
1b4dc5361c
commit
51f179f84a
4 changed files with 105 additions and 16 deletions
|
|
@ -29,9 +29,84 @@ using HttpServer.Headers;
|
|||
using Newtonsoft.Json;
|
||||
using TShockAPI;
|
||||
using HttpListener = HttpServer.HttpListener;
|
||||
using System.Collections;
|
||||
|
||||
namespace Rests
|
||||
{
|
||||
/// <summary>
|
||||
/// Wraps an <see cref="IParameter"/>, providing URI-unescaping for its value
|
||||
/// </summary>
|
||||
public class EscapedParameter
|
||||
{
|
||||
private IParameter _parameter;
|
||||
|
||||
/// <summary>
|
||||
/// Name of the parameter
|
||||
/// </summary>
|
||||
public string Name => _parameter.Name;
|
||||
/// <summary>
|
||||
/// URI-unescaped value of the parameter
|
||||
/// </summary>
|
||||
public string Value => Uri.UnescapeDataString(_parameter.Value);
|
||||
|
||||
/// <summary>
|
||||
/// Constructs a new EscapedParameter wrapping the given <see cref="IParameter"/>
|
||||
/// </summary>
|
||||
/// <param name="parameter"></param>
|
||||
public EscapedParameter(IParameter parameter)
|
||||
{
|
||||
_parameter = parameter;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Wraps an <see cref="IParameterCollection"/>, providing URI-unescaping for the parameters in the collection
|
||||
/// </summary>
|
||||
public class EscapedParameterCollection : IEnumerable<EscapedParameter>
|
||||
{
|
||||
private readonly IParameterCollection _collection;
|
||||
|
||||
/// <summary>
|
||||
/// Retrieve a parameter by name, returning the URI-unescaped value
|
||||
/// </summary>
|
||||
/// <param name="key"></param>
|
||||
/// <returns></returns>
|
||||
public string this[string key]
|
||||
{
|
||||
get
|
||||
{
|
||||
string value = _collection[key];
|
||||
return value == null ? value : Uri.UnescapeDataString(value);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Constructs a new EscapedParameterCollection wrapping the given <see cref="IParameterCollection"/>
|
||||
/// </summary>
|
||||
/// <param name="collection"></param>
|
||||
public EscapedParameterCollection(IParameterCollection collection)
|
||||
{
|
||||
_collection = collection;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns an enumerator that can be used to iterate over this collection
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public IEnumerator<EscapedParameter> GetEnumerator()
|
||||
{
|
||||
return GetEnumerator();
|
||||
}
|
||||
|
||||
IEnumerator IEnumerable.GetEnumerator()
|
||||
{
|
||||
foreach (IParameter param in _collection)
|
||||
{
|
||||
yield return new EscapedParameter(param);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Rest command delegate
|
||||
/// </summary>
|
||||
|
|
@ -51,7 +126,7 @@ namespace Rests
|
|||
/// <summary>
|
||||
/// Parameters sent in the request
|
||||
/// </summary>
|
||||
public IParameterCollection Parameters { get; private set; }
|
||||
public EscapedParameterCollection Parameters { get; private set; }
|
||||
/// <summary>
|
||||
/// The HTTP request
|
||||
/// </summary>
|
||||
|
|
@ -74,12 +149,8 @@ namespace Rests
|
|||
/// <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)
|
||||
{
|
||||
Verbs = verbs;
|
||||
Parameters = param;
|
||||
Request = request;
|
||||
TokenData = SecureRest.TokenData.None;
|
||||
Context = context;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -91,6 +162,19 @@ namespace Rests
|
|||
/// <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)
|
||||
{
|
||||
}
|
||||
|
||||
/// <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;
|
||||
|
|
|
|||
|
|
@ -1261,7 +1261,7 @@ namespace TShockAPI
|
|||
return bool.TryParse(val, out ret) ? ret : def;
|
||||
}
|
||||
|
||||
private object PlayerFind(IParameterCollection parameters)
|
||||
private object PlayerFind(EscapedParameterCollection parameters)
|
||||
{
|
||||
string name = parameters["player"];
|
||||
if (string.IsNullOrWhiteSpace(name))
|
||||
|
|
@ -1279,7 +1279,7 @@ namespace TShockAPI
|
|||
}
|
||||
}
|
||||
|
||||
private object UserFind(IParameterCollection parameters)
|
||||
private object UserFind(EscapedParameterCollection parameters)
|
||||
{
|
||||
string name = parameters["user"];
|
||||
if (string.IsNullOrWhiteSpace(name))
|
||||
|
|
@ -1314,7 +1314,7 @@ namespace TShockAPI
|
|||
return account;
|
||||
}
|
||||
|
||||
private object GroupFind(IParameterCollection parameters)
|
||||
private object GroupFind(EscapedParameterCollection parameters)
|
||||
{
|
||||
var name = parameters["group"];
|
||||
if (string.IsNullOrWhiteSpace(name))
|
||||
|
|
@ -1327,7 +1327,7 @@ namespace TShockAPI
|
|||
return group;
|
||||
}
|
||||
|
||||
private Dictionary<string, object> PlayerFilter(TSPlayer tsPlayer, IParameterCollection parameters, bool viewips = false)
|
||||
private Dictionary<string, object> PlayerFilter(TSPlayer tsPlayer, EscapedParameterCollection parameters, bool viewips = false)
|
||||
{
|
||||
var player = new Dictionary<string, object>
|
||||
{
|
||||
|
|
@ -1343,7 +1343,7 @@ namespace TShockAPI
|
|||
{
|
||||
player.Add("ip", tsPlayer.IP);
|
||||
}
|
||||
foreach (IParameter filter in parameters)
|
||||
foreach (EscapedParameter filter in parameters)
|
||||
{
|
||||
if (player.ContainsKey(filter.Name) && !player[filter.Name].Equals(filter.Value))
|
||||
return null;
|
||||
|
|
@ -1351,7 +1351,7 @@ namespace TShockAPI
|
|||
return player;
|
||||
}
|
||||
|
||||
private object PlayerSetMute(IParameterCollection parameters, bool mute)
|
||||
private object PlayerSetMute(EscapedParameterCollection parameters, bool mute)
|
||||
{
|
||||
var ret = PlayerFind(parameters);
|
||||
if (ret is RestObject)
|
||||
|
|
|
|||
|
|
@ -21,6 +21,9 @@ using System.Collections.Generic;
|
|||
|
||||
namespace Rests
|
||||
{
|
||||
/// <summary>
|
||||
/// A dictionary collection of verbs used in a REST request
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
public class RestVerbs : Dictionary<string, string>
|
||||
{
|
||||
|
|
@ -35,7 +38,9 @@ namespace Rests
|
|||
{
|
||||
string ret;
|
||||
if (TryGetValue(key, out ret))
|
||||
return ret;
|
||||
{
|
||||
return Uri.UnescapeDataString(ret);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
set
|
||||
|
|
@ -56,4 +61,4 @@ namespace Rests
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -103,8 +103,8 @@ namespace Rests
|
|||
|
||||
private object NewTokenV2(RestRequestArgs args)
|
||||
{
|
||||
var user = args.Parameters["username"];
|
||||
var pass = args.Parameters["password"];
|
||||
var user = Uri.UnescapeDataString(args.Parameters["username"]);
|
||||
var pass = Uri.UnescapeDataString(args.Parameters["password"]);
|
||||
var context = args.Context;
|
||||
|
||||
return this.NewTokenInternal(user, pass, context);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue