Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

REST API v3 #6

Open
pedzed opened this issue Aug 14, 2015 · 23 comments
Open

REST API v3 #6

pedzed opened this issue Aug 14, 2015 · 23 comments

Comments

@pedzed
Copy link

pedzed commented Aug 14, 2015

TShock's REST API v2 is out for quite some time now and it would be nice to have a next version. This gives room to fix some inconsistencies, remove duplication, fix issues and add features.

For example purposes, I will use 127.0.0.1 for the host and 7878 for the REST port. Also, because JSON does not officially support comments, I "faked" the comments.

Consistency

Base URL

One issue we currently face is that you have to use v1 for some endpoints and for some other endpoints v2. In v3 everything should be called from http://127.0.0.1:7878/v3/.

Keys

Keys MUST be lower_under.

Values

A value SHOULD NOT contain multiple values. buffs from REST v2 is a good example of how it should not be done.

{
    "//": "...",
    "buffs": "147, 86, 158, 146, 87, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0"
}

Dates

All dates SHOULD be available as specified in ISO 8601.

Complete date plus hours and minutes:
YYYY-MM-DDThh:mmTZD (eg 1997-07-16T19:20+01:00)

http://www.w3.org/TR/NOTE-datetime

Security

GET can expose sensitive data. And besides,

the convention has been established that the GET and HEAD methods SHOULD NOT have the significance of taking an action other than retrieval. These methods ought to be considered "safe".

http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9.1.1

Like in v1 and v2, the token should not be in the URL.

Usernames, passwords, session tokens, and API keys should not appear in the URL, as this can be captured in web server logs, which makes them intrinsically valuable.

https://www.owasp.org/index.php/REST_Security_Cheat_Sheet

Endpoints

Tokens

Generating a token

Deprecates: /token/create
http://127.0.0.1:7878/v3/token/generate
data:

username = 'restuser'
password = 'restpass'

Example response:

{
    "status": 201,
    "response": "Successfully generated token.",
    "data": {
        "token": "5C58D5332D5A51DCC5CFFEBD3813014ECF0248BA104CF12ADE0F93E192E77347",
        "expiration_date": "2015-7-24T13:39Z"
    }
}

Validating a token

Deprecates: /tokentest
http://127.0.0.1:7878/v3/token/validate
data:

token = '5C58D5332D5A51DCC5CFFEBD3813014ECF0248BA104CF12ADE0F93E192E77347'

Example response:

{
    "status": 200,
    "response": "Token is valid.",
    "data": {
        "token": "5C58D5332D5A51DCC5CFFEBD3813014ECF0248BA104CF12ADE0F93E192E77347",
        "expiration_date": "2015-7-24T13:39Z"
    }
}

Server

Information

Deprecates: /v2/status, /v2/server/status
http://127.0.0.1:7878/v3/server/info
data:

token = '5C58D5332D5A51DCC5CFFEBD3813014ECF0248BA104CF12ADE0F93E192E77347'

Example response:

{
    "status": 200,
    "data": {
        "name": "TerraServer",
        "host": "127.0.0.1",
        "port": "7777",
        "software": {
            "name": "tshock",
            "version": "4.4.0"
        }
    }
}

Executing a command

Deprecates: /v2/server/rawcmd, /v2/world/butcher, /world/meteor, /world/bloodmoon/{bool}, /v2/players/kick, /v2/players/kill, /v2/players/mute, /v2/players/unmute, /v2/world/save, /v2/server/broadcast
http://127.0.0.1:7878/v3/server/execute-command
data:

token = '5C58D5332D5A51DCC5CFFEBD3813014ECF0248BA104CF12ADE0F93E192E77347'
command = 'time noon'

Example response:

{
    "status": 200,
    "response": "Server set the time to 12:00."
}

Changing server password

http://127.0.0.1:7878/v3/server/update-password
data:

token = '5C58D5332D5A51DCC5CFFEBD3813014ECF0248BA104CF12ADE0F93E192E77347'
password = '123123'

Example response:

{
    "status": 200,
    "response": "Successfully changed server password."
}

Shutting the server down

Deprecates: /v2/server/off
http://127.0.0.1:7878/v3/server/shut-down
data:

token = '5C58D5332D5A51DCC5CFFEBD3813014ECF0248BA104CF12ADE0F93E192E77347'
save = false // Optional; default true

Example response:

{
    "status": 200,
    "response": "Server shut down. World not saved."
}

Starting the server up

New feature
http://127.0.0.1:7878/v3/server/start-up
data:

token = '5C58D5332D5A51DCC5CFFEBD3813014ECF0248BA104CF12ADE0F93E192E77347'
port = 8888 // Optional; default 7777

Example response:

{
    "status": 200
}

World

Information

Deprecates: /world/read, /v2/server/status
http://127.0.0.1:7878/v3/world
data:

token = '5C58D5332D5A51DCC5CFFEBD3813014ECF0248BA104CF12ADE0F93E192E77347'

Example response:

{
    "status": 200,
    "data": {
        "id": 18624254254,
        "name": "World 3",
        "size": {
            "type": "medium",
            "width": 6400,
            "height": 1800
        },
        "mode": "expert",
        "creation_date": "2015-7-24T13:39Z",
        "//": "In what format is the time??",
        "time": "42149",
        "is_day": true,
        "is_bloodmoon": false,
        "//": "TODO: Improve invasionsize.",
        "invasionsize": 0
    }
}

Auto-saving

Deprecates: /v2/world/autosave/state/{bool}
http://127.0.0.1:7878/v3/world/auto-save
data:

token = '5C58D5332D5A51DCC5CFFEBD3813014ECF0248BA104CF12ADE0F93E192E77347'
mode = false // Optional; default true

Example response:

{
    "status": 200,
    "response": "Successfully set auto-save to true."
}

Groups

Group information

Deprecates: /v2/groups/list, /v2/groups/read
http://127.0.0.1:7878/v3/groups
data:

token = '5C58D5332D5A51DCC5CFFEBD3813014ECF0248BA104CF12ADE0F93E192E77347'

Example response:

{
    "status": 200,
    "response": "Successfully fetched 8 groups.",
    "data": {
        "groups": [
            {
                "name": "default",
                "parent": "guest",
                "rgb_chat_color": [
                    255,
                    255,
                    255
                ],
                "permissions": [
                    "tshock.reservedslot"
                ],
                "negatedpermissions": [],
                "totalpermissions": [
                    "tshock.reservedslot",
                    "tshock.warp",
                    "// ...",
                    "tshock.canchat"
                ]
            },
            "// ..."
        ]
    }
}

Create group

Deprecates: /v2/groups/create
http://127.0.0.1:7878/v3/group/create
data:

token = '5C58D5332D5A51DCC5CFFEBD3813014ECF0248BA104CF12ADE0F93E192E77347'
name = 'Team Penguin'
prefix = '(Team Penguin)'
suffix = null
parent_type = 'id' // Optional; defaults to "name"; options: id, name
parent_group = 23
permissions = [
    'tshock.tp.self',
    'tshock.tp.others'
]
rgb_chat_color = [
    255,
    255,
    255
]

Example response:

{
    "status": 201,
    "response": "Successfully created group \"Team Penguin\"."
}

Update group

Deprecates: /v2/groups/update
http://127.0.0.1:7878/v3/group/update
data:

token = '5C58D5332D5A51DCC5CFFEBD3813014ECF0248BA104CF12ADE0F93E192E77347'
type = 'id' // Optional; defaults to "name"; options: id, name
name = 24
prefix = '(Team Penguin)'
suffix = null
parent_type = 'id' // Optional; defaults to "name"; options: id, name
parent_group = 23
permissions = [
    'tshock.tp.self',
    'tshock.tp.others'
]
rgb_chat_color = [
    255,
    255,
    255
]

Example response:

{
    "status": 201,
    "response": "Successfully created group \"Team Penguin\"."
}

Delete group

Deprecates: /v2/groups/destroy
http://127.0.0.1:7878/v3/group/delete
data:

token = '5C58D5332D5A51DCC5CFFEBD3813014ECF0248BA104CF12ADE0F93E192E77347'
type = 'id' // Optional; defaults to "name"; options: id, name
group = 24

Example response:

{
    "status": 200,
    "response": "Successfully deleted group \"Team Penguin\"."
}

Users

Registered users info

Relevant: Pryaxis/TShock#901
Deprecates: /v2/users/read
http://127.0.0.1:7878/v3/users
data:

token = '5C58D5332D5A51DCC5CFFEBD3813014ECF0248BA104CF12ADE0F93E192E77347'

Example response:

{
    "status": 200,
    "response": "Successfully fetched 4 online users.",
    "data": {
        "maximum_allowed": 7,
        "online": [
            {
                "nickname": "Ped",
                "username": "ped",
                "group": "superadmin",
                "team": 0,
                "ip": "127.0.0.1",
                "position": {
                    "longtitude": 3219,
                    "latitude": 290
                },
                "buffs": [
                    {
                        "id": 147,
                        "name": "Banners",
                        "description": [
                            "Increased damage and defense from the following:",
                            "Zombie",
                            "Green Slime"
                        ],
                        "seconds_left": null
                    },
                    {
                        "id": 121,
                        "name": "Fishing",
                        "description": "Increased fishing level",
                        "seconds_left": 480
                    }
                ],
                "inventory": {
                    "items": [
                        {
                            "id": 200,
                            "name": "Green Phaseblade",
                            "description": [
                                "23 melee damage",
                                "9% critical strike chance",
                                "Fast speed",
                                "Weak knockback",
                                "Material",
                                "+5% damage",
                                "+15% knockback"
                            ],
                            "prefix": {
                                "id": 7,
                                "name": "Unpleasant"
                            },
                            "amount": 1
                        },
                        "// x50 elements"
                    ],
                    "coins": [
                        "// Same as items, but without prefix",
                        "// x4 elements"
                    ],
                    "ammo": [
                        "// Same as items, but without prefix",
                        "// x4 elements"
                    ],
                    "trash": null,
                    "holding_item": null,
                    "helmet": {
                        "dye": {
                            "id": 213,
                            "name": "Brown Dye",
                            "description": [
                                "Material"
                            ]
                        },
                        "vanity": {
                            "//": "Same as dye, but with prefix",
                            "prefix": {
                                "id": 7,
                                "name": "Unpleasant"
                            }
                        },
                        "item": {
                            "//": "Same as dye, but with prefix",
                        }
                    },
                    "shirt": {
                        "//": "Same as helmet"
                    },
                    "pants": {
                        "//": "Same as helmet"
                    },
                    "accessories": [
                        {
                            "dye": {
                                "//": "Same as helmet's dye"
                            },
                            "vanity": {
                                "//": "Same as helmet's vanity"
                            },
                            "item": {
                                "//": "Same as dye, but with prefix"
                            }
                        }
                        "// x5 elements"
                    ],
                    "pet": {
                        "dye": {
                            "//": "Same as helmet's dye"
                        },
                        "item": {
                            "//": "Same as helmet's item"
                        }
                    },
                    "light_pet": {
                        "//": "Same as pet"
                    },
                    "mount": {
                        "//": "Same as pet"
                    },
                    "minecart": {
                        "//": "Same as pet"
                    },
                    "grappling_hook": {
                        "//": "Same as pet"
                    }
                }
            },
            "// Other players"
        ]
    }
}

Online info

Relevant: Pryaxis/TShock#901
Deprecates: /v2/server/status, /v2/users/activelist, /v2/players/read, /v2/players/list
http://127.0.0.1:7878/v3/online-users
data:

token = '5C58D5332D5A51DCC5CFFEBD3813014ECF0248BA104CF12ADE0F93E192E77347'

Example response:

{
    "status": 200,
    "response": "Successfully fetched 4 online users.",
    "data": {
        "maximum_allowed": 7,
        "online": [
            {
                "nickname": "Ped",
                "username": "ped",
                "group": "superadmin",
                "team": 0,
                "ip": "127.0.0.1",
                "position": {
                    "longtitude": 3219,
                    "latitude": 290
                },
                "buffs": [
                    {
                        "id": 147,
                        "name": "Banners",
                        "description": [
                            "Increased damage and defense from the following:",
                            "Zombie",
                            "Green Slime"
                        ],
                        "seconds_left": null
                    },
                    {
                        "id": 121,
                        "name": "Fishing",
                        "description": "Increased fishing level",
                        "seconds_left": 480
                    }
                ],
                "inventory": {
                    "items": [
                        {
                            "id": 200,
                            "name": "Green Phaseblade",
                            "description": [
                                "23 melee damage",
                                "9% critical strike chance",
                                "Fast speed",
                                "Weak knockback",
                                "Material",
                                "+5% damage",
                                "+15% knockback"
                            ],
                            "prefix": {
                                "id": 7,
                                "name": "Unpleasant"
                            },
                            "amount": 1
                        },
                        "// x50 elements"
                    ],
                    "coins": [
                        "// Same as items, but without prefix",
                        "// x4 elements"
                    ],
                    "ammo": [
                        "// Same as items, but without prefix",
                        "// x4 elements"
                    ],
                    "trash": null,
                    "holding_item": null,
                    "helmet": {
                        "dye": {
                            "id": 213,
                            "name": "Brown Dye",
                            "description": [
                                "Material"
                            ]
                        },
                        "vanity": {
                            "//": "Same as dye, but with prefix",
                            "prefix": {
                                "id": 7,
                                "name": "Unpleasant"
                            }
                        },
                        "item": {
                            "//": "Same as dye, but with prefix",
                        }
                    },
                    "shirt": {
                        "//": "Same as helmet"
                    },
                    "pants": {
                        "//": "Same as helmet"
                    },
                    "accessories": [
                        {
                            "dye": {
                                "//": "Same as helmet's dye"
                            },
                            "vanity": {
                                "//": "Same as helmet's vanity"
                            },
                            "item": {
                                "//": "Same as dye, but with prefix"
                            }
                        }
                        "// x5 elements"
                    ],
                    "pet": {
                        "dye": {
                            "//": "Same as helmet's dye"
                        },
                        "item": {
                            "//": "Same as helmet's item"
                        }
                    },
                    "light_pet": {
                        "//": "Same as pet"
                    },
                    "mount": {
                        "//": "Same as pet"
                    },
                    "minecart": {
                        "//": "Same as pet"
                    },
                    "grappling_hook": {
                        "//": "Same as pet"
                    }
                }
            },
            "// Other players"
        ]
    }
}

Create user

Deprecates: /v2/users/create
http://127.0.0.1:7878/v3/user/create
data:

token = '5C58D5332D5A51DCC5CFFEBD3813014ECF0248BA104CF12ADE0F93E192E77347'
username = 'ped'
password = '123123'
group = 'moderator' // Optional; defaults to "default"

Example response:

{
    "status": 201,
    "response": "Successfully created moderator \"ped\"."
}

Update user

Deprecates: /v2/users/update
http://127.0.0.1:7878/v3/user/update
data:

token = '5C58D5332D5A51DCC5CFFEBD3813014ECF0248BA104CF12ADE0F93E192E77347'
type = 'id' // Optional; defaults to "username"; options: id, username
user = 254
// TODO: Add more parameters

Example response:

{
    "status": 200,
    "response": "Successfully updated user 254."
}

Delete user

Deprecates: /v2/users/destroy
http://127.0.0.1:7878/v3/user/delete
data:

token = '5C58D5332D5A51DCC5CFFEBD3813014ECF0248BA104CF12ADE0F93E192E77347'
type = 'id' // Optional; defaults to "username"; options: id, username
user = 254

Example response:

{
    "status": 200,
    "response": "Successfully deleted user from database."
}

Bans

Deprecates: /v2/players/ban

REST API v1 & v2

v1 is out for a very long time. I propose to remove the support to get rid of legacy code. I also propose to deprecate v2 and remove it in August 2018.

Feel free to comment on this. I might have missed something or made some mistakes along the way.

@WhiTexz If v3 is already out, then you can obviously name it v4. I am not aware of v3.

@pedzed
Copy link
Author

pedzed commented Aug 14, 2015

Some things missing in my proposal are:

  • Request methods (GET/POST/HEAD/PUT/...)
  • How to start the server (back-end)
  • How to authenticate securely (back-end)
  • Some response statuses should be more specific than 200 OK
  • Some response messages should be added/improved
  • Inventory: extra accessory slot

@hakusaro
Copy link
Member

Everything here seems like a solid idea to me.

@pedzed
Copy link
Author

pedzed commented Aug 14, 2015

@nicatronTg What do you suggest for starting the server through REST? I cannot think of an other way besides not completely exiting TShock.

@AxisKriel
Copy link
Member

You'd most likely need to separate the HttpServer process handling REST requests from TShock/TSApi in order to do that.

@Ijwu
Copy link
Contributor

Ijwu commented Aug 16, 2015

With the move to v3 we should switch to OWIN and Katana as our server.

Edit: Wrong button, sorry folks.

@Ijwu Ijwu closed this as completed Aug 16, 2015
@Ijwu Ijwu reopened this Aug 16, 2015
@pedzed
Copy link
Author

pedzed commented Oct 11, 2015

Any updates on this?

@Ijwu
Copy link
Contributor

Ijwu commented Oct 12, 2015

Rest V3 is coming with Orion at some point. With Orion we are moving to https://github.com/DeathCradle/Open-Terraria-API. OTAPI has webapi built in so we will eventually construct our REST layer on top of that. It's not going to be soon, but it will happen.

@Ijwu
Copy link
Contributor

Ijwu commented Nov 25, 2015

Throwing out updates, I'll make it a point to discuss with DeathCradle where the REST API integration is with OTAPI and get this on my "to-do soon" list if it's in a working state.

@hakusaro
Copy link
Member

@Ijwu @DeathCradle poking you both on this issue since it hasn't been worked in ages

@Ijwu
Copy link
Contributor

Ijwu commented Oct 11, 2016

I will have to have a 1 on 1 with @DeathCradle and actually figure this stuff out. If I don't get the chance to talk to him then I will look at the current OTAPI source and see if a REST framework is built out at all. I would say there hasn't been progress on this all year, it fell through the cracks as a non-essential feature. I'll personally pick up on this and see where we can go with it.

@Ijwu Ijwu self-assigned this Oct 11, 2016
@hakusaro
Copy link
Member

Please document this conversation here. I don't want to have the conversation lost in Slack or something and then never documented. Otherwise, sounds good c:

@SignatureBeef
Copy link
Member

@Ijwu The REST framework is now done in Orion as OTAPI v2 is now purely a low level Terraria API.
The above controllers are still to be done though, in TS5 or Orion.

@Ijwu
Copy link
Contributor

Ijwu commented Oct 11, 2016

@DeathCradle Confirm for me, then, that there is currently no progress towards the REST API within Orion/TShock 5.

@tylerjwatson
Copy link
Member

@Ijwu see #33 - the progress is with a REST service, which spins up a fully managed instance of OWIN self-host with WebAPI 2 front end. It should harvest controllers within the current app domain, and should be ready for controllers to be added in other services.

Alternatively, we can discuss a design where controllers are constructed dynamically by calls to a REST service method like AddEndpoint<>.

There most definitely is progress. Thanks to @DeathCradle for all his work on it

@hakusaro
Copy link
Member

At least far as I'm concerned right now REST API will be fully implemented in Orion and no REST stuff will touch TShock unless it's TShock related (warps come to mind). If this isn't the intention then let me know so I can update the feature table for TShock 5.

@tylerjwatson
Copy link
Member

TShock unless it's TShock related

Agree, not currently. But TShock can feel free to yield its own endpoints to the REST service as it sees fit. Most of the REST functionality will interact directly with other services to instrument the services' operations remotely.

@hakusaro
Copy link
Member

Well right now things like AAA are handling what TShock was; I'd say that probably takes care of a lot of it. Things like warps and regions I could see being exposed by TShock over rest and not Orion.

@tylerjwatson
Copy link
Member

AAA's implementation (and all of the relevant parts of TShock) shall be moved into TShockv5 when they are done and someone spins up an assembly.

Most of that stuff hijacked from TShock is only in Orion right now to support easy development&test methodologies, and will be moved out as we draw closer to a public release

@hakusaro
Copy link
Member

Cool.

I'm completely confused now.
On Tue, Oct 11, 2016 at 5:46 PM Tyler Watson notifications@github.com
wrote:

AAA's implementation (and all of the relevant parts of TShock) shall be
moved into TShockv5 when they are done and someone spins up an assembly.

Most of that stuff hijacked from TShock is only in Orion right now to
support easy development&test methodologies, and will be moved out as we
draw closer to a public release


You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
#6 (comment), or mute
the thread
https://github.com/notifications/unsubscribe-auth/AAggp7UAfuHKk1uNRqFI2t3AiRA48HmJks5qzB_UgaJpZM4FryGK
.

@hakusaro
Copy link
Member

@tylerjwatson so is Orion going to have no services out of the box? Right now I was classifying Orion as handling core authentication + database. Is that not correct?

@QuiCM
Copy link
Member

QuiCM commented Oct 12, 2016

@nicatronTg Orion contains service definitions, TS5 will contain concrete implementations.

E.G., IUserAccountService would be in Orion, while PlainTextAccountService would be part of TShock

@hakusaro
Copy link
Member

So, just for my curiosity, the benefit for creating the service definitions in Orion is...?

@QuiCM
Copy link
Member

QuiCM commented Oct 12, 2016

Orion is a mid-level wrapper for OTAPI.
Instead of the TShock 4 architecture where plugins must depend on both TShock and TSAPI (and TShock ends up fulfilling an API role), plugins should only need to have a dependency on Orion (and any plugins they may depend upon).

Orion acts a full API providing services for anything a plugin should need. Plugins request a service and it is provided to them.

An english example using the aforementioned IUserAccountService:
Plugin P wants to get a user's account, so it asks to be provided with an IUserAccountService.
Plugin TShock has registered an IUserAccountService called PlainTextAccountService with Orion.
This service is provided in its abstract form of IUserAccountService to plugin P.
P does not need to know anything about the concrete implementation provided by PlainTextAccountService.

In this way any service implementations can change , but because plugins depend upon the definition, they do not need to update to conform to the implementation change.

Hope that helps a bit

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

7 participants