Skip to content

Commit 0fca2cc

Browse files
committed
Refactor Grant method in orgRole to enhance error handling and role verification. Replaced role existence check with a direct API request, improved entitlement ID validation, and streamlined request creation for assigning roles to users.
1 parent f9d0764 commit 0fca2cc

File tree

1 file changed

+14
-25
lines changed

1 file changed

+14
-25
lines changed

pkg/connector/org_role.go

Lines changed: 14 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import (
55
"fmt"
66
"net/http"
77
"strconv"
8+
"strings"
89

910
v2 "github.com/conductorone/baton-sdk/pb/c1/connector/v2"
1011
"github.com/conductorone/baton-sdk/pkg/annotations"
@@ -270,7 +271,6 @@ func (o *orgRoleResourceType) Grants(
270271
func (o *orgRoleResourceType) Grant(ctx context.Context, principal *v2.Resource, entitlement *v2.Entitlement) (annotations.Annotations, error) {
271272
l := ctxzap.Extract(ctx)
272273

273-
// Needs review, I copied this from the team grant function, but roles can be granted to teams as well, but we don't necessarily support that so wasn't sure if this was the intended behavior.
274274
if principal.Id.ResourceType != resourceTypeUser.Id {
275275
l.Warn(
276276
"github-connector: only users can be granted organization roles",
@@ -291,24 +291,17 @@ func (o *orgRoleResourceType) Grant(ctx context.Context, principal *v2.Resource,
291291
}
292292

293293
// First verify that the role exists
294-
roles, resp, err := o.client.Organizations.ListRoles(ctx, orgName)
294+
req, err := o.client.NewRequest("GET", fmt.Sprintf("orgs/%s/organization-roles/%d", orgName, roleID), nil)
295295
if err != nil {
296-
if resp != nil && (resp.StatusCode == http.StatusForbidden || resp.StatusCode == http.StatusNotFound) {
297-
return nil, fmt.Errorf("failed to verify role: organization not found or insufficient permissions")
298-
}
299-
return nil, fmt.Errorf("failed to verify role: %w", err)
296+
return nil, fmt.Errorf("failed to create request: %w", err)
300297
}
301298

302-
// Check if the role exists
303-
roleExists := false
304-
for _, role := range roles.CustomRepoRoles {
305-
if role.GetID() == roleID {
306-
roleExists = true
307-
break
308-
}
299+
resp, err := o.client.Do(ctx, req, nil)
300+
if err != nil {
301+
return nil, fmt.Errorf("failed to get role existence: %w", err)
309302
}
310303

311-
if !roleExists {
304+
if resp.StatusCode != http.StatusOK {
312305
return nil, fmt.Errorf("role with ID %d not found in organization %s", roleID, orgName)
313306
}
314307

@@ -317,25 +310,21 @@ func (o *orgRoleResourceType) Grant(ctx context.Context, principal *v2.Resource,
317310
return nil, fmt.Errorf("invalid user ID: %w", err)
318311
}
319312

313+
enIDParts := strings.Split(entitlement.Id, ":")
314+
if len(enIDParts) != 3 {
315+
return nil, fmt.Errorf("github-connectorv2: invalid entitlement ID: %s", entitlement.Id)
316+
}
317+
320318
user, _, err := o.client.Users.GetByID(ctx, userID)
321319
if err != nil {
322320
return nil, fmt.Errorf("failed to get user: %w", err)
323321
}
324322

325-
l.Info("attempting to assign role",
326-
zap.String("org", orgName),
327-
zap.Int64("role_id", roleID),
328-
zap.String("user", user.GetLogin()),
329-
)
330-
331-
// Use the client's HTTP client to make the request with the correct URL format. Couldn't find a built in function for this. Cursor suggested this approach.
332-
url := fmt.Sprintf("orgs/%s/organization-roles/users/%s/%d", orgName, user.GetLogin(), roleID)
333-
req, err := o.client.NewRequest("PUT", url, nil)
323+
reqs, err := o.client.NewRequest("PUT", fmt.Sprintf("orgs/%s/organization-roles/users/%s/%d", orgName, user.GetLogin(), roleID), nil)
334324
if err != nil {
335325
return nil, fmt.Errorf("failed to create request: %w", err)
336326
}
337-
338-
resp, err = o.client.Do(ctx, req, nil)
327+
resp, err = o.client.Do(ctx, reqs, nil)
339328
if err != nil {
340329
if resp != nil {
341330
l.Error("failed to assign role",

0 commit comments

Comments
 (0)