diff --git a/CHANGELOG.md b/CHANGELOG.md
index fa98e0ca..d66fea41 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -11,6 +11,10 @@ This is the rolling changelog for TShock for Terraria. Use past tense when addin
* Fixed butterfly statues spawning catchable butterflies (@DogooFalchion).
* Implemented some missing balance changes lost in prior version patches (@DogooFalchion).
* Added alias for server shutdown command: stop (@nicatronTg).
+* Removed the old REST model. This includes the following endpoints:
+ * `/status`
+ * `/v2/players/read`
+ * `/v2/server/rawcmd` (@WhiteXZ).
## TShock 4.3.20
* Security improvement: The auth system is now automatically disabled if a superadmin exists in the database (@Enerdy).
diff --git a/TShockAPI/ConfigFile.cs b/TShockAPI/ConfigFile.cs
index c0227d05..2d2d26d2 100755
--- a/TShockAPI/ConfigFile.cs
+++ b/TShockAPI/ConfigFile.cs
@@ -443,10 +443,6 @@ namespace TShockAPI
[Description("#.#.# = Red/Blue/Green - RGB Colors for broadcasts. Max value: 255.")]
public int[] BroadcastRGB = { 127, 255, 212 };
- // TODO: Get rid of this when the old REST permission model is removed.
- [Description("Whether the REST API should use the new permission model. Note: The old permission model will become depracted in the future.")]
- public bool RestUseNewPermissionModel = true;
-
/// ApplicationRestTokens - A dictionary of REST tokens that external applications may use to make queries to your server.
[Description("A dictionary of REST tokens that external applications may use to make queries to your server.")]
public Dictionary ApplicationRestTokens = new Dictionary();
diff --git a/TShockAPI/Rest/RestManager.cs b/TShockAPI/Rest/RestManager.cs
index d74aa6c5..d16e17f6 100644
--- a/TShockAPI/Rest/RestManager.cs
+++ b/TShockAPI/Rest/RestManager.cs
@@ -103,14 +103,12 @@ namespace TShockAPI
if (TShock.Config.EnableTokenEndpointAuthentication)
{
Rest.Register(new SecureRestCommand("/v2/server/status", ServerStatusV2));
- Rest.Register(new SecureRestCommand("/status", ServerStatus));
Rest.Register(new SecureRestCommand("/v3/server/motd", ServerMotd));
Rest.Register(new SecureRestCommand("/v3/server/rules", ServerRules));
}
else
{
Rest.Register(new RestCommand("/v2/server/status", (a) => this.ServerStatusV2(new RestRequestArgs(a.Verbs, a.Parameters, a.Request, SecureRest.TokenData.None, a.Context))));
- Rest.Register(new RestCommand("/status", (a) => this.ServerStatus(new RestRequestArgs(a.Verbs, a.Parameters, a.Request, SecureRest.TokenData.None, a.Context))));
Rest.Register(new RestCommand("/v3/server/motd", (a) => this.ServerMotd(new RestRequestArgs(a.Verbs, a.Parameters, a.Request, SecureRest.TokenData.None, a.Context))));
Rest.Register(new RestCommand("/v3/server/rules", (a) => this.ServerRules(new RestRequestArgs(a.Verbs, a.Parameters, a.Request, SecureRest.TokenData.None, a.Context))));
}
@@ -119,7 +117,6 @@ namespace TShockAPI
Rest.Register(new SecureRestCommand("/v3/server/reload", ServerReload, RestPermissions.restcfg));
Rest.Register(new SecureRestCommand("/v2/server/off", ServerOff, RestPermissions.restmaintenance));
Rest.Register(new SecureRestCommand("/v3/server/restart", ServerRestart, RestPermissions.restmaintenance));
- Rest.Register(new SecureRestCommand("/v2/server/rawcmd", ServerCommand, RestPermissions.restrawcommand));
Rest.Register(new SecureRestCommand("/v3/server/rawcmd", ServerCommandV3, RestPermissions.restrawcommand));
Rest.Register(new SecureRestCommand("/tokentest", ServerTokenTest));
@@ -148,7 +145,6 @@ namespace TShockAPI
// Player Commands
Rest.Register(new SecureRestCommand("/lists/players", PlayerList));
Rest.Register(new SecureRestCommand("/v2/players/list", PlayerListV2));
- Rest.Register(new SecureRestCommand("/v2/players/read", PlayerReadV2, RestPermissions.restuserinfo));
Rest.Register(new SecureRestCommand("/v3/players/read", PlayerReadV3, RestPermissions.restuserinfo));
Rest.Register(new SecureRestCommand("/v2/players/kick", PlayerKickV2, RestPermissions.restkick));
Rest.Register(new SecureRestCommand("/v2/players/ban", PlayerBanV2, RestPermissions.restban, RestPermissions.restmanagebans));
@@ -166,28 +162,6 @@ namespace TShockAPI
#region RestServerMethods
- [Description("Executes a remote command on the server, and returns the output of the command.")]
- [RouteAttribute("/v2/server/rawcmd")]
- [Permission(RestPermissions.restrawcommand)]
- [Noun("cmd", true, "The command and arguments to execute.", typeof(String))]
- [Token]
- private object ServerCommand(RestRequestArgs args)
- {
- if (string.IsNullOrWhiteSpace(args.Parameters["cmd"]))
- return RestMissingParam("cmd");
-
- Group restPlayerGroup;
- // TODO: Get rid of this when the old REST permission model is removed.
- if (TShock.Config.RestUseNewPermissionModel)
- restPlayerGroup = TShock.Groups.GetGroupByName(args.TokenData.UserGroupName);
- else
- restPlayerGroup = new SuperAdminGroup();
-
- TSRestPlayer tr = new TSRestPlayer(args.TokenData.Username, restPlayerGroup);
- Commands.HandleCommand(tr, args.Parameters["cmd"]);
- return RestResponse(string.Join("\n", tr.GetCommandOutput()));
- }
-
[Description("Executes a remote command on the server, and returns the output of the command.")]
[RouteAttribute("/v3/server/rawcmd")]
[Permission(RestPermissions.restrawcommand)]
@@ -198,12 +172,7 @@ namespace TShockAPI
if (string.IsNullOrWhiteSpace(args.Parameters["cmd"]))
return RestMissingParam("cmd");
- Group restPlayerGroup;
- // TODO: Get rid of this when the old REST permission model is removed.
- if (TShock.Config.RestUseNewPermissionModel)
- restPlayerGroup = TShock.Groups.GetGroupByName(args.TokenData.UserGroupName);
- else
- restPlayerGroup = new SuperAdminGroup();
+ Group restPlayerGroup = TShock.Groups.GetGroupByName(args.TokenData.UserGroupName);
TSRestPlayer tr = new TSRestPlayer(args.TokenData.Username, restPlayerGroup);
Commands.HandleCommand(tr, args.Parameters["cmd"]);
@@ -305,21 +274,6 @@ namespace TShockAPI
};
}
- [Description("Returns the current status of the server.")]
- [Route("/status")]
- [Token]
- private object ServerStatus(RestRequestArgs args)
- {
- var activeplayers = Main.player.Where(p => null != p && p.active).ToList();
- return new RestObject()
- {
- {"name", TShock.Config.ServerName},
- {"port", Convert.ToString(Netplay.ListenPort)},
- {"playercount", Convert.ToString(activeplayers.Count())},
- {"players", string.Join(", ", activeplayers.Select(p => p.name))},
- };
- }
-
[Description("Get a list of information about the current TShock server.")]
[Route("/v2/server/status")]
[Token]
@@ -791,32 +745,6 @@ namespace TShockAPI
return new RestObject() { { "players", playerList } };
}
- [Description("Get information for a user.")]
- [Route("/v2/players/read")]
- [Permission(RestPermissions.restuserinfo)]
- [Noun("player", true, "The player to lookup", typeof(String))]
- [Token]
- private object PlayerReadV2(RestRequestArgs args)
- {
- var ret = PlayerFind(args.Parameters);
- if (ret is RestObject)
- return ret;
-
- TSPlayer player = (TSPlayer)ret;
- var activeItems = player.TPlayer.inventory.Where(p => p.active).ToList();
- return new RestObject()
- {
- {"nickname", player.Name},
- {"username", null == player.User ? "" : player.User.Name},
- {"ip", player.IP},
- {"group", player.Group.Name},
- {"registered", null == player.User ? "" : player.User.Registered},
- {"position", player.TileX + "," + player.TileY},
- {"inventory", string.Join(", ", activeItems.Select(p => (p.name + ":" + p.stack)))},
- {"buffs", string.Join(", ", player.TPlayer.buffType)}
- };
- }
-
[Description("Get information for a user.")]
[Route("/v3/players/read")]
[Permission(RestPermissions.restuserinfo)]
diff --git a/TShockAPI/Rest/SecureRest.cs b/TShockAPI/Rest/SecureRest.cs
index f8290784..cf3a9fd2 100644
--- a/TShockAPI/Rest/SecureRest.cs
+++ b/TShockAPI/Rest/SecureRest.cs
@@ -44,12 +44,12 @@ namespace Rests
{
Tokens = new Dictionary();
AppTokens = new Dictionary();
-
+
Register(new RestCommand("/v2/token/create", NewTokenV2) { DoLog = false });
Register(new SecureRestCommand("/token/destroy/{token}", DestroyToken));
Register(new SecureRestCommand("/v3/token/destroy/all", DestroyAllTokens, RestPermissions.restmanage));
- foreach (KeyValuePair t in TShockAPI.TShock.RESTStartupTokens)
+ foreach (KeyValuePair t in TShock.RESTStartupTokens)
{
AppTokens.Add(t.Key, t.Value);
}
@@ -58,29 +58,6 @@ namespace Rests
{
AppTokens.Add(t.Key, t.Value);
}
-
- // TODO: Get rid of this when the old REST permission model is removed.
- if (TShock.Config.RestApiEnabled && !TShock.Config.RestUseNewPermissionModel)
- {
- string warningMessage = string.Concat(
- "You're using the old REST permission model which is highly vulnerable in matter of security. ",
- "The old model will be removed with the next maintenance release of TShock. In order to switch to the new model, ",
- "change the config setting \"RestUseNewPermissionModel\" to true."
- );
- TShock.Log.Warn(warningMessage);
- Console.ForegroundColor = ConsoleColor.Red;
- Console.WriteLine(warningMessage);
- Console.ForegroundColor = ConsoleColor.Gray;
- }
- else if (TShock.Config.RestApiEnabled)
- {
- string warningMessage = string.Concat(
- "You're using the new more secure REST permission model which can lead to compatibility problems ",
- "with existing REST services. If compatibility problems occur, you can switch back to the unsecure permission ",
- "model by changing the config setting \"RestUseNewPermissionModel\" to false, which is not recommended."
- );
- TShock.Log.ConsoleInfo(warningMessage);
- }
}
private void AddTokenToBucket(string ip)
@@ -206,23 +183,19 @@ namespace Rests
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)
{
- Group userGroup = TShock.Groups.GetGroupByName(tokenData.UserGroupName);
- if (userGroup == null)
- {
- Tokens.Remove(token);
+ Tokens.Remove(token);
- return new RestObject("403")
- { Error = "Not authorized. The provided token became invalid due to group changes, please create a new 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) };
- }
+ 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, context);