kbin's API is coming soon! I've finished up all of the endpoints required for a useful API, so it will enter review soon! The PR is here
This will allow apps like @artemisapp to interact more effectively with kbin!
#kbinMeta

WIP: Add REST API and OAuth2 Server
**This PR is being split to make reviews easier**
* #815
* #817
* #883
* #950
* more on their way...
I've started working on a basic REST API for kbin and I wanted to put it out there for feedback - there are still lots of items to implement and designs to discuss.
This likely should be split into several issues / a milestone rather than just being a single pull request
### OAuth
API requests which access restricted data or modify state must be authenticated by Bearer token, retrieved via OAuth2 `authorization_code` or `client_credentials` flow:
#### authorization_code
1. Client makes a request to `GET /authorize?response_type=code&client_id={{oauth_client_id}}&redirect_uri={{uri}}&scope={{scopes}}&state={{oauth_state}}`
2. User is directed to login if not already logged in.
3. Once logged in, user is directed to the consent page that explains what permissions the app is asking for.
4. Permission is checked:
- If the user denies the app permission, the user will be redirected to the given redirect URI (if it is one of the URIs your client was initially created with) with an error message explaining that the user denied the request.
- If the user permits the app to use those permissions, the user will be redirected with the following request:
- `GET {{uri}}/?code={{code}}&state={{oauth_state}}`
5. The client will need to verify the state is correct, then use the code to make a form-data POST request to retrieve the token:
```
POST /token
grant_type=authorization_code
client_id={{oauth_client_id}}
client_secret={{oauth_client_secret}}
code={{code}}
redirect_uri={{uri}}
```
6. The server will verify the information and return json with the following data:
```
{
"token_type": "Bearer",
"expires_in": 3600,
"access_token": "{{token}}",
"refresh_token": "{{refresh_token}}"
}
```
7. The client can save the access token and use it to authenticate against the API to enjoy a higher rate limit and write/moderate/admin permissions depending on grants requested and user permissions available.
8. When the access token expires, the client may use the refresh token to perform a refresh_token grant_type to avoid making the user log back in.
#### client_credentials
1. The client will use its id and secret to make a form-data POST request to retrieve a token authorizing it to use a bot account created when the client was created.
```
POST /token
grant_type=client_credentials
client_id={{oauth_client_id}}
client_secret={{oauth_client_secret}}
scope=scope1 scope2 scope3 (etc...)
```
2. The server will verify the information and return json with the following data:
```
{
"token_type": "Bearer",
"expires_in": 3600,
"access_token": "{{token}}"
}
```
3. The client can save the token and use it to access the API as a user distinguished as a bot account.
### Todo List:
- [ ] Add general usage APIs
- [ ] Entries/Thread API
- [x] OpenAPI specification
- [ ] API test cases
- [x] Rate limiting
- [x] Retrieve entries by id
- [x] Retrieve a list of entries from the instance
- [x] Filterable by language(s)
- [x] Create an entry in a specific magazine
- [x] Upload images with entries
- [x] Update single entry by id
- [x] Delete entry by id
- [x] Upvote entry
- [x] Downvote entry
- [x] Boost entry
- [x] Report entry
- [x] Retrieve a list of entries from a specific magazine
- [x] Filterable by language(s)
- [x] Filterable by preferred languages
- [x] Retrieve a list of entries from subscribed magazines
- [x] Retrieve a list of entries from moderated magazines
- [ ] Entry Comments API
- [x] OpenAPI specification
- [ ] API test cases
- [x] Rate limiting
- [x] Retrieve comments of an entry
- [x] Filterable by language(s)
- [x] Filterable by preferred languages
- [x] Add a comment to an entry
- [x] Add a comment reply to another comment
- [x] Upload images with comments
- [x] Retrieve a comment by id
- [x] Update comment by id
- [x] Delete comment by id
- [x] Upvote comment (Favourite)
- [x] Downvote comment
- [x] Boost comment
- [x] Report comment
- [ ] Posts/Microblog API
- [x] OpenAPI specification
- [ ] API test cases
- [x] Rate limiting
- [x] Create post
- [x] Upload images with posts
- [x] Retrieve post by id
- [x] Retrieve posts from magazine
- [x] Filterable by language(s)
- [x] Filterable by preferred languages
- [x] Update post by id
- [x] Delete post by id
- [x] Boost post
- [x] Favourite post
- [x] Report post
- [ ] Post Comments API
- [x] OpenApi specification
- [ ] API test cases
- [x] Rate limiting
- [x] Create comment on post
- [x] Create comment as reply
- [x] Upload images with comments
- [x] Retrieve post comment by id
- [x] Retrieve comments from a post
- [x] Filterable by language(s)
- [x] Filterable by preferred languages
- [x] Update post comment by id
- [x] Delete post comment by id
- [x] Boost post comment
- [x] Favourite post comment
- [x] Report post comment
- [ ] Magazine API
- [x] OpenAPI specification
- [ ] API test cases
- [x] Rate limiting
- [x] Retrieve details about a magazine (title, rules, description, isAdult, moderators, tags, badges, etc)
- [x] By name as well
- [x] Retrieve list of magazines
- [x] Retrieve list of user's subscribed magazines
- [x] Retrieve list of user's moderated magazines
- [x] Retrieve list of user's blocked magazines
- [x] Subscribe to magazine
- [x] Unsubscribe from magazine
- [x] Block magazine
- [x] Unblock magazine
- [x] Retrieve Mod Log
- [ ] User API
- [x] OpenAPI specification
- [ ] API test cases
- [x] Rate limiting
- [x] Retrieve user details
- [x] Follow user
- [x] Unfollow user
- [x] Retrieve users following a user
- [x] Retrieve users followed by a user (if visible)
- [x] Retrieve user's subscribed magazines
- [x] Retrieve user's subscribed domains
- [x] Block user
- [x] Unblock user
- [x] Retrieve current user's blocked users
- [x] Edit current user's profile
- [x] Edit current user's settings
- [ ] Message API
- [x] OpenAPI specification
- [ ] API test cases
- [x] Rate limiting
- [x] Retrieve incoming messages
- [x] Mark messages as read
- [x] Mark messages as not read
- [x] Message user
- [x] Reply to message thread
- [ ] Notification API
- [x] OpenAPI specification
- [ ] API test cases
- [x] Rate limiting
- [x] Retrieve incoming notifications
- [x] Retrieve a count of unread notifications
- [x] Mark a notification as read
- [x] Mark a notification as not read
- [x] Mark all notifications as read
- [x] Delete a notification
- [x] Delete all notifications
- [ ] Domain API
- [x] OpenAPI specification
- [ ] API test cases
- [x] Rate limiting
- [x] Retrieve domain details
- [x] Retrieve entries from domain
- [x] Filterable by language(s)
- [x] Filterable by preferred languages
- [x] Retrieve entry comments from domain
- [x] Filterable by language(s)
- [x] Filterable by preferred languages
- [x] Subscribe to domain
- [x] Unsubscribe from domain
- [x] Block domain
- [x] Unblock domain
- [ ] Instance API
- [x] OpenAPI specification
- [ ] API test cases
- [x] Retrieve instance About text
- [x] Retrieve instance FAQ text
- [x] Retrieve instance Contact text
- [x] Retrieve instance Terms of Service text
- [x] Retrieve instance Privacy policy text
- [x] Retrieve global mod log
- [ ] Add moderation APIs
- [x] OpenAPI specification
- [ ] API test cases
- [x] Mark threads as adult
- [x] Mark comments as adult
- [x] Mark posts as adult
- [x] Mark post comments as adult
- [x] Pin threads
- [x] Trash threads
- [x] Restore threads
- [x] Trash comments
- [x] Restore comments
- [x] Trash posts
- [x] Restore posts
- [x] Trash post comments
- [x] Restore post comments
- [x] Ban user from magazine
- [x] Change language tag of threads
- [x] Change language tag of comments
- [x] Change language tag of posts
- [x] Change language tag of post comments
- [ ] Add magazine admin APIs
- [x] OpenAPI specification
- [ ] API test cases
- [x] Create magazine
- [x] Update magazine
- [x] (Soft) Delete magazine
- [x] Purge Entry
- [x] Retrieve reports
- [x] Reject reports
- [x] Accept reports
* I think reports should be accessible to all mods, not just the magazine creator
- [x] Add moderator(s)
- [x] Remove moderator(s)
- [x] Create badge(s)
- [x] Delete badge(s)
* How do these actually work? Are these meant to be like flair on reddit?
- [x] Add tag(s)
- [x] Remove tag(s)
- [x] Retrieve list of banned users
- [x] Remove user from ban list
- [x] Retrieve list of trashed entries
* Also should be available to any mod
- [x] Retrieve appearance settings
- [x] Update appearance settings
- [x] Retrieve magazine statistics
- [ ] Admin APIs
- [x] OpenAPI specification
- [ ] API test cases
- [x] Move entry to another magazine
- [x] Ban/unban user from instance
- [x] Retrieve a list of banned users
- [x] Delete user from instance
- [x] Purge user from instance
- [x] Purge threads/posts/comments
- [x] Verify user on instance
- [x] Retrieve instance stats
- [x] Retrieve instance settings
- [x] Update instance settings
- [x] Update instance About text
- [x] Update instance FAQ text
- [x] Update instance Contact text
- [x] Update instance Terms of Service text
- [x] Update instance Privacy policy text
- [x] Retrieve list of defederated instances
- [x] Defederate instance
- [x] Refederate instance
- [x] Retrieve oauth2 clients
- [x] Retrieve oauth2 client usage stats
- [x] Revoke oauth2 client keys
- [ ] Instance Admin Configs
- [x] Configurable rate limiting
- [x] View API usage data
- [ ] Authentication/Authorization pass
- [x] OpenAPI specification
- [x] API test cases
- [x] Implement OAuth2 server for 3rd party application user auth
- [x] Add a user consent page informing the user what permissions the app is requesting
- [x] Add the minimum page needed to accept
- [x] Add information about what roles grant what permissions in a decent manner
- [x] Add translatable messages for the page's text and role grants
- [x] Add optional client logo to consent page
- [ ] Maybe? make it look nice (I am not a UI designer so I'll probably leave this for a future PR by someone else)
- [x] Add API to create an API client - similar to Mastodon's [here](https://docs.joinmastodon.org/spec/oauth/)
- [x] Add API to view oauth consents given to (an) app(s)
- [x] Add API to revoke oauth consent from an app
- [ ] Add page to revoke oauth consent from an app
- [x] Add appropriate roles to existing APIs
- [x] Flesh out what roles need to be separated and break them down by permissions
- [x] Enable heavily rate limited anonymous read access to the API - should be enough for normal human usage of the API, but anything heavier should prefer a token
Let me know what you think should be added/changed/improved about this list and about the code I've currently got - I'm learning PHP with this project so I expect there to be lots of improvements to be made
Codeberg.org