[feature] Application creation + management via API + settings panel (#3906)

* [feature] Application creation + management via API + settings panel

* fix docs links

* add errnorows test

* use known application as shorter

* add comment about side effects
This commit is contained in:
tobi
2025-03-17 15:06:17 +01:00
committed by GitHub
parent d3c3d34aae
commit d5847e2d2b
61 changed files with 3036 additions and 252 deletions

View File

@@ -2,6 +2,9 @@
Using the client API requires authentication. This page documents the general flow for retrieving an authentication token with examples for doing this on the CLI using `curl`.
!!! tip
If you want to get an API access token via the settings panel instead, without having to use the command line, see the [Application documentation](https://docs.gotosocial.org/en/latest/user_guide/settings/#applications).
## Create a new application
We need to register a new application, which we can then use to request an OAuth token. This is done by making a `POST` request to the `/api/v1/apps` endpoint. Replace `your_app_name` in the command below with the name you want to use for your application:
@@ -19,18 +22,15 @@ curl \
The string `urn:ietf:wg:oauth:2.0:oob` is an indication of what is known as out-of-band authentication - a technique used in multi-factor authentication to reduce the number of ways that a bad actor can intrude on the authentication process. In this instance, it allows us to view and manually copy the tokens created to use further in this process.
Note that `scopes` can be any space-separated combination of:
- `read`
- `write`
- `admin`
!!! tip "Scopes"
It is always good practice to grant your application the lowest tier permissions it needs to do its job. e.g. If your application won't be making posts, use `scope=read` or even a subscope of that.
In this spirit, "read" is used in the example above, which means that the application will be restricted to only being able to do "read" actions.
For a list of available scopes, see [the swagger docs](https://docs.gotosocial.org/en/latest/api/swagger/).
!!! warning
GoToSocial does not currently support scoped authorization tokens, so any token you obtain in this process will be able to perform all actions on your behalf, including admin actions if your account has admin permissions. Nevertheless, it is always good practice to grant your application the lowest tier permissions it needs to do its job. e.g. If your application won't be making posts, use scope=read.
In this spirit, "read" is used in the example above, which means that in the future when scoped tokens are supported, the application will be restricted to only being able to do "read" actions.
You can read more about additional planned OAuth security features [right here](https://github.com/superseriousbusiness/gotosocial/issues/2232).
GoToSocial did not support scoped authorization tokens before version 0.19.0, so if you are using a version of GoToSocial below that, then any token you obtain in this process will be able to perform all actions on your behalf, including admin actions if your account has admin permissions.
A successful call returns a response with a `client_id` and `client_secret`, which we are going need to use in the rest of the process. It looks something like this:
@@ -126,7 +126,6 @@ See this example:
```bash
curl \
-H 'Content-Type: application/json' \
-H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \
'https://example.org/api/v1/accounts/verify_credentials'
```
@@ -140,7 +139,6 @@ For example, you can issue another `GET` request to the API using the same acces
```bash
curl \
-H 'Content-Type: application/json' \
-H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \
'https://example.org/api/v1/notifications'
```

View File

@@ -828,6 +828,11 @@ definitions:
description: Client secret associated with this application.
type: string
x-go-name: ClientSecret
created_at:
description: When the application was created. (ISO 8601 Datetime)
example: "2021-07-30T09:20:25+00:00"
type: string
x-go-name: CreatedAt
id:
description: The ID of the application.
example: 01FBVD42CQ3ZEEVMW180SBX03B
@@ -3649,6 +3654,54 @@ info:
contact:
email: admin@gotosocial.org
name: GoToSocial Authors
description: |-
This document describes the GoToSocial HTTP API.
For information on how to authenticate with the API using an OAuth access token, see the documentation here: https://docs.gotosocial.org/en/latest/api/authentication/.
Available scopes are:
admin: grants admin access to everything
admin:read: grants admin read access to everything
admin:read:accounts: grants admin read access to accounts
admin:read:domain_allows: grants admin read access to domain_allows
admin:read:domain_blocks: grants admin read access to domain_blocks
admin:read:reports: grants admin read access to reports
admin:write: grants admin write access to everything
admin:write:accounts: grants write read access to accounts
admin:write:domain_allows: grants admin write access to domain_allows
admin:write:domain_blocks: grants write read access to domain_blocks
admin:write:reports: grants admin write access to reports
profile: grants read access to verify_credentials
push: grants read/write access to push
read: grants read access to everything
read:accounts: grants read access to accounts
read:applications: grants read access to user-managed applications
read:blocks: grants read access to blocks
read:bookmarks: grants read access to bookmarks
read:favourites: grants read access to accounts
read:filters: grants read access to filters
read:follows: grants read access to follows
read:lists: grants read access to lists
read:mutes: grants read access to mutes
read:notifications: grants read access to notifications
read:search: grants read access to search
read:statuses: grants read access to statuses
write: grants write access to everything
write:accounts: grants write access to accounts
write:applications: grants write access to user-managed applications
write:blocks: grants write access to blocks
write:bookmarks: grants write access to bookmarks
write:conversations: grants write access to conversations
write:favourites: grants write access to favourites
write:filters: grants write access to filters
write:follows: grants write access to follows
write:lists: grants write access to lists
write:media: grants write access to media
write:mutes: grants write access to mutes
write:notifications: grants write access to notifications
write:reports: grants write access to reports
write:statuses: grants write access to statuses
license:
name: AGPL3
url: https://www.gnu.org/licenses/agpl-3.0.en.html
@@ -7484,6 +7537,63 @@ paths:
tags:
- announcements
/api/v1/apps:
get:
description: |-
The next and previous queries can be parsed from the returned Link header.
Example:
```
<https://example.org/api/v1/apps?limit=80&max_id=01FC0SKA48HNSVR6YKZCQGS2V8>; rel="next", <https://example.org/api/v1/apps?limit=80&min_id=01FC0SKW5JK2Q4EVAV2B462YY0>; rel="prev"
````
operationId: appsGet
parameters:
- description: Return only items *OLDER* than the given max item ID. The item with the specified ID will not be included in the response.
in: query
name: max_id
type: string
- description: Return only items *newer* than the given since item ID. The item with the specified ID will not be included in the response.
in: query
name: since_id
type: string
- description: Return only items *immediately newer* than the given since item ID. The item with the specified ID will not be included in the response.
in: query
name: min_id
type: string
- default: 20
description: Number of items to return.
in: query
name: limit
type: integer
produces:
- application/json
responses:
"200":
description: ""
headers:
Link:
description: Links to the next and previous queries.
type: string
schema:
items:
$ref: '#/definitions/application'
type: array
"400":
description: bad request
"401":
description: unauthorized
"404":
description: not found
"406":
description: not acceptable
"500":
description: internal server error
security:
- OAuth2 Bearer:
- read:applications
summary: Get an array of applications that are managed by the requester.
tags:
- apps
post:
consumes:
- application/json
@@ -7493,8 +7603,10 @@ paths:
The registered application can be used to obtain an application token.
This can then be used to register a new account, or (through user auth) obtain an access token.
The parameters can also be given in the body of the request, as JSON, if the content-type is set to 'application/json'.
The parameters can also be given in the body of the request, as XML, if the content-type is set to 'application/xml'.
If the application was registered with a Bearer token passed in the Authorization header, the created application will be managed by the authenticated user (must have scope write:applications).
Parameters can also be given in the body of the request, as JSON, if the content-type is set to 'application/json'.
Parameters can also be given in the body of the request, as XML, if the content-type is set to 'application/xml'.
operationId: appCreate
parameters:
- description: The name of the application.
@@ -7548,6 +7660,69 @@ paths:
summary: Register a new application on this instance.
tags:
- apps
/api/v1/apps/{id}:
delete:
operationId: appDelete
parameters:
- description: The id of the application to delete.
in: path
name: id
required: true
type: string
produces:
- application/json
responses:
"200":
description: The deleted application.
schema:
$ref: '#/definitions/application'
"400":
description: bad request
"401":
description: unauthorized
"404":
description: not found
"406":
description: not acceptable
"500":
description: internal server error
security:
- OAuth2 Bearer:
- write:applications
summary: Delete a single application managed by the requester.
tags:
- apps
get:
operationId: appGet
parameters:
- description: The id of the requested application.
in: path
name: id
required: true
type: string
produces:
- application/json
responses:
"200":
description: The requested application.
schema:
$ref: '#/definitions/application'
"400":
description: bad request
"401":
description: unauthorized
"404":
description: not found
"406":
description: not acceptable
"500":
description: internal server error
security:
- OAuth2 Bearer:
- read:applications
summary: Get a single application managed by the requester.
tags:
- apps
/api/v1/blocks:
get:
description: |-
@@ -11705,15 +11880,15 @@ paths:
````
operationId: tokensInfoGet
parameters:
- description: Return only items *OLDER* than the given max status ID. The item with the specified ID will not be included in the response.
- description: Return only items *OLDER* than the given max item ID. The item with the specified ID will not be included in the response.
in: query
name: max_id
type: string
- description: Return only items *newer* than the given since status ID. The item with the specified ID will not be included in the response.
- description: Return only items *newer* than the given since item ID. The item with the specified ID will not be included in the response.
in: query
name: since_id
type: string
- description: Return only items *immediately newer* than the given since status ID. The item with the specified ID will not be included in the response.
- description: Return only items *immediately newer* than the given since item ID. The item with the specified ID will not be included in the response.
in: query
name: min_id
type: string
@@ -12927,6 +13102,7 @@ securityDefinitions:
push: grants read/write access to push
read: grants read access to everything
read:accounts: grants read access to accounts
read:applications: grants read access to user-managed applications
read:blocks: grants read access to blocks
read:bookmarks: grants read access to bookmarks
read:favourites: grants read access to accounts
@@ -12939,6 +13115,7 @@ securityDefinitions:
read:statuses: grants read access to statuses
write: grants write access to everything
write:accounts: grants write access to accounts
write:applications: grants write access to user-managed applications
write:blocks: grants write access to blocks
write:bookmarks: grants write access to bookmarks
write:conversations: grants write access to conversations

Binary file not shown.

After

Width:  |  Height:  |  Size: 245 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 161 KiB

View File

@@ -17,6 +17,56 @@
// GoToSocial Swagger documentation.
//
// This document describes the GoToSocial HTTP API.
//
// For information on how to authenticate with the API using an OAuth access token, see the documentation here: https://docs.gotosocial.org/en/latest/api/authentication/.
//
// Available scopes are:
//
// - admin: grants admin access to everything
// - admin:read: grants admin read access to everything
// - admin:read:accounts: grants admin read access to accounts
// - admin:read:domain_allows: grants admin read access to domain_allows
// - admin:read:domain_blocks: grants admin read access to domain_blocks
// - admin:read:reports: grants admin read access to reports
// - admin:write: grants admin write access to everything
// - admin:write:accounts: grants write read access to accounts
// - admin:write:domain_allows: grants admin write access to domain_allows
// - admin:write:domain_blocks: grants write read access to domain_blocks
// - admin:write:reports: grants admin write access to reports
// - profile: grants read access to verify_credentials
// - push: grants read/write access to push
// - read: grants read access to everything
// - read:accounts: grants read access to accounts
// - read:applications: grants read access to user-managed applications
// - read:blocks: grants read access to blocks
// - read:bookmarks: grants read access to bookmarks
// - read:favourites: grants read access to accounts
// - read:filters: grants read access to filters
// - read:follows: grants read access to follows
// - read:lists: grants read access to lists
// - read:mutes: grants read access to mutes
// - read:notifications: grants read access to notifications
// - read:search: grants read access to search
// - read:statuses: grants read access to statuses
// - write: grants write access to everything
// - write:accounts: grants write access to accounts
// - write:applications: grants write access to user-managed applications
// - write:blocks: grants write access to blocks
// - write:bookmarks: grants write access to bookmarks
// - write:conversations: grants write access to conversations
// - write:favourites: grants write access to favourites
// - write:filters: grants write access to filters
// - write:follows: grants write access to follows
// - write:lists: grants write access to lists
// - write:media: grants write access to media
// - write:mutes: grants write access to mutes
// - write:notifications: grants write access to notifications
// - write:reports: grants write access to reports
// - write:statuses: grants write access to statuses
//
// ---
//
// Schemes: https, http
// BasePath: /
// Version: REPLACE_ME
@@ -31,45 +81,47 @@
// authorizationUrl: https://example.org/oauth/authorize
// tokenUrl: https://example.org/oauth/token
// scopes:
// read: grants read access to everything
// write: grants write access to everything
// push: grants read/write access to push
// profile: grants read access to verify_credentials
// read:accounts: grants read access to accounts
// write:accounts: grants write access to accounts
// read:blocks: grants read access to blocks
// write:blocks: grants write access to blocks
// read:bookmarks: grants read access to bookmarks
// write:bookmarks: grants write access to bookmarks
// write:conversations: grants write access to conversations
// read:favourites: grants read access to accounts
// write:favourites: grants write access to favourites
// read:filters: grants read access to filters
// write:filters: grants write access to filters
// read:follows: grants read access to follows
// write:follows: grants write access to follows
// read:lists: grants read access to lists
// write:lists: grants write access to lists
// write:media: grants write access to media
// read:mutes: grants read access to mutes
// write:mutes: grants write access to mutes
// read:notifications: grants read access to notifications
// write:notifications: grants write access to notifications
// write:reports: grants write access to reports
// read:search: grants read access to search
// read:statuses: grants read access to statuses
// write:statuses: grants write access to statuses
// admin: grants admin access to everything
// admin:read: grants admin read access to everything
// admin:write: grants admin write access to everything
// admin:read:accounts: grants admin read access to accounts
// admin:write:accounts: grants write read access to accounts
// admin:read:reports: grants admin read access to reports
// admin:write:reports: grants admin write access to reports
// admin:read:domain_allows: grants admin read access to domain_allows
// admin:write:domain_allows: grants admin write access to domain_allows
// admin:read:domain_blocks: grants admin read access to domain_blocks
// admin:read:reports: grants admin read access to reports
// admin:write: grants admin write access to everything
// admin:write:accounts: grants write read access to accounts
// admin:write:domain_allows: grants admin write access to domain_allows
// admin:write:domain_blocks: grants write read access to domain_blocks
// admin:write:reports: grants admin write access to reports
// profile: grants read access to verify_credentials
// push: grants read/write access to push
// read: grants read access to everything
// read:accounts: grants read access to accounts
// read:applications: grants read access to user-managed applications
// read:blocks: grants read access to blocks
// read:bookmarks: grants read access to bookmarks
// read:favourites: grants read access to accounts
// read:filters: grants read access to filters
// read:follows: grants read access to follows
// read:lists: grants read access to lists
// read:mutes: grants read access to mutes
// read:notifications: grants read access to notifications
// read:search: grants read access to search
// read:statuses: grants read access to statuses
// write: grants write access to everything
// write:accounts: grants write access to accounts
// write:applications: grants write access to user-managed applications
// write:blocks: grants write access to blocks
// write:bookmarks: grants write access to bookmarks
// write:conversations: grants write access to conversations
// write:favourites: grants write access to favourites
// write:filters: grants write access to filters
// write:follows: grants write access to follows
// write:lists: grants write access to lists
// write:media: grants write access to media
// write:mutes: grants write access to mutes
// write:notifications: grants write access to notifications
// write:reports: grants write access to reports
// write:statuses: grants write access to statuses
// OAuth2 Application:
// type: oauth2
// flow: application

View File

@@ -287,3 +287,70 @@ Logging out of an application does not necessarily remove the token from the GoT
!!! note
Token "Last used" time is approximate and may be off by an hour in either direction.
## Applications
In the applications section, you can create a new managed OAuth client application, and search through applications that you've created.
### What is an OAuth client application?
A GoToSocial OAuth client application is equivalent to an OAuth 2.0 client as described in [the Auth0 roles docs](https://auth0.com/intro-to-iam/what-is-oauth-2#oauth20-roles).
When you create an application, you can then, as the "Resource Owner" of your account, give the application access to your account via an access token, which the application can use to interact with the GoToSocial client API "as you", or "on your behalf".
For example, when you log in to your GoToSocial account using Tusky, Tusky first registers itself with your instance as an OAuth client application, and then requests the instance to redirect you to a page where you can sign in with your GoToSocial email address and password in order to authorize Tusky to get an access code. Tusky then stores and uses that access code in all further requests, to do what you tell it to do: post statuses, read timelines, etc.
The advantage of OAuth client applications is that they never store (or even see) your password: they only ever act as you using their access token, which can be invalidated so that the application cannot access your account anymore, without you having to change your password (see [Access Tokens](#access-tokens)).
!!! note "Managed vs unmanaged applications"
A *managed* application is one that you created yourself via the settings panel, and have the ability to request tokens for, and delete. This differs somewhat from applications like Tusky, which are not considered to be *managed* applications, as they were not created by a user in the settings panel.
### What is a redirect URI?
Redirect URIs offer a security measure that prevents applications from being to redirect to malicious addresses after authorization. This is best explained in the OAuth 2.0 documentation, see:
- [Redirect URIs](https://www.oauth.com/oauth2-servers/redirect-uris/)
- [Redirect URL Registration](https://www.oauth.com/oauth2-servers/redirect-uris/redirect-uri-registration/)
Whatever service you are trying to create an application for will usually tell you what redirect URI(s) you need to enter when creating an application.
### What is a scope?
Scopes are a space-separated list of identifiers that can be specified when creating an application (or getting a token for that application) in order to prevent the application or its access token from accessing more data than it needs to do its job.
For example, if you create an application with only scope `read`, then any tokens owned by that application will have only `read` access to your account: they will not be able to post, delete, or take other *write*-type actions as you.
GoToSocial offers a range of scopes very similar to what the Mastodon API offers. You can see a list of scopes (and what they do) here: https://docs.gotosocial.org/en/latest/api/swagger/.
Like Mastodon, GoToSocial allows you to specify scopes both when you create an application, *and* when you subsequently request a token. So you could create an application with scope `read write`, but request a token with only `read` scope, or with an even narrower scope like `read:accounts`. Any scopes specified when requesting a token must be covered by the scopes permitted to the application. For example, you cannot request a token with scope `write` if your application only has scope `read`.
For more information on scopes in general, see the OAuth 2.0 docs:
- [Scope](https://www.oauth.com/oauth2-servers/scope/)
- [Defining Scopes](https://www.oauth.com/oauth2-servers/scope/defining-scopes/)
### Search Applications
Using this section, you can see an overview of applications that you've created via the settings panel, and click on an application to go to the details view for that application.
### New Application
![The new application form.](../public/user-settings-applications-new.png)
To create a new managed OAuth application, you must provide at least a name for your application. If you want, you can provide a website too.
If you don't provide any scopes, then the application will have scope `read` by default.
If you don't specify any redirect URIs, then the application will have the out-of-band redirect URI `urn:ietf:wg:oauth:2.0:oob` by default.
If you want to be able to use the settings panel to easily get an access token for the application that you create, then you must include the given settings panel callback URL in your redirect URIs list. This will be in the form `https://[your_instance_host]/settings/user/applications/callback`.
### Application Details
![The details view for an application.](../public/user-settings-applications-details.png)
On the details page for an application, you can view the application's client ID and client secret, which you can use in a command-line tool like `curl` to manually get an authorization code + access token for the application.
If you included the settings panel callback URL in your redirect URIs list, you can also use this page to request an access token for your account. This will redirect you to the sign in page for your instance, where you must provide your credentials in order to authorize your application. You will then be redirected again to the settings panel callback URL, where you can receive your access token.
You can also use this page to delete your application. When a managed application is deleted, all tokens that were created via that application will also be deleted, so ensure you only do this when your application is not being used.