TShock/TShockAPI/Rest/RestCommand.cs
White e3a8112b5b REST updates.
Rest.cs got a lot of commenting at last.
Redirects and upgrades can now be easily added for REST routes via the `Rest.RegisterRedirect(base, target, upgrade)` method.
Redirects added for all routes. Upgrades added for `/world/bloodmoon` and `/v2/world/autosave`, as they both use old-style REST verbs.
2017-02-02 14:28:35 +10:30

106 lines
No EOL
3.6 KiB
C#

/*
TShock, a server mod for Terraria
Copyright (C) 2011-2016 Nyx Studios (fka. The TShock Team)
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
using System.Linq;
using System.Text.RegularExpressions;
using HttpServer;
namespace Rests
{
public class RestCommand
{
public string Name { get; protected set; }
public string UriTemplate { get; protected set; }
public string UriVerbMatch { get; protected set; }
public string[] UriVerbs { get; protected set; }
public virtual bool RequiresToken { get { return false; } }
public bool DoLog { get; set; }
private RestCommandD callback;
/// <summary>
/// Creates a new <see cref="RestCommand"/> used with the REST API
/// </summary>
/// <param name="name">Used for identification</param>
/// <param name="uritemplate">Url template</param>
/// <param name="callback">Rest Command callback</param>
public RestCommand(string name, string uritemplate, RestCommandD callback)
{
Name = name;
UriTemplate = uritemplate;
UriVerbMatch = string.Format("^{0}$", string.Join("([^/]*)", Regex.Split(uritemplate, "\\{[^\\{\\}]*\\}")));
var matches = Regex.Matches(uritemplate, "\\{([^\\{\\}]*)\\}");
UriVerbs = (from Match match in matches select match.Groups[1].Value).ToArray();
this.callback = callback;
DoLog = true;
}
/// <summary>
/// Creates a new <see cref="RestCommand"/> used with the REST API
/// </summary>
/// <param name="uritemplate">Url template</param>
/// <param name="callback">Rest Command callback</param>
public RestCommand(string uritemplate, RestCommandD callback)
: this(string.Empty, uritemplate, callback)
{
}
public bool HasVerbs
{
get { return UriVerbs.Length > 0; }
}
public virtual object Execute(RestVerbs verbs, IParameterCollection parameters, IRequest request, IHttpContext context)
{
return callback(new RestRequestArgs(verbs, parameters, request, context));
}
}
public class SecureRestCommand: RestCommand
{
public override bool RequiresToken { get { return true; } }
public string[] Permissions { get; set; }
private RestCommandD callback;
public SecureRestCommand(string name, string uritemplate, RestCommandD callback, params string[] permissions)
: base(name, uritemplate, null)
{
this.callback = callback;
Permissions = permissions;
}
public SecureRestCommand(string uritemplate, RestCommandD callback, params string[] permissions)
: this(string.Empty, uritemplate, callback, permissions)
{
}
public override object Execute(RestVerbs verbs, IParameterCollection parameters, IRequest request, IHttpContext context)
{
return new RestObject("401") { Error = "Not authorized. The specified API endpoint requires a token." };
}
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));
}
}
}