Skip to content

Commit e518ba8

Browse files
authored
Merge pull request #23 from ConductorOne/goldschmidt/pages-provisioning
Provisioning for page
2 parents 78de76a + df7afda commit e518ba8

File tree

10 files changed

+547
-120
lines changed

10 files changed

+547
-120
lines changed

.golangci.yml

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ linters-settings:
3131
rules:
3232
- name: atomic
3333
- name: line-length-limit
34-
arguments: [ 200 ]
34+
arguments: [ 300 ]
3535
# These are functions that we use without checking the errors often. Most of these can't return an error even
3636
# though they implement an interface that can.
3737
- name: unhandled-error
@@ -73,7 +73,6 @@ linters:
7373
- durationcheck # check for two durations multiplied together
7474
- errorlint # errorlint is a linter for that can be used to find code that will cause problems with the error wrapping scheme introduced in Go 1.13.
7575
- exhaustive # check exhaustiveness of enum switch statements
76-
- exportloopref # checks for pointers to enclosing loop variables
7776
- forbidigo # Forbids identifiers
7877
- gochecknoinits # Checks that no init functions are present in Go code
7978
- goconst # Finds repeated strings that could be replaced by a constant

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ CREATE USER baton WITH PASSWORD 'secure-password';
1414
```postgresql
1515
GRANT SELECT ("id", "name", "organizationId", "universalAccess", "universalResourceAccess", "universalQueryLibraryAccess",
1616
"userListAccess", "auditLogAccess", "unpublishedReleaseAccess") ON groups TO baton;
17-
GRANT SELECT, INSERT, UPDATE ("id", "accessLevel") ON group_pages TO baton;
17+
GRANT SELECT, INSERT, UPDATE ("id", "accessLevel"), DELETE ON group_pages TO baton;
1818
GRANT SELECT, INSERT, UPDATE ("id", "accessLevel") ON group_folder_defaults TO baton;
1919
GRANT SELECT, INSERT, UPDATE ("id", "accessLevel") on group_resources TO baton;
2020
GRANT SELECT, INSERT, UPDATE ("id", "accessLevel") on group_resource_folder_defaults TO baton;

pkg/client/group.go

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,53 @@ func (c *Client) GetGroupPage(ctx context.Context, groupID int64, pageID int64)
102102
return &ret, nil
103103
}
104104

105+
func (c *Client) InsertGroupPage(ctx context.Context, groupID int64, pageID int64, accessLevel string) error {
106+
l := ctxzap.Extract(ctx)
107+
l.Debug("inserting group page", zap.Int64("group_id", groupID), zap.Int64("page_id", pageID), zap.String("access_level", accessLevel))
108+
109+
args := []interface{}{groupID, pageID, accessLevel}
110+
sb := &strings.Builder{}
111+
_, _ = sb.WriteString(`INSERT INTO group_pages ("groupId", "pageId", "accessLevel", "createdAt", "updatedAt") VALUES ($1, $2, $3, NOW(), NOW())`)
112+
113+
if _, err := c.db.Exec(ctx, sb.String(), args...); err != nil {
114+
return err
115+
}
116+
117+
return nil
118+
}
119+
120+
func (c *Client) UpdateGroupPage(ctx context.Context, id int64, accessLevel string) error {
121+
l := ctxzap.Extract(ctx)
122+
l.Debug("updating group page", zap.Int64("id", id), zap.String("access_level", accessLevel))
123+
124+
args := []interface{}{accessLevel, id}
125+
sb := &strings.Builder{}
126+
_, _ = sb.WriteString(`UPDATE group_pages SET "accessLevel" = $1 WHERE "id"=$2`)
127+
128+
_, err := c.db.Exec(ctx, sb.String(), args...)
129+
130+
if err != nil {
131+
return err
132+
}
133+
134+
return nil
135+
}
136+
137+
func (c *Client) DeleteGroupPage(ctx context.Context, id int64) error {
138+
l := ctxzap.Extract(ctx)
139+
l.Debug("deleting group page", zap.Int64("id", id))
140+
141+
args := []interface{}{id}
142+
sb := &strings.Builder{}
143+
_, _ = sb.WriteString(`DELETE FROM group_pages WHERE "id"=$1`)
144+
145+
if _, err := c.db.Exec(ctx, sb.String(), args...); err != nil {
146+
return err
147+
}
148+
149+
return nil
150+
}
151+
105152
func (c *Client) GetGroupFolderDefault(ctx context.Context, groupID int64, folderID int64) (*GroupFolderDefault, error) {
106153
l := ctxzap.Extract(ctx)
107154
l.Debug("getting group folder default", zap.Int64("group_id", groupID), zap.Int64("folder_id", folderID))
@@ -219,6 +266,38 @@ func (c *Client) GetGroup(ctx context.Context, groupID int64) (*GroupModel, erro
219266
return &ret, nil
220267
}
221268

269+
func (c *Client) GetGroupByName(ctx context.Context, organizationID *int64, name string) (*GroupModel, error) {
270+
l := ctxzap.Extract(ctx)
271+
l.Debug("getting group by name", zap.Any("organization_id", organizationID), zap.String("name", name))
272+
273+
args := []interface{}{organizationID, name}
274+
sb := &strings.Builder{}
275+
_, _ = sb.WriteString(`select "id", "name", "organizationId", "universalAccess", "universalResourceAccess",
276+
"universalQueryLibraryAccess", "userListAccess", "auditLogAccess", "unpublishedReleaseAccess"
277+
from groups WHERE "organizationId"=$1 AND "name"=$2`)
278+
279+
var ret GroupModel
280+
err := pgxscan.Get(ctx, c.db, &ret, sb.String(), args...)
281+
if err != nil {
282+
return nil, err
283+
}
284+
285+
return &ret, nil
286+
}
287+
288+
func (c *Client) CreateGroup(ctx context.Context, organizationID *int64, name string) error {
289+
l := ctxzap.Extract(ctx)
290+
l.Debug("create group", zap.Any("organization_id", organizationID), zap.String("name", name))
291+
292+
args := []interface{}{name, organizationID}
293+
294+
if _, err := c.db.Exec(ctx, `INSERT INTO groups ("name", "organizationId", "createdAt", "updatedAt", "archivedAt", "usageAnalyticsAccess", "themeAccess", "unpublishedReleaseAccess", "accountDetailsAccess") VALUES ($1, $2,NOW(), NOW(), NULL, false, false, false, false)`, args...); err != nil {
295+
return err
296+
}
297+
298+
return nil
299+
}
300+
222301
func (c *Client) ListGroupsForOrg(ctx context.Context, orgID int64, pager *Pager) ([]*GroupModel, string, error) {
223302
l := ctxzap.Extract(ctx)
224303
l.Debug("listing groups for org", zap.Int64("org_id", orgID))

pkg/connector/connector.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ func (c *ConnectorImpl) ResourceSyncers(ctx context.Context) []connectorbuilder.
5353
}
5454

5555
if !c.skipPages {
56-
syncers = append(syncers, newPageSyncer(ctx, c.client, c.skipDisabledUsers))
56+
syncers = append(syncers, newPageSyncer(c.client, c.skipDisabledUsers))
5757
}
5858

5959
if !c.skipResources {

pkg/connector/groups.go

Lines changed: 37 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,9 @@ import (
88
v2 "github.com/conductorone/baton-sdk/pb/c1/connector/v2"
99
"github.com/conductorone/baton-sdk/pkg/annotations"
1010
"github.com/conductorone/baton-sdk/pkg/pagination"
11-
resources "github.com/conductorone/baton-sdk/pkg/types/resource"
11+
ent "github.com/conductorone/baton-sdk/pkg/types/entitlement"
12+
"github.com/conductorone/baton-sdk/pkg/types/grant"
13+
rs "github.com/conductorone/baton-sdk/pkg/types/resource"
1214
"github.com/grpc-ecosystem/go-grpc-middleware/logging/zap/ctxzap"
1315
"go.uber.org/zap"
1416
)
@@ -24,14 +26,6 @@ const (
2426
memberEntitlementSlug = "member"
2527
)
2628

27-
func adminEntitlementId(groupID *v2.ResourceId) string {
28-
return fmt.Sprintf("entitlement:%s:admin", groupID.Resource)
29-
}
30-
31-
func memberEntitlementId(groupID *v2.ResourceId) string {
32-
return fmt.Sprintf("entitlement:%s:member", groupID.Resource)
33-
}
34-
3529
type groupSyncer struct {
3630
resourceType *v2.ResourceType
3731
client *client.Client
@@ -66,61 +60,48 @@ func (s *groupSyncer) List(
6660
}
6761

6862
var ret []*v2.Resource
69-
for _, o := range groups {
70-
var annos annotations.Annotations
7163

64+
for _, o := range groups {
7265
p := make(map[string]interface{})
7366

7467
if o.OrganizationID != nil {
7568
p["organization_id"] = o.GetOrgID()
7669
}
7770

78-
gt, err := resources.NewGroupTrait(resources.WithGroupProfile(p))
71+
options := []rs.ResourceOption{
72+
rs.WithGroupTrait(rs.WithGroupProfile(p)),
73+
rs.WithParentResourceID(parentResourceID),
74+
}
75+
76+
resource, err := rs.NewResource(o.GetName(), s.resourceType, formatObjectID(resourceTypeGroup.Id, o.ID), options...)
7977
if err != nil {
8078
return nil, "", nil, err
8179
}
8280

83-
annos.Append(gt)
84-
85-
ret = append(ret, &v2.Resource{
86-
DisplayName: o.GetName(),
87-
Id: &v2.ResourceId{
88-
ResourceType: s.resourceType.Id,
89-
Resource: formatObjectID(s.resourceType.Id, o.ID),
90-
},
91-
ParentResourceId: parentResourceID,
92-
Annotations: annos,
93-
})
81+
ret = append(ret, resource)
9482
}
9583

9684
return ret, nextPageToken, nil, nil
9785
}
9886

9987
func (s *groupSyncer) Entitlements(ctx context.Context, resource *v2.Resource, pToken *pagination.Token) ([]*v2.Entitlement, string, annotations.Annotations, error) {
100-
var ret []*v2.Entitlement
101-
var annos annotations.Annotations
102-
103-
ret = append(ret, &v2.Entitlement{
104-
Resource: resource,
105-
Id: memberEntitlementId(resource.Id),
106-
DisplayName: fmt.Sprintf("%s Group Member", resource.DisplayName),
107-
Description: fmt.Sprintf("Is member of the %s organization", resource.DisplayName),
108-
GrantableTo: []*v2.ResourceType{resourceTypeUser},
109-
Annotations: annos,
110-
Purpose: v2.Entitlement_PURPOSE_VALUE_ASSIGNMENT,
111-
Slug: memberEntitlementSlug,
112-
})
113-
114-
ret = append(ret, &v2.Entitlement{
115-
Resource: resource,
116-
Id: adminEntitlementId(resource.Id),
117-
DisplayName: fmt.Sprintf("%s Group Admin", resource.DisplayName),
118-
Description: fmt.Sprintf("Is admin of the %s group", resource.DisplayName),
119-
GrantableTo: []*v2.ResourceType{resourceTypeUser},
120-
Annotations: annos,
121-
Purpose: v2.Entitlement_PURPOSE_VALUE_ASSIGNMENT,
122-
Slug: adminEntitlementSlug,
123-
})
88+
ret := []*v2.Entitlement{
89+
ent.NewAssignmentEntitlement(
90+
resource,
91+
memberEntitlementSlug,
92+
ent.WithGrantableTo(resourceTypeUser),
93+
ent.WithDisplayName(fmt.Sprintf("%s Group Member", resource.DisplayName)),
94+
ent.WithDescription(fmt.Sprintf("Is member of the %s group", resource.DisplayName)),
95+
),
96+
ent.NewAssignmentEntitlement(
97+
resource,
98+
adminEntitlementSlug,
99+
ent.WithGrantableTo(resourceTypeUser),
100+
ent.WithDisplayName(fmt.Sprintf("%s Group Admin", resource.DisplayName)),
101+
ent.WithDescription(fmt.Sprintf("Is admin of the %s group", resource.DisplayName)),
102+
),
103+
}
104+
124105
return ret, "", nil, nil
125106
}
126107

@@ -142,22 +123,15 @@ func (s *groupSyncer) Grants(ctx context.Context, resource *v2.Resource, pToken
142123
if m.IsAdmin {
143124
level = "admin"
144125
}
145-
entitlementID := fmt.Sprintf("entitlement:%s:%s", resource.Id.Resource, level)
146-
principalID := formatObjectID(resourceTypeUser.Id, m.GetUserID())
147-
148-
ret = append(ret, &v2.Grant{
149-
Entitlement: &v2.Entitlement{
150-
Id: entitlementID,
151-
Resource: resource,
152-
},
153-
Principal: &v2.Resource{
154-
Id: &v2.ResourceId{
155-
ResourceType: resourceTypeUser.Id,
156-
Resource: principalID,
157-
},
158-
},
159-
Id: fmt.Sprintf("grant:%s:%s", entitlementID, principalID),
160-
})
126+
127+
principalID, err := rs.NewResourceID(resourceTypeUser, formatObjectID(resourceTypeUser.Id, m.GetUserID()))
128+
if err != nil {
129+
return nil, "", nil, err
130+
}
131+
132+
newGrant := grant.NewGrant(resource, level, principalID)
133+
134+
ret = append(ret, newGrant)
161135
}
162136

163137
return ret, nextPageToken, nil, nil

pkg/connector/helpers.go

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,23 +3,17 @@ package connector
33
import (
44
"fmt"
55
"strconv"
6-
"strings"
76

87
v2 "github.com/conductorone/baton-sdk/pb/c1/connector/v2"
98
"github.com/conductorone/baton-sdk/pkg/pagination"
109
)
1110

1211
func formatObjectID(resourceTypeID string, id int64) string {
13-
return fmt.Sprintf("%s:%d", resourceTypeID, id)
12+
return fmt.Sprintf("%c%d", resourceTypeID[0], id)
1413
}
1514

1615
func parseObjectID(id string) (int64, error) {
17-
parts := strings.SplitN(id, ":", 2)
18-
if len(parts) != 2 {
19-
return 0, fmt.Errorf("invalid object ID %s", id)
20-
}
21-
22-
return strconv.ParseInt(parts[1], 10, 64)
16+
return strconv.ParseInt(id[1:], 10, 64)
2317
}
2418

2519
func formatGroupObjectID(id int64) string {

0 commit comments

Comments
 (0)