This repository has been archived by the owner on Jan 15, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 97
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: Add methods for managing RBAC assignment through resource permi…
…ssions endpoints
- Loading branch information
Aaron Godin
committed
Nov 1, 2023
1 parent
6d42666
commit a79cffe
Showing
11 changed files
with
424 additions
and
40 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,21 @@ | ||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= | ||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= | ||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= | ||
github.com/gobs/pretty v0.0.0-20180724170744-09732c25a95b h1:/vQ+oYKu+JoyaMPDsv5FzwuL2wwWBgBbtj/YLCi4LuA= | ||
github.com/gobs/pretty v0.0.0-20180724170744-09732c25a95b/go.mod h1:Xo4aNUOrJnVruqWQJBtW6+bTBDTniY8yZum5rF3b5jw= | ||
github.com/hashicorp/go-cleanhttp v0.5.2 h1:035FKYIWjmULyFRBKPs8TBQoi0x6d9G4xc9neXJWAZQ= | ||
github.com/hashicorp/go-cleanhttp v0.5.2/go.mod h1:kO/YDlP8L1346E6Sodw+PrpBSV4/SoxCXGY6BqNFT48= | ||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= | ||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= | ||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= | ||
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= | ||
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= | ||
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= | ||
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= | ||
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= | ||
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= | ||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= | ||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= | ||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= | ||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= | ||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
package gapi | ||
|
||
import ( | ||
"fmt" | ||
"strconv" | ||
) | ||
|
||
// ResourceIdent represents anything that can be considered a resource identifier. | ||
type ResourceIdent interface { | ||
fmt.Stringer | ||
} | ||
|
||
// ResourceID wraps `int64` to be a valid `ResourceIdent` | ||
type ResourceID int64 | ||
|
||
func (id ResourceID) String() string { | ||
return strconv.FormatInt(int64(id), 10) | ||
} | ||
|
||
// ResourceUID wraps `string` to be a valid `ResourceIdent` | ||
type ResourceUID string | ||
|
||
func (id ResourceUID) String() string { | ||
return string(id) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,85 @@ | ||
package gapi | ||
|
||
import ( | ||
"encoding/json" | ||
"fmt" | ||
) | ||
|
||
type ResourcePermission struct { | ||
ID int64 `json:"id"` | ||
RoleName string `json:"roleName"` | ||
IsManaged bool `json:"isManaged"` | ||
IsInherited bool `json:"isInherited"` | ||
IsServiceAccount bool `json:"isServiceAccount"` | ||
UserID int64 `json:"userId,omitempty"` | ||
UserLogin string `json:"userLogin,omitempty"` | ||
UserAvatarURL string `json:"userAvatarUrl,omitempty"` | ||
Team string `json:"team,omitempty"` | ||
TeamID int64 `json:"teamId,omitempty"` | ||
TeamAvatarUrl string `json:"teamAvatarUrl,omitempty"` | ||
BuiltInRole string `json:"builtInRole,omitempty"` | ||
Actions []string `json:"actions"` | ||
Permission string `json:"permission"` | ||
} | ||
|
||
type SetResourcePermissionsBody struct { | ||
Permissions []SetResourcePermissionItem `json:"permissions"` | ||
} | ||
|
||
type SetResourcePermissionBody struct { | ||
Permission SetResourcePermissionItem `json:"permission"` | ||
} | ||
|
||
type SetResourcePermissionItem struct { | ||
UserID int64 `json:"userId,omitempty"` | ||
TeamID int64 `json:"teamId,omitempty"` | ||
BuiltinRole string `json:"builtInRole,omitempty"` | ||
Permission string `json:"permission"` | ||
} | ||
|
||
type SetResourcePermissionsResponse struct { | ||
Message string `json:"message"` | ||
} | ||
|
||
func (c *Client) listResourcePermissions(resource string, ident ResourceIdent) ([]*ResourcePermission, error) { | ||
path := fmt.Sprintf("/api/access-control/%s/%s", resource, ident.String()) | ||
result := make([]*ResourcePermission, 0) | ||
if err := c.request("GET", path, nil, nil, &result); err != nil { | ||
return nil, fmt.Errorf("error getting %s resource permissions at %s: %w", resource, path, err) | ||
} | ||
return result, nil | ||
} | ||
|
||
func (c *Client) setResourcePermissions(resource string, ident ResourceIdent, body SetResourcePermissionsBody) (*SetResourcePermissionsResponse, error) { | ||
path := fmt.Sprintf("/api/access-control/%s/%s", resource, ident.String()) | ||
data, err := json.Marshal(body) | ||
if err != nil { | ||
return nil, fmt.Errorf("marshal err: %w", err) | ||
} | ||
|
||
result := SetResourcePermissionsResponse{} | ||
if err := c.request("POST", path, nil, data, &result); err != nil { | ||
return nil, fmt.Errorf("error setting %s resource permissions at %s: %w", resource, path, err) | ||
} | ||
return &result, nil | ||
} | ||
|
||
func (c *Client) setResourcePermissionByAssignment( | ||
resource string, | ||
ident ResourceIdent, | ||
assignmentKind string, | ||
assignmentIdent ResourceIdent, | ||
body SetResourcePermissionBody, | ||
) (*SetResourcePermissionsResponse, error) { | ||
path := fmt.Sprintf("/api/access-control/%s/%s/%s/%s", resource, ident.String(), assignmentKind, assignmentIdent.String()) | ||
data, err := json.Marshal(body) | ||
if err != nil { | ||
return nil, fmt.Errorf("marshal err: %w", err) | ||
} | ||
|
||
result := SetResourcePermissionsResponse{} | ||
if err := c.request("POST", path, nil, data, &result); err != nil { | ||
return nil, fmt.Errorf("error setting %s resource permissions for %s at %s: %w", resource, assignmentKind, path, err) | ||
} | ||
return &result, nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
package gapi | ||
|
||
import ( | ||
"net/http" | ||
"testing" | ||
|
||
"github.com/gobs/pretty" | ||
) | ||
|
||
const ( | ||
resourcePermissionsListJSON = `[ | ||
{ | ||
"id": 1, | ||
"roleName": "basic:admin", | ||
"isManaged": false, | ||
"isInherited": false, | ||
"isServiceAccount": false, | ||
"builtInRole": "Admin", | ||
"actions": [ | ||
"datasources:delete", | ||
"datasources:query", | ||
"datasources:read", | ||
"datasources:write", | ||
"datasources.caching:read", | ||
"datasources.caching:write", | ||
"datasources.permissions:read", | ||
"datasources.permissions:write" | ||
], | ||
"permission": "Admin" | ||
} | ||
]` | ||
resourcePermissionsResponseJSON = `{"message":"Permissions updated"}` | ||
) | ||
|
||
func TestListResourcePermissions(t *testing.T) { | ||
client := gapiTestTools(t, http.StatusOK, resourcePermissionsListJSON) | ||
res, err := client.listResourcePermissions("datasources", ResourceID(1)) | ||
if err != nil { | ||
t.Error(err) | ||
} | ||
t.Log(pretty.PrettyFormat(res)) | ||
} | ||
|
||
func TestSetResourcePermissions(t *testing.T) { | ||
client := gapiTestTools(t, http.StatusOK, resourcePermissionsResponseJSON) | ||
res, err := client.setResourcePermissions("datasources", ResourceID(1), SetResourcePermissionsBody{ | ||
Permissions: []SetResourcePermissionItem{ | ||
{ | ||
UserID: 1, | ||
Permission: "View", | ||
}, | ||
}, | ||
}) | ||
if err != nil { | ||
t.Error(err) | ||
} | ||
t.Log(pretty.PrettyFormat(res)) | ||
} | ||
|
||
func TestSetResourcePermissionsByAssignment(t *testing.T) { | ||
client := gapiTestTools(t, http.StatusOK, resourcePermissionsResponseJSON) | ||
res, err := client.setResourcePermissionByAssignment("datasources", ResourceID(1), "users", ResourceID(1), SetResourcePermissionBody{ | ||
Permission: SetResourcePermissionItem{ | ||
Permission: "View", | ||
}, | ||
}) | ||
if err != nil { | ||
t.Error(err) | ||
} | ||
t.Log(pretty.PrettyFormat(res)) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
package gapi | ||
|
||
import ( | ||
"testing" | ||
|
||
"github.com/stretchr/testify/require" | ||
) | ||
|
||
func TestResourceIdent(t *testing.T) { | ||
require.Equal(t, "1", ResourceID(1).String()) | ||
require.Equal(t, ResourceUID("testing").String(), "testing") | ||
} |
Oops, something went wrong.