mirror of
https://github.com/pushbits/server.git
synced 2025-06-06 12:41:59 +02:00
commit
c723287211
8 changed files with 246 additions and 15 deletions
59
.github/workflows/documentation.yml
vendored
Normal file
59
.github/workflows/documentation.yml
vendored
Normal file
|
@ -0,0 +1,59 @@
|
||||||
|
name: Documentation
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
paths-ignore:
|
||||||
|
- '**.md'
|
||||||
|
- '**.jpg'
|
||||||
|
- '**.jpeg'
|
||||||
|
- '**.png'
|
||||||
|
- '**.yaml'
|
||||||
|
- '**.json'
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build_documentation:
|
||||||
|
name: Build documentation
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
if: ${{ github.ref == 'refs/heads/main' }}
|
||||||
|
steps:
|
||||||
|
- name: Checkout the repository
|
||||||
|
uses: actions/checkout@v2
|
||||||
|
with:
|
||||||
|
ref: ${{ github.head_ref }}
|
||||||
|
|
||||||
|
- name: Install swag
|
||||||
|
run: go install github.com/swaggo/swag/cmd/swag
|
||||||
|
|
||||||
|
- name: Install redoc
|
||||||
|
run: sudo apt install npm && sudo npm install redoc
|
||||||
|
|
||||||
|
- name: Build the API documentation
|
||||||
|
run: /home/runner/go/bin/swag init --parseDependency=true -d . -g cmd/pushbits/main.go
|
||||||
|
|
||||||
|
- name: Build static HTML
|
||||||
|
run: npx redoc-cli bundle docs/swagger.yaml --output index.html
|
||||||
|
|
||||||
|
- name: Setup SSH keys and known_hosts
|
||||||
|
env:
|
||||||
|
SSH_AUTH_SOCK: /tmp/ssh_agent.sock
|
||||||
|
run: |
|
||||||
|
ssh-agent -a $SSH_AUTH_SOCK > /dev/null
|
||||||
|
ssh-add - <<< "${{ secrets.WEBSITE_DEPLOY_KEY }}"
|
||||||
|
|
||||||
|
- name: Checkout website
|
||||||
|
env:
|
||||||
|
SSH_AUTH_SOCK: /tmp/ssh_agent.sock
|
||||||
|
run: mkdir website && git clone git@github.com:pushbits/website.git website
|
||||||
|
|
||||||
|
- name: Copy index.html
|
||||||
|
run: cp index.html website/static/api/index.html
|
||||||
|
|
||||||
|
- name: Set Git config
|
||||||
|
run: git config --global user.email "pipeline@pushbits.io" && git config --global user.name "PushBits Pipeline"
|
||||||
|
|
||||||
|
- name: Commit and push
|
||||||
|
env:
|
||||||
|
SSH_AUTH_SOCK: /tmp/ssh_agent.sock
|
||||||
|
run: cd website && git add . && git commit -m "Update documentation to ${{ github.sha }}" && git push
|
4
.gitignore
vendored
4
.gitignore
vendored
|
@ -20,3 +20,7 @@ config.yml
|
||||||
# vendor/
|
# vendor/
|
||||||
|
|
||||||
*.code-workspace
|
*.code-workspace
|
||||||
|
|
||||||
|
# Build documentation
|
||||||
|
|
||||||
|
docs/
|
|
@ -26,6 +26,21 @@ func setupCleanup(db *database.Database, dp *dispatcher.Dispatcher) {
|
||||||
}()
|
}()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// @title PushBits Server API Documentation
|
||||||
|
// @version 0.7.2
|
||||||
|
// @description Documentation for the PushBits server API. <br> [Contact](https://www.eiken.dev/)
|
||||||
|
|
||||||
|
// @contact.name PushBits
|
||||||
|
// @contact.url https://github.com/pushbits
|
||||||
|
|
||||||
|
// @license.name ISC
|
||||||
|
// @license.url https://github.com/pushbits/server/blob/master/LICENSE
|
||||||
|
|
||||||
|
// @host your-domain.net
|
||||||
|
// @BasePath /
|
||||||
|
// @query.collection.format multi
|
||||||
|
|
||||||
|
// @securityDefinitions.basic BasicAuth
|
||||||
func main() {
|
func main() {
|
||||||
log.Println("Starting PushBits.")
|
log.Println("Starting PushBits.")
|
||||||
|
|
||||||
|
|
|
@ -109,7 +109,19 @@ func (h *ApplicationHandler) updateApplication(ctx *gin.Context, a *model.Applic
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// CreateApplication creates an application.
|
// CreateApplication godoc
|
||||||
|
// @Summary Create Application
|
||||||
|
// @Description Create a new application
|
||||||
|
// @ID post-application
|
||||||
|
// @Tags Application
|
||||||
|
// @Accept json,mpfd
|
||||||
|
// @Produce json
|
||||||
|
// @Param name query string true "Name of the application"
|
||||||
|
// @Param strict_compatability query boolean false "Use strict compatability mode"
|
||||||
|
// @Success 200 {object} model.Application
|
||||||
|
// @Failure 400 ""
|
||||||
|
// @Security BasicAuth
|
||||||
|
// @Router /application [post]
|
||||||
func (h *ApplicationHandler) CreateApplication(ctx *gin.Context) {
|
func (h *ApplicationHandler) CreateApplication(ctx *gin.Context) {
|
||||||
var createApplication model.CreateApplication
|
var createApplication model.CreateApplication
|
||||||
|
|
||||||
|
@ -131,7 +143,17 @@ func (h *ApplicationHandler) CreateApplication(ctx *gin.Context) {
|
||||||
ctx.JSON(http.StatusOK, &application)
|
ctx.JSON(http.StatusOK, &application)
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetApplications returns all applications of the current user.
|
// GetApplications godoc
|
||||||
|
// @Summary Get Applications
|
||||||
|
// @Description Get all applications from current user
|
||||||
|
// @ID get-application
|
||||||
|
// @Tags Application
|
||||||
|
// @Accept json,mpfd
|
||||||
|
// @Produce json
|
||||||
|
// @Success 200 {array} model.Application
|
||||||
|
// @Failure 500 ""
|
||||||
|
// @Security BasicAuth
|
||||||
|
// @Router /application [get]
|
||||||
func (h *ApplicationHandler) GetApplications(ctx *gin.Context) {
|
func (h *ApplicationHandler) GetApplications(ctx *gin.Context) {
|
||||||
user := authentication.GetUser(ctx)
|
user := authentication.GetUser(ctx)
|
||||||
if user == nil {
|
if user == nil {
|
||||||
|
@ -146,7 +168,18 @@ func (h *ApplicationHandler) GetApplications(ctx *gin.Context) {
|
||||||
ctx.JSON(http.StatusOK, &applications)
|
ctx.JSON(http.StatusOK, &applications)
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetApplication returns the application with the specified ID.
|
// GetApplication godoc
|
||||||
|
// @Summary Get Application
|
||||||
|
// @Description Get single application by ID
|
||||||
|
// @ID get-application-id
|
||||||
|
// @Tags Application
|
||||||
|
// @Accept json,mpfd
|
||||||
|
// @Produce json
|
||||||
|
// @Param id path int true "ID of the application"
|
||||||
|
// @Success 200 {object} model.Application
|
||||||
|
// @Failure 404,403 ""
|
||||||
|
// @Security BasicAuth
|
||||||
|
// @Router /application/{id} [get]
|
||||||
func (h *ApplicationHandler) GetApplication(ctx *gin.Context) {
|
func (h *ApplicationHandler) GetApplication(ctx *gin.Context) {
|
||||||
application, err := getApplication(ctx, h.DB)
|
application, err := getApplication(ctx, h.DB)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -167,7 +200,18 @@ func (h *ApplicationHandler) GetApplication(ctx *gin.Context) {
|
||||||
ctx.JSON(http.StatusOK, &application)
|
ctx.JSON(http.StatusOK, &application)
|
||||||
}
|
}
|
||||||
|
|
||||||
// DeleteApplication deletes an application with a certain ID.
|
// DeleteApplication godoc
|
||||||
|
// @Summary Delete Application
|
||||||
|
// @Description Delete an application
|
||||||
|
// @ID delete-application-id
|
||||||
|
// @Tags Application
|
||||||
|
// @Accept json,mpfd
|
||||||
|
// @Produce json
|
||||||
|
// @Param id path int true "ID of the application"
|
||||||
|
// @Success 200 ""
|
||||||
|
// @Failure 500,404,403 ""
|
||||||
|
// @Security BasicAuth
|
||||||
|
// @Router /application/{id} [delete]
|
||||||
func (h *ApplicationHandler) DeleteApplication(ctx *gin.Context) {
|
func (h *ApplicationHandler) DeleteApplication(ctx *gin.Context) {
|
||||||
application, err := getApplication(ctx, h.DB)
|
application, err := getApplication(ctx, h.DB)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -185,7 +229,21 @@ func (h *ApplicationHandler) DeleteApplication(ctx *gin.Context) {
|
||||||
ctx.JSON(http.StatusOK, gin.H{})
|
ctx.JSON(http.StatusOK, gin.H{})
|
||||||
}
|
}
|
||||||
|
|
||||||
// UpdateApplication updates an application with a certain ID.
|
// UpdateApplication godoc
|
||||||
|
// @Summary Update Application
|
||||||
|
// @Description Update an application
|
||||||
|
// @ID put-application-id
|
||||||
|
// @Tags Application
|
||||||
|
// @Accept json,mpfd
|
||||||
|
// @Produce json
|
||||||
|
// @Param id path int true "ID of the application"
|
||||||
|
// @Param name query string false "New name for the application"
|
||||||
|
// @Param refresh_token query bool false "Generate new refresh token for the application"
|
||||||
|
// @Param strict_compatability query bool false "Whether to use strict compataibility mode"
|
||||||
|
// @Success 200 ""
|
||||||
|
// @Failure 500,404,403 ""
|
||||||
|
// @Security BasicAuth
|
||||||
|
// @Router /application/{id} [put]
|
||||||
func (h *ApplicationHandler) UpdateApplication(ctx *gin.Context) {
|
func (h *ApplicationHandler) UpdateApplication(ctx *gin.Context) {
|
||||||
application, err := getApplication(ctx, h.DB)
|
application, err := getApplication(ctx, h.DB)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -11,7 +11,15 @@ type HealthHandler struct {
|
||||||
DB Database
|
DB Database
|
||||||
}
|
}
|
||||||
|
|
||||||
// Health returns the health status of the server.
|
// Health godoc
|
||||||
|
// @Summary Health of the application
|
||||||
|
// @ID get-health
|
||||||
|
// @Tags Health
|
||||||
|
// @Accept json,mpfd
|
||||||
|
// @Produce json
|
||||||
|
// @Success 200 ""
|
||||||
|
// @Failure 500 ""
|
||||||
|
// @Router /health [get]
|
||||||
func (h *HealthHandler) Health(ctx *gin.Context) {
|
func (h *HealthHandler) Health(ctx *gin.Context) {
|
||||||
if err := h.DB.Health(); err != nil {
|
if err := h.DB.Health(); err != nil {
|
||||||
ctx.AbortWithError(http.StatusInternalServerError, err)
|
ctx.AbortWithError(http.StatusInternalServerError, err)
|
||||||
|
|
|
@ -29,7 +29,21 @@ type NotificationHandler struct {
|
||||||
DP NotificationDispatcher
|
DP NotificationDispatcher
|
||||||
}
|
}
|
||||||
|
|
||||||
// CreateNotification is used to create a new notification for a user.
|
// CreateNotification godoc
|
||||||
|
// @Summary Create a Notification
|
||||||
|
// @Description Creates a new notification for the given channel
|
||||||
|
// @ID post-message
|
||||||
|
// @Tags Application
|
||||||
|
// @Accept json,mpfd
|
||||||
|
// @Produce json
|
||||||
|
// @Param message query string true "The message to send"
|
||||||
|
// @Param title query string false "The title to send"
|
||||||
|
// @Param priority query integer false "The notifications priority"
|
||||||
|
// @Param extras query model.NotificationExtras false "JSON object with additional information"
|
||||||
|
// @Param token query string true "Channels token, can also be provieded in the header"
|
||||||
|
// @Success 200 {object} model.Notification
|
||||||
|
// @Failure 500,404,403 ""
|
||||||
|
// @Router /message [post]
|
||||||
func (h *NotificationHandler) CreateNotification(ctx *gin.Context) {
|
func (h *NotificationHandler) CreateNotification(ctx *gin.Context) {
|
||||||
var notification model.Notification
|
var notification model.Notification
|
||||||
|
|
||||||
|
@ -58,7 +72,18 @@ func (h *NotificationHandler) CreateNotification(ctx *gin.Context) {
|
||||||
ctx.JSON(http.StatusOK, ¬ification)
|
ctx.JSON(http.StatusOK, ¬ification)
|
||||||
}
|
}
|
||||||
|
|
||||||
// DeleteNotification is used to delete (or mark as deleted) a notification for a user
|
// DeleteNotification godoc
|
||||||
|
// @Summary Delete a Notification
|
||||||
|
// @Description Informs the channel that the notification is deleted
|
||||||
|
// @ID deöete-message-id
|
||||||
|
// @Tags Application
|
||||||
|
// @Accept json,mpfd
|
||||||
|
// @Produce json
|
||||||
|
// @Param message_id path string true "ID of the message to delete"
|
||||||
|
// @Param token query string true "Channels token, can also be provieded in the header"
|
||||||
|
// @Success 200 ""
|
||||||
|
// @Failure 500,404,403 ""
|
||||||
|
// @Router /message/{message_id} [DELETE]
|
||||||
func (h *NotificationHandler) DeleteNotification(ctx *gin.Context) {
|
func (h *NotificationHandler) DeleteNotification(ctx *gin.Context) {
|
||||||
application := authentication.GetApplication(ctx)
|
application := authentication.GetApplication(ctx)
|
||||||
id, err := getMessageID(ctx)
|
id, err := getMessageID(ctx)
|
||||||
|
|
|
@ -112,8 +112,22 @@ func (h *UserHandler) updateUser(ctx *gin.Context, u *model.User, updateUser mod
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// CreateUser creates a new user.
|
// CreateUser godoc
|
||||||
// This method assumes that the requesting user has privileges.
|
// This method assumes that the requesting user has privileges.
|
||||||
|
// @Summary Create a User
|
||||||
|
// @Description Creates a new user
|
||||||
|
// @ID post-user
|
||||||
|
// @Tags User
|
||||||
|
// @Accept json,mpfd
|
||||||
|
// @Produce json
|
||||||
|
// @Param name query string true "Name of the user"
|
||||||
|
// @Param is_admin query bool false "Whether to set the user as admin or not"
|
||||||
|
// @Param matrix_id query string true "Matrix ID of the user in the format @user:domain.tld"
|
||||||
|
// @Param password query string true "The users password"
|
||||||
|
// @Success 200 {object} model.ExternalUser
|
||||||
|
// @Failure 500,404,403 ""
|
||||||
|
// @Security BasicAuth
|
||||||
|
// @Router /user [post]
|
||||||
func (h *UserHandler) CreateUser(ctx *gin.Context) {
|
func (h *UserHandler) CreateUser(ctx *gin.Context) {
|
||||||
var createUser model.CreateUser
|
var createUser model.CreateUser
|
||||||
|
|
||||||
|
@ -137,8 +151,18 @@ func (h *UserHandler) CreateUser(ctx *gin.Context) {
|
||||||
ctx.JSON(http.StatusOK, user.IntoExternalUser())
|
ctx.JSON(http.StatusOK, user.IntoExternalUser())
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetUsers returns all users.
|
// GetUsers godoc
|
||||||
// This method assumes that the requesting user has privileges.
|
// This method assumes that the requesting user has privileges.
|
||||||
|
// @Summary Get Users
|
||||||
|
// @Description Gets a list of all users
|
||||||
|
// @ID get-user
|
||||||
|
// @Tags User
|
||||||
|
// @Accept json,mpfd
|
||||||
|
// @Produce json
|
||||||
|
// @Success 200 {object} []model.ExternalUser
|
||||||
|
// @Failure 500 ""
|
||||||
|
// @Security BasicAuth
|
||||||
|
// @Router /user [get]
|
||||||
func (h *UserHandler) GetUsers(ctx *gin.Context) {
|
func (h *UserHandler) GetUsers(ctx *gin.Context) {
|
||||||
users, err := h.DB.GetUsers()
|
users, err := h.DB.GetUsers()
|
||||||
if success := successOrAbort(ctx, http.StatusInternalServerError, err); !success {
|
if success := successOrAbort(ctx, http.StatusInternalServerError, err); !success {
|
||||||
|
@ -154,8 +178,19 @@ func (h *UserHandler) GetUsers(ctx *gin.Context) {
|
||||||
ctx.JSON(http.StatusOK, &externalUsers)
|
ctx.JSON(http.StatusOK, &externalUsers)
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetUser returns the user with the specified ID.
|
// GetUser godoc
|
||||||
// This method assumes that the requesting user has privileges.
|
// This method assumes that the requesting user has privileges.
|
||||||
|
// @Summary Get User
|
||||||
|
// @Description Gets single user
|
||||||
|
// @ID get-user-id
|
||||||
|
// @Tags User
|
||||||
|
// @Accept json,mpfd
|
||||||
|
// @Produce json
|
||||||
|
// @Param id path integer true "The users id"
|
||||||
|
// @Success 200 {object} model.ExternalUser
|
||||||
|
// @Failure 500,404 ""
|
||||||
|
// @Security BasicAuth
|
||||||
|
// @Router /user/{id} [get]
|
||||||
func (h *UserHandler) GetUser(ctx *gin.Context) {
|
func (h *UserHandler) GetUser(ctx *gin.Context) {
|
||||||
user, err := getUser(ctx, h.DB)
|
user, err := getUser(ctx, h.DB)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -165,9 +200,19 @@ func (h *UserHandler) GetUser(ctx *gin.Context) {
|
||||||
ctx.JSON(http.StatusOK, user.IntoExternalUser())
|
ctx.JSON(http.StatusOK, user.IntoExternalUser())
|
||||||
}
|
}
|
||||||
|
|
||||||
// DeleteUser deletes a user with a certain ID.
|
// DeleteUser godoc
|
||||||
//
|
|
||||||
// This method assumes that the requesting user has privileges.
|
// This method assumes that the requesting user has privileges.
|
||||||
|
// @Summary Delete User
|
||||||
|
// @Description Delete user
|
||||||
|
// @ID delete-user-id
|
||||||
|
// @Tags User
|
||||||
|
// @Accept json,mpfd
|
||||||
|
// @Produce json
|
||||||
|
// @Param id path integer true "The users id"
|
||||||
|
// @Success 200 ""
|
||||||
|
// @Failure 500,404 ""
|
||||||
|
// @Security BasicAuth
|
||||||
|
// @Router /user/{id} [delete]
|
||||||
func (h *UserHandler) DeleteUser(ctx *gin.Context) {
|
func (h *UserHandler) DeleteUser(ctx *gin.Context) {
|
||||||
user, err := getUser(ctx, h.DB)
|
user, err := getUser(ctx, h.DB)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -194,10 +239,24 @@ func (h *UserHandler) DeleteUser(ctx *gin.Context) {
|
||||||
ctx.JSON(http.StatusOK, gin.H{})
|
ctx.JSON(http.StatusOK, gin.H{})
|
||||||
}
|
}
|
||||||
|
|
||||||
// UpdateUser updates a user with a certain ID.
|
// UpdateUser godoc
|
||||||
//
|
|
||||||
// This method assumes that the requesting user has privileges. If users can later update their own user, make sure they
|
// This method assumes that the requesting user has privileges. If users can later update their own user, make sure they
|
||||||
// cannot give themselves privileges.
|
// cannot give themselves privileges.
|
||||||
|
// @Summary Update User
|
||||||
|
// @Description Update user information
|
||||||
|
// @ID put-user-id
|
||||||
|
// @Tags User
|
||||||
|
// @Accept json,mpfd
|
||||||
|
// @Produce json
|
||||||
|
// @Param id path integer true "The users id"
|
||||||
|
// @Param name query string true "Name of the user"
|
||||||
|
// @Param is_admin query bool false "Whether to set the user as admin or not"
|
||||||
|
// @Param matrix_id query string true "Matrix ID of the user in the format @user:domain.tld"
|
||||||
|
// @Param password query string true "The users password"
|
||||||
|
// @Success 200 ""
|
||||||
|
// @Failure 500,404,400 ""
|
||||||
|
// @Security BasicAuth
|
||||||
|
// @Router /user/{id} [put]
|
||||||
func (h *UserHandler) UpdateUser(ctx *gin.Context) {
|
func (h *UserHandler) UpdateUser(ctx *gin.Context) {
|
||||||
user, err := getUser(ctx, h.DB)
|
user, err := getUser(ctx, h.DB)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -21,3 +21,6 @@ type DeleteNotification struct {
|
||||||
ID string `json:"id" form:"id"`
|
ID string `json:"id" form:"id"`
|
||||||
Date time.Time `json:"date"`
|
Date time.Time `json:"date"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NotificationExtras is need to document Notification.Extras in a format that the tool can read.
|
||||||
|
type NotificationExtras map[string]interface{}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue