Skip to content

feat(common-contacts): groups on the organization instance - #4976

Merged
shepilov merged 7 commits into
masterfrom
feat/common-contacts-groups-on-org
Oct 27, 2026
Merged

shepilov merged 7 commits into
masterfrom
feat/common-contacts-groups-on-org

Conversation

@MontaGhanmy

@MontaGhanmy MontaGhanmy commented Oct 7, 2026 •

Copy link
Copy Markdown
Contributor

Summary

  • Use centralized_org_directory to write B2B groups only on the organization instance. common_contacts independently controls contacts-service integration.
  • With centralization disabled, continue propagating group creation, updates, membership changes and deletion to member instances.
  • Resolve managed B2B groups on the organization instance even while replication is retained. Read their contacts there and exclude the sharer; personal groups remain local.
  • Allow fallback to local group copies only while replication is retained. In centralized mode, a deleted organization group cannot be shared through a stale local copy.
  • Preserve feed-owned fields while common_contacts is enabled; resume B2B email/name updates when it is disabled. Keep the contact ID and group relationships, and fill a missing Cozy URL from B2B data.
  • Paginate group contacts before excluding the sharer, so groups above 1,000 members expand completely.
  • Keep centralized_org_directory: false for the initial backend rollout so the existing sharing UI retains its local contacts and groups.
  • Known limitation before enabling centralization: organization-instance group changes do not yet reach sharings on member instances. The share-group trigger fires on the organization instance. See Propagate organization group changes to member-instance sharings #5102, docs: add organization members and contacts storage adr #4917 and linagora/twake-workplace-private#1608.
  • Depends on feat(common-contacts): remove the member copies once the org instance is filled #4975.

Part of linagora/twake-workplace-private#1780.

@rezk2ll rezk2ll left a comment •

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One path was missed though: MembersFromContacts (model/sharing/member.go L213-L225) still calls contact.FindGroup(inst, id) on the member instance, which has no groups db anymore.

So creating a nested shared drive with a B2B group (POST /sharings/drives/:id/:file-id/drives) returns 404 "Database does not exist". I hit it locally.

Using findGroup + GetAllContacts + isSelf there, like AddGroup does, should be enough. Worth adding the case to TestAddGroupFromOrgInstance too.

// With the feed, the groups live on the organization instance only.
if inst.HasCommonContacts() && !inst.IsOrganizationInstance() {
continue
}

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

member.removed and group.deleted now only run on the org instance, so the share-group trigger never fires where alice's group sharing actually lives.

Result: a removed member keeps access. Locally carol was still in alice's sharings and shared drive after being removed, and after the group was deleted. Renames are lost too.

Is that accepted until ADR 052? Or should these two events keep running on member instances for now?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Accepted for now, common_contacts isn't enabled anywhere yet. Keeping the events on member instances wouldn't help: there's no group or copy left there for share-group to fire on. It needs the fan-out from the org instance (open point of #4917) before we turn the flag on.

setContactDirectoryMetadata(&c.JSONDoc, input, input.Email)
} else {
applyManagedContactFields(c, input)
}

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In this branch, could you set cozy from input.CozyURL when the contact has none? applyCard already does that.

Otherwise the group member gets a mail invite instead of a cozy to cozy one.

The test at groups_test.go L375 asserts the empty URL right now, so it would need to change.

Comment thread model/sharing/group.go
}
group, err := contact.FindGroup(inst, groupID)
return group, inst, err
}

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This reads any group on the org instance, in any context.

A non B2B group an admin creates there can be shared by a member who can't even read it, and that exposes its members. I reproduced that one.

Contexts without common_contacts also start reading the org instance here.

I'd gate it on inst.HasCommonContacts() and IsManagedDirectoryGroupID, and check IsManagedDirectoryDoc on what comes back.

Comment thread model/sharing/group.go Outdated
}
email, _ := inst.SettingsEMail()
return m.Email != "" && strings.EqualFold(m.Email, email)
}

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

isSelf reads the settings doc once per member. I counted 50 GETs for a 20 member group.

Reading SettingsEMail and PageURL once before the loop would fix it.

@shepilov
shepilov added this pull request to stack #5114 October 27, 2026 16:40
@shepilov
shepilov force-pushed the feat/common-contacts-groups-on-org branch from 7337a6e to 8fc77f2 Compare October 27, 2026 16:55
@shepilov
shepilov force-pushed the feat/common-contacts-groups-on-org branch 2 times, most recently from 6b35180 to e81976f Compare October 27, 2026 18:35
Base automatically changed from feat/common-contacts-remove-member-copies to master October 27, 2026 18:35
@shepilov
shepilov force-pushed the feat/common-contacts-groups-on-org branch from e81976f to d6bfe5e Compare October 27, 2026 18:35
@shepilov
shepilov merged commit cd14c76 into master Oct 27, 2026
4 checks passed
@shepilov
shepilov deleted the feat/common-contacts-groups-on-org branch October 27, 2026 18:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants