-
-
Notifications
You must be signed in to change notification settings - Fork 82
/
API.dox
508 lines (296 loc) · 24.1 KB
/
API.dox
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
/*!
@page api API
@tableofcontents
@section api_swag OpenAPI Spec
TGS has a, from code, generated OpenAPI 3.0 specification. It is much more authorative than these documents.
The most up to date version should be found in the most recent appveyor build artifacts. It is also included in release artifacts.
You can use the API explorer SwaggerUI to interact with it: https://tgstation.github.io/tgs-api-doc-host/
@section api_intro Introduction
The TGS API is designed to be a fully realized RESTful service. Once hosted, follow the specified protocol for developing new clients or one off requests that provide full control over the server
Routes and their usages are defined as follows
[I (If Instance is required)] <`Http Method`> "<`Route`>" [Request Model] => <`Response Model`>
@section api_lib Official Libraries
The TGS API's canonical definitions are provided as a .NET Standard library in the form of a nuget package located here: https://www.nuget.org/packages/Tgstation.Server.Api
An all inclusive TAP interface for using the API is also provided in this package: https://www.nuget.org/packages/Tgstation.Server.Client
Last off, if anything in this API doesn't seem to hold true when tested against the server, please open an issue on the repository.
@subsection api_interp Interpreting C# Models
This document will reference the canonical C# models in the @ref Tgstation.Server.Api.Models namespace. Note that these models are built to mirror the JSON requests and responses with a couple caveats.
- The first letter of every field name will/must be lowercase in JSON models
- Fields marked 'Required' should be ignored, this is a semantic for the backing SQL database
- Id fields must be specified when making POST requests
- All other fields are optional and may be absent from responses or requests unless otherwise specified
- Request models can be found in @ref Tgstation.Server.Api.Models.Request. Response models can be found in @ref Tgstation.Server.Api.Models.Response.
@section api_header Headers
TGS expects this set of headers. Failure to provide them will result in 400 error responses
- User-Agent: The user agent product header value of the calling program
- Api: Another product header value representing the version of the API to use. Currently this must be: Tgstation.Server.Api/4.0.0.0
For POST, PATCH, and PUT requests you must also include the content type. Currently only json is supported
- Content-Type: application/json
For requests made to any Instance based API's a header with the Instance's ID must be provided
- Instance: The ID of the instance being accessed
An Authentication header is also required. See @ref api_auth
@section api_response Response Codes
TGS will only every return the response codes listed here
- 200: OK. The response body will contain a json model or array depending on the API called.
- 201: Created. Returned when the request created an entity, 202 trumps this
- 202: Accepted. Used when a response triggers a long running operation such as a @ref Tgstation.Server.Api.Models.Job or server restart
- 204: No Content. Identical to 200 with no response body.
- 400: Bad Request. The response body will contain an @ref Tgstation.Server.Api.Models.ErrorMessage model detailing the error
- 401: Unauthorized. Invalid or expired credentials were provided. Check rights APIs for updates. See @ref api_auth for details
- 403: Forbidden. User tried to make a request they were not allowed to perform.
- 404: Not found. A resource was requested that had never existed. In the case of retrieving a resource by ID, it could potentially exist in the future
- 406: Not Acceptable. Consequence of failing to provide an Accept header
- 408: Request Timeout. The client took to long to continue a request
- 409: Conflict. Documented in the requests that use them
- 410: Gone. Attempted to access/modify a resource that ideally should have been ready, but isn't or no longer is
- 422: Unprocessable Entity: Used specifically when an operation that requires a server restart is unable to be performed due to the @ref Tgstation.Server.Host.Watchdog not being present in the deployment. Should not happen with a proper server configuration. Response body contains an @ref Tgstation.Server.Api.Models.ErrorMessage
- 424: Failed Dependency: When a request that depends on an external API fails for a reason other than rate limiting. The response body will contain an @ref Tgstation.Server.Api.Models.ErrorMessage model detailing the error.
- 429: Rate limited. Used with operations that rely on GitHub.com. If a rate limit is hit for an operation this will be returned. Response will contain a Retry-After header with the amount of seconds to wait.
- 500: Server error. Please report the request and response body to the code repository
- 501: Not implemented. Functionality not available in the current server version
- 503: Service unavailable. The server is either starting up or shutting down and isn't ready to respond to requests. You can try again soon and a response/lack thereof will indicate which of the two events it was
@section api_ver Server Information
The versions of the TGS host can be retireved with this request.
Note: This endpoint does not require authentication
GET "/" => @ref Tgstation.Server.Api.Models.ServerInformation
The Version model fields are based on the C# one and looks like this:
@code{.json}
{
"version": "<major>.<minor>.<patch>.<revision>"
}
@endcode
Other fields may be present in the Version model but should be ignored. See a description of these version numbers <a href="https://github.com/tgstation/tgstation-server/blob/master/.github/CONTRIBUTING.md#versioning">here</a>.
@section api_auth Authentication
Every request made to TGS requires authentication. It is provided in the form of the Authorization header.
The first request made to TGS must be to login the user
POST "/" => @ref Tgstation.Server.Api.Models.Token
Headers:
- Authorization:Basic `<Base64 encoded credentials in the form username:password>`
If the provided credentials are valid and your user account is enabled you will recieve a @ref Tgstation.Server.Api.Models.Token object
@code{.json}
{
"bearer": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxIiwiZXhwIjoiMTUzMzIzNjk0MSIsIm5iZiI6IjE1MzMyMzYwNDEiLCJpc3MiOiJUZ3N0YXRpb24uU2VydmVyLkhvc3QiLCJhdWQiOiJUZ3N0YXRpb24uU2VydmVyLkFwaSJ9.QWFSWNi9mgol582zaK4MQ5XDK2gZF-Nx3z9_ToHjKW4"
}
@endcode
If your account is disabled, you will receive a 403 response.
You may recognize the bearer value as a <a href="https://jwt.io">Json Web Token</a>. This is a secure representation of your identity to the server. It expires after a set period of time or until your password changes. It must be present for requests made to all other APIs. To do so add the following header to your other requests
- Authorization:Bearer `<your bearer token>`
Continue to use this token until you begin to receive 401 responses from the API. Then repeat the process to get a new one if your credentials are still valid
@subsection api_auth_o OAuth 2.0
TGS supports OAuth 2.0 with select providers for authentication.
The flow for this is as follows:
- Retrieve the @ref api_ver to find out which @ref Tgstation.Server.Api.Models.OAuthProvider are enabled and their respective information.
- Send the user to the Authorization Request endpoint for the provider using the client ID from above. See https://tools.ietf.org/html/rfc6749#section-4.1.1. DO NOT specify a redirect URI, this should be configured in the provider.
- Retrieve the authorization response code after successfully completing the authorize step above.
- Perform the following request:
POST "/" => @ref Tgstation.Server.Api.Models.Token
Headers:
- Authorization:OAuth `OAuth Authorization Response Code`
- OAuthProvider:<Provider Name>
You will be granted a bearer token as in basic auth. This will have an extended expiration to avoid repeating the entire process.
@subsubsection api_auth_o_providers Supported Providers
- GitHub: https://developer.github.com/apps/building-oauth-apps/authorizing-oauth-apps
- Discord: https://discord.com/developers/docs/topics/oauth2
- TGForums: https://tgstation13.org/phpBB/viewtopic.php?f=45&t=30155
- Keycloak: https://plugins.miniorange.com/keycloak-single-sign-on-wordpress-sso-oauth-openid-connect
@section api_perms Permissions
Almost all actions available require some level of user permissions. Which are divided into two categories:
- General permissions apply to a user across the entire service
- Instance permissions apply only when interacting with a specific instance
Permissions are represented a a 32 bit integer in the form of bitflags. The two endpoints for retrieving these permission are:
GET "/Users" => @ref Tgstation.Server.Api.Models.User
I GET "/InstanceUser" => @ref Tgstation.Server.Api.Models.InstanceUser
See individual documentation of each permission enum for their usage
@section api_transfer File Transfers
Certain responses inherit from @ref Tgstation.Server.Api.Models.FileTicketResult. These are special in that, having that model's @ref Tgstation.Server.Api.Models.FileTicketResult.FileTicket field populated indicates there is a pending file download or upload to take place. These are handled in the "/Transfer" endpoint.
To perform a file download make the following request:
GET "/Transfer?ticket=<@ref Tgstation.Server.Api.Models.FileTicketResult.FileTicket>" => application/octet-stream
To perform a file upload make the following request:
PUT "/Transfer?ticket=<@ref Tgstation.Server.Api.Models.FileTicketResult.FileTicket>" application/octet-stream => OK
File tickets are only valid for a short time after the initial request is made and should be dealt with immediately. Ensure that the file tickets are properly URL encoded.
@section api_user User Management
TGS start with one user: "Admin". The password is "ISolemlySwearToDeleteTheDataDirectory"
There are two types of users that can be created: Database users and system users. Database users are your plain login/password style users. System users are based on either Windows or POSIX accounts depending on the host system. They cannot be created by TGS and have to be activated by adding them to the Database similarly to a normal user using the "SystemIdentifier" field which should generally be set to their username or DOMAIN\\Username in an active directory environment. These act the same as regular users with the only exception being @ref api_config. See that section for details.
New users can be created with the following method.
PUT "/User" @ref Tgstation.Server.Api.Models.UserUpdate => @ref Tgstation.Server.Api.Models.User
To create a regular user, populate the name and password fields. To create a system user populate the SystemIdentifier field. Users rights and enabled status can also be specified in this call. To change them later use this API.
POST "/User" @ref Tgstation.Server.Api.Models.UserUpdate => @ref Tgstation.Server.Api.Models.User
Passowords for database users may be changed as well using this call. The capitalization of the display name of a user may also be changed
@subsection api_iuser Instance User Management
Instance users must be created for a given instance before being manipulated. The creator of an instance starts with full permissions on it
I PUT "/InstanceUser" @ref Tgstation.Server.Api.Models.InstanceUser => @ref Tgstation.Server.Api.Models.InstanceUser
They can be updated with a similar POST
I POST "/InstanceUser" @ref Tgstation.Server.Api.Models.InstanceUser => @ref Tgstation.Server.Api.Models.InstanceUser
Unlike regular users, they can also be deleted, which prevents the user from discovering the instance
I DELETE "/InstanceUser/{UserId}" => OK
Users with the permission to modify @ref Tgstation.Server.Api.Models.Instance objects can also gain user editing rights for any Instance. See @ref api_instance
@section api_admin Server-wide Administrative Actions
You can retrieve server update information with this
GET "/Administration" => @ref Tgstation.Server.Api.Models.Administration
If you want to perform a live update of the server use
POST "/Administration" @ref Tgstation.Server.Api.Models.Administration => OK
With the @ref Tgstation.Server.Api.Models.Administration.NewVersion field set
Any DreamDaemon servers running will persist while the server installs the new version from the official tgstation-server GitHub (If it exists)
If the server is otherwise acting funky and you wish to restart it, use this request:
DELETE "/Administration" => OK
@section api_inst Instances
Instances are DreamDaemon server configurations, they live in their own directory on the disk somewhere you specify. TGS starts with no default instance, to create one use this request:
PUT "/Instance" @ref Tgstation.Server.Api.Models.Instance => @ref Tgstation.Server.Api.Models.Instance
This normally returns 201 BUT, in the case of attaching an existing instance, 200 will instead be returned
The user that creates an instance will be given full @ref Tgstation.Server.Api.Models.InstanceUser permission. The path must not exist at the time of creation. Support for attaching instances from backups is yet to come.
A specific Instance may be retrieved with:
GET "/Instances/{InstanceID}" => @ref Tgstation.Server.Api.Models.Instance
Instances start offline, regardless of what was specified during the create request. An offline instance will return 403 for all requests made to it.
To online or change other instance variables use the following request. Note that using this request (even with an empty object) will automatically give you the @ref Tgstation.Server.Api.Rights.InstanceUserRights.WriteUsers right for that instance if you don't have it
POST "/Instance" @ref Tgstation.Server.Api.Models.Instance => @ref Tgstation.Server.Api.Models.Instance
Note that onlining an offline instance will never automatically start DreamDaemon. That must be done as a seperate step.
Instances can be detached which will delete all meta knowledge of the instance (Compile metadata, job metadata, repository commit metadata, Test merge metadata, etc...) but leave the files intact. That can be done with this request:
DELETE "/Instance/{InstanceId}" => OK
@subsection api_job Jobs
Some requests return @ref Tgstation.Server.Api.Models.Job objects. These are long running tasks the server will perform asyncronously and can be polled for status.
Note that the job representing instance move operations must be queried and cancelled differently than others. See the documentation of @ref Tgstation.Server.Api.Models.Instance.MoveJob for details
To list all jobs in an Instance use the following request
I GET "/Job/List" => Array of @ref Tgstation.Server.Api.Models.Job
Note that the response for this request will only have the @ref Tgstation.Server.Api.Models.Job.Id field populated
To get full details of _active_ jobs use the following request:
I GET "/Job" => Array of @ref Tgstation.Server.Api.Models.Job
To get full details of a specific job use the following request:
I GET "/Job/{JobId}" => @ref Tgstation.Server.Api.Models.Job
To cancel a running job (If the job can be cancelled and you have sufficient rights) use the following request:
I DELETE "/Job/{JobId}" => OK
@subsection api_chat Chat Bots
Each chat bot is represented by a @ref Tgstation.Server.Api.Models.ChatBot object
Chat bots can be created/updated/deleted with the following requests respectively
I PUT "/Chat" @ref Tgstation.Server.Api.Models.ChatBot => Tgstation.Server.Api.Models.ChatBot
I POST "/Chat" @ref Tgstation.Server.Api.Models.ChatBot => Tgstation.Server.Api.Models.ChatBot
I DELETE "/Chat/{ChatBotId}" => OK
The @ref Tgstation.Server.Api.Models.Internal.ChatBot.ConnectionString must differ based on what kind of chat bot you wish to create. Each @ref Tgstation.Server.Api.Models.ChatProvider has a @ref Tgstation.Server.Api.Models.Internal.ChatConnectionStringBuilder that dictates how to form it
For IRC chat bots see @ref Tgstation.Server.Api.Models.IrcConnectionStringBuilder
For Discord chat bots see @ref Tgstation.Server.Api.Models.DiscordConnectionStringBuilder
A specific bot's settings may be retrieved with:
I GET "/Chat/{ChatBotId}" => @ref Tgstation.Server.Api.Models.ChatBot
Also note that if the @ref Tgstation.Server.Api.Models.ChatBot.Channels is present in a POST request, the list will fully replace any active channels
@subsection api_byond Byond Version Management
To get the Byond version used for new compilations use the following request:
I GET "/Byond" => @ref Tgstation.Server.Api.Models.Byond
To set the active Byond version:
I POST "/Byond" @ref Tgstation.Server.Api.Models.Byond => @ref Tgstation.Server.Api.Models.Byond
This will queue up a job to install the byond version if it doesn't exist which will be returned in the response. The @ref Tgstation.Server.Api.Models.Internal.RawData.Content field can be used to upload custom zip files.
To list all installed Byond versions use the following request:
I GET "/Byond/List" => Array of @ref Tgstation.Server.Api.Models.Byond
@subsection Git Repository Management
To read the current repository state use the following request:
I GET "/Repository" => @ref Tgstation.Server.Api.Models.Repository
To clone the repository if it doesn't yet exist use the following request:
I PUT "/Repository" => @ref Tgstation.Server.Api.Models.Repository
The clone job will be represented by the @ref Tgstation.Server.Api.Models.Repository.ActiveJob field. Specify the @ref Tgstation.Server.Api.Models.Repository.Origin URL. Optionally specify the initial @ref Tgstation.Server.Api.Models.Repository.Reference as a git tag or branch. Be sure to specify the authentication fields if necessary to access your repository. Will return 409 if the repository already exists or is already being cloned
To delete an existing repository make the following request:
I DELETE "/Repository" => OK
Modifications to the repository are done with the following request:
I POST "/Repository" => @ref Tgstation.Server.Api.Models.Repository => @ref Tgstation.Server.Api.Models.Repository
Each update that requires git changes creates a job specified in the @ref Tgstation.Server.Api.Models.Repository.ActiveJob field jobs will be queued in succession. See below for POST examples.
@subsubsection api_repopost Repository Commands for Git Aliases
All these actions are done with the POST method
git pull (Only if @ref Tgstation.Server.Api.Models.Repository.Reference is set):
@code{.json}
{
"updateFromOrigin": true
}
@endcode
git checkout <`commit sha`> (Unsets @ref Tgstation.Server.Api.Models.Repository.Reference):
@code{.json}
{
"checkoutSha": "<commit sha>"
}
@endcode
git checkout -f <`branch or tag`> && git clean -fxd (Sets @ref Tgstation.Server.Api.Models.Repository.Reference):
@code{.json}
{
"reference": "<branch or tag>"
}
@endcode
git fetch && git checkout -f branch && git clean -fxd && git reset --hard origin/branch (Sets @ref Tgstation.Server.Api.Models.Repository.Reference);
@code{.json}
{
"updateFromOrigin": true,
"reference": "branch"
}
@endcode
@subsubsection api_repotm Test Merging
Any of the above POST methods can be combined with the @ref Tgstation.Server.Api.Models.Repository.NewTestMerges field to add test merges on top of the checked out commit.
@code{.json}
{
"newTestMerges": [
{
"number": 12345,
"comment": "I'm merging this for x reason"
},
{
"number": 12346,
"pullRequestRevision": "abcdef1"
}
]
}
@endcode
If the server detects a set of @ref Tgstation.Server.Api.Models.TestMergeParameters being applied that it has seen before, it'll instead attempt to checkout the commit that was created then.
@subsubsection api_repounsetauth Unsetting Authentication
The repository uses the @ref Tgstation.Server.Api.Models.Repository.AccessUser and @ref Tgstation.Server.Api.Models.Repository.AccessToken credentials to access the remote repository if these fields are set. To unset them you must set both of them to an empty string like so
@code{.json}
{
"accessUser": "",
"accessToken": ""
}
@endcode
This will remove both fields from the database
@subsection api_dm Compiler Handling
The DM compiler can run one job at a time for an Instance. Instead of using standard @ref Tgstation.Server.Api.Models.Job.Progress it uses the @ref Tgstation.Server.Api.Models.DreamMaker.Status field to denote it's current stage. It can be retrieved like this:
I GET "/DreamMaker" => @ref Tgstation.Server.Api.Models.DreamMaker
This will also return the last successful @ref Tgstation.Server.Api.Models.CompileJob as well as the @ref Tgstation.Server.Api.Models.Internal.DreamMakerSettings.ProjectName
The ProjectName field can be changed with this method:
I POST "/DreamMaker" @ref Tgstation.Server.Api.Models.DreamMaker => @ref Tgstation.Server.Api.Models.DreamMaker
To start a compile job use the following request:
I PUT "/DreamMaker" Empty => @ref Tgstation.Server.Api.Models.Job
The job object returned represents the compile job
"Empty" refers to an empty json object like so:
@code{.json}
{}
@endcode
The compiler endpoint is also used to read compile jobs
To list successful compile jobs ids use:
I GET "/DreamMaker/List" => Array of @ref Tgstation.Server.Api.Models.CompileJob
To get a specific compile job use:
I GET "/DreamMaker/{CompileJobId}" => @ref Tgstation.Server.Api.Models.CompileJob
@subsection api_config Static Files
Static files can be both read and written.
To get the contents of a static file directory use the following method
I GET "/Config/List/<path to directory>" => Array of @ref Tgstation.Server.Api.Models.ConfigurationFile
Where the path is formatted as: directory/inner_directory/more_directories
If the path is empty, the root directory will be retrieved. The @ref Tgstation.Server.Api.Models.ConfigurationFile.Content and @ref Tgstation.Server.Api.Models.ConfigurationFile.LastReadHash fields will not be populated for this response
If you do not have access to list the requested directory, a 403 response will be returned. If the path actually represents a file or the directory no longer exists a 410 response will be returned.
To create an empty config directory use the following request
I PUT "/Config" @ref Tgstation.Server.Api.Models.ConfigurationFile => @ref Tgstation.Server.Api.Models.ConfigurationFile
To get the content of a static file use the following method
I GET "/Config/File/<path to file>" => @ref Tgstation.Server.Api.Models.ConfigurationFile
410 will be returned if the path doesn't exist. @ref Tgstation.Server.Api.Models.ConfigurationFile.Content will only be populated if the path is a file the user has access to, otherwise the other fields will be populated appropriately.
To create, write, and delete files use the following request
I POST "/Config" @ref Tgstation.Server.Api.Models.ConfigurationFile => @ref Tgstation.Server.Api.Models.ConfigurationFile
When creating a file, only @ref Tgstation.Server.Api.Models.ConfigurationFile.Path and @ref Tgstation.Server.Api.Models.ConfigurationFile.Content should be specified
If the file already exists, the @ref Tgstation.Server.Api.Models.ConfigurationFile.LastReadHash field must also be present with the last version received from the server for that file. If this does not match at the time of the request, 409 will be returned, indicating the file has changed since it was last viewed by the client.
To delete a file set @ref Tgstation.Server.Api.Models.ConfigurationFile.Content to null in the request.
To delete an empty directory use the following request
I DELETE "/Config" @ref Tgstation.Server.Api.Models.ConfigurationFile => OK
Where the request @ref Tgstation.Server.Api.Models.ConfigurationFile.Path is set to the directory to delete
@subsection api_dog Watchdog
To read watchdog status use the following request:
I GET "/DreamDaemon" => @ref Tgstation.Server.Api.Models.DreamDaemon
To update watchdog settings use the following request:
I POST "/DreamDaemon" => @ref Tgstation.Server.Api.Models.DreamDaemon
Note that soft restart/shutdown operations cannot be cancelled via this method, they can be changed from one to another however.
To start the watchdog use the following request:
I PUT "/DreamDaemon" Empty => @ref Tgstation.Server.Api.Models.Job
To restart the watchdog use the following request:
I PATCH "/DreamDaemon" Empty => @ref Tgstation.Server.Api.Models.Job
The returned jobs represents the startup process for the watchdog
To stop the watchdog use the following request:
I DELETE "/DreamDaemon" => OK
*/