added endpoints to list + trust identities

see #66
This commit is contained in:
Bernhard B
2021-01-18 20:21:17 +01:00
parent 3f08a07a30
commit 5d89b3fa51
5 changed files with 430 additions and 0 deletions

View File

@@ -37,6 +37,14 @@ type GroupEntry struct {
Blocked bool `json:"blocked"` Blocked bool `json:"blocked"`
} }
type IdentityEntry struct {
Number string `json:"number"`
Status string `json:"status"`
Fingerprint string `json:"fingerprint"`
Added string `json:"added"`
SafetyNumber string `json:"safety_number"`
}
type RegisterNumberRequest struct { type RegisterNumberRequest struct {
UseVoice bool `json:"use_voice"` UseVoice bool `json:"use_voice"`
Captcha string `json:"captcha"` Captcha string `json:"captcha"`
@@ -79,6 +87,10 @@ type UpdateProfileRequest struct {
Base64Avatar string `json:"base64_avatar"` Base64Avatar string `json:"base64_avatar"`
} }
type TrustIdentityRequest struct {
VerifiedSafetyNumber string `json:"verified_safety_number"`
}
func convertInternalGroupIdToGroupId(internalId string) string { func convertInternalGroupIdToGroupId(internalId string) string {
return groupPrefix + base64.StdEncoding.EncodeToString([]byte(internalId)) return groupPrefix + base64.StdEncoding.EncodeToString([]byte(internalId))
} }
@@ -192,6 +204,36 @@ func send(c *gin.Context, attachmentTmpDir string, signalCliConfig string, numbe
c.JSON(201, nil) c.JSON(201, nil)
} }
func parseWhitespaceDelimitedKeyValueStringList(in string, keys []string) []map[string]string {
l := []map[string]string{}
lines := strings.Split(in, "\n")
for _, line := range lines {
if line == "" {
continue
}
m := make(map[string]string)
temp := line
for i, key := range keys {
if i == 0 {
continue
}
idx := strings.Index(temp, " " + key + ": ")
pair := temp[:idx]
value := strings.TrimPrefix(pair, key + ": ")
temp = strings.TrimLeft(temp[idx:], " "+key+": ")
m[keys[i-1]] = value
}
m[keys[len(keys)-1]] = temp
l = append(l, m)
}
return l
}
func getGroups(number string, signalCliConfig string) ([]GroupEntry, error) { func getGroups(number string, signalCliConfig string) ([]GroupEntry, error) {
groupEntries := []GroupEntry{} groupEntries := []GroupEntry{}
@@ -789,6 +831,11 @@ func (a *Api) ServeAttachment(c *gin.Context) {
func (a *Api) UpdateProfile(c *gin.Context) { func (a *Api) UpdateProfile(c *gin.Context) {
number := c.Param("number") number := c.Param("number")
if number == "" {
c.JSON(400, Error{Msg: "Couldn't process request - number missing"})
return
}
var req UpdateProfileRequest var req UpdateProfileRequest
err := c.BindJSON(&req) err := c.BindJSON(&req)
if err != nil { if err != nil {
@@ -870,3 +917,88 @@ func (a *Api) UpdateProfile(c *gin.Context) {
func (a *Api) Health(c *gin.Context) { func (a *Api) Health(c *gin.Context) {
c.Status(http.StatusNoContent) c.Status(http.StatusNoContent)
} }
// @Summary List Identities
// @Tags Identities
// @Description List all identities for the given number.
// @Produce json
// @Success 200 {object} []IdentityEntry
// @Param number path string true "Registered Phone Number"
// @Router /v1/identities/{number} [get]
func (a *Api) ListIdentities(c *gin.Context) {
number := c.Param("number")
if number == "" {
c.JSON(400, Error{Msg: "Couldn't process request - number missing"})
return
}
out, err := runSignalCli(true, []string{"--config", a.signalCliConfig, "-u", number, "listIdentities"}, "")
if err != nil {
c.JSON(500, Error{Msg: err.Error()})
return
}
identityEntries := []IdentityEntry{}
keyValuePairs := parseWhitespaceDelimitedKeyValueStringList(out, []string{"NumberAndTrustStatus", "Added", "Fingerprint", "Safety Number"})
for _, keyValuePair := range keyValuePairs {
numberAndTrustStatus := keyValuePair["NumberAndTrustStatus"]
numberAndTrustStatusSplitted := strings.Split(numberAndTrustStatus, ":")
identityEntry := IdentityEntry{Number: strings.Trim(numberAndTrustStatusSplitted[0], " "),
Status: strings.Trim(numberAndTrustStatusSplitted[1], " "),
Added: keyValuePair["Added"],
Fingerprint: strings.Trim(keyValuePair["Fingerprint"], " "),
SafetyNumber: strings.Trim(keyValuePair["Safety Number"], " "),
}
identityEntries = append(identityEntries, identityEntry)
}
c.JSON(200, identityEntries)
}
// @Summary Trust Identity
// @Tags Identities
// @Description Trust an identity.
// @Produce json
// @Success 204 {string} OK
// @Param data body TrustIdentityRequest true "Input Data"
// @Param number path string true "Registered Phone Number"
// @Param numberToTrust path string true "Number To Trust"
// @Router /v1/identities/{number}/{numberToTrust} [put]
func (a *Api) TrustIdentity(c *gin.Context) {
number := c.Param("number")
if number == "" {
c.JSON(400, Error{Msg: "Couldn't process request - number missing"})
return
}
numberToTrust := c.Param("numbertotrust")
if numberToTrust == "" {
c.JSON(400, Error{Msg: "Couldn't process request - number to trust missing"})
return
}
var req TrustIdentityRequest
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.VerifiedSafetyNumber == "" {
c.JSON(400, Error{Msg: "Couldn't process request - verified safety number missing"})
return
}
cmd := []string{"--config", a.signalCliConfig, "-u", number, "trust", numberToTrust, "--verified-safety-number", req.VerifiedSafetyNumber}
_, err = runSignalCli(true, cmd, "")
if err != nil {
c.JSON(400, Error{Msg: err.Error()})
return
}
c.Status(http.StatusNoContent)
}

View File

@@ -284,6 +284,83 @@ var doc = `{
} }
} }
}, },
"/v1/identities/{number}": {
"get": {
"description": "List all identities for the given number.",
"produces": [
"application/json"
],
"tags": [
"Identities"
],
"summary": "List Identities",
"parameters": [
{
"type": "string",
"description": "Registered Phone Number",
"name": "number",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"type": "array",
"items": {
"$ref": "#/definitions/api.IdentityEntry"
}
}
}
}
}
},
"/v1/identities/{number}/{numberToTrust}": {
"put": {
"description": "Trust an identity.",
"produces": [
"application/json"
],
"tags": [
"Identities"
],
"summary": "Trust Identity",
"parameters": [
{
"description": "Input Data",
"name": "data",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/api.TrustIdentityRequest"
}
},
{
"type": "string",
"description": "Registered Phone Number",
"name": "number",
"in": "path",
"required": true
},
{
"type": "string",
"description": "Number To Trust",
"name": "numberToTrust",
"in": "path",
"required": true
}
],
"responses": {
"204": {
"description": "No Content",
"schema": {
"type": "string"
}
}
}
}
},
"/v1/profiles/{number}": { "/v1/profiles/{number}": {
"put": { "put": {
"description": "Set your name and optional an avatar.", "description": "Set your name and optional an avatar.",
@@ -627,6 +704,26 @@ var doc = `{
} }
} }
}, },
"api.IdentityEntry": {
"type": "object",
"properties": {
"added": {
"type": "string"
},
"fingerprint": {
"type": "string"
},
"number": {
"type": "string"
},
"safety_number": {
"type": "string"
},
"status": {
"type": "string"
}
}
},
"api.SendMessageV1": { "api.SendMessageV1": {
"type": "object", "type": "object",
"properties": { "properties": {
@@ -673,6 +770,14 @@ var doc = `{
} }
} }
}, },
"api.TrustIdentityRequest": {
"type": "object",
"properties": {
"verified_safety_number": {
"type": "string"
}
}
},
"api.UpdateProfileRequest": { "api.UpdateProfileRequest": {
"type": "object", "type": "object",
"properties": { "properties": {
@@ -717,6 +822,10 @@ var doc = `{
{ {
"description": "Update Profile.", "description": "Update Profile.",
"name": "Profiles" "name": "Profiles"
},
{
"description": "List and Trust Identities.",
"name": "Identities"
} }
] ]
}` }`

View File

@@ -269,6 +269,83 @@
} }
} }
}, },
"/v1/identities/{number}": {
"get": {
"description": "List all identities for the given number.",
"produces": [
"application/json"
],
"tags": [
"Identities"
],
"summary": "List Identities",
"parameters": [
{
"type": "string",
"description": "Registered Phone Number",
"name": "number",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"type": "array",
"items": {
"$ref": "#/definitions/api.IdentityEntry"
}
}
}
}
}
},
"/v1/identities/{number}/{numberToTrust}": {
"put": {
"description": "Trust an identity.",
"produces": [
"application/json"
],
"tags": [
"Identities"
],
"summary": "Trust Identity",
"parameters": [
{
"description": "Input Data",
"name": "data",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/api.TrustIdentityRequest"
}
},
{
"type": "string",
"description": "Registered Phone Number",
"name": "number",
"in": "path",
"required": true
},
{
"type": "string",
"description": "Number To Trust",
"name": "numberToTrust",
"in": "path",
"required": true
}
],
"responses": {
"204": {
"description": "No Content",
"schema": {
"type": "string"
}
}
}
}
},
"/v1/profiles/{number}": { "/v1/profiles/{number}": {
"put": { "put": {
"description": "Set your name and optional an avatar.", "description": "Set your name and optional an avatar.",
@@ -612,6 +689,26 @@
} }
} }
}, },
"api.IdentityEntry": {
"type": "object",
"properties": {
"added": {
"type": "string"
},
"fingerprint": {
"type": "string"
},
"number": {
"type": "string"
},
"safety_number": {
"type": "string"
},
"status": {
"type": "string"
}
}
},
"api.SendMessageV1": { "api.SendMessageV1": {
"type": "object", "type": "object",
"properties": { "properties": {
@@ -658,6 +755,14 @@
} }
} }
}, },
"api.TrustIdentityRequest": {
"type": "object",
"properties": {
"verified_safety_number": {
"type": "string"
}
}
},
"api.UpdateProfileRequest": { "api.UpdateProfileRequest": {
"type": "object", "type": "object",
"properties": { "properties": {
@@ -702,6 +807,10 @@
{ {
"description": "Update Profile.", "description": "Update Profile.",
"name": "Profiles" "name": "Profiles"
},
{
"description": "List and Trust Identities.",
"name": "Identities"
} }
] ]
} }

View File

@@ -36,6 +36,19 @@ definitions:
name: name:
type: string type: string
type: object type: object
api.IdentityEntry:
properties:
added:
type: string
fingerprint:
type: string
number:
type: string
safety_number:
type: string
status:
type: string
type: object
api.SendMessageV1: api.SendMessageV1:
properties: properties:
base64_attachment: base64_attachment:
@@ -66,6 +79,11 @@ definitions:
type: string type: string
type: array type: array
type: object type: object
api.TrustIdentityRequest:
properties:
verified_safety_number:
type: string
type: object
api.UpdateProfileRequest: api.UpdateProfileRequest:
properties: properties:
base64_avatar: base64_avatar:
@@ -257,6 +275,57 @@ paths:
summary: API Health Check summary: API Health Check
tags: tags:
- General - General
/v1/identities/{number}:
get:
description: List all identities for the given number.
parameters:
- description: Registered Phone Number
in: path
name: number
required: true
type: string
produces:
- application/json
responses:
"200":
description: OK
schema:
items:
$ref: '#/definitions/api.IdentityEntry'
type: array
summary: List Identities
tags:
- Identities
/v1/identities/{number}/{numberToTrust}:
put:
description: Trust an identity.
parameters:
- description: Input Data
in: body
name: data
required: true
schema:
$ref: '#/definitions/api.TrustIdentityRequest'
- description: Registered Phone Number
in: path
name: number
required: true
type: string
- description: Number To Trust
in: path
name: numberToTrust
required: true
type: string
produces:
- application/json
responses:
"204":
description: No Content
schema:
type: string
summary: Trust Identity
tags:
- Identities
/v1/profiles/{number}: /v1/profiles/{number}:
put: put:
description: Set your name and optional an avatar. description: Set your name and optional an avatar.
@@ -459,3 +528,5 @@ tags:
name: Attachments name: Attachments
- description: Update Profile. - description: Update Profile.
name: Profiles name: Profiles
- description: List and Trust Identities.
name: Identities

View File

@@ -37,6 +37,9 @@ import (
// @tag.name Profiles // @tag.name Profiles
// @tag.description Update Profile. // @tag.description Update Profile.
// @tag.name Identities
// @tag.description List and Trust Identities.
// @host 127.0.0.1:8080 // @host 127.0.0.1:8080
// @BasePath / // @BasePath /
func main() { func main() {
@@ -106,6 +109,12 @@ func main() {
{ {
profiles.PUT(":number", api.UpdateProfile) profiles.PUT(":number", api.UpdateProfile)
} }
identities := v1.Group("identities")
{
identities.GET(":number", api.ListIdentities)
identities.PUT(":number/trust/:numbertotrust", api.TrustIdentity)
}
} }
v2 := router.Group("/v2") v2 := router.Group("/v2")