fix: align group private chat permission semantics
This commit is contained in:
@@ -406,6 +406,7 @@ type TenantBusinessAdapter interface {
|
||||
TenantGroupMemberGet(t.TenantID, string, t.Uid) (*t.GroupMember, error)
|
||||
TenantGroupMemberList(t.TenantID, string, t.GroupMemberListOptions) ([]t.GroupMember, string, error)
|
||||
TenantGroupMemberUpdate(t.TenantID, string, t.Uid, t.GroupMemberPatch) (*t.GroupMember, error)
|
||||
TenantUsersShareOpenPrivateGroup(t.TenantID, t.Uid, t.Uid) (bool, error)
|
||||
TenantGroupInvitationCreate(t.TenantID, *t.GroupInvitation) (*t.GroupInvitation, error)
|
||||
TenantGroupInvitationAccept(t.TenantID, string, t.Uid, any, time.Time) (*t.GroupInvitation, error)
|
||||
TenantGroupJoinRequestCreate(t.TenantID, *t.GroupJoinRequest) (*t.GroupJoinRequest, error)
|
||||
|
||||
@@ -171,3 +171,24 @@ func TestSharedDBGroupFileLinkIncludesTenantID(t *testing.T) {
|
||||
t.Fatal("TenantGroupFileCreate must not rely on im_filemsglinks.tenant_id default")
|
||||
}
|
||||
}
|
||||
|
||||
func TestTenantUsersShareOpenPrivateGroupChecksBothMembersAndSetting(t *testing.T) {
|
||||
source, err := os.ReadFile("tenant_groups.go")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
body := sourceBetween(t, string(source), "func (a *adapter) TenantUsersShareOpenPrivateGroup", "\nfunc (a *adapter) TenantGroupMemberUpdate")
|
||||
for _, required := range []string{
|
||||
"INNER JOIN im_group_members AS gm2",
|
||||
"gm2.topic=gm1.topic",
|
||||
"INNER JOIN im_group_settings AS gs",
|
||||
"gs.member_private_chat=1",
|
||||
"gm1.member_status=?",
|
||||
"gm2.member_status=?",
|
||||
"gs.group_status=?",
|
||||
} {
|
||||
if !strings.Contains(body, required) {
|
||||
t.Fatalf("TenantUsersShareOpenPrivateGroup must check active shared group and setting; missing %q", required)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -394,6 +394,39 @@ func (a *adapter) TenantGroupMemberList(id t.TenantID, topic string, opts t.Grou
|
||||
return items, next, rows.Err()
|
||||
}
|
||||
|
||||
func (a *adapter) TenantUsersShareOpenPrivateGroup(id t.TenantID, userID, peerID t.Uid) (bool, error) {
|
||||
if tenantAdp, err := a.routeGroupTenant(id); err != nil {
|
||||
return false, err
|
||||
} else if tenantAdp != a {
|
||||
return tenantAdp.TenantUsersShareOpenPrivateGroup(id, userID, peerID)
|
||||
}
|
||||
if userID.IsZero() || peerID.IsZero() || userID == peerID {
|
||||
return false, t.ErrMalformed
|
||||
}
|
||||
ctx, cancel := a.getContext()
|
||||
if cancel != nil {
|
||||
defer cancel()
|
||||
}
|
||||
var exists int
|
||||
err := a.db.GetContext(ctx, &exists, tenantShardSQL(id, `
|
||||
SELECT 1
|
||||
FROM im_group_members AS gm1
|
||||
INNER JOIN im_group_members AS gm2
|
||||
ON gm2.tenant_id=gm1.tenant_id AND gm2.topic=gm1.topic
|
||||
INNER JOIN im_group_settings AS gs
|
||||
ON gs.tenant_id=gm1.tenant_id AND gs.topic=gm1.topic
|
||||
WHERE gm1.tenant_id=? AND gm1.user_id=? AND gm1.member_status=?
|
||||
AND gm2.user_id=? AND gm2.member_status=?
|
||||
AND gs.group_status=? AND gs.member_private_chat=1
|
||||
LIMIT 1`),
|
||||
id, decodeUID(userID), t.GroupMemberStatusActive,
|
||||
decodeUID(peerID), t.GroupMemberStatusActive, t.GroupStatusActive)
|
||||
if err == sql.ErrNoRows {
|
||||
return false, nil
|
||||
}
|
||||
return exists == 1, err
|
||||
}
|
||||
|
||||
func (a *adapter) TenantGroupMemberUpdate(id t.TenantID, topic string, uid t.Uid, patch t.GroupMemberPatch) (*t.GroupMember, error) {
|
||||
if tenantAdp, err := a.routeGroupTenant(id); err != nil {
|
||||
return nil, err
|
||||
|
||||
Reference in New Issue
Block a user