diff --git a/src/api/api.go b/src/api/api.go index f0025f8..b02336c 100644 --- a/src/api/api.go +++ b/src/api/api.go @@ -39,6 +39,14 @@ type GroupEntry struct { InviteLink string `json:"invite_link"` } +type LoggingConfiguration struct { + Level string `json:"Level"` +} + +type Configuration struct { + Logging LoggingConfiguration `json:"logging"` +} + type SignalCliGroupEntry struct { Name string `json:"name"` Id string `json:"id"` @@ -127,6 +135,19 @@ func cleanupTmpFiles(paths []string) { } } +func getContainerId() (string, error) { + data, err := ioutil.ReadFile("/proc/1/cpuset") + if err != nil { + return "", err + } + lines := strings.Split(string(data), "\n") + if len(lines) == 0 { + return "", errors.New("Couldn't get docker container id (empty)") + } + containerId := strings.Replace(lines[0], "/docker/", "", -1) + return containerId, nil +} + func send(c *gin.Context, attachmentTmpDir string, signalCliConfig string, number string, message string, recipients []string, base64Attachments []string, isGroup bool) { cmd := []string{"--config", signalCliConfig, "-u", number, "send"} @@ -280,6 +301,17 @@ func getGroups(number string, signalCliConfig string) ([]GroupEntry, error) { } func runSignalCli(wait bool, args []string, stdin string) (string, error) { + containerId, err := getContainerId() + + log.Debug("If you want to run this command manually, run the following steps on your host system:") + if err == nil { + log.Debug("*) docker exec -it ", containerId, " /bin/bash") + } else { + log.Debug("*) docker exec -it /bin/bash") + } + log.Debug("*) su signal-api") + log.Debug("*) signal-cli ", strings.Join(args, " ")) + cmd := exec.Command("signal-cli", args...) if stdin != "" { cmd.Stdin = strings.NewReader(stdin) @@ -311,6 +343,7 @@ func runSignalCli(wait bool, args []string, stdin string) (string, error) { return "", errors.New(errBuffer.String()) } } + return outBuffer.String(), nil } else { stdout, err := cmd.StdoutPipe() @@ -1006,3 +1039,58 @@ func (a *Api) TrustIdentity(c *gin.Context) { } c.Status(http.StatusNoContent) } + +// @Summary Set the REST API configuration. +// @Tags General +// @Description Set the REST API configuration. +// @Accept json +// @Produce json +// @Success 201 {string} string "OK" +// @Failure 400 {object} Error +// @Param data body Configuration true "Configuration" +// @Router /v1/configuration [post] +func (a *Api) SetConfiguration(c *gin.Context) { + var req Configuration + err := c.BindJSON(&req) + if err != nil { + c.JSON(400, Error{Msg: "Couldn't process request - invalid request"}) + log.Error(err.Error()) + return + } + + if req.Logging.Level != "" { + if req.Logging.Level == "debug" { + log.SetLevel(log.DebugLevel) + } else if req.Logging.Level == "info" { + log.SetLevel(log.InfoLevel) + } else if req.Logging.Level == "warn" { + log.SetLevel(log.WarnLevel) + } else { + c.JSON(400, Error{Msg: "Couldn't set log level - invalid log level"}) + return + } + } + c.Status(http.StatusNoContent) +} + +// @Summary List the REST API configuration. +// @Tags General +// @Description List the REST API configuration. +// @Accept json +// @Produce json +// @Success 200 {object} Configuration +// @Failure 400 {object} Error +// @Router /v1/configuration [get] +func (a *Api) GetConfiguration(c *gin.Context) { + logLevel := "" + if log.GetLevel() == log.DebugLevel { + logLevel = "debug" + } else if log.GetLevel() == log.InfoLevel { + logLevel = "info" + } else if log.GetLevel() == log.WarnLevel { + logLevel = "warn" + } + + configuration := Configuration{Logging: LoggingConfiguration{Level: logLevel}} + c.JSON(200, configuration) +} diff --git a/src/docs/docs.go b/src/docs/docs.go index 99b5122..096c166 100644 --- a/src/docs/docs.go +++ b/src/docs/docs.go @@ -142,6 +142,73 @@ var doc = `{ } } }, + "/v1/configuration": { + "get": { + "description": "List the REST API configuration.", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "General" + ], + "summary": "List the REST API configuration.", + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/api.Configuration" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/api.Error" + } + } + } + }, + "post": { + "description": "Set the REST API configuration.", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "General" + ], + "summary": "Set the REST API configuration.", + "parameters": [ + { + "description": "Configuration", + "name": "data", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/api.Configuration" + } + } + ], + "responses": { + "201": { + "description": "OK", + "schema": { + "type": "string" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/api.Error" + } + } + } + } + }, "/v1/groups/{number}": { "get": { "description": "List all Signal Groups.", @@ -662,6 +729,15 @@ var doc = `{ } } }, + "api.Configuration": { + "type": "object", + "properties": { + "logging": { + "type": "object", + "$ref": "#/definitions/api.LoggingConfiguration" + } + } + }, "api.CreateGroup": { "type": "object", "properties": { @@ -681,9 +757,6 @@ var doc = `{ "api.GroupEntry": { "type": "object", "properties": { - "active": { - "type": "boolean" - }, "blocked": { "type": "boolean" }, @@ -693,6 +766,9 @@ var doc = `{ "internal_id": { "type": "string" }, + "invite_link": { + "type": "string" + }, "members": { "type": "array", "items": { @@ -701,6 +777,18 @@ var doc = `{ }, "name": { "type": "string" + }, + "pending_invites": { + "type": "array", + "items": { + "type": "string" + } + }, + "pending_requests": { + "type": "array", + "items": { + "type": "string" + } } } }, @@ -724,6 +812,14 @@ var doc = `{ } } }, + "api.LoggingConfiguration": { + "type": "object", + "properties": { + "Level": { + "type": "string" + } + } + }, "api.SendMessageV1": { "type": "object", "properties": { diff --git a/src/docs/swagger.json b/src/docs/swagger.json index 4cdd0b0..fb8c762 100644 --- a/src/docs/swagger.json +++ b/src/docs/swagger.json @@ -127,6 +127,73 @@ } } }, + "/v1/configuration": { + "get": { + "description": "List the REST API configuration.", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "General" + ], + "summary": "List the REST API configuration.", + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/api.Configuration" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/api.Error" + } + } + } + }, + "post": { + "description": "Set the REST API configuration.", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "General" + ], + "summary": "Set the REST API configuration.", + "parameters": [ + { + "description": "Configuration", + "name": "data", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/api.Configuration" + } + } + ], + "responses": { + "201": { + "description": "OK", + "schema": { + "type": "string" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/api.Error" + } + } + } + } + }, "/v1/groups/{number}": { "get": { "description": "List all Signal Groups.", @@ -647,6 +714,15 @@ } } }, + "api.Configuration": { + "type": "object", + "properties": { + "logging": { + "type": "object", + "$ref": "#/definitions/api.LoggingConfiguration" + } + } + }, "api.CreateGroup": { "type": "object", "properties": { @@ -666,9 +742,6 @@ "api.GroupEntry": { "type": "object", "properties": { - "active": { - "type": "boolean" - }, "blocked": { "type": "boolean" }, @@ -678,6 +751,9 @@ "internal_id": { "type": "string" }, + "invite_link": { + "type": "string" + }, "members": { "type": "array", "items": { @@ -686,6 +762,18 @@ }, "name": { "type": "string" + }, + "pending_invites": { + "type": "array", + "items": { + "type": "string" + } + }, + "pending_requests": { + "type": "array", + "items": { + "type": "string" + } } } }, @@ -709,6 +797,14 @@ } } }, + "api.LoggingConfiguration": { + "type": "object", + "properties": { + "Level": { + "type": "string" + } + } + }, "api.SendMessageV1": { "type": "object", "properties": { diff --git a/src/docs/swagger.yaml b/src/docs/swagger.yaml index f96f1ec..4ae44c4 100644 --- a/src/docs/swagger.yaml +++ b/src/docs/swagger.yaml @@ -9,6 +9,12 @@ definitions: type: string type: array type: object + api.Configuration: + properties: + logging: + $ref: '#/definitions/api.LoggingConfiguration' + type: object + type: object api.CreateGroup: properties: id: @@ -21,20 +27,28 @@ definitions: type: object api.GroupEntry: properties: - active: - type: boolean blocked: type: boolean id: type: string internal_id: type: string + invite_link: + type: string members: items: type: string type: array name: type: string + pending_invites: + items: + type: string + type: array + pending_requests: + items: + type: string + type: array type: object api.IdentityEntry: properties: @@ -49,6 +63,11 @@ definitions: status: type: string type: object + api.LoggingConfiguration: + properties: + Level: + type: string + type: object api.SendMessageV1: properties: base64_attachment: @@ -181,6 +200,50 @@ paths: summary: Serve Attachment. tags: - Attachments + /v1/configuration: + get: + consumes: + - application/json + description: List the REST API configuration. + produces: + - application/json + responses: + "200": + description: OK + schema: + $ref: '#/definitions/api.Configuration' + "400": + description: Bad Request + schema: + $ref: '#/definitions/api.Error' + summary: List the REST API configuration. + tags: + - General + post: + consumes: + - application/json + description: Set the REST API configuration. + parameters: + - description: Configuration + in: body + name: data + required: true + schema: + $ref: '#/definitions/api.Configuration' + produces: + - application/json + responses: + "201": + description: OK + schema: + type: string + "400": + description: Bad Request + schema: + $ref: '#/definitions/api.Error' + summary: Set the REST API configuration. + tags: + - General /v1/groups/{number}: get: consumes: diff --git a/src/main.go b/src/main.go index e0c9123..96ab61b 100644 --- a/src/main.go +++ b/src/main.go @@ -20,7 +20,7 @@ import ( // @description This is the Signal Cli REST API documentation. // @tag.name General -// @tag.description List general information. +// @tag.description Some general endpoints. // @tag.name Devices // @tag.description Register and link Devices. @@ -65,6 +65,12 @@ func main() { about.GET("", api.About) } + configuration := v1.Group("/configuration") + { + configuration.GET("", api.GetConfiguration) + configuration.POST("", api.SetConfiguration) + } + health := v1.Group("/health") { health.GET("", api.Health)