From 7c9e9ce04fc4985414120965d622fb876646b0a3 Mon Sep 17 00:00:00 2001 From: Bernhard B Date: Mon, 15 Sep 2025 12:34:43 +0200 Subject: [PATCH] extended groups POST/PUT request * added possibility to change permissions with the groups PUT request * added possibility to change the send messages permission when creating a group with the POST request see #746 --- src/api/api.go | 63 ++++++++++++++++++++++++++++++----- src/client/client.go | 76 ++++++++++++++++++++++++++++++++----------- src/docs/docs.go | 10 ++++++ src/docs/swagger.json | 10 ++++++ src/docs/swagger.yaml | 7 ++++ 5 files changed, 138 insertions(+), 28 deletions(-) diff --git a/src/api/api.go b/src/api/api.go index 2462129..ffcfcd0 100644 --- a/src/api/api.go +++ b/src/api/api.go @@ -39,8 +39,9 @@ type UpdateContactRequest struct { } type GroupPermissions struct { - AddMembers string `json:"add_members" enums:"only-admins,every-member"` - EditGroup string `json:"edit_group" enums:"only-admins,every-member"` + AddMembers string `json:"add_members" enums:"only-admins,every-member"` + EditGroup string `json:"edit_group" enums:"only-admins,every-member"` + SendMessages string `json:"send_messages" enums:"only-admins,every-member"` } type CreateGroupRequest struct { @@ -53,11 +54,12 @@ type CreateGroupRequest struct { } type UpdateGroupRequest struct { - Base64Avatar *string `json:"base64_avatar"` - Description *string `json:"description"` - Name *string `json:"name"` - ExpirationTime *int `json:"expiration_time"` - GroupLinkState *string `json:"group_link" enums:"disabled,enabled,enabled-with-approval"` + Base64Avatar *string `json:"base64_avatar"` + Description *string `json:"description"` + Name *string `json:"name"` + ExpirationTime *int `json:"expiration_time"` + GroupLinkState *string `json:"group_link" enums:"disabled,enabled,enabled-with-approval"` + Permissions *GroupPermissions `json:"permissions"` } type ChangeGroupMembersRequest struct { @@ -696,6 +698,7 @@ func (a *Api) CreateGroup(c *gin.Context) { editGroupPermission := client.DefaultGroupPermission addMembersPermission := client.DefaultGroupPermission + sendMessagesPermission := client.DefaultGroupPermission groupLinkState := client.DefaultGroupLinkState if req.Permissions.AddMembers != "" { @@ -714,6 +717,15 @@ func (a *Api) CreateGroup(c *gin.Context) { editGroupPermission = editGroupPermission.FromString(req.Permissions.EditGroup) } + if req.Permissions.SendMessages != "" { + if !utils.StringInSlice(req.Permissions.SendMessages, []string{"every-member", "only-admins"}) { + c.JSON(400, Error{Msg: "Invalid send messages permissions provided - only 'every-member' and 'only-admins' allowed!"}) + return + } + + sendMessagesPermission = sendMessagesPermission.FromString(req.Permissions.SendMessages) + } + if req.GroupLinkState != "" { if !utils.StringInSlice(req.GroupLinkState, []string{"enabled", "enabled-with-approval", "disabled"}) { c.JSON(400, Error{Msg: "Invalid group link provided - only 'enabled', 'enabled-with-approval' and 'disabled' allowed!"}) @@ -722,7 +734,8 @@ func (a *Api) CreateGroup(c *gin.Context) { groupLinkState = groupLinkState.FromString(req.GroupLinkState) } - groupId, err := a.signalClient.CreateGroup(number, req.Name, req.Members, req.Description, editGroupPermission, addMembersPermission, groupLinkState, req.ExpirationTime) + groupId, err := a.signalClient.CreateGroup(number, req.Name, req.Members, req.Description, editGroupPermission, addMembersPermission, + sendMessagesPermission, groupLinkState, req.ExpirationTime) if err != nil { c.JSON(400, Error{Msg: err.Error()}) return @@ -1548,7 +1561,39 @@ func (a *Api) UpdateGroup(c *gin.Context) { groupLinkState = &gLinkStateVal } - err = a.signalClient.UpdateGroup(number, internalGroupId, req.Base64Avatar, req.Description, req.Name, req.ExpirationTime, groupLinkState) + editGroupPermission := client.DefaultGroupPermission + addMembersPermission := client.DefaultGroupPermission + sendMessagesPermission := client.DefaultGroupPermission + + if req.Permissions != nil { + if req.Permissions.AddMembers != "" { + if !utils.StringInSlice(req.Permissions.AddMembers, []string{"every-member", "only-admins"}) { + c.JSON(400, Error{Msg: "Invalid add members permission provided - only 'every-member' and 'only-admins' allowed!"}) + return + } + addMembersPermission = addMembersPermission.FromString(req.Permissions.AddMembers) + } + + if req.Permissions.EditGroup != "" { + if !utils.StringInSlice(req.Permissions.EditGroup, []string{"every-member", "only-admins"}) { + c.JSON(400, Error{Msg: "Invalid edit group permissions provided - only 'every-member' and 'only-admins' allowed!"}) + return + } + editGroupPermission = editGroupPermission.FromString(req.Permissions.EditGroup) + } + + if req.Permissions.SendMessages != "" { + if !utils.StringInSlice(req.Permissions.SendMessages, []string{"every-member", "only-admins"}) { + c.JSON(400, Error{Msg: "Invalid send messages permissions provided - only 'every-member' and 'only-admins' allowed!"}) + return + } + + sendMessagesPermission = sendMessagesPermission.FromString(req.Permissions.SendMessages) + } + } + + err = a.signalClient.UpdateGroup(number, internalGroupId, req.Base64Avatar, req.Description, req.Name, req.ExpirationTime, groupLinkState, + editGroupPermission, addMembersPermission, sendMessagesPermission) if err != nil { c.JSON(400, Error{Msg: err.Error()}) return diff --git a/src/client/client.go b/src/client/client.go index cf55d14..61050a5 100644 --- a/src/client/client.go +++ b/src/client/client.go @@ -5,13 +5,14 @@ import ( "encoding/json" "errors" "fmt" - log "github.com/sirupsen/logrus" "io/ioutil" "os" "path/filepath" "strconv" "strings" + log "github.com/sirupsen/logrus" + securejoin "github.com/cyphar/filepath-securejoin" "github.com/h2non/filetype" @@ -509,7 +510,7 @@ func (s *SignalClient) send(signalCliSendRequest ds.SignalCliSendRequest) (*Send PreviewTitle *string `json:"preview-title,omitempty"` PreviewImage *string `json:"preview-image,omitempty"` PreviewDescription *string `json:"preview-description,omitempty"` - ViewOnce bool `json:"view-once,omitempty"` + ViewOnce bool `json:"view-once,omitempty"` } request := Request{Message: signalCliSendRequest.Message} @@ -981,17 +982,19 @@ func (s *SignalClient) RemoveReceiveChannel(channelUuid string) { jsonRpc2Client.RemoveReceiveChannel(channelUuid) } -func (s *SignalClient) CreateGroup(number string, name string, members []string, description string, editGroupPermission GroupPermission, addMembersPermission GroupPermission, groupLinkState GroupLinkState, expirationTime *int) (string, error) { +func (s *SignalClient) CreateGroup(number string, name string, members []string, description string, editGroupPermission GroupPermission, addMembersPermission GroupPermission, + sendMessagesPermission GroupPermission, groupLinkState GroupLinkState, expirationTime *int) (string, error) { var internalGroupId string if s.signalCliMode == JsonRpc { type Request struct { - Name string `json:"name"` - Members []string `json:"members"` - Link string `json:"link,omitempty"` - Description string `json:"description,omitempty"` - EditGroupPermissions string `json:"setPermissionEditDetails,omitempty"` - AddMembersPermissions string `json:"setPermissionAddMember,omitempty"` - Expiration int `json:"expiration,omitempty"` + Name string `json:"name"` + Members []string `json:"members"` + Link string `json:"link,omitempty"` + Description string `json:"description,omitempty"` + EditGroupPermissions string `json:"setPermissionEditDetails,omitempty"` + AddMembersPermissions string `json:"setPermissionAddMember,omitempty"` + SendMessagesPermissions string `json:"setPermissionSendMessages,omitempty"` + Expiration int `json:"expiration,omitempty"` } request := Request{Name: name, Members: prefixUsernameMembers(members)} @@ -1011,6 +1014,10 @@ func (s *SignalClient) CreateGroup(number string, name string, members []string, request.AddMembersPermissions = addMembersPermission.String() } + if sendMessagesPermission != DefaultGroupPermission { + request.SendMessagesPermissions = sendMessagesPermission.String() + } + if expirationTime != nil { request.Expiration = *expirationTime } @@ -1046,6 +1053,10 @@ func (s *SignalClient) CreateGroup(number string, name string, members []string, cmd = append(cmd, []string{"--set-permission-edit-details", editGroupPermission.String()}...) } + if sendMessagesPermission != DefaultGroupPermission { + cmd = append(cmd, []string{"--set-permission-send-messages", sendMessagesPermission.String()}...) + } + if groupLinkState != DefaultGroupLinkState { cmd = append(cmd, []string{"--link", groupLinkState.String()}...) } @@ -1077,7 +1088,7 @@ func prefixUsernameMembers(members []string) []string { for _, member := range members { recipientType, err := getRecipientType(member) if err == nil && recipientType == ds.Username { - res = append(res, "u:" + member) + res = append(res, "u:"+member) } else { res = append(res, member) } @@ -1767,8 +1778,8 @@ func (s *SignalClient) QuitGroup(number string, groupId string) error { return err } -func (s *SignalClient) UpdateGroup(number string, groupId string, base64Avatar *string, groupDescription *string, - groupName *string, expirationTime *int, groupLinkState *GroupLinkState) error { +func (s *SignalClient) UpdateGroup(number string, groupId string, base64Avatar *string, groupDescription *string, groupName *string, expirationTime *int, + groupLinkState *GroupLinkState, editGroupPermission GroupPermission, addMembersPermission GroupPermission, sendMessagesPermission GroupPermission) error { var err error var avatarTmpPath string = "" if base64Avatar != nil { @@ -1808,12 +1819,15 @@ func (s *SignalClient) UpdateGroup(number string, groupId string, base64Avatar * if s.signalCliMode == JsonRpc { type Request struct { - GroupId string `json:"groupId"` - Avatar string `json:"avatar,omitempty"` - Description *string `json:"description,omitempty"` - Name *string `json:"name,omitempty"` - Expiration int `json:"expiration,omitempty"` - Link string `json:"link,omitempty"` + GroupId string `json:"groupId"` + Avatar string `json:"avatar,omitempty"` + Description *string `json:"description,omitempty"` + Name *string `json:"name,omitempty"` + Expiration int `json:"expiration,omitempty"` + Link string `json:"link,omitempty"` + EditGroupPermissions string `json:"setPermissionEditDetails,omitempty"` + AddMembersPermissions string `json:"setPermissionAddMember,omitempty"` + SendMessagesPermissions string `json:"setPermissionSendMessages,omitempty"` } request := Request{GroupId: groupId} @@ -1832,6 +1846,18 @@ func (s *SignalClient) UpdateGroup(number string, groupId string, base64Avatar * request.Link = (*groupLinkState).String() } + if editGroupPermission != DefaultGroupPermission { + request.EditGroupPermissions = editGroupPermission.String() + } + + if addMembersPermission != DefaultGroupPermission { + request.AddMembersPermissions = addMembersPermission.String() + } + + if sendMessagesPermission != DefaultGroupPermission { + request.SendMessagesPermissions = sendMessagesPermission.String() + } + jsonRpc2Client, err := s.getJsonRpc2Client() if err != nil { return err @@ -1859,6 +1885,18 @@ func (s *SignalClient) UpdateGroup(number string, groupId string, base64Avatar * cmd = append(cmd, []string{"--link", (*groupLinkState).String()}...) } + if addMembersPermission != DefaultGroupPermission { + cmd = append(cmd, []string{"--set-permission-add-member", addMembersPermission.String()}...) + } + + if editGroupPermission != DefaultGroupPermission { + cmd = append(cmd, []string{"--set-permission-edit-details", editGroupPermission.String()}...) + } + + if sendMessagesPermission != DefaultGroupPermission { + cmd = append(cmd, []string{"--set-permission-send-messages", sendMessagesPermission.String()}...) + } + _, err = s.cliClient.Execute(true, cmd, "") } diff --git a/src/docs/docs.go b/src/docs/docs.go index c8ca455..380e0d4 100644 --- a/src/docs/docs.go +++ b/src/docs/docs.go @@ -2371,6 +2371,13 @@ const docTemplate = `{ "only-admins", "every-member" ] + }, + "send_messages": { + "type": "string", + "enum": [ + "only-admins", + "every-member" + ] } } }, @@ -2704,6 +2711,9 @@ const docTemplate = `{ }, "name": { "type": "string" + }, + "permissions": { + "$ref": "#/definitions/api.GroupPermissions" } } }, diff --git a/src/docs/swagger.json b/src/docs/swagger.json index ba1d52f..5fb4b44 100644 --- a/src/docs/swagger.json +++ b/src/docs/swagger.json @@ -2368,6 +2368,13 @@ "only-admins", "every-member" ] + }, + "send_messages": { + "type": "string", + "enum": [ + "only-admins", + "every-member" + ] } } }, @@ -2701,6 +2708,9 @@ }, "name": { "type": "string" + }, + "permissions": { + "$ref": "#/definitions/api.GroupPermissions" } } }, diff --git a/src/docs/swagger.yaml b/src/docs/swagger.yaml index 9263b8c..d4420c6 100644 --- a/src/docs/swagger.yaml +++ b/src/docs/swagger.yaml @@ -76,6 +76,11 @@ definitions: - only-admins - every-member type: string + send_messages: + enum: + - only-admins + - every-member + type: string type: object api.LoggingConfiguration: properties: @@ -297,6 +302,8 @@ definitions: type: string name: type: string + permissions: + $ref: '#/definitions/api.GroupPermissions' type: object api.UpdateProfileRequest: properties: