mirror of
https://github.com/aljazceru/signal-cli-rest-api.git
synced 2025-12-19 23:54:22 +01:00
103
src/api/api.go
103
src/api/api.go
@@ -10,12 +10,18 @@ import (
|
|||||||
"os/exec"
|
"os/exec"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
"path/filepath"
|
||||||
|
"net/http"
|
||||||
|
"strconv"
|
||||||
|
"io/ioutil"
|
||||||
|
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
uuid "github.com/gofrs/uuid"
|
uuid "github.com/gofrs/uuid"
|
||||||
"github.com/h2non/filetype"
|
"github.com/h2non/filetype"
|
||||||
log "github.com/sirupsen/logrus"
|
log "github.com/sirupsen/logrus"
|
||||||
qrcode "github.com/skip2/go-qrcode"
|
qrcode "github.com/skip2/go-qrcode"
|
||||||
|
"github.com/gabriel-vasile/mimetype"
|
||||||
|
"github.com/cyphar/filepath-securejoin"
|
||||||
)
|
)
|
||||||
|
|
||||||
const groupPrefix = "group."
|
const groupPrefix = "group."
|
||||||
@@ -618,7 +624,7 @@ func (a *Api) DeleteGroup(c *gin.Context) {
|
|||||||
|
|
||||||
// @Summary Link device and generate QR code.
|
// @Summary Link device and generate QR code.
|
||||||
// @Tags Devices
|
// @Tags Devices
|
||||||
// @Description test
|
// @Description Link device and generate QR code
|
||||||
// @Produce json
|
// @Produce json
|
||||||
// @Success 200 {string} string "Image"
|
// @Success 200 {string} string "Image"
|
||||||
// @Failure 400 {object} Error
|
// @Failure 400 {object} Error
|
||||||
@@ -658,3 +664,98 @@ func (a *Api) GetQrCodeLink(c *gin.Context) {
|
|||||||
|
|
||||||
c.Data(200, "image/png", png)
|
c.Data(200, "image/png", png)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// @Summary List all attachments.
|
||||||
|
// @Tags Attachments
|
||||||
|
// @Description List all downloaded attachments
|
||||||
|
// @Produce json
|
||||||
|
// @Success 200 {object} []string
|
||||||
|
// @Failure 400 {object} Error
|
||||||
|
// @Router /v1/attachments [get]
|
||||||
|
func (a *Api) GetAttachments(c *gin.Context) {
|
||||||
|
files := []string{}
|
||||||
|
err := filepath.Walk(a.signalCliConfig + "/attachments/", func(path string, info os.FileInfo, err error) error {
|
||||||
|
if info.IsDir() {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
files = append(files, filepath.Base(path))
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
c.JSON(500, Error{Msg: "Couldn't get list of attachments: " + err.Error()})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
c.JSON(200, files)
|
||||||
|
}
|
||||||
|
|
||||||
|
// @Summary Remove attachment.
|
||||||
|
// @Tags Attachments
|
||||||
|
// @Description Remove the attachment with the given id from filesystem.
|
||||||
|
// @Produce json
|
||||||
|
// @Success 200 {string} OK
|
||||||
|
// @Failure 400 {object} Error
|
||||||
|
// @Param attachment path string true "Attachment ID"
|
||||||
|
// @Router /v1/attachments/{attachment} [delete]
|
||||||
|
func (a *Api) RemoveAttachment(c *gin.Context) {
|
||||||
|
attachment := c.Param("attachment")
|
||||||
|
path, err := securejoin.SecureJoin(a.signalCliConfig + "/attachments/", attachment)
|
||||||
|
if err != nil {
|
||||||
|
c.JSON(400, Error{Msg: "Please provide a valid attachment name"})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, err := os.Stat(path); os.IsNotExist(err) {
|
||||||
|
c.JSON(404, Error{Msg: "No attachment with that name found"})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
err = os.Remove(path)
|
||||||
|
if err != nil {
|
||||||
|
c.JSON(500, Error{Msg: "Couldn't delete attachment - please try again later"})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
c.Status(http.StatusNoContent)
|
||||||
|
}
|
||||||
|
|
||||||
|
// @Summary Serve Attachment.
|
||||||
|
// @Tags Attachments
|
||||||
|
// @Description Serve the attachment with the given id
|
||||||
|
// @Produce json
|
||||||
|
// @Success 200 {string} OK
|
||||||
|
// @Failure 400 {object} Error
|
||||||
|
// @Param attachment path string true "Attachment ID"
|
||||||
|
// @Router /v1/attachments/{attachment} [get]
|
||||||
|
func (a *Api) ServeAttachment(c *gin.Context) {
|
||||||
|
attachment := c.Param("attachment")
|
||||||
|
path, err := securejoin.SecureJoin(a.signalCliConfig + "/attachments/", attachment)
|
||||||
|
if err != nil {
|
||||||
|
c.JSON(400, Error{Msg: "Please provide a valid attachment name"})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, err := os.Stat(path); os.IsNotExist(err) {
|
||||||
|
c.JSON(404, Error{Msg: "No attachment with that name found"})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
imgBytes, err := ioutil.ReadFile(path)
|
||||||
|
if err != nil {
|
||||||
|
c.JSON(500, Error{Msg: "Couldn't read attachment - please try again later"})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
mime, err := mimetype.DetectReader(bytes.NewReader(imgBytes))
|
||||||
|
if err != nil {
|
||||||
|
c.JSON(500, Error{Msg: "Couldn't detect MIME type for attachment"})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
c.Writer.Header().Set("Content-Type", mime.String())
|
||||||
|
c.Writer.Header().Set("Content-Length", strconv.Itoa(len(imgBytes)))
|
||||||
|
_, err = c.Writer.Write(imgBytes)
|
||||||
|
if err != nil {
|
||||||
|
c.JSON(500, Error{Msg: "Couldn't serve attachment - please try again later"})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
103
src/docs/docs.go
103
src/docs/docs.go
@@ -45,6 +45,103 @@ var doc = `{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"/v1/attachments": {
|
||||||
|
"get": {
|
||||||
|
"description": "List all downloaded attachments",
|
||||||
|
"produces": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"Attachments"
|
||||||
|
],
|
||||||
|
"summary": "List all attachments.",
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "OK",
|
||||||
|
"schema": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"400": {
|
||||||
|
"description": "Bad Request",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/api.Error"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"/v1/attachments/{attachment}": {
|
||||||
|
"get": {
|
||||||
|
"description": "Serve the attachment with the given id",
|
||||||
|
"produces": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"Attachments"
|
||||||
|
],
|
||||||
|
"summary": "Serve Attachment.",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"type": "string",
|
||||||
|
"description": "Attachment ID",
|
||||||
|
"name": "attachment",
|
||||||
|
"in": "path",
|
||||||
|
"required": true
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "OK",
|
||||||
|
"schema": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"400": {
|
||||||
|
"description": "Bad Request",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/api.Error"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"delete": {
|
||||||
|
"description": "Remove the attachment with the given id from filesystem.",
|
||||||
|
"produces": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"Attachments"
|
||||||
|
],
|
||||||
|
"summary": "Remove attachment.",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"type": "string",
|
||||||
|
"description": "Attachment ID",
|
||||||
|
"name": "attachment",
|
||||||
|
"in": "path",
|
||||||
|
"required": true
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "OK",
|
||||||
|
"schema": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"400": {
|
||||||
|
"description": "Bad Request",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/api.Error"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"/v1/groups/{number}": {
|
"/v1/groups/{number}": {
|
||||||
"get": {
|
"get": {
|
||||||
"description": "List all Signal Groups.",
|
"description": "List all Signal Groups.",
|
||||||
@@ -169,7 +266,7 @@ var doc = `{
|
|||||||
},
|
},
|
||||||
"/v1/qrcodelink": {
|
"/v1/qrcodelink": {
|
||||||
"get": {
|
"get": {
|
||||||
"description": "test",
|
"description": "Link device and generate QR code",
|
||||||
"produces": [
|
"produces": [
|
||||||
"application/json"
|
"application/json"
|
||||||
],
|
],
|
||||||
@@ -537,6 +634,10 @@ var doc = `{
|
|||||||
{
|
{
|
||||||
"description": "Send and Receive Signal Messages.",
|
"description": "Send and Receive Signal Messages.",
|
||||||
"name": "Messages"
|
"name": "Messages"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "List and Delete Attachments.",
|
||||||
|
"name": "Attachments"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}`
|
}`
|
||||||
|
|||||||
@@ -30,6 +30,103 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"/v1/attachments": {
|
||||||
|
"get": {
|
||||||
|
"description": "List all downloaded attachments",
|
||||||
|
"produces": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"Attachments"
|
||||||
|
],
|
||||||
|
"summary": "List all attachments.",
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "OK",
|
||||||
|
"schema": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"400": {
|
||||||
|
"description": "Bad Request",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/api.Error"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"/v1/attachments/{attachment}": {
|
||||||
|
"get": {
|
||||||
|
"description": "Serve the attachment with the given id",
|
||||||
|
"produces": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"Attachments"
|
||||||
|
],
|
||||||
|
"summary": "Serve Attachment.",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"type": "string",
|
||||||
|
"description": "Attachment ID",
|
||||||
|
"name": "attachment",
|
||||||
|
"in": "path",
|
||||||
|
"required": true
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "OK",
|
||||||
|
"schema": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"400": {
|
||||||
|
"description": "Bad Request",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/api.Error"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"delete": {
|
||||||
|
"description": "Remove the attachment with the given id from filesystem.",
|
||||||
|
"produces": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"Attachments"
|
||||||
|
],
|
||||||
|
"summary": "Remove attachment.",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"type": "string",
|
||||||
|
"description": "Attachment ID",
|
||||||
|
"name": "attachment",
|
||||||
|
"in": "path",
|
||||||
|
"required": true
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "OK",
|
||||||
|
"schema": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"400": {
|
||||||
|
"description": "Bad Request",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/api.Error"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"/v1/groups/{number}": {
|
"/v1/groups/{number}": {
|
||||||
"get": {
|
"get": {
|
||||||
"description": "List all Signal Groups.",
|
"description": "List all Signal Groups.",
|
||||||
@@ -154,7 +251,7 @@
|
|||||||
},
|
},
|
||||||
"/v1/qrcodelink": {
|
"/v1/qrcodelink": {
|
||||||
"get": {
|
"get": {
|
||||||
"description": "test",
|
"description": "Link device and generate QR code",
|
||||||
"produces": [
|
"produces": [
|
||||||
"application/json"
|
"application/json"
|
||||||
],
|
],
|
||||||
@@ -522,6 +619,10 @@
|
|||||||
{
|
{
|
||||||
"description": "Send and Receive Signal Messages.",
|
"description": "Send and Receive Signal Messages.",
|
||||||
"name": "Messages"
|
"name": "Messages"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "List and Delete Attachments.",
|
||||||
|
"name": "Attachments"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
@@ -92,6 +92,70 @@ paths:
|
|||||||
summary: Lists general information about the API
|
summary: Lists general information about the API
|
||||||
tags:
|
tags:
|
||||||
- General
|
- General
|
||||||
|
/v1/attachments:
|
||||||
|
get:
|
||||||
|
description: List all downloaded attachments
|
||||||
|
produces:
|
||||||
|
- application/json
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: OK
|
||||||
|
schema:
|
||||||
|
items:
|
||||||
|
type: string
|
||||||
|
type: array
|
||||||
|
"400":
|
||||||
|
description: Bad Request
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/api.Error'
|
||||||
|
summary: List all attachments.
|
||||||
|
tags:
|
||||||
|
- Attachments
|
||||||
|
/v1/attachments/{attachment}:
|
||||||
|
delete:
|
||||||
|
description: Remove the attachment with the given id from filesystem.
|
||||||
|
parameters:
|
||||||
|
- description: Attachment ID
|
||||||
|
in: path
|
||||||
|
name: attachment
|
||||||
|
required: true
|
||||||
|
type: string
|
||||||
|
produces:
|
||||||
|
- application/json
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: OK
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
"400":
|
||||||
|
description: Bad Request
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/api.Error'
|
||||||
|
summary: Remove attachment.
|
||||||
|
tags:
|
||||||
|
- Attachments
|
||||||
|
get:
|
||||||
|
description: Serve the attachment with the given id
|
||||||
|
parameters:
|
||||||
|
- description: Attachment ID
|
||||||
|
in: path
|
||||||
|
name: attachment
|
||||||
|
required: true
|
||||||
|
type: string
|
||||||
|
produces:
|
||||||
|
- application/json
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: OK
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
"400":
|
||||||
|
description: Bad Request
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/api.Error'
|
||||||
|
summary: Serve Attachment.
|
||||||
|
tags:
|
||||||
|
- Attachments
|
||||||
/v1/groups/{number}:
|
/v1/groups/{number}:
|
||||||
get:
|
get:
|
||||||
consumes:
|
consumes:
|
||||||
@@ -175,7 +239,7 @@ paths:
|
|||||||
- Groups
|
- Groups
|
||||||
/v1/qrcodelink:
|
/v1/qrcodelink:
|
||||||
get:
|
get:
|
||||||
description: test
|
description: Link device and generate QR code
|
||||||
produces:
|
produces:
|
||||||
- application/json
|
- application/json
|
||||||
responses:
|
responses:
|
||||||
@@ -342,3 +406,5 @@ tags:
|
|||||||
name: Groups
|
name: Groups
|
||||||
- description: Send and Receive Signal Messages.
|
- description: Send and Receive Signal Messages.
|
||||||
name: Messages
|
name: Messages
|
||||||
|
- description: List and Delete Attachments.
|
||||||
|
name: Attachments
|
||||||
|
|||||||
10
src/main.go
10
src/main.go
@@ -31,6 +31,9 @@ import (
|
|||||||
// @tag.name Messages
|
// @tag.name Messages
|
||||||
// @tag.description Send and Receive Signal Messages.
|
// @tag.description Send and Receive Signal Messages.
|
||||||
|
|
||||||
|
// @tag.name Attachments
|
||||||
|
// @tag.description List and Delete Attachments.
|
||||||
|
|
||||||
// @host 127.0.0.1:8080
|
// @host 127.0.0.1:8080
|
||||||
// @BasePath /
|
// @BasePath /
|
||||||
func main() {
|
func main() {
|
||||||
@@ -76,6 +79,13 @@ func main() {
|
|||||||
{
|
{
|
||||||
link.GET("", api.GetQrCodeLink)
|
link.GET("", api.GetQrCodeLink)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
attachments := v1.Group("attachments")
|
||||||
|
{
|
||||||
|
attachments.GET("", api.GetAttachments)
|
||||||
|
attachments.DELETE(":attachment", api.RemoveAttachment)
|
||||||
|
attachments.GET(":attachment", api.ServeAttachment)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
v2 := router.Group("/v2")
|
v2 := router.Group("/v2")
|
||||||
|
|||||||
Reference in New Issue
Block a user