Skip to content

Commit

Permalink
Rename the sharing group when the contacts group is renamed (#4361)
Browse files Browse the repository at this point in the history
  • Loading branch information
nono authored Mar 26, 2024
2 parents da7e4d5 + f422d9a commit c1cb0ed
Show file tree
Hide file tree
Showing 4 changed files with 80 additions and 10 deletions.
37 changes: 31 additions & 6 deletions model/job/trigger_share_group.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,12 @@ type ShareGroupTrigger struct {

// ShareGroupMessage is used for jobs on the share-group worker.
type ShareGroupMessage struct {
ContactID string `json:"contact_id"`
GroupsAdded []string `json:"added"`
GroupsRemoved []string `json:"removed"`
BecomeInvitable bool `json:"invitable"`
ContactID string `json:"contact_id,omitempty"`
GroupsAdded []string `json:"added,omitempty"`
GroupsRemoved []string `json:"removed,omitempty"`
BecomeInvitable bool `json:"invitable,omitempty"`
DeletedDoc *couchdb.JSONDoc `json:"deleted_doc,omitempty"`
RenamedGroup *couchdb.JSONDoc `json:"renamed_group,omitempty"`
}

func NewShareGroupTrigger(broker Broker) *ShareGroupTrigger {
Expand All @@ -47,13 +48,37 @@ func (t *ShareGroupTrigger) Schedule() {
}

func (t *ShareGroupTrigger) match(e *realtime.Event) *ShareGroupMessage {
if e.Doc.DocType() != consts.Contacts {
if e.Verb == realtime.EventNotify {
return nil
}
if e.Verb == realtime.EventNotify {
switch e.Doc.DocType() {
case consts.Groups:
return t.matchGroup(e)
case consts.Contacts:
return t.matchContact(e)
}
return nil
}

func (t *ShareGroupTrigger) matchGroup(e *realtime.Event) *ShareGroupMessage {
if e.Verb != realtime.EventUpdate {
return nil
}
newdoc, ok := e.Doc.(*couchdb.JSONDoc)
if !ok {
return nil
}
olddoc, ok := e.OldDoc.(*couchdb.JSONDoc)
if !ok {
return nil
}
if newdoc.M["name"] == olddoc.M["name"] {
return nil
}
return &ShareGroupMessage{RenamedGroup: newdoc}
}

func (t *ShareGroupTrigger) matchContact(e *realtime.Event) *ShareGroupMessage {
newdoc, ok := e.Doc.(*couchdb.JSONDoc)
if !ok {
return nil
Expand Down
30 changes: 30 additions & 0 deletions model/sharing/group.go
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,10 @@ func (s *Sharing) RevokeGroup(inst *instance.Instance, index int) error {
// finds the sharings for this group, and adds or removes the member to those
// sharings.
func UpdateGroups(inst *instance.Instance, msg job.ShareGroupMessage) error {
if msg.RenamedGroup != nil {
return updateRenamedGroup(inst, msg.RenamedGroup)
}

var c *contact.Contact
if msg.DeletedDoc != nil {
c = &contact.Contact{JSONDoc: *msg.DeletedDoc}
Expand Down Expand Up @@ -168,6 +172,32 @@ func UpdateGroups(inst *instance.Instance, msg job.ShareGroupMessage) error {
return errm
}

func updateRenamedGroup(inst *instance.Instance, doc *couchdb.JSONDoc) error {
sharings, err := FindActive(inst)
if err != nil {
return err
}

var errm error
for _, s := range sharings {
for idx, group := range s.Groups {
if group.ID == doc.ID() {
if name, ok := doc.M["name"].(string); ok {
group.Name = name
s.Groups[idx] = group
if err := couchdb.UpdateDoc(inst, s); err != nil {
errm = multierror.Append(errm, err)
}
cloned := s.Clone().(*Sharing)
go cloned.NotifyRecipients(inst, nil)
}
}
}
}

return errm
}

// AddMemberToGroup adds a contact to a sharing via a group (on the owner).
func (s *Sharing) AddMemberToGroup(inst *instance.Instance, groupIndex int, contact *contact.Contact) error {
readOnly := s.Groups[groupIndex].ReadOnly
Expand Down
16 changes: 12 additions & 4 deletions tests/system/lib/group.rb
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
class Group
include Model

attr_reader :name
attr_accessor :name

def self.doctype
"io.cozy.contacts.groups"
Expand All @@ -19,8 +19,16 @@ def self.from_json(j)
end

def as_json
{
name: @name
}
if @couch_id && @couch_rev
{
_id: @couch_id,
_rev: @couch_rev,
name: @name
}
else
{
name: @name
}
end
end
end
7 changes: 7 additions & 0 deletions tests/system/tests/sharing_several_members.rb
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,13 @@
assert info.dig("attributes", "groups", 0, "revoked")
check_sharing_has_groups_and_members info, [g1, g2], members, revoked

# Check that we can rename a group
g1.name = Faker::Kpop.solo
g1.save inst
sleep 1
info = Sharing.get_sharing_info inst, sharing.couch_id, Folder.doctype
assert_equal g1.name, info.dig("attributes", "groups", 0, "name")

# Check that the files are the same on disk
da = File.join Helpers.current_dir, inst.domain, folder.name
db = File.join Helpers.current_dir, inst_bob.domain,
Expand Down

0 comments on commit c1cb0ed

Please sign in to comment.