Skip to content

Commit

Permalink
Add comments and add missing doc file
Browse files Browse the repository at this point in the history
  • Loading branch information
mohammed-madi committed May 16, 2024
1 parent eb9953f commit dc66efe
Show file tree
Hide file tree
Showing 2 changed files with 95 additions and 38 deletions.
28 changes: 28 additions & 0 deletions docs/api/paths/diagnostic/db-_user-name-_all_channels.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# Copyright 2022-Present Couchbase, Inc.
#
# Use of this software is governed by the Business Source License included
# in the file licenses/BSL-Couchbase.txt. As of the Change Date specified
# in that file, in accordance with the Business Source License, use of this
# software will be governed by the Apache License, Version 2.0, included in
# the file licenses/APL2.txt.
parameters:
- $ref: ../../components/parameters.yaml#/db
- $ref: ../../components/parameters.yaml#/user-name
get:
summary: Get all channels for a user
description: |-
Retrieve all channels that a user has access to.
Required Sync Gateway RBAC roles:
* Sync Gateway Architect
* Sync Gateway Application
* Sync Gateway Application Read Only
responses:
'200':
$ref: ../../components/responses.yaml#/All_user_channels_response
'404':
$ref: ../../components/responses.yaml#/Not-found
tags:
- Database Security
operationId: get_db-_user-name_-all_channels
105 changes: 67 additions & 38 deletions rest/diagnostic_api_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,6 @@ type roleGrant struct {

func (g roleGrant) getPayload(t testing.TB) string {
config := auth.PrincipalConfig{
//Name: base.StringPtr(g.role),
Password: base.StringPtr(RestTesterDefaultUserPassword),
}
for keyspace, chans := range g.adminChannels {
Expand All @@ -126,22 +125,22 @@ func (g roleGrant) request(rt *RestTester) {
}

type docGrant struct {
userName string
dynamicRoles string
dynamicChannels string
output string
userName string
dynamicRole string
dynamicChannel string
output string
}

func (g docGrant) getPayload(t testing.TB) string {
role := fmt.Sprintf(`"role":"role:%s",`, g.dynamicRoles)
if g.dynamicRoles == "" {
role := fmt.Sprintf(`"role":"role:%s",`, g.dynamicRole)
if g.dynamicRole == "" {
role = ""
}
user := fmt.Sprintf(`"user":["%s"],`, g.userName)
if g.userName == "" {
user = ""
}
payload := fmt.Sprintf(`{%s %s "channel":"%s"}`, user, role, g.dynamicChannels)
payload := fmt.Sprintf(`{%s %s "channel":"%s"}`, user, role, g.dynamicChannel)

return payload
}
Expand Down Expand Up @@ -364,8 +363,8 @@ func TestGetAllChannelsByUser(t *testing.T) {
user: "alice",
},
docGrant{
userName: "alice",
dynamicChannels: "A",
userName: "alice",
dynamicChannel: "A",
output: `
{"all_channels":{"_default._default": {
"A": { "entries" : ["2-0"], "updated_at":0}
Expand All @@ -376,17 +375,20 @@ func TestGetAllChannelsByUser(t *testing.T) {
{
name: "dynamic role grant channels",
grants: []grant{
// create user
userGrant{
user: "alice",
},
// create role with channels
roleGrant{
role: "role1",
adminChannels: map[string][]string{defaultKeyspace: {"A", "B"}},
},
// assign role through the sync fn and check output
docGrant{
userName: "alice",
dynamicRoles: "role1",
dynamicChannels: "chan1",
userName: "alice",
dynamicRole: "role1",
dynamicChannel: "chan1",
output: `
{"all_channels":{"_default._default": {
"A": { "entries" : ["3-0"], "updated_at":0},
Expand All @@ -399,13 +401,15 @@ func TestGetAllChannelsByUser(t *testing.T) {
{
name: "channel assigned through both dynamic and admin grants, assert earlier sequence (admin) is used",
grants: []grant{
// create user and assign channels through admin_channels
userGrant{
user: "alice",
adminChannels: map[string][]string{defaultKeyspace: {"A"}},
},
// assign channels through sync fn and assert on sequences
docGrant{
userName: "alice",
dynamicChannels: "A",
userName: "alice",
dynamicChannel: "A",
output: `
{"all_channels":{"_default._default": {
"A": { "entries" : ["1-0"], "updated_at":0}
Expand All @@ -416,13 +420,16 @@ func TestGetAllChannelsByUser(t *testing.T) {
{
name: "channel assigned through both dynamic and admin grants, assert earlier sequence (dynamic) is used",
grants: []grant{
// create user with no channels
userGrant{
user: "alice",
},
// create doc and assign dynamic chan through sync fn
docGrant{
userName: "alice",
dynamicChannels: "A",
userName: "alice",
dynamicChannel: "A",
},
// assign same channels through admin_channels and assert on sequences
userGrant{
user: "alice",
adminChannels: map[string][]string{defaultKeyspace: {"A"}},
Expand All @@ -436,14 +443,17 @@ func TestGetAllChannelsByUser(t *testing.T) {
{
name: "channel assigned through both admin and admin role grants, assert earlier sequence (admin) is used",
grants: []grant{
// create user and assign channel through admin_channels
userGrant{
user: "alice",
adminChannels: map[string][]string{defaultKeyspace: {"A"}},
},
// create role with same channel
roleGrant{
role: "role1",
adminChannels: map[string][]string{defaultKeyspace: {"A"}},
},
// assign role through admin_roles and assert on sequences
userGrant{
user: "alice",
roles: []string{"role1"},
Expand All @@ -457,17 +467,21 @@ func TestGetAllChannelsByUser(t *testing.T) {
{
name: "channel assigned through both admin and admin role grants, assert earlier sequence (admin role) is used",
grants: []grant{
// create user with no channels
userGrant{
user: "alice",
},
// create role with channel
roleGrant{
role: "role1",
adminChannels: map[string][]string{defaultKeyspace: {"A"}},
},
// assign role through admin_roles
userGrant{
user: "alice",
roles: []string{"role1"},
},
// assign role channel through admin_channels and assert on sequences
userGrant{
user: "alice",
adminChannels: map[string][]string{defaultKeyspace: {"A"}},
Expand All @@ -481,18 +495,22 @@ func TestGetAllChannelsByUser(t *testing.T) {
{
name: "channel assigned through both dynamic role and admin grants, assert earlier sequence (dynamic role) is used",
grants: []grant{
// create user with no channels
userGrant{
user: "alice",
},
// create role with channel
roleGrant{
role: "role1",
adminChannels: map[string][]string{defaultKeyspace: {"A"}},
},
// create doc and assign role through sync fn
docGrant{
userName: "alice",
dynamicRoles: "role1",
dynamicChannels: "docChan",
userName: "alice",
dynamicRole: "role1",
dynamicChannel: "docChan",
},
// assign role cahnnel to user through admin_channels and assert on sequences
userGrant{
user: "alice",
adminChannels: map[string][]string{defaultKeyspace: {"A"}},
Expand All @@ -507,22 +525,21 @@ func TestGetAllChannelsByUser(t *testing.T) {
{
name: "channel assigned through both dynamic role and admin grants, assert earlier sequence (admin) is used",
grants: []grant{
// create user with channel
userGrant{
user: "alice",
adminChannels: map[string][]string{defaultKeyspace: {"A"}},
},
// create role with same channel
roleGrant{
role: "role1",
adminChannels: map[string][]string{defaultKeyspace: {"A"}},
},
// assign role to user through sync fn and assert channel sequence is from admin_channels
docGrant{
userName: "alice",
dynamicRoles: "role1",
dynamicChannels: "docChan",
},
userGrant{
user: "alice",
adminChannels: map[string][]string{defaultKeyspace: {"A"}},
userName: "alice",
dynamicRole: "role1",
dynamicChannel: "docChan",
output: `
{"all_channels":{"_default._default": {
"A": { "entries" : ["1-0"], "updated_at":0},
Expand All @@ -534,22 +551,27 @@ func TestGetAllChannelsByUser(t *testing.T) {
{
name: "channel assigned through both dynamic role and admin role grants, assert earlier sequence (dynamic role) is used",
grants: []grant{
// create user with no channels
userGrant{
user: "alice",
},
// create role with channel
roleGrant{
role: "role1",
adminChannels: map[string][]string{defaultKeyspace: {"A"}},
},
// create another role with same channel
roleGrant{
role: "role2",
adminChannels: map[string][]string{defaultKeyspace: {"A"}},
},
// assign first role through sync fn
docGrant{
userName: "alice",
dynamicRoles: "role1",
dynamicChannels: "docChan",
userName: "alice",
dynamicRole: "role1",
dynamicChannel: "docChan",
},
// assign second role through admin_roles and assert sequence is from dynamic (first) role
userGrant{
user: "alice",
roles: []string{"role2"},
Expand All @@ -564,25 +586,30 @@ func TestGetAllChannelsByUser(t *testing.T) {
{
name: "channel assigned through both dynamic role and admin role grants, assert earlier sequence (admin role) is used",
grants: []grant{
// create user with no channels
userGrant{
user: "alice",
},
// create role with channel
roleGrant{
role: "role1",
adminChannels: map[string][]string{defaultKeyspace: {"A"}},
},
// create another role with same channel
roleGrant{
role: "role2",
adminChannels: map[string][]string{defaultKeyspace: {"A"}},
},
// assign role through admin_roles
userGrant{
user: "alice",
roles: []string{"role2"},
roles: []string{"role1"},
},
// assign other role through sync fn and assert earlier sequences are returned
docGrant{
userName: "alice",
dynamicRoles: "role1",
dynamicChannels: "docChan",
userName: "alice",
dynamicRole: "role2",
dynamicChannel: "docChan",
output: `
{"all_channels":{"_default._default": {
"A": { "entries" : ["4-0"], "updated_at":0},
Expand All @@ -604,7 +631,7 @@ func TestGetAllChannelsByUser(t *testing.T) {
dbConfig.Sync = base.StringPtr(`function(doc) {channel(doc.channel); access(doc.user, doc.channel); role(doc.user, doc.role);}`)
rt.CreateDatabase("db", dbConfig)

// create user with adminChannels1
// iterate and execute grants in each test case
for i, grant := range test.grants {
t.Logf("Processing grant %d", i+1)
grant.request(rt)
Expand Down Expand Up @@ -633,6 +660,7 @@ func TestGetAllChannelsByUserWithSingleNamedCollection(t *testing.T) {
}
assert.Equal(t, expectedKeyspaces, rt.GetKeyspaces())

// add single named collection
newCollection := base.ScopeAndCollectionName{Scope: base.DefaultScope, Collection: t.Name()}
require.NoError(t, rt.TestBucket.CreateDataStore(base.TestCtx(t), newCollection))
defer func() {
Expand Down Expand Up @@ -664,7 +692,7 @@ func TestGetAllChannelsByUserWithSingleNamedCollection(t *testing.T) {
}
grant.request(rt)

// check single named collection is handled
// add channel to single named collection and assert its handled
grant = userGrant{
user: "alice",
adminChannels: map[string][]string{defaultKeyspace: {"A"}, newCollection.String(): {"D"}},
Expand Down Expand Up @@ -730,7 +758,7 @@ func TestGetAllChannelsByUserWithMultiCollections(t *testing.T) {
}
grant.request(rt)

// check single named collection is handled
// add channel to collection with no channels and assert multi collection is handled
grant = userGrant{
user: "alice",
adminChannels: map[string][]string{keyspace2: {"A"}, keyspace1: {"D"}},
Expand Down Expand Up @@ -836,10 +864,10 @@ func TestGetAllChannelsByUserDeletedRole(t *testing.T) {
roleGrant.request(rt)
userGrant.request(rt)

// Delete role and assert its channels no longer appear in response
resp := rt.SendAdminRequest("DELETE", "/db/_role/role1", ``)
RequireStatus(t, resp, http.StatusOK)

// Delete role and assert its channels no longer appear in response
userGrant.output = `{}`
userGrant.roles = []string{}
userGrant.request(rt)
Expand All @@ -856,6 +884,7 @@ func TestGetAllChannelsByUserNonexistentAndDeletedUser(t *testing.T) {
dbConfig := rt.NewDbConfig()
dbConfig.Scopes = nil
rt.CreateDatabase("db", dbConfig)

// assert the endpoint returns 404 when user is not found
resp := rt.SendDiagnosticRequest("GET", "/db/_user/user1/_all_channels", ``)
RequireStatus(t, resp, http.StatusNotFound)
Expand Down

0 comments on commit dc66efe

Please sign in to comment.