Tasks, spelling mistakes and API docs

- Configured VSCode tasks.

- Fixed some grammar mistakes.

- Added OpenAPI documentation.
This commit is contained in:
zervo 2024-08-11 00:23:15 +02:00 committed by zervo
parent f911506891
commit 751c841fa2
8 changed files with 962 additions and 7 deletions

2
.vscode/launch.json vendored
View file

@ -4,6 +4,8 @@
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0", "version": "0.2.0",
"configurations": [ "configurations": [
{ {
"name": "Launch Package", "name": "Launch Package",
"type": "go", "type": "go",

35
.vscode/tasks.json vendored Normal file
View file

@ -0,0 +1,35 @@
{
"version": "2.0.0",
"type": "shell",
"command": "go",
"cwd": "${workspaceFolder}",
"tasks": [
{
"label": "install",
"args": ["install", "-v", "./..."],
"group": "build",
},
{
"label": "run file",
"args": ["run", "${file}"],
"group": "build",
},
{
"label": "run project",
"args": ["run", "./cmd/stbackend/main.go"],
"group":"build",
"options":{
"env":{
"DATABASE_URL": "test",
"DATABASE_DIALECT": "sqlite",
"JWT_SECRET": "JwTDeVSeCRet15243"
}
},
},
{
"label": "test",
"args": ["test", "-v", "./..."],
"group": "test",
},
],
}

View file

@ -0,0 +1,459 @@
openapi: 3.0.0
info:
description: "This is the API specification for the ScheduleTogether Backend."
version: 0.1.0
title: ScheduleTogether Backend
termsOfService: http://swagger.io/terms/
contact:
email: contact@dev.zervo.org
license:
name: AGPL 3.0
url: https://www.gnu.org/licenses/agpl-3.0.html
tags:
- name: account
description: Everything related to account management
externalDocs:
description: Find out more
url: https://git.zervo.org/ScheduleTogether/Backend/src/branch/main/internal/api/handlers/account_handler.go
- name: users
description: Everything related to user management
externalDocs:
description: Find out more
url: https://git.zervo.org/ScheduleTogether/Backend/src/branch/main/internal/api/handlers/users_handler.go
- name: friends
description: Everything related to friends management
externalDocs:
description: Find out more
url: https://git.zervo.org/ScheduleTogether/Backend/src/branch/main/internal/api/handlers/friends_handler.go
paths:
/account/register:
post:
tags:
- account
summary: Register a new user account
description: "Used to register a new user account. By default, newly created unverified accounts will be deleted after a while. To fully complete registration, an account verify request must be sent following the registration request."
operationId: registerAccount
requestBody:
$ref: "#/components/requestBodies/AccountRegister"
responses:
"400":
description: Request body validation failed
content:
application/json:
schema:
$ref: "#/components/schemas/CommonError"
"200":
description: Registration successful
content:
application/json:
schema:
$ref: "#/components/schemas/AccountRegisterResponse"
/account/verify:
post:
tags:
- account
summary: Verify a registered account
description: "Used to verify a newly registered user account. AKA complete user account registration."
operationId: verifyAccount
requestBody:
$ref: "#/components/requestBodies/AccountVerify"
responses:
"200":
description: Verification successful
content:
application/json:
schema:
$ref: "#/components/schemas/CommonMessage"
"400":
description: Invalid UUID or verification token
content:
application/json:
schema:
$ref: "#/components/schemas/CommonError"
/account/signin:
post:
tags:
- account
summary: Sign in to an existing user account
description: "Used to retrieve a session (jwt) token for a user account, that can in turn be used to authenticate subsequent requests."
operationId: signinAccount
requestBody:
$ref: "#/components/requestBodies/AccountSignin"
responses:
"401":
description: Authentication failed
content:
application/json:
schema:
$ref: "#/components/schemas/CommonError"
"400":
description: Request body validation failed
content:
application/json:
schema:
$ref: "#/components/schemas/CommonError"
"200":
description: Signed in successfully
content:
application/json:
schema:
$ref: "#/components/schemas/AccountSigninResponse"
/account/logout:
post:
tags:
- account
summary: Log out of a user account
description: "Used to invalidate a user account session (aka log out) based on context. REQUIRES: Authentication."
operationId: logoutAccount
responses:
"401":
description: Unauthorized
"200":
description: Successfully logged out
content:
application/json:
schema:
$ref: "#/components/schemas/CommonMessage"
/users:
get:
tags:
- users
summary: Get all users
description: "WILL BE PAGINATED IN THE FUTURE. Get all available users on the instance. REQUIRES: Authentication, GetAllUsers permission."
operationId: getUsers
responses:
"500":
description: Something went wrong
content:
application/json:
schema:
$ref: "#/components/schemas/CommonError"
"401":
description: Unauthorized
"200":
description: Successfully got all users
content:
application/json:
schema:
$ref: "#/components/schemas/GetAllUsersResponse"
/users/{userId}:
get:
tags:
- users
summary: Get user by internal ID
description: "Get user information about one account by internal user account ID. REQUIRES: Authentication, GetUserById permission."
operationId: getUserById
parameters:
- in: path
name: userId
schema:
type: integer
required: true
description: Numeric internal ID of the user to get
responses:
"401":
description: Unauthorized
"400":
description: Invalid parameters
content:
application/json:
schema:
$ref: "#/components/schemas/CommonError"
"404":
description: User not found
content:
application/json:
schema:
$ref: "#/components/schemas/CommonError"
"200":
description: Successfully got user
content:
application/json:
schema:
$ref: "#/components/schemas/DetailedUser"
/users/uuid/{userUuid}:
get:
tags:
- users
summary: Get user by UUID
description: "Get user information about one account by public user account UUID. REQUIRES: Authentication, GetUserByUuid permission."
operationId: getUserByUuid
parameters:
- in: path
name: userUuid
schema:
type: string
required: true
description: UUID of user to get
responses:
"401":
description: Unauthorized
"400":
description: Invalid parameters
content:
application/json:
schema:
$ref: "#/components/schemas/CommonError"
"404":
description: User not found
content:
application/json:
schema:
$ref: "#/components/schemas/CommonError"
"200":
description: Successfully got user
content:
application/json:
schema:
$ref: "#/components/schemas/DetailedUser"
/users/self:
get:
tags:
- users
summary: Get own user by session
description: "Get user information about the account which was used to authenticate the request. REQUIRES: Authentication, GetOwnUser permission."
operationId: getOwnUser
responses:
"401":
description: Unauthorized
"200":
description: Successfully got user
content:
application/json:
schema:
$ref: "#/components/schemas/DetailedUser"
/friends/add:
post:
tags:
- friends
summary: Create a friend request
description: "Create (AKA send) a friend request to another user account. The request is sent from the account used to perform this POST to the provided target account. REQUIRES: Authentication, SendFriendRequest permission."
operationId: addFriend
requestBody:
$ref: "#/components/requestBodies/FriendAdd"
responses:
"401":
description: Unauthorized
"400":
description: User does not exist, Already friends with user or Request already sent
content:
application/json:
schema:
$ref: "#/components/schemas/CommonError"
"200":
description: Friend request added successfully
content:
application/json:
schema:
$ref: "#/components/schemas/CommonMessage"
/friends/accept:
post:
tags:
- friends
summary: Accept an incoming friend request
description: "Accept an incoming friend request to your user account, from another user account. The request is accepted by the account used to perform this POST request. REQUIRES: Authentication, AcceptFriendRequest permission."
operationId: acceptFriend
requestBody:
$ref: "#/components/requestBodies/FriendAccept"
responses:
"401":
description: Unauthorized
"400":
description: User does not exist, You are already friends with user or Friend request not found
content:
application/json:
schema:
$ref: "#/components/schemas/CommonError"
"200":
description: Friend request accepted successfully
content:
application/json:
schema:
$ref: "#/components/schemas/CommonMessage"
/friends:
get:
tags:
- friends
summary: Get current incoming friend requests
description: "Get all current incoming friend requests to the user account used to authorize this POST request. REQUIRES: Authentication, GetOwnFriendRequests permission."
operationId: getFriendRequests
responses:
"401":
description: Unauthorized
"200":
description: Retrieved all incoming friend requests successfully
content:
application/json:
schema:
$ref: "#/components/schemas/FriendGetRequestsResponse"
externalDocs:
description: Find out more about ScheduleTogether
url: https://git.zervo.org/ScheduleTogether
servers:
- url: http://localhost:8080
- url: https://stbackend.swagger.io/v2
components:
requestBodies:
AccountRegister:
content:
application/json:
schema:
$ref: "#/components/schemas/AccountRegisterRequest"
AccountVerify:
content:
application/json:
schema:
$ref: "#/components/schemas/AccountVerifyRequest"
AccountSignin:
content:
application/json:
schema:
$ref: "#/components/schemas/AccountSigninRequest"
FriendAdd:
content:
application/json:
schema:
$ref: "#/components/schemas/FriendAddRequest"
FriendAccept:
content:
application/json:
schema:
$ref: "#/components/schemas/FriendAcceptRequest"
schemas:
CommonError:
type: object
properties:
error:
type: string
description: A string describing the error
CommonMessage:
type: object
properties:
message:
type: string
description: A message
DetailedUser:
type: object
properties:
id:
type: integer
description: Internal user ID
uuid:
type: string
description: Public unique user identifier
username:
type: string
firstName:
type: string
lastName:
type: string
email:
type: string
verified:
type: boolean
friends:
type: array
items:
type: string
AccountRegisterRequest:
type: object
properties:
firstName:
type: string
lastName:
type: string
username:
type: string
minLength: 5
maxLength: 18
email:
type: string
password:
type: string
minLength: 8
maxLength: 128
AccountRegisterResponse:
type: object
properties:
message:
type: string
description: A message describing the result
uuid:
type: string
description: The UUID of the newly created user
mustVerify:
type: boolean
description: Whether or not user needs to send account verify request to complete registration
AccountVerifyRequest:
type: object
properties:
uuid:
type: string
description: The UUID of the user account to verify
token:
type: string
description: The verification token
AccountSigninRequest:
type: object
properties:
username:
type: string
password:
type: string
AccountSigninResponse:
type: object
properties:
token:
type: string
description: The token to be used for authenticating all requests for this session
GetAllUsersResponse:
type: array
items:
$ref: "#/components/schemas/DetailedUser"
FriendRequest:
type: object
properties:
created_at:
type: string
description: Timestamp at which the friend request was created
source_username:
type: string
description: The username of the requesting user
source_uuid:
type: string
description: The UUID of the requesting user
target_uuid:
description: The UUID of the receiving user
FriendAddRequest:
type: object
properties:
username:
type: string
description: The username of the target user
FriendAcceptRequest:
type: object
properties:
uuid:
type: string
description: The UUID of the user from which you want to accept a friend request
FriendGetRequestsResponse:
type: object
properties:
amount:
type: integer
description: The amount of incoming friend requests
requests:
type: array
items:
$ref: "#/components/schemas/FriendRequest"

459
api/openapi/openapi.yaml Normal file
View file

@ -0,0 +1,459 @@
openapi: 3.0.0
info:
description: "This is the API specification for the ScheduleTogether Backend."
version: 0.1.0
title: ScheduleTogether Backend
termsOfService: http://zervo.org/terms/
contact:
email: contact@dev.zervo.org
license:
name: AGPL 3.0
url: https://www.gnu.org/licenses/agpl-3.0.html
tags:
- name: account
description: Everything related to account management
externalDocs:
description: Find out more
url: https://git.zervo.org/ScheduleTogether/Backend/src/branch/main/internal/api/handlers/account_handler.go
- name: users
description: Everything related to user management
externalDocs:
description: Find out more
url: https://git.zervo.org/ScheduleTogether/Backend/src/branch/main/internal/api/handlers/users_handler.go
- name: friends
description: Everything related to friends management
externalDocs:
description: Find out more
url: https://git.zervo.org/ScheduleTogether/Backend/src/branch/main/internal/api/handlers/friends_handler.go
paths:
/account/register:
post:
tags:
- account
summary: Register a new user account
description: "Used to register a new user account. By default, newly created unverified accounts will be deleted after a while. To fully complete registration, an account verify request must be sent following the registration request."
operationId: registerAccount
requestBody:
$ref: "#/components/requestBodies/AccountRegister"
responses:
"400":
description: Request body validation failed
content:
application/json:
schema:
$ref: "#/components/schemas/CommonError"
"200":
description: Registration successful
content:
application/json:
schema:
$ref: "#/components/schemas/AccountRegisterResponse"
/account/verify:
post:
tags:
- account
summary: Verify a registered account
description: "Used to verify a newly registered user account. AKA complete user account registration."
operationId: verifyAccount
requestBody:
$ref: "#/components/requestBodies/AccountVerify"
responses:
"200":
description: Verification successful
content:
application/json:
schema:
$ref: "#/components/schemas/CommonMessage"
"400":
description: Invalid UUID or verification token
content:
application/json:
schema:
$ref: "#/components/schemas/CommonError"
/account/signin:
post:
tags:
- account
summary: Sign in to an existing user account
description: "Used to retrieve a session (jwt) token for a user account, that can in turn be used to authenticate subsequent requests."
operationId: signinAccount
requestBody:
$ref: "#/components/requestBodies/AccountSignin"
responses:
"401":
description: Authentication failed
content:
application/json:
schema:
$ref: "#/components/schemas/CommonError"
"400":
description: Request body validation failed
content:
application/json:
schema:
$ref: "#/components/schemas/CommonError"
"200":
description: Signed in successfully
content:
application/json:
schema:
$ref: "#/components/schemas/AccountSigninResponse"
/account/logout:
post:
tags:
- account
summary: Log out of a user account
description: "Used to invalidate a user account session (aka log out) based on context. REQUIRES: Authentication."
operationId: logoutAccount
responses:
"401":
description: Unauthorized
"200":
description: Successfully logged out
content:
application/json:
schema:
$ref: "#/components/schemas/CommonMessage"
/users:
get:
tags:
- users
summary: Get all users
description: "WILL BE PAGINATED IN THE FUTURE. Get all available users on the instance. REQUIRES: Authentication, GetAllUsers permission."
operationId: getUsers
responses:
"500":
description: Something went wrong
content:
application/json:
schema:
$ref: "#/components/schemas/CommonError"
"401":
description: Unauthorized
"200":
description: Successfully got all users
content:
application/json:
schema:
$ref: "#/components/schemas/GetAllUsersResponse"
/users/{userId}:
get:
tags:
- users
summary: Get user by internal ID
description: "Get user information about one account by internal user account ID. REQUIRES: Authentication, GetUserById permission."
operationId: getUserById
parameters:
- in: path
name: userId
schema:
type: integer
required: true
description: Numeric internal ID of the user to get
responses:
"401":
description: Unauthorized
"400":
description: Invalid parameters
content:
application/json:
schema:
$ref: "#/components/schemas/CommonError"
"404":
description: User not found
content:
application/json:
schema:
$ref: "#/components/schemas/CommonError"
"200":
description: Successfully got user
content:
application/json:
schema:
$ref: "#/components/schemas/DetailedUser"
/users/uuid/{userUuid}:
get:
tags:
- users
summary: Get user by UUID
description: "Get user information about one account by public user account UUID. REQUIRES: Authentication, GetUserByUuid permission."
operationId: getUserByUuid
parameters:
- in: path
name: userUuid
schema:
type: string
required: true
description: UUID of user to get
responses:
"401":
description: Unauthorized
"400":
description: Invalid parameters
content:
application/json:
schema:
$ref: "#/components/schemas/CommonError"
"404":
description: User not found
content:
application/json:
schema:
$ref: "#/components/schemas/CommonError"
"200":
description: Successfully got user
content:
application/json:
schema:
$ref: "#/components/schemas/DetailedUser"
/users/self:
get:
tags:
- users
summary: Get own user by session
description: "Get user information about the account which was used to authenticate the request. REQUIRES: Authentication, GetOwnUser permission."
operationId: getOwnUser
responses:
"401":
description: Unauthorized
"200":
description: Successfully got user
content:
application/json:
schema:
$ref: "#/components/schemas/DetailedUser"
/friends/add:
post:
tags:
- friends
summary: Create a friend request
description: "Create (AKA send) a friend request to another user account. The request is sent from the account used to perform this POST to the provided target account. REQUIRES: Authentication, SendFriendRequest permission."
operationId: addFriend
requestBody:
$ref: "#/components/requestBodies/FriendAdd"
responses:
"401":
description: Unauthorized
"400":
description: User does not exist, Already friends with user or Request already sent
content:
application/json:
schema:
$ref: "#/components/schemas/CommonError"
"200":
description: Friend request added successfully
content:
application/json:
schema:
$ref: "#/components/schemas/CommonMessage"
/friends/accept:
post:
tags:
- friends
summary: Accept an incoming friend request
description: "Accept an incoming friend request to your user account, from another user account. The request is accepted by the account used to perform this POST request. REQUIRES: Authentication, AcceptFriendRequest permission."
operationId: acceptFriend
requestBody:
$ref: "#/components/requestBodies/FriendAccept"
responses:
"401":
description: Unauthorized
"400":
description: User does not exist, You are already friends with user or Friend request not found
content:
application/json:
schema:
$ref: "#/components/schemas/CommonError"
"200":
description: Friend request accepted successfully
content:
application/json:
schema:
$ref: "#/components/schemas/CommonMessage"
/friends:
get:
tags:
- friends
summary: Get current incoming friend requests
description: "Get all current incoming friend requests to the user account used to authorize this POST request. REQUIRES: Authentication, GetOwnFriendRequests permission."
operationId: getFriendRequests
responses:
"401":
description: Unauthorized
"200":
description: Retrieved all incoming friend requests successfully
content:
application/json:
schema:
$ref: "#/components/schemas/FriendGetRequestsResponse"
externalDocs:
description: Find out more about ScheduleTogether
url: https://git.zervo.org/ScheduleTogether
servers:
- url: http://localhost:8080
- url: https://stbackend.swagger.io/v2
components:
requestBodies:
AccountRegister:
content:
application/json:
schema:
$ref: "#/components/schemas/AccountRegisterRequest"
AccountVerify:
content:
application/json:
schema:
$ref: "#/components/schemas/AccountVerifyRequest"
AccountSignin:
content:
application/json:
schema:
$ref: "#/components/schemas/AccountSigninRequest"
FriendAdd:
content:
application/json:
schema:
$ref: "#/components/schemas/FriendAddRequest"
FriendAccept:
content:
application/json:
schema:
$ref: "#/components/schemas/FriendAcceptRequest"
schemas:
CommonError:
type: object
properties:
error:
type: string
description: A string describing the error
CommonMessage:
type: object
properties:
message:
type: string
description: A message
DetailedUser:
type: object
properties:
id:
type: integer
description: Internal user ID
uuid:
type: string
description: Public unique user identifier
username:
type: string
firstName:
type: string
lastName:
type: string
email:
type: string
verified:
type: boolean
friends:
type: array
items:
type: string
AccountRegisterRequest:
type: object
properties:
firstName:
type: string
lastName:
type: string
username:
type: string
minLength: 5
maxLength: 18
email:
type: string
password:
type: string
minLength: 8
maxLength: 128
AccountRegisterResponse:
type: object
properties:
message:
type: string
description: A message describing the result
uuid:
type: string
description: The UUID of the newly created user
mustVerify:
type: boolean
description: Whether or not user needs to send account verify request to complete registration
AccountVerifyRequest:
type: object
properties:
uuid:
type: string
description: The UUID of the user account to verify
token:
type: string
description: The verification token
AccountSigninRequest:
type: object
properties:
username:
type: string
password:
type: string
AccountSigninResponse:
type: object
properties:
token:
type: string
description: The token to be used for authenticating all requests for this session
GetAllUsersResponse:
type: array
items:
$ref: "#/components/schemas/DetailedUser"
FriendRequest:
type: object
properties:
created_at:
type: string
description: Timestamp at which the friend request was created
source_username:
type: string
description: The username of the requesting user
source_uuid:
type: string
description: The UUID of the requesting user
target_uuid:
description: The UUID of the receiving user
FriendAddRequest:
type: object
properties:
username:
type: string
description: The username of the target user
FriendAcceptRequest:
type: object
properties:
uuid:
type: string
description: The UUID of the user from which you want to accept a friend request
FriendGetRequestsResponse:
type: object
properties:
amount:
type: integer
description: The amount of incoming friend requests
requests:
type: array
items:
$ref: "#/components/schemas/FriendRequest"

View file

@ -62,7 +62,7 @@ func AccountRegister_Handler(ctx iris.Context) {
func AccountVerify_Handler(ctx iris.Context) { func AccountVerify_Handler(ctx iris.Context) {
var requestBody types.AccountVerifyRequest var requestBody types.AccountVerifyRequest
// Validate the request body against the AccountRegisterRequest schema // Validate the request body against the AccountVerifyRequest schema
if err := ctx.ReadJSON(&requestBody); err != nil { if err := ctx.ReadJSON(&requestBody); err != nil {
ctx.StatusCode(iris.StatusBadRequest) ctx.StatusCode(iris.StatusBadRequest)
ctx.JSON(types.CommonErrorResponse{ ctx.JSON(types.CommonErrorResponse{
@ -71,7 +71,7 @@ func AccountVerify_Handler(ctx iris.Context) {
return return
} }
// Call the AccountRegister_Service function to register user // Call the AccountVerify_Service function to verify user
accounts.AccountVerify_Service(ctx, requestBody) accounts.AccountVerify_Service(ctx, requestBody)
} }

View file

@ -95,7 +95,7 @@ func validateUserProperties(ctx iris.Context, request types.AccountRegisterReque
return errors.New("validation failed") return errors.New("validation failed")
} }
if len(request.Username) > 15 { if len(request.Username) > 18 {
ctx.StatusCode(iris.StatusBadRequest) ctx.StatusCode(iris.StatusBadRequest)
ctx.JSON(types.UserRegisterFieldValidationErrorResponse{ ctx.JSON(types.UserRegisterFieldValidationErrorResponse{
ValidationFailed: true, ValidationFailed: true,

View file

@ -85,7 +85,7 @@ func FriendAccept_Service(ctx iris.Context, req types.FriendsAcceptRequest) {
tx.Rollback() tx.Rollback()
ctx.StatusCode(iris.StatusBadRequest) ctx.StatusCode(iris.StatusBadRequest)
ctx.JSON(types.CommonErrorResponse{ ctx.JSON(types.CommonErrorResponse{
Error: "Friend request already sent", Error: "Friend request not found",
}) })
return return
} }

View file

@ -34,7 +34,7 @@ import (
func FriendsGetRequests_Service(ctx iris.Context, id uint) { func FriendsGetRequests_Service(ctx iris.Context, id uint) {
// Make sure a userId was passed // Make sure a userId was passed
if id == 0 { if id == 0 {
ctx.StatusCode(iris.StatusBadRequest) ctx.StatusCode(iris.StatusInternalServerError)
ctx.JSON(types.CommonErrorResponse{ ctx.JSON(types.CommonErrorResponse{
Error: "Something went wrong, please try again later", Error: "Something went wrong, please try again later",
}) })
@ -46,7 +46,7 @@ func FriendsGetRequests_Service(ctx iris.Context, id uint) {
var user db.User var user db.User
err := db.Db.Where("id = ?", id).First(&user).Error err := db.Db.Where("id = ?", id).First(&user).Error
if err != nil { if err != nil {
ctx.StatusCode(iris.StatusBadRequest) ctx.StatusCode(iris.StatusInternalServerError)
ctx.JSON(types.CommonErrorResponse{ ctx.JSON(types.CommonErrorResponse{
Error: "Something went wrong, please try again later", Error: "Something went wrong, please try again later",
}) })
@ -56,7 +56,7 @@ func FriendsGetRequests_Service(ctx iris.Context, id uint) {
// Get friend requests targeted at user // Get friend requests targeted at user
var friendRequests []db.FriendRequest var friendRequests []db.FriendRequest
err = db.Db.Where("target = ?", user.Uuid).Find(&friendRequests).Error err = db.Db.Where("target = ?", user.Uuid).Find(&friendRequests).Error
if err == nil { if err == nil { // CHECK
ctx.StatusCode(iris.StatusBadRequest) ctx.StatusCode(iris.StatusBadRequest)
ctx.JSON(types.CommonErrorResponse{ ctx.JSON(types.CommonErrorResponse{
Error: "Something went wrong, please try again later", Error: "Something went wrong, please try again later",