Multiple grant scope IDs (#4251)
Co-authored-by: Timothy Messier <tim.messier@gmail.com> Co-authored-by: Todd <github@quaddi.com>
This commit is contained in:
70 files changed
+5460
-1009
No files matched your search
@@ -15,3 +15,9 @@ issues:
|
||||
- linters:
|
||||
- staticcheck
|
||||
text: "SA1019: pbs.AuthorizedWorkerList is deprecated:"
|
||||
- linters:
|
||||
- staticcheck
|
||||
text: "SA1019: item.GetGrantScopeId is deprecated:"
|
||||
- linters:
|
||||
- staticcheck
|
||||
text: "SA1019: out.GrantScopeId is deprecated:"
|
||||
@@ -15,9 +15,18 @@ Canonical reference for changes, improvements, and bugfixes for Boundary.
|
||||
affects existing addresses (not just creation/updating via the API) so any
|
||||
existing addresses containing a port will not be able to be used as part of a
|
||||
target's session authorization call.
|
||||
* The `grant_scope_id` field on roles is now deprecated in favor of the multiple
|
||||
grant scope support.
|
||||
|
||||
### New and Improved
|
||||
|
||||
* Multiple grant scopes in roles: Roles now support multiple grant scopes, along
|
||||
with the special values `this`, `children` (global/org only) to apply to all
|
||||
direct children of a scope, and `descendants` (global only) to apply to all
|
||||
descendants of a scope. These use the new actions `add-grant-scopes`,
|
||||
`set-grant-scopes`, and `remove-grant-scopes` on roles. For now the
|
||||
`grant_scope_id` field on roles will continue to be able to be set, which will
|
||||
set a single grant scope, but this capability is now deprecated.
|
||||
* Policies (Enterprise and HCP Boundary only): This release introduces Policies, a
|
||||
Boundary resource that represents a Governance Policy to enforce. The first
|
||||
implementation targets Storage Policies, which enables administrators to automate
|
||||
|
||||
@@ -157,6 +157,7 @@ protobuild:
|
||||
@protoc-go-inject-tag -input=./internal/iam/store/role.pb.go
|
||||
@protoc-go-inject-tag -input=./internal/iam/store/principal_role.pb.go
|
||||
@protoc-go-inject-tag -input=./internal/iam/store/role_grant.pb.go
|
||||
@protoc-go-inject-tag -input=./internal/iam/store/role_grant_scope.pb.go
|
||||
@protoc-go-inject-tag -input=./internal/iam/store/user.pb.go
|
||||
@protoc-go-inject-tag -input=./internal/iam/store/scope.pb.go
|
||||
@protoc-go-inject-tag -input=./internal/iam/store/group.pb.go
|
||||
|
||||
@@ -27,6 +27,7 @@ type Role struct {
|
||||
UpdatedTime time.Time `json:"updated_time,omitempty"`
|
||||
Version uint32 `json:"version,omitempty"`
|
||||
GrantScopeId string `json:"grant_scope_id,omitempty"`
|
||||
GrantScopeIds []string `json:"grant_scope_ids,omitempty"`
|
||||
PrincipalIds []string `json:"principal_ids,omitempty"`
|
||||
Principals []*Principal `json:"principals,omitempty"`
|
||||
GrantStrings []string `json:"grant_strings,omitempty"`
|
||||
@@ -448,6 +449,76 @@ func (c *Client) List(ctx context.Context, scopeId string, opt ...Option) (*Role
|
||||
return target, nil
|
||||
}
|
||||
|
||||
func (c *Client) AddGrantScopes(ctx context.Context, id string, version uint32, grantScopeIds []string, opt ...Option) (*RoleUpdateResult, error) {
|
||||
if id == "" {
|
||||
return nil, fmt.Errorf("empty id value passed into AddGrantScopes request")
|
||||
}
|
||||
|
||||
if len(grantScopeIds) == 0 {
|
||||
return nil, errors.New("empty grantScopeIds passed into AddGrantScopes request")
|
||||
}
|
||||
|
||||
if c.client == nil {
|
||||
return nil, errors.New("nil client")
|
||||
}
|
||||
|
||||
opts, apiOpts := getOpts(opt...)
|
||||
|
||||
if version == 0 {
|
||||
if !opts.withAutomaticVersioning {
|
||||
return nil, errors.New("zero version number passed into AddGrantScopes request")
|
||||
}
|
||||
existingTarget, existingErr := c.Read(ctx, id, append([]Option{WithSkipCurlOutput(true)}, opt...)...)
|
||||
if existingErr != nil {
|
||||
if api.AsServerError(existingErr) != nil {
|
||||
return nil, fmt.Errorf("error from controller when performing initial check-and-set read: %w", existingErr)
|
||||
}
|
||||
return nil, fmt.Errorf("error performing initial check-and-set read: %w", existingErr)
|
||||
}
|
||||
if existingTarget == nil {
|
||||
return nil, errors.New("nil resource response found when performing initial check-and-set read")
|
||||
}
|
||||
if existingTarget.Item == nil {
|
||||
return nil, errors.New("nil resource found when performing initial check-and-set read")
|
||||
}
|
||||
version = existingTarget.Item.Version
|
||||
}
|
||||
|
||||
opts.postMap["version"] = version
|
||||
|
||||
opts.postMap["grant_scope_ids"] = grantScopeIds
|
||||
|
||||
req, err := c.client.NewRequest(ctx, "POST", fmt.Sprintf("roles/%s:add-grant-scopes", url.PathEscape(id)), opts.postMap, apiOpts...)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error creating AddGrantScopes request: %w", err)
|
||||
}
|
||||
|
||||
if len(opts.queryMap) > 0 {
|
||||
q := url.Values{}
|
||||
for k, v := range opts.queryMap {
|
||||
q.Add(k, v)
|
||||
}
|
||||
req.URL.RawQuery = q.Encode()
|
||||
}
|
||||
|
||||
resp, err := c.client.Do(req)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error performing client request during AddGrantScopes call: %w", err)
|
||||
}
|
||||
|
||||
target := new(RoleUpdateResult)
|
||||
target.Item = new(Role)
|
||||
apiErr, err := resp.Decode(target.Item)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error decoding AddGrantScopes response: %w", err)
|
||||
}
|
||||
if apiErr != nil {
|
||||
return nil, apiErr
|
||||
}
|
||||
target.response = resp
|
||||
return target, nil
|
||||
}
|
||||
|
||||
func (c *Client) AddGrants(ctx context.Context, id string, version uint32, grantStrings []string, opt ...Option) (*RoleUpdateResult, error) {
|
||||
if id == "" {
|
||||
return nil, fmt.Errorf("empty id value passed into AddGrants request")
|
||||
@@ -588,6 +659,72 @@ func (c *Client) AddPrincipals(ctx context.Context, id string, version uint32, p
|
||||
return target, nil
|
||||
}
|
||||
|
||||
func (c *Client) SetGrantScopes(ctx context.Context, id string, version uint32, grantScopeIds []string, opt ...Option) (*RoleUpdateResult, error) {
|
||||
if id == "" {
|
||||
return nil, fmt.Errorf("empty id value passed into SetGrantScopes request")
|
||||
}
|
||||
|
||||
if c.client == nil {
|
||||
return nil, errors.New("nil client")
|
||||
}
|
||||
|
||||
opts, apiOpts := getOpts(opt...)
|
||||
|
||||
if version == 0 {
|
||||
if !opts.withAutomaticVersioning {
|
||||
return nil, errors.New("zero version number passed into SetGrantScopes request")
|
||||
}
|
||||
existingTarget, existingErr := c.Read(ctx, id, append([]Option{WithSkipCurlOutput(true)}, opt...)...)
|
||||
if existingErr != nil {
|
||||
if api.AsServerError(existingErr) != nil {
|
||||
return nil, fmt.Errorf("error from controller when performing initial check-and-set read: %w", existingErr)
|
||||
}
|
||||
return nil, fmt.Errorf("error performing initial check-and-set read: %w", existingErr)
|
||||
}
|
||||
if existingTarget == nil {
|
||||
return nil, errors.New("nil resource response found when performing initial check-and-set read")
|
||||
}
|
||||
if existingTarget.Item == nil {
|
||||
return nil, errors.New("nil resource found when performing initial check-and-set read")
|
||||
}
|
||||
version = existingTarget.Item.Version
|
||||
}
|
||||
|
||||
opts.postMap["version"] = version
|
||||
|
||||
opts.postMap["grant_scope_ids"] = grantScopeIds
|
||||
|
||||
req, err := c.client.NewRequest(ctx, "POST", fmt.Sprintf("roles/%s:set-grant-scopes", url.PathEscape(id)), opts.postMap, apiOpts...)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error creating SetGrantScopes request: %w", err)
|
||||
}
|
||||
|
||||
if len(opts.queryMap) > 0 {
|
||||
q := url.Values{}
|
||||
for k, v := range opts.queryMap {
|
||||
q.Add(k, v)
|
||||
}
|
||||
req.URL.RawQuery = q.Encode()
|
||||
}
|
||||
|
||||
resp, err := c.client.Do(req)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error performing client request during SetGrantScopes call: %w", err)
|
||||
}
|
||||
|
||||
target := new(RoleUpdateResult)
|
||||
target.Item = new(Role)
|
||||
apiErr, err := resp.Decode(target.Item)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error decoding SetGrantScopes response: %w", err)
|
||||
}
|
||||
if apiErr != nil {
|
||||
return nil, apiErr
|
||||
}
|
||||
target.response = resp
|
||||
return target, nil
|
||||
}
|
||||
|
||||
func (c *Client) SetGrants(ctx context.Context, id string, version uint32, grantStrings []string, opt ...Option) (*RoleUpdateResult, error) {
|
||||
if id == "" {
|
||||
return nil, fmt.Errorf("empty id value passed into SetGrants request")
|
||||
@@ -720,6 +857,76 @@ func (c *Client) SetPrincipals(ctx context.Context, id string, version uint32, p
|
||||
return target, nil
|
||||
}
|
||||
|
||||
func (c *Client) RemoveGrantScopes(ctx context.Context, id string, version uint32, grantScopeIds []string, opt ...Option) (*RoleUpdateResult, error) {
|
||||
if id == "" {
|
||||
return nil, fmt.Errorf("empty id value passed into RemoveGrantScopes request")
|
||||
}
|
||||
|
||||
if len(grantScopeIds) == 0 {
|
||||
return nil, errors.New("empty grantScopeIds passed into RemoveGrantScopes request")
|
||||
}
|
||||
|
||||
if c.client == nil {
|
||||
return nil, errors.New("nil client")
|
||||
}
|
||||
|
||||
opts, apiOpts := getOpts(opt...)
|
||||
|
||||
if version == 0 {
|
||||
if !opts.withAutomaticVersioning {
|
||||
return nil, errors.New("zero version number passed into RemoveGrantScopes request")
|
||||
}
|
||||
existingTarget, existingErr := c.Read(ctx, id, append([]Option{WithSkipCurlOutput(true)}, opt...)...)
|
||||
if existingErr != nil {
|
||||
if api.AsServerError(existingErr) != nil {
|
||||
return nil, fmt.Errorf("error from controller when performing initial check-and-set read: %w", existingErr)
|
||||
}
|
||||
return nil, fmt.Errorf("error performing initial check-and-set read: %w", existingErr)
|
||||
}
|
||||
if existingTarget == nil {
|
||||
return nil, errors.New("nil resource response found when performing initial check-and-set read")
|
||||
}
|
||||
if existingTarget.Item == nil {
|
||||
return nil, errors.New("nil resource found when performing initial check-and-set read")
|
||||
}
|
||||
version = existingTarget.Item.Version
|
||||
}
|
||||
|
||||
opts.postMap["version"] = version
|
||||
|
||||
opts.postMap["grant_scope_ids"] = grantScopeIds
|
||||
|
||||
req, err := c.client.NewRequest(ctx, "POST", fmt.Sprintf("roles/%s:remove-grant-scopes", url.PathEscape(id)), opts.postMap, apiOpts...)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error creating RemoveGrantScopes request: %w", err)
|
||||
}
|
||||
|
||||
if len(opts.queryMap) > 0 {
|
||||
q := url.Values{}
|
||||
for k, v := range opts.queryMap {
|
||||
q.Add(k, v)
|
||||
}
|
||||
req.URL.RawQuery = q.Encode()
|
||||
}
|
||||
|
||||
resp, err := c.client.Do(req)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error performing client request during RemoveGrantScopes call: %w", err)
|
||||
}
|
||||
|
||||
target := new(RoleUpdateResult)
|
||||
target.Item = new(Role)
|
||||
apiErr, err := resp.Decode(target.Item)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error decoding RemoveGrantScopes response: %w", err)
|
||||
}
|
||||
if apiErr != nil {
|
||||
return nil, apiErr
|
||||
}
|
||||
target.response = resp
|
||||
return target, nil
|
||||
}
|
||||
|
||||
func (c *Client) RemoveGrants(ctx context.Context, id string, version uint32, grantStrings []string, opt ...Option) (*RoleUpdateResult, error) {
|
||||
if id == "" {
|
||||
return nil, fmt.Errorf("empty id value passed into RemoveGrants request")
|
||||
|
||||
@@ -32,6 +32,7 @@ const (
|
||||
PrincipalIdsField = "principal_ids"
|
||||
PrincipalsField = "principals"
|
||||
GrantScopeIdField = "grant_scope_id"
|
||||
GrantScopeIdsField = "grant_scope_ids"
|
||||
GrantsField = "grants"
|
||||
GrantStringsField = "grant_strings"
|
||||
PrimaryAuthMethodIdField = "primary_auth_method_id"
|
||||
|
||||
@@ -14,6 +14,10 @@ const (
|
||||
RecoveryUserId = "u_recovery"
|
||||
|
||||
MinimumSupportedPostgresVersion = "12"
|
||||
|
||||
GrantScopeThis = "this"
|
||||
GrantScopeChildren = "children"
|
||||
GrantScopeDescendants = "descendants"
|
||||
)
|
||||
|
||||
type (
|
||||
|
||||
@@ -316,6 +316,10 @@ var inputStructs = []*structInfo{
|
||||
SliceType: "[]string",
|
||||
VarName: "grantStrings",
|
||||
},
|
||||
"GrantScopes": {
|
||||
SliceType: "[]string",
|
||||
VarName: "grantScopeIds",
|
||||
},
|
||||
},
|
||||
pluralResourceName: "roles",
|
||||
versionEnabled: true,
|
||||
|
||||
@@ -12,6 +12,7 @@ import (
|
||||
|
||||
"github.com/hashicorp/boundary/api/authmethods"
|
||||
"github.com/hashicorp/boundary/api/authtokens"
|
||||
"github.com/hashicorp/boundary/api/roles"
|
||||
"github.com/hashicorp/boundary/globals"
|
||||
"github.com/hashicorp/boundary/internal/auth/password"
|
||||
"github.com/hashicorp/boundary/internal/authtoken"
|
||||
@@ -48,6 +49,26 @@ func TestFetchActionSetForId(t *testing.T) {
|
||||
return tc.AuthTokenRepo(), nil
|
||||
}
|
||||
|
||||
// Delete the global default role so it doesn't interfere with the
|
||||
// permissions we're testing here
|
||||
rolesClient := roles.NewClient(tc.Client())
|
||||
rolesResp, err := rolesClient.List(tc.Context(), scope.Global.String())
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, rolesResp)
|
||||
assert.Len(t, rolesResp.GetItems(), 3)
|
||||
var adminRoleId string
|
||||
for _, item := range rolesResp.GetItems() {
|
||||
if strings.Contains(item.Name, "Authenticated User") ||
|
||||
strings.Contains(item.Name, "Login") {
|
||||
_, err := rolesClient.Delete(tc.Context(), item.Id)
|
||||
require.NoError(t, err)
|
||||
} else {
|
||||
adminRoleId = item.Id
|
||||
}
|
||||
}
|
||||
_, err = rolesClient.Delete(tc.Context(), adminRoleId)
|
||||
require.NoError(t, err)
|
||||
|
||||
orgRole := iam.TestRole(t, conn, org.GetPublicId())
|
||||
iam.TestUserRole(t, conn, orgRole.PublicId, token.UserId)
|
||||
iam.TestRoleGrant(t, conn, orgRole.PublicId, "ids=ttcp_foo;actions=read,update")
|
||||
@@ -132,6 +153,21 @@ func TestRecursiveListingDifferentOutputFields(t *testing.T) {
|
||||
token := tc.Token()
|
||||
client.SetToken(token.Token)
|
||||
|
||||
// Delete the global default role so it doesn't interfere with the
|
||||
// permissions we're testing here
|
||||
rolesClient := roles.NewClient(tc.Client())
|
||||
rolesResp, err := rolesClient.List(tc.Context(), scope.Global.String())
|
||||
require.NoError(err)
|
||||
require.NotNil(rolesResp)
|
||||
assert.Len(rolesResp.GetItems(), 3)
|
||||
for _, item := range rolesResp.GetItems() {
|
||||
if strings.Contains(item.Name, "Authenticated User") ||
|
||||
strings.Contains(item.Name, "Login") {
|
||||
_, err := rolesClient.Delete(tc.Context(), item.Id)
|
||||
require.NoError(err)
|
||||
}
|
||||
}
|
||||
|
||||
// Set some global permissions so we can read the auth method there. Here we
|
||||
// will expect the defaults.
|
||||
globalRole := iam.TestRole(t, conn, scope.Global.String())
|
||||
@@ -146,7 +182,7 @@ func TestRecursiveListingDifferentOutputFields(t *testing.T) {
|
||||
orgRole := iam.TestRole(t, conn, org.GetPublicId())
|
||||
iam.TestUserRole(t, conn, orgRole.PublicId, token.UserId)
|
||||
// The first and second will actually not take effect for output
|
||||
// grantsbecause it's a list and output fields are scoped by action. So we
|
||||
// grants because it's a list and output fields are scoped by action. So we
|
||||
// expect only name and scope_id for the auth methods in the scope, using
|
||||
// two patterns below. However, since you need an action on the resource for
|
||||
// list to return anything, those grants allow us to list the items, while
|
||||
|
||||
@@ -114,11 +114,19 @@ func (b *Server) CreateDevDatabase(ctx context.Context, opt ...Option) error {
|
||||
return err
|
||||
}
|
||||
|
||||
if _, err := b.CreateInitialLoginRole(ctx); err != nil {
|
||||
if c != nil {
|
||||
err = errors.Join(err, c())
|
||||
if !opts.withSkipDefaultRoleCreation {
|
||||
if _, err := b.CreateInitialLoginRole(ctx); err != nil {
|
||||
if c != nil {
|
||||
err = errors.Join(err, c())
|
||||
}
|
||||
return err
|
||||
}
|
||||
if _, err := b.CreateInitialAuthenticatedUserRole(ctx, WithAuthUserTargetAuthorizeSessionGrant(true)); err != nil {
|
||||
if c != nil {
|
||||
err = errors.Join(err, c())
|
||||
}
|
||||
return err
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
if opts.withSkipAuthMethodCreation {
|
||||
@@ -151,7 +159,10 @@ func (b *Server) CreateDevDatabase(ctx context.Context, opt ...Option) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
if _, _, err := b.CreateInitialScopes(ctx); err != nil {
|
||||
if _, _, err := b.CreateInitialScopes(ctx, WithIamOptions(
|
||||
iam.WithSkipAdminRoleCreation(true),
|
||||
iam.WithSkipDefaultRoleCreation(true),
|
||||
)); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
|
||||
@@ -45,26 +45,84 @@ func (b *Server) CreateInitialLoginRole(ctx context.Context) (*iam.Role, error)
|
||||
|
||||
pr, err := iam.NewRole(ctx,
|
||||
scope.Global.String(),
|
||||
iam.WithName("Login and Default Grants"),
|
||||
iam.WithDescription(`Role created for login capability, account self-management, and other default grants for users of the global scope at its creation time`),
|
||||
iam.WithName("Login Grants"),
|
||||
iam.WithDescription(`Role created for login capability for unauthenticated users`),
|
||||
)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error creating in memory role for generated grants: %w", err)
|
||||
}
|
||||
role, err := iamRepo.CreateRole(ctx, pr)
|
||||
role, _, _, _, err := iamRepo.CreateRole(ctx, pr)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error creating role for default generated grants: %w", err)
|
||||
}
|
||||
if _, err := iamRepo.AddRoleGrants(ctx, role.PublicId, role.Version, []string{
|
||||
"ids=*;type=scope;actions=list,no-op",
|
||||
"ids=*;type=auth-method;actions=authenticate,list",
|
||||
"ids={{.Account.Id}};actions=read,change-password",
|
||||
"ids=*;type=auth-token;actions=list,read:self,delete:self",
|
||||
"ids=*;type=auth-method;actions=list,authenticate",
|
||||
"ids=*;type=auth-token;actions=read:self,delete:self",
|
||||
}); err != nil {
|
||||
return nil, fmt.Errorf("error creating grant for default generated grants: %w", err)
|
||||
return nil, fmt.Errorf("error creating grant for initial login grants: %w", err)
|
||||
}
|
||||
if _, err := iamRepo.AddPrincipalRoles(ctx, role.PublicId, role.Version+1, []string{globals.AnonymousUserId}, nil); err != nil {
|
||||
return nil, fmt.Errorf("error adding principal to role for default generated grants: %w", err)
|
||||
if _, err := iamRepo.AddPrincipalRoles(ctx, role.PublicId, role.Version+1, []string{globals.AnonymousUserId}); err != nil {
|
||||
return nil, fmt.Errorf("error adding principal to role for initial login grants: %w", err)
|
||||
}
|
||||
if _, _, err := iamRepo.SetRoleGrantScopes(ctx, role.PublicId, role.Version+2, []string{"this", "descendants"}); err != nil {
|
||||
return nil, fmt.Errorf("error adding scope grants to role for initial login grants: %w", err)
|
||||
}
|
||||
|
||||
return role, nil
|
||||
}
|
||||
|
||||
func (b *Server) CreateInitialAuthenticatedUserRole(ctx context.Context, opt ...Option) (*iam.Role, error) {
|
||||
rw := db.New(b.Database)
|
||||
|
||||
kmsCache, err := kms.New(ctx, rw, rw)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error creating kms cache: %w", err)
|
||||
}
|
||||
if err := kmsCache.AddExternalWrappers(
|
||||
b.Context,
|
||||
kms.WithRootWrapper(b.RootKms),
|
||||
); err != nil {
|
||||
return nil, fmt.Errorf("error adding config keys to kms: %w", err)
|
||||
}
|
||||
|
||||
iamRepo, err := iam.NewRepository(ctx, rw, rw, kmsCache, iam.WithRandomReader(b.SecureRandomReader))
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("unable to create repo for initial login role: %w", err)
|
||||
}
|
||||
|
||||
pr, err := iam.NewRole(ctx,
|
||||
scope.Global.String(),
|
||||
iam.WithName("Authenticated User Grants"),
|
||||
iam.WithDescription(`Role created for account self-management, and other initial authenticated user grants`),
|
||||
)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error creating in memory role for generated grants: %w", err)
|
||||
}
|
||||
role, _, _, _, err := iamRepo.CreateRole(ctx, pr)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error creating role for default generated grants: %w", err)
|
||||
}
|
||||
grants := []string{
|
||||
"ids=*;type=scope;actions=read",
|
||||
"ids=*;type=auth-token;actions=list",
|
||||
"ids={{.Account.Id}};actions=read,change-password",
|
||||
"ids=*;type=session;actions=list,read:self,cancel:self",
|
||||
}
|
||||
opts := GetOpts(opt...)
|
||||
if opts.withAuthUserTargetAuthorizeSessionGrant {
|
||||
grants = append(grants, "ids=*;type=target;actions=list,read,authorize-session")
|
||||
} else {
|
||||
grants = append(grants, "ids=*;type=target;actions=list,read")
|
||||
}
|
||||
if _, err := iamRepo.AddRoleGrants(ctx, role.PublicId, role.Version, grants); err != nil {
|
||||
return nil, fmt.Errorf("error creating grant for initial authenticated user grants: %w", err)
|
||||
}
|
||||
if _, err := iamRepo.AddPrincipalRoles(ctx, role.PublicId, role.Version+1, []string{globals.AnyAuthenticatedUserId}); err != nil {
|
||||
return nil, fmt.Errorf("error adding principal to role for initial authenticated user grants: %w", err)
|
||||
}
|
||||
if _, _, err := iamRepo.SetRoleGrantScopes(ctx, role.PublicId, role.Version+2, []string{"this", "descendants"}); err != nil {
|
||||
return nil, fmt.Errorf("error adding scope grants to role for initial authenticated user grants: %w", err)
|
||||
}
|
||||
|
||||
return role, nil
|
||||
@@ -201,21 +259,24 @@ func (b *Server) CreateInitialPasswordAuthMethod(ctx context.Context) (*password
|
||||
pr, err := iam.NewRole(ctx,
|
||||
scope.Global.String(),
|
||||
iam.WithName("Administration"),
|
||||
iam.WithDescription(fmt.Sprintf(`Provides admin grants within the "%s" scope to the initial user`, scope.Global.String())),
|
||||
iam.WithDescription("Provides admin grants within all scopes to the initial admin user"),
|
||||
)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error creating in memory role for generated grants: %w", err)
|
||||
}
|
||||
defPermsRole, err := iamRepo.CreateRole(ctx, pr)
|
||||
adminRole, _, _, _, err := iamRepo.CreateRole(ctx, pr)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error creating role for default generated grants: %w", err)
|
||||
}
|
||||
if _, err := iamRepo.AddRoleGrants(ctx, defPermsRole.PublicId, defPermsRole.Version, []string{"ids=*;type=*;actions=*"}); err != nil {
|
||||
if _, err := iamRepo.AddRoleGrants(ctx, adminRole.PublicId, adminRole.Version, []string{"ids=*;type=*;actions=*"}); err != nil {
|
||||
return nil, fmt.Errorf("error creating grant for default generated grants: %w", err)
|
||||
}
|
||||
if _, err := iamRepo.AddPrincipalRoles(ctx, defPermsRole.PublicId, defPermsRole.Version+1, []string{u.GetPublicId()}, nil); err != nil {
|
||||
if _, err := iamRepo.AddPrincipalRoles(ctx, adminRole.PublicId, adminRole.Version+1, []string{u.GetPublicId()}, nil); err != nil {
|
||||
return nil, fmt.Errorf("error adding principal to role for default generated grants: %w", err)
|
||||
}
|
||||
if _, _, err := iamRepo.SetRoleGrantScopes(ctx, adminRole.PublicId, adminRole.Version+2, []string{"this", "descendants"}); err != nil {
|
||||
return nil, fmt.Errorf("error adding scope grants to role for default generated grants: %w", err)
|
||||
}
|
||||
return u, nil
|
||||
}
|
||||
|
||||
@@ -256,7 +317,7 @@ func (b *Server) CreateInitialPasswordAuthMethod(ctx context.Context) (*password
|
||||
return am, u, nil
|
||||
}
|
||||
|
||||
func (b *Server) CreateInitialScopes(ctx context.Context) (*iam.Scope, *iam.Scope, error) {
|
||||
func (b *Server) CreateInitialScopes(ctx context.Context, opt ...Option) (*iam.Scope, *iam.Scope, error) {
|
||||
rw := db.New(b.Database)
|
||||
|
||||
kmsCache, err := kms.New(ctx, rw, rw)
|
||||
@@ -270,6 +331,8 @@ func (b *Server) CreateInitialScopes(ctx context.Context) (*iam.Scope, *iam.Scop
|
||||
return nil, nil, fmt.Errorf("error adding config keys to kms: %w", err)
|
||||
}
|
||||
|
||||
opts := GetOpts(opt...)
|
||||
|
||||
iamRepo, err := iam.NewRepository(ctx, rw, rw, kmsCache)
|
||||
if err != nil {
|
||||
return nil, nil, fmt.Errorf("error creating scopes repository: %w", err)
|
||||
@@ -282,17 +345,20 @@ func (b *Server) CreateInitialScopes(ctx context.Context) (*iam.Scope, *iam.Scop
|
||||
return nil, nil, fmt.Errorf("error generating initial org id: %w", err)
|
||||
}
|
||||
}
|
||||
opts := []iam.Option{
|
||||
iamOpts := []iam.Option{
|
||||
iam.WithName("Generated org scope"),
|
||||
iam.WithDescription("Provides an initial org scope in Boundary"),
|
||||
iam.WithRandomReader(b.SecureRandomReader),
|
||||
iam.WithPublicId(b.DevOrgId),
|
||||
}
|
||||
orgScope, err := iam.NewOrg(ctx, opts...)
|
||||
if len(opts.withIamOptions) > 0 {
|
||||
iamOpts = append(iamOpts, opts.withIamOptions...)
|
||||
}
|
||||
orgScope, err := iam.NewOrg(ctx, iamOpts...)
|
||||
if err != nil {
|
||||
return nil, nil, fmt.Errorf("error creating new in memory org scope: %w", err)
|
||||
}
|
||||
orgScope, err = iamRepo.CreateScope(ctx, orgScope, b.DevUserId, opts...)
|
||||
orgScope, err = iamRepo.CreateScope(ctx, orgScope, b.DevUserId, iamOpts...)
|
||||
if err != nil {
|
||||
return nil, nil, fmt.Errorf("error saving org scope to the db: %w", err)
|
||||
}
|
||||
@@ -305,17 +371,20 @@ func (b *Server) CreateInitialScopes(ctx context.Context) (*iam.Scope, *iam.Scop
|
||||
return nil, nil, fmt.Errorf("error generating initial project id: %w", err)
|
||||
}
|
||||
}
|
||||
opts = []iam.Option{
|
||||
iamOpts = []iam.Option{
|
||||
iam.WithName("Generated project scope"),
|
||||
iam.WithDescription("Provides an initial project scope in Boundary"),
|
||||
iam.WithRandomReader(b.SecureRandomReader),
|
||||
iam.WithPublicId(b.DevProjectId),
|
||||
}
|
||||
projScope, err := iam.NewProject(ctx, b.DevOrgId, opts...)
|
||||
if len(opts.withIamOptions) > 0 {
|
||||
iamOpts = append(iamOpts, opts.withIamOptions...)
|
||||
}
|
||||
projScope, err := iam.NewProject(ctx, b.DevOrgId, iamOpts...)
|
||||
if err != nil {
|
||||
return nil, nil, fmt.Errorf("error creating new in memory project scope: %w", err)
|
||||
}
|
||||
projScope, err = iamRepo.CreateScope(ctx, projScope, b.DevUserId, opts...)
|
||||
projScope, err = iamRepo.CreateScope(ctx, projScope, b.DevUserId, iamOpts...)
|
||||
if err != nil {
|
||||
return nil, nil, fmt.Errorf("error saving project scope to the db: %w", err)
|
||||
}
|
||||
@@ -472,17 +541,6 @@ func (b *Server) CreateInitialTargetWithAddress(ctx context.Context) (target.Tar
|
||||
b.InfoKeys = append(b.InfoKeys, "generated target with address id")
|
||||
b.Info["generated target with address id"] = b.DevTargetId
|
||||
|
||||
if b.DevUnprivilegedUserId != "" {
|
||||
iamRepo, err := iam.NewRepository(ctx, rw, rw, kmsCache, iam.WithRandomReader(b.SecureRandomReader))
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to create iam repository: %w", err)
|
||||
}
|
||||
err = unprivilegedDevUserRoleSetup(ctx, iamRepo, b.DevUnprivilegedUserId, b.DevProjectId, b.DevTargetId)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to set up unprivileged dev user: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
return tt, nil
|
||||
}
|
||||
|
||||
@@ -540,17 +598,6 @@ func (b *Server) CreateInitialTargetWithHostSources(ctx context.Context) (target
|
||||
b.InfoKeys = append(b.InfoKeys, "generated target with host source id")
|
||||
b.Info["generated target with host source id"] = b.DevSecondaryTargetId
|
||||
|
||||
if b.DevUnprivilegedUserId != "" {
|
||||
iamRepo, err := iam.NewRepository(ctx, rw, rw, kmsCache, iam.WithRandomReader(b.SecureRandomReader))
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to create iam repository: %w", err)
|
||||
}
|
||||
err = unprivilegedDevUserRoleSetup(ctx, iamRepo, b.DevUnprivilegedUserId, b.DevProjectId, b.DevSecondaryTargetId)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to set up unprivileged dev user: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
return tt, nil
|
||||
}
|
||||
|
||||
@@ -626,83 +673,3 @@ func (b *Server) RegisterPlugin(ctx context.Context, name string, hostClient plg
|
||||
|
||||
return plg, nil
|
||||
}
|
||||
|
||||
// unprivilegedDevUserRoleSetup adds dev user to the role that grants
|
||||
// list/read:self/cancel:self on sessions and read:self/delete:self/list on
|
||||
// tokens. It also creates a role with an `authorize-session` grant for the
|
||||
// provided targetId.
|
||||
func unprivilegedDevUserRoleSetup(ctx context.Context, repo *iam.Repository, userId, projectId, targetId string) error {
|
||||
noopFilter := func(ctx context.Context, item *iam.Role) (bool, error) {
|
||||
return true, nil
|
||||
}
|
||||
roles, err := iam.ListRoles(ctx, []byte("dummy grant"), globals.DefaultMaxPageSize, noopFilter, repo, []string{projectId})
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to list existing roles for project id %q: %w", projectId, err)
|
||||
}
|
||||
|
||||
// Look for default grants role to set unprivileged user as a principal.
|
||||
defaultRoleIdx := -1
|
||||
for i, r := range roles.Items {
|
||||
// Hacky, I know, but saves a DB trip to look up other
|
||||
// characteristics like "if any principals are currently attached".
|
||||
// No matter what we pick here it's a bit heuristical.
|
||||
if r.Name == "Default Grants" {
|
||||
defaultRoleIdx = i
|
||||
break
|
||||
}
|
||||
}
|
||||
if defaultRoleIdx == -1 {
|
||||
return fmt.Errorf("couldn't find default grants role for project id %q", projectId)
|
||||
}
|
||||
defaultRole := roles.Items[defaultRoleIdx]
|
||||
|
||||
// This function may be called more than once for the same boundary
|
||||
// deployment (eg: if we're creating more than one target), so we need to
|
||||
// check if the unprivileged user is not already a principal for the default
|
||||
// role in this project, as attempting to add an existing principal is an
|
||||
// error.
|
||||
principals, err := repo.ListPrincipalRoles(ctx, defaultRole.GetPublicId())
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to list principals for default project role: %w", err)
|
||||
}
|
||||
found := false
|
||||
for _, p := range principals {
|
||||
if p.PrincipalId == userId {
|
||||
found = true
|
||||
}
|
||||
}
|
||||
if !found {
|
||||
_, err = repo.AddPrincipalRoles(ctx, defaultRole.GetPublicId(), defaultRole.GetVersion(), []string{userId})
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to add %q as principal for role id %q", userId, defaultRole.GetPublicId())
|
||||
}
|
||||
defaultRole.Version++ // The above call increments the role version in the database, so we must also track that with our state.
|
||||
}
|
||||
|
||||
// Create a new role for the "authorize-session" grant and add the
|
||||
// unprivileged user as a principal.
|
||||
asRole, err := iam.NewRole(ctx,
|
||||
projectId,
|
||||
iam.WithName(fmt.Sprintf("Session authorization for %s", targetId)),
|
||||
iam.WithDescription(fmt.Sprintf("Provides grants within the dev project scope to allow the initial unprivileged user to authorize sessions against %s", targetId)),
|
||||
)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to create role object: %w", err)
|
||||
}
|
||||
|
||||
asRole, err = repo.CreateRole(ctx, asRole)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to create role for unprivileged user: %w", err)
|
||||
}
|
||||
if _, err := repo.AddPrincipalRoles(ctx, asRole.GetPublicId(), asRole.GetVersion(), []string{userId}, nil); err != nil {
|
||||
return fmt.Errorf("failed to add unprivileged user as principal to new role: %w", err)
|
||||
}
|
||||
asRole.Version++
|
||||
|
||||
_, err = repo.AddRoleGrants(ctx, asRole.GetPublicId(), asRole.GetVersion(), []string{fmt.Sprintf("ids=%s;actions=authorize-session", targetId)})
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to add authorize-session grant for unprivileged user: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
+51
-22
@@ -5,6 +5,7 @@ package base
|
||||
|
||||
import (
|
||||
"github.com/hashicorp/boundary/internal/event"
|
||||
"github.com/hashicorp/boundary/internal/iam"
|
||||
"github.com/hashicorp/boundary/sdk/pbs/plugin"
|
||||
wrapping "github.com/hashicorp/go-kms-wrapping/v2"
|
||||
)
|
||||
@@ -25,28 +26,31 @@ type Option func(*Options)
|
||||
|
||||
// Options - how Options are represented.
|
||||
type Options struct {
|
||||
withNoTokenScope bool
|
||||
withNoTokenValue bool
|
||||
withSkipDatabaseDestruction bool
|
||||
withSkipAuthMethodCreation bool
|
||||
withSkipOidcAuthMethodCreation bool
|
||||
withSkipLdapAuthMethodCreation bool
|
||||
withSkipScopesCreation bool
|
||||
withSkipHostResourcesCreation bool
|
||||
withSkipTargetCreation bool
|
||||
withContainerImage string
|
||||
withDialect string
|
||||
withDatabaseTemplate string
|
||||
withEventerConfig *event.EventerConfig
|
||||
withEventFlags *EventFlags
|
||||
withEventWrapper wrapping.Wrapper
|
||||
withAttributeFieldPrefix string
|
||||
withStatusCode int
|
||||
withHostPlugin func() (string, plugin.HostPluginServiceClient)
|
||||
withEventGating bool
|
||||
withImplicitId string
|
||||
WithSkipScopeIdFlag bool
|
||||
WithInterceptedToken *string
|
||||
withNoTokenScope bool
|
||||
withNoTokenValue bool
|
||||
withSkipDefaultRoleCreation bool
|
||||
withSkipDatabaseDestruction bool
|
||||
withSkipAuthMethodCreation bool
|
||||
withSkipOidcAuthMethodCreation bool
|
||||
withSkipLdapAuthMethodCreation bool
|
||||
withSkipScopesCreation bool
|
||||
withSkipHostResourcesCreation bool
|
||||
withSkipTargetCreation bool
|
||||
withContainerImage string
|
||||
withDialect string
|
||||
withDatabaseTemplate string
|
||||
withEventerConfig *event.EventerConfig
|
||||
withEventFlags *EventFlags
|
||||
withEventWrapper wrapping.Wrapper
|
||||
withAttributeFieldPrefix string
|
||||
withStatusCode int
|
||||
withHostPlugin func() (string, plugin.HostPluginServiceClient)
|
||||
withEventGating bool
|
||||
withImplicitId string
|
||||
WithSkipScopeIdFlag bool
|
||||
WithInterceptedToken *string
|
||||
withAuthUserTargetAuthorizeSessionGrant bool
|
||||
withIamOptions []iam.Option
|
||||
}
|
||||
|
||||
func getDefaultOptions() Options {
|
||||
@@ -81,6 +85,14 @@ func WithNoTokenValue() Option {
|
||||
}
|
||||
}
|
||||
|
||||
// WithSkipDefaultRoleCreation tells the command not to instantiate the default
|
||||
// global role
|
||||
func WithSkipDefaultRoleCreation() Option {
|
||||
return func(o *Options) {
|
||||
o.withSkipDefaultRoleCreation = true
|
||||
}
|
||||
}
|
||||
|
||||
// WithSkipAuthMethodCreation tells the command not to instantiate any auth
|
||||
// method on first run.
|
||||
func WithSkipAuthMethodCreation() Option {
|
||||
@@ -227,3 +239,20 @@ func WithInterceptedToken(s *string) Option {
|
||||
o.WithInterceptedToken = s
|
||||
}
|
||||
}
|
||||
|
||||
// WithAuthUserTargetAuthorizeSessionGrant indicates that we should add an
|
||||
// authorize-session grant to the global authenticated user role. This is the
|
||||
// default for dev mode.
|
||||
func WithAuthUserTargetAuthorizeSessionGrant(with bool) Option {
|
||||
return func(o *Options) {
|
||||
o.withAuthUserTargetAuthorizeSessionGrant = with
|
||||
}
|
||||
}
|
||||
|
||||
// WithIamOptions provides options to pass through to the IAM package when
|
||||
// creating initial resources
|
||||
func WithIamOptions(with ...iam.Option) Option {
|
||||
return func(o *Options) {
|
||||
o.withIamOptions = with
|
||||
}
|
||||
}
|
||||
@@ -7,6 +7,7 @@ import (
|
||||
"testing"
|
||||
|
||||
"github.com/hashicorp/boundary/internal/event"
|
||||
"github.com/hashicorp/boundary/internal/iam"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
@@ -71,6 +72,13 @@ func Test_GetOpts(t *testing.T) {
|
||||
testOpts.withNoTokenValue = true
|
||||
assert.Equal(opts, testOpts)
|
||||
})
|
||||
t.Run("WithSkipDefaultRoleCreation", func(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
opts := GetOpts(WithSkipDefaultRoleCreation())
|
||||
testOpts := getDefaultOptions()
|
||||
testOpts.withSkipDefaultRoleCreation = true
|
||||
assert.Equal(opts, testOpts)
|
||||
})
|
||||
t.Run("WithSkipAuthMethodCreation", func(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
opts := GetOpts(WithSkipAuthMethodCreation())
|
||||
@@ -151,4 +159,20 @@ func Test_GetOpts(t *testing.T) {
|
||||
testOpts.WithInterceptedToken = &s
|
||||
assert.Equal(opts, testOpts)
|
||||
})
|
||||
|
||||
t.Run("WithAuthUserTargetAuthorizeSessionGrant", func(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
opts := getDefaultOptions()
|
||||
assert.False(opts.withAuthUserTargetAuthorizeSessionGrant)
|
||||
opts = GetOpts(WithAuthUserTargetAuthorizeSessionGrant(true))
|
||||
assert.True(opts.withAuthUserTargetAuthorizeSessionGrant)
|
||||
})
|
||||
|
||||
t.Run("WithIamOptions", func(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
testOpts := getDefaultOptions()
|
||||
assert.Len(testOpts.withIamOptions, 0)
|
||||
opts := GetOpts(WithIamOptions(iam.WithSkipAdminRoleCreation(true)))
|
||||
assert.Len(opts.withIamOptions, 1)
|
||||
})
|
||||
}
|
||||
@@ -895,6 +895,21 @@ func initCommands(ui, serverCmdUi cli.Ui, runOpts *RunOptions) {
|
||||
Command: base.NewCommand(ui, opts...),
|
||||
Func: "remove-grants",
|
||||
}),
|
||||
"roles add-grant-scopes": clientCacheWrapper(
|
||||
&rolescmd.Command{
|
||||
Command: base.NewCommand(ui, opts...),
|
||||
Func: "add-grant-scopes",
|
||||
}),
|
||||
"roles set-grant-scopes": clientCacheWrapper(
|
||||
&rolescmd.Command{
|
||||
Command: base.NewCommand(ui, opts...),
|
||||
Func: "set-grant-scopes",
|
||||
}),
|
||||
"roles remove-grant-scopes": clientCacheWrapper(
|
||||
&rolescmd.Command{
|
||||
Command: base.NewCommand(ui, opts...),
|
||||
Func: "remove-grant-scopes",
|
||||
}),
|
||||
|
||||
"scopes": func() (cli.Command, error) {
|
||||
return &scopescmd.Command{
|
||||
|
||||
@@ -71,6 +71,13 @@ func (c *Command) Flags() *base.FlagSets {
|
||||
}
|
||||
|
||||
func (c *Command) Run(args []string) int {
|
||||
f := c.Flags()
|
||||
|
||||
if err := f.Parse(args); err != nil {
|
||||
c.PrintCliError(err)
|
||||
return base.CommandUserError
|
||||
}
|
||||
|
||||
client, err := c.Client(base.WithNoTokenScope(), base.WithNoTokenValue())
|
||||
if c.WrapperCleanupFunc != nil {
|
||||
defer func() {
|
||||
@@ -84,13 +91,6 @@ func (c *Command) Run(args []string) int {
|
||||
return base.CommandCliError
|
||||
}
|
||||
|
||||
f := c.Flags()
|
||||
|
||||
if err := f.Parse(args); err != nil {
|
||||
c.PrintCliError(err)
|
||||
return base.CommandUserError
|
||||
}
|
||||
|
||||
// Lookup the primary auth method ID in the global scope
|
||||
aClient := authmethods.NewClient(client)
|
||||
pri, err := getPrimaryAuthMethodId(c.Context, aClient, scope.Global.String(), "")
|
||||
|
||||
@@ -107,7 +107,7 @@ type RoleInfo struct {
|
||||
Name string `json:"name"`
|
||||
}
|
||||
|
||||
func generateInitialRoleTableOutput(in *RoleInfo) string {
|
||||
func generateInitialLoginRoleTableOutput(in *RoleInfo) string {
|
||||
nonAttributeMap := map[string]any{
|
||||
"Role ID": in.RoleId,
|
||||
"Name": in.Name,
|
||||
@@ -129,6 +129,28 @@ func generateInitialRoleTableOutput(in *RoleInfo) string {
|
||||
return base.WrapForHelpText(ret)
|
||||
}
|
||||
|
||||
func generateInitialAuthenticatedUserRoleOutput(in *RoleInfo) string {
|
||||
nonAttributeMap := map[string]any{
|
||||
"Role ID": in.RoleId,
|
||||
"Name": in.Name,
|
||||
}
|
||||
|
||||
maxLength := 0
|
||||
for k := range nonAttributeMap {
|
||||
if len(k) > maxLength {
|
||||
maxLength = len(k)
|
||||
}
|
||||
}
|
||||
|
||||
ret := []string{
|
||||
"",
|
||||
"Initial authenticated user role information:",
|
||||
base.WrapMap(2, maxLength+2, nonAttributeMap),
|
||||
}
|
||||
|
||||
return base.WrapForHelpText(ret)
|
||||
}
|
||||
|
||||
type AuthInfo struct {
|
||||
AuthMethodId string `json:"auth_method_id"`
|
||||
AuthMethodName string `json:"auth_method_name"`
|
||||
|
||||
@@ -37,16 +37,17 @@ type InitCommand struct {
|
||||
// deferred function on the Run method.
|
||||
configWrapperCleanupFunc func() error
|
||||
|
||||
flagConfig []string
|
||||
flagConfigKms string
|
||||
flagLogLevel string
|
||||
flagLogFormat string
|
||||
flagMigrationUrl string
|
||||
flagSkipInitialLoginRoleCreation bool
|
||||
flagSkipAuthMethodCreation bool
|
||||
flagSkipScopesCreation bool
|
||||
flagSkipHostResourcesCreation bool
|
||||
flagSkipTargetCreation bool
|
||||
flagConfig []string
|
||||
flagConfigKms string
|
||||
flagLogLevel string
|
||||
flagLogFormat string
|
||||
flagMigrationUrl string
|
||||
flagSkipInitialLoginRoleCreation bool
|
||||
flagSkipInitialAuthenticatedUserRoleCreation bool
|
||||
flagSkipAuthMethodCreation bool
|
||||
flagSkipScopesCreation bool
|
||||
flagSkipHostResourcesCreation bool
|
||||
flagSkipTargetCreation bool
|
||||
}
|
||||
|
||||
func (c *InitCommand) Synopsis() string {
|
||||
@@ -124,31 +125,37 @@ func (c *InitCommand) Flags() *base.FlagSets {
|
||||
f.BoolVar(&base.BoolVar{
|
||||
Name: "skip-initial-login-role-creation",
|
||||
Target: &c.flagSkipInitialLoginRoleCreation,
|
||||
Usage: "If not set, a default role allowing necessary grants for logging in will not be created as part of initialization. If set, the recovery KMS will be needed to perform any actions.",
|
||||
Usage: "If set, a role providing necessary grants for logging in will not be created as part of initialization. If set, the recovery KMS will be needed to perform any actions.",
|
||||
})
|
||||
|
||||
f.BoolVar(&base.BoolVar{
|
||||
Name: "skip-initial-authenticated-user-role-creation",
|
||||
Target: &c.flagSkipInitialAuthenticatedUserRoleCreation,
|
||||
Usage: "If set, a role providing initial grants for any authenticated user will not be created as part of initialization.",
|
||||
})
|
||||
|
||||
f.BoolVar(&base.BoolVar{
|
||||
Name: "skip-auth-method-creation",
|
||||
Target: &c.flagSkipAuthMethodCreation,
|
||||
Usage: "If not set, an auth method will not be created as part of initialization. If set, the recovery KMS will be needed to perform any actions.",
|
||||
Usage: "If set, an auth method will not be created as part of initialization. If set, the recovery KMS will be needed to perform any actions.",
|
||||
})
|
||||
|
||||
f.BoolVar(&base.BoolVar{
|
||||
Name: "skip-scopes-creation",
|
||||
Target: &c.flagSkipScopesCreation,
|
||||
Usage: "If not set, scopes will not be created as part of initialization.",
|
||||
Usage: "If set, scopes will not be created as part of initialization.",
|
||||
})
|
||||
|
||||
f.BoolVar(&base.BoolVar{
|
||||
Name: "skip-host-resources-creation",
|
||||
Target: &c.flagSkipHostResourcesCreation,
|
||||
Usage: "If not set, host resources (host catalog, host set, host) will not be created as part of initialization.",
|
||||
Usage: "If set, host resources (host catalog, host set, host) will not be created as part of initialization.",
|
||||
})
|
||||
|
||||
f.BoolVar(&base.BoolVar{
|
||||
Name: "skip-target-creation",
|
||||
Target: &c.flagSkipTargetCreation,
|
||||
Usage: "If not set, a target will not be created as part of initialization.",
|
||||
Usage: "If set, a target will not be created as part of initialization.",
|
||||
})
|
||||
|
||||
f.StringVar(&base.StringVar{
|
||||
@@ -330,11 +337,32 @@ func (c *InitCommand) Run(args []string) (retCode int) {
|
||||
}
|
||||
switch base.Format(c.UI) {
|
||||
case "table":
|
||||
c.UI.Output(generateInitialRoleTableOutput(roleInfo))
|
||||
c.UI.Output(generateInitialLoginRoleTableOutput(roleInfo))
|
||||
case "json":
|
||||
jsonMap["login_role"] = roleInfo
|
||||
}
|
||||
|
||||
if c.flagSkipInitialAuthenticatedUserRoleCreation {
|
||||
return base.CommandSuccess
|
||||
}
|
||||
|
||||
role, err = c.CreateInitialAuthenticatedUserRole(c.Context)
|
||||
if err != nil {
|
||||
c.UI.Error(fmt.Errorf("Error creating initial global-scoped authenticated user role: %w", err).Error())
|
||||
return base.CommandCliError
|
||||
}
|
||||
|
||||
roleInfo = &RoleInfo{
|
||||
RoleId: role.PublicId,
|
||||
Name: role.Name,
|
||||
}
|
||||
switch base.Format(c.UI) {
|
||||
case "table":
|
||||
c.UI.Output(generateInitialAuthenticatedUserRoleOutput(roleInfo))
|
||||
case "json":
|
||||
jsonMap["authenticated_user_role"] = roleInfo
|
||||
}
|
||||
|
||||
if c.flagSkipAuthMethodCreation {
|
||||
return base.CommandSuccess
|
||||
}
|
||||
|
||||
@@ -79,7 +79,7 @@ type Command struct {
|
||||
flagTargetDefaultPort int
|
||||
flagTargetSessionMaxSeconds int
|
||||
flagTargetSessionConnectionLimit int
|
||||
flagControllerAPIListenAddr string
|
||||
flagControllerApiListenAddr string
|
||||
flagControllerClusterListenAddr string
|
||||
flagControllerPublicClusterAddr string
|
||||
flagControllerOnly bool
|
||||
@@ -102,6 +102,8 @@ type Command struct {
|
||||
flagCreateLoopbackPlugin bool
|
||||
flagPluginExecutionDir string
|
||||
flagSkipPlugins bool
|
||||
flagSkipOidcAuthMethodCreation bool
|
||||
flagSkipLdapAuthMethodCreation bool
|
||||
flagWorkerDnsServer string
|
||||
flagWorkerAuthMethod string
|
||||
flagWorkerAuthStorageDir string
|
||||
@@ -202,7 +204,7 @@ func (c *Command) Flags() *base.FlagSets {
|
||||
|
||||
f.StringVar(&base.StringVar{
|
||||
Name: "api-listen-address",
|
||||
Target: &c.flagControllerAPIListenAddr,
|
||||
Target: &c.flagControllerApiListenAddr,
|
||||
EnvVar: "BOUNDARY_DEV_CONTROLLER_API_LISTEN_ADDRESS",
|
||||
Usage: "Address to bind to for controller \"api\" purpose. If this begins with a forward slash, it will be assumed to be a Unix domain socket path.",
|
||||
})
|
||||
@@ -381,6 +383,16 @@ func (c *Command) Flags() *base.FlagSets {
|
||||
Usage: "Skip loading compiled-in plugins. This does not prevent loopback plugins from being loaded if enabled.",
|
||||
Hidden: true,
|
||||
})
|
||||
f.BoolVar(&base.BoolVar{
|
||||
Name: "skip-oidc-auth-method-creation",
|
||||
Target: &c.flagSkipOidcAuthMethodCreation,
|
||||
Usage: "Skip creating a test OIDC auth method. This is useful if e.g. running a Unix API listener.",
|
||||
})
|
||||
f.BoolVar(&base.BoolVar{
|
||||
Name: "skip-ldap-auth-method-creation",
|
||||
Target: &c.flagSkipLdapAuthMethodCreation,
|
||||
Usage: "Skip creating a test LDAP auth method. This is useful if e.g. running a Unix API listener.",
|
||||
})
|
||||
f.StringVar(&base.StringVar{
|
||||
Name: "worker-dns-server",
|
||||
Target: &c.flagWorkerDnsServer,
|
||||
@@ -594,8 +606,8 @@ func (c *Command) Run(args []string) int {
|
||||
}
|
||||
switch l.Purpose[0] {
|
||||
case "api":
|
||||
if c.flagControllerAPIListenAddr != "" {
|
||||
l.Address = c.flagControllerAPIListenAddr
|
||||
if c.flagControllerApiListenAddr != "" {
|
||||
l.Address = c.flagControllerApiListenAddr
|
||||
}
|
||||
if strings.HasPrefix(l.Address, "/") {
|
||||
l.Type = "unix"
|
||||
@@ -750,6 +762,12 @@ func (c *Command) Run(args []string) int {
|
||||
}
|
||||
|
||||
var opts []base.Option
|
||||
if c.flagSkipOidcAuthMethodCreation {
|
||||
opts = append(opts, base.WithSkipOidcAuthMethodCreation())
|
||||
}
|
||||
if c.flagSkipLdapAuthMethodCreation {
|
||||
opts = append(opts, base.WithSkipLdapAuthMethodCreation())
|
||||
}
|
||||
if c.flagCreateLoopbackPlugin {
|
||||
c.DevLoopbackPluginId = "pl_1234567890"
|
||||
c.EnabledPlugins = append(c.EnabledPlugins, base.EnabledPluginLoopback)
|
||||
|
||||
@@ -26,41 +26,42 @@ func init() {
|
||||
}
|
||||
|
||||
type extraCmdVars struct {
|
||||
flagGrantScopeId string
|
||||
flagPrincipals []string
|
||||
flagGrants []string
|
||||
flagGrantScopeIds []string
|
||||
flagPrincipals []string
|
||||
flagGrants []string
|
||||
}
|
||||
|
||||
func extraActionsFlagsMapFuncImpl() map[string][]string {
|
||||
return map[string][]string{
|
||||
"create": {"grant-scope-id"},
|
||||
"update": {"grant-scope-id"},
|
||||
"add-principals": {"id", "principal", "version"},
|
||||
"set-principals": {"id", "principal", "version"},
|
||||
"remove-principals": {"id", "principal", "version"},
|
||||
"add-grants": {"id", "grant", "version"},
|
||||
"set-grants": {"id", "grant", "version"},
|
||||
"remove-grants": {"id", "grant", "version"},
|
||||
"create": {"grant-scope-id"},
|
||||
"update": {"grant-scope-id"},
|
||||
"add-principals": {"id", "principal", "version"},
|
||||
"set-principals": {"id", "principal", "version"},
|
||||
"remove-principals": {"id", "principal", "version"},
|
||||
"add-grants": {"id", "grant", "version"},
|
||||
"set-grants": {"id", "grant", "version"},
|
||||
"remove-grants": {"id", "grant", "version"},
|
||||
"add-grant-scopes": {"id", "grant-scope-id", "version"},
|
||||
"set-grant-scopes": {"id", "grant-scope-id", "version"},
|
||||
"remove-grant-scopes": {"id", "grant-scope-id", "version"},
|
||||
}
|
||||
}
|
||||
|
||||
func extraSynopsisFuncImpl(c *Command) string {
|
||||
switch c.Func {
|
||||
case "add-principals", "set-principals", "remove-principals":
|
||||
return c.principalsGrantsSynopsisFunc(c.Func, true)
|
||||
return c.principalsGrantsSynopsisFunc(c.Func, "principals (users, groups)")
|
||||
case "add-grants", "set-grants", "remove-grants":
|
||||
return c.principalsGrantsSynopsisFunc(c.Func, false)
|
||||
return c.principalsGrantsSynopsisFunc(c.Func, "grants")
|
||||
case "add-grant-scopes":
|
||||
return c.principalsGrantsSynopsisFunc(c.Func, "grant scopes")
|
||||
}
|
||||
|
||||
return ""
|
||||
}
|
||||
|
||||
func (c *Command) principalsGrantsSynopsisFunc(inFunc string, principals bool) string {
|
||||
func (c *Command) principalsGrantsSynopsisFunc(inFunc, switchStr string) string {
|
||||
var in string
|
||||
switchStr := "principals (users, groups)"
|
||||
if !principals {
|
||||
switchStr = "grants"
|
||||
}
|
||||
switch {
|
||||
case strings.HasPrefix(inFunc, "add"):
|
||||
in = fmt.Sprintf("Add %s to", switchStr)
|
||||
@@ -141,6 +142,39 @@ func (c *Command) extraHelpFunc(helpMap map[string]func() string) string {
|
||||
"",
|
||||
})
|
||||
|
||||
case "add-grant-scopes":
|
||||
helpStr = base.WrapForHelpText([]string{
|
||||
"Usage: boundary roles add-grant-scopes [options] [args]",
|
||||
"",
|
||||
` Adds grant scopes to a role given its ID. The "grant-scope-id" flag can be specified multiple times. Example:`,
|
||||
"",
|
||||
` $ boundary roles add-grant-scopes -id o_1234567890 -grant-scope-id "this" -grant-scope-id "children"`,
|
||||
"",
|
||||
"",
|
||||
})
|
||||
|
||||
case "set-grant-scopes":
|
||||
helpStr = base.WrapForHelpText([]string{
|
||||
"Usage: boundary roles set-grant-scopes [options] [args]",
|
||||
"",
|
||||
` Sets the complete set of grant scopes on a role given its ID. The "grant-scope-id" flag can be specified multiple times. Example:`,
|
||||
"",
|
||||
` $ boundary roles set-grant-scopes -id o_1234567890 -grant-scope-id "this" -grant-scope-id "children"`,
|
||||
"",
|
||||
"",
|
||||
})
|
||||
|
||||
case "remove-grant-scopes":
|
||||
helpStr = base.WrapForHelpText([]string{
|
||||
"Usage: boundary roles remove-grant-scopes [options] [args]",
|
||||
"",
|
||||
` Removes grant scopes from a role given its ID. The "grant-scope-id" flags can be specified multiple times. Example:`,
|
||||
"",
|
||||
` $ boundary roles remove-grant-scopes -id o_1234567890 -grant-scope-id "this" -grant-scope-id "children"`,
|
||||
"",
|
||||
"",
|
||||
})
|
||||
|
||||
default:
|
||||
helpStr = helpMap["base"]()
|
||||
}
|
||||
@@ -151,10 +185,10 @@ func extraFlagsFuncImpl(c *Command, _ *base.FlagSets, f *base.FlagSet) {
|
||||
for _, name := range flagsMap[c.Func] {
|
||||
switch name {
|
||||
case "grant-scope-id":
|
||||
f.StringVar(&base.StringVar{
|
||||
f.StringSliceVar(&base.StringSliceVar{
|
||||
Name: "grant-scope-id",
|
||||
Target: &c.flagGrantScopeId,
|
||||
Usage: "The scope ID for grants set on the role",
|
||||
Target: &c.flagGrantScopeIds,
|
||||
Usage: "The scope IDs to inherit grants set on the role",
|
||||
})
|
||||
case "principal":
|
||||
f.StringSliceVar(&base.StringSliceVar{
|
||||
@@ -173,15 +207,21 @@ func extraFlagsFuncImpl(c *Command, _ *base.FlagSets, f *base.FlagSet) {
|
||||
}
|
||||
|
||||
func extraFlagsHandlingFuncImpl(c *Command, _ *base.FlagSets, opts *[]roles.Option) bool {
|
||||
switch c.flagGrantScopeId {
|
||||
case "":
|
||||
case "null":
|
||||
*opts = append(*opts, roles.DefaultGrantScopeId())
|
||||
default:
|
||||
*opts = append(*opts, roles.WithGrantScopeId(c.flagGrantScopeId))
|
||||
}
|
||||
|
||||
switch c.Func {
|
||||
case "create", "update":
|
||||
switch len(c.flagGrantScopeIds) {
|
||||
case 0:
|
||||
case 1:
|
||||
if c.flagGrantScopeIds[0] == "null" {
|
||||
*opts = append(*opts, roles.DefaultGrantScopeId())
|
||||
} else {
|
||||
*opts = append(*opts, roles.WithGrantScopeId(c.flagGrantScopeIds[0]))
|
||||
}
|
||||
default:
|
||||
c.UI.Error("-grant-scope-id cannot be specified multiple times when using the deprecated create/update grant_scope_id mechanism")
|
||||
return false
|
||||
}
|
||||
|
||||
case "add-principals", "remove-principals":
|
||||
if len(c.flagPrincipals) == 0 {
|
||||
c.UI.Error("No principals supplied via -principal")
|
||||
@@ -194,6 +234,12 @@ func extraFlagsHandlingFuncImpl(c *Command, _ *base.FlagSets, opts *[]roles.Opti
|
||||
return false
|
||||
}
|
||||
|
||||
case "add-grant-scopes", "remove-grant-scopes":
|
||||
if len(c.flagGrantScopeIds) == 0 {
|
||||
c.UI.Error("No grant scope IDs supplied via -grant-scope-id")
|
||||
return false
|
||||
}
|
||||
|
||||
case "set-principals":
|
||||
switch len(c.flagPrincipals) {
|
||||
case 0:
|
||||
@@ -215,6 +261,17 @@ func extraFlagsHandlingFuncImpl(c *Command, _ *base.FlagSets, opts *[]roles.Opti
|
||||
c.flagGrants = nil
|
||||
}
|
||||
}
|
||||
|
||||
case "set-grant-scopes":
|
||||
switch len(c.flagGrantScopeIds) {
|
||||
case 0:
|
||||
c.UI.Error("No grant scope IDs supplied via -grant-scope-id")
|
||||
return false
|
||||
case 1:
|
||||
if c.flagGrantScopeIds[0] == "null" {
|
||||
c.flagGrantScopeIds = nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if len(c.flagGrants) > 0 {
|
||||
@@ -277,6 +334,24 @@ func executeExtraActionsImpl(c *Command, origResp *api.Response, origItem *roles
|
||||
return nil, nil, nil, err
|
||||
}
|
||||
return result.GetResponse(), result.GetItem(), nil, err
|
||||
case "add-grant-scopes":
|
||||
result, err := roleClient.AddGrantScopes(c.Context, c.FlagId, version, c.flagGrantScopeIds, opts...)
|
||||
if err != nil {
|
||||
return nil, nil, nil, err
|
||||
}
|
||||
return result.GetResponse(), result.GetItem(), nil, err
|
||||
case "set-grant-scopes":
|
||||
result, err := roleClient.SetGrantScopes(c.Context, c.FlagId, version, c.flagGrantScopeIds, opts...)
|
||||
if err != nil {
|
||||
return nil, nil, nil, err
|
||||
}
|
||||
return result.GetResponse(), result.GetItem(), nil, err
|
||||
case "remove-grant-scopes":
|
||||
result, err := roleClient.RemoveGrantScopes(c.Context, c.FlagId, version, c.flagGrantScopeIds, opts...)
|
||||
if err != nil {
|
||||
return nil, nil, nil, err
|
||||
}
|
||||
return result.GetResponse(), result.GetItem(), nil, err
|
||||
}
|
||||
return origResp, origItem, origItems, origError
|
||||
}
|
||||
@@ -407,6 +482,17 @@ func printItemTable(item *roles.Role, resp *api.Response) string {
|
||||
fmt.Sprintf(" %s", grant.Canonical),
|
||||
)
|
||||
}
|
||||
if len(item.GrantScopeIds) > 0 {
|
||||
ret = append(ret,
|
||||
"",
|
||||
fmt.Sprintf(" Grant Scope IDs: %s", ""),
|
||||
)
|
||||
}
|
||||
for _, grantScope := range item.GrantScopeIds {
|
||||
ret = append(ret,
|
||||
fmt.Sprintf(" ID: %s", grantScope),
|
||||
)
|
||||
}
|
||||
|
||||
return base.WrapForHelpText(ret)
|
||||
}
|
||||
@@ -269,6 +269,30 @@ func (c *Command) Run(args []string) int {
|
||||
version = uint32(c.FlagVersion)
|
||||
}
|
||||
|
||||
case "add-grant-scopes":
|
||||
switch c.FlagVersion {
|
||||
case 0:
|
||||
opts = append(opts, roles.WithAutomaticVersioning(true))
|
||||
default:
|
||||
version = uint32(c.FlagVersion)
|
||||
}
|
||||
|
||||
case "remove-grant-scopes":
|
||||
switch c.FlagVersion {
|
||||
case 0:
|
||||
opts = append(opts, roles.WithAutomaticVersioning(true))
|
||||
default:
|
||||
version = uint32(c.FlagVersion)
|
||||
}
|
||||
|
||||
case "set-grant-scopes":
|
||||
switch c.FlagVersion {
|
||||
case 0:
|
||||
opts = append(opts, roles.WithAutomaticVersioning(true))
|
||||
default:
|
||||
version = uint32(c.FlagVersion)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if ok := extraFlagsHandlingFunc(c, f, &opts); !ok {
|
||||
|
||||
@@ -567,7 +567,7 @@ var inputStructs = map[string][]*cmdInfo{
|
||||
Container: "Scope",
|
||||
HasName: true,
|
||||
HasDescription: true,
|
||||
VersionedActions: []string{"update", "add-grants", "remove-grants", "set-grants", "add-principals", "remove-principals", "set-principals"},
|
||||
VersionedActions: []string{"update", "add-grants", "remove-grants", "set-grants", "add-principals", "remove-principals", "set-principals", "add-grant-scopes", "remove-grant-scopes", "set-grant-scopes"},
|
||||
},
|
||||
},
|
||||
"scopes": {
|
||||
|
||||
@@ -6,6 +6,8 @@ package roles
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
"github.com/hashicorp/boundary/globals"
|
||||
"github.com/hashicorp/boundary/internal/daemon/controller/auth"
|
||||
@@ -47,6 +49,9 @@ var (
|
||||
action.AddGrants,
|
||||
action.SetGrants,
|
||||
action.RemoveGrants,
|
||||
action.AddGrantScopes,
|
||||
action.SetGrantScopes,
|
||||
action.RemoveGrantScopes,
|
||||
)
|
||||
|
||||
// CollectionActions contains the set of actions that can be performed on
|
||||
@@ -144,7 +149,7 @@ func (s Service) ListRoles(ctx context.Context, req *pbs.ListRolesRequest) (*pbs
|
||||
if !ok {
|
||||
return false, nil
|
||||
}
|
||||
pbItem, err := toProto(ctx, item, nil, nil, outputOpts...)
|
||||
pbItem, err := toProto(ctx, item, nil, nil, nil, outputOpts...)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
@@ -209,7 +214,7 @@ func (s Service) ListRoles(ctx context.Context, req *pbs.ListRolesRequest) (*pbs
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
item, err := toProto(ctx, item, nil, nil, outputOpts...)
|
||||
item, err := toProto(ctx, item, nil, nil, nil, outputOpts...)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(ctx, err, op)
|
||||
}
|
||||
@@ -248,7 +253,7 @@ func (s Service) GetRole(ctx context.Context, req *pbs.GetRoleRequest) (*pbs.Get
|
||||
if authResults.Error != nil {
|
||||
return nil, authResults.Error
|
||||
}
|
||||
r, prs, rgs, err := s.getFromRepo(ctx, req.GetId())
|
||||
r, prs, rgs, grantScopes, err := s.getFromRepo(ctx, req.GetId())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -267,7 +272,7 @@ func (s Service) GetRole(ctx context.Context, req *pbs.GetRoleRequest) (*pbs.Get
|
||||
outputOpts = append(outputOpts, handlers.WithAuthorizedActions(authResults.FetchActionSetForId(ctx, r.GetPublicId(), IdActions).Strings()))
|
||||
}
|
||||
|
||||
item, err := toProto(ctx, r, prs, rgs, outputOpts...)
|
||||
item, err := toProto(ctx, r, prs, rgs, grantScopes, outputOpts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -286,7 +291,7 @@ func (s Service) CreateRole(ctx context.Context, req *pbs.CreateRoleRequest) (*p
|
||||
if authResults.Error != nil {
|
||||
return nil, authResults.Error
|
||||
}
|
||||
r, err := s.createInRepo(ctx, authResults.Scope.GetId(), req.GetItem())
|
||||
r, prs, rgs, grantScopes, err := s.createInRepo(ctx, authResults.Scope.GetId(), req.GetItem())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -305,7 +310,7 @@ func (s Service) CreateRole(ctx context.Context, req *pbs.CreateRoleRequest) (*p
|
||||
outputOpts = append(outputOpts, handlers.WithAuthorizedActions(authResults.FetchActionSetForId(ctx, r.GetPublicId(), IdActions).Strings()))
|
||||
}
|
||||
|
||||
item, err := toProto(ctx, r, nil, nil, outputOpts...)
|
||||
item, err := toProto(ctx, r, prs, rgs, grantScopes, outputOpts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -324,7 +329,7 @@ func (s Service) UpdateRole(ctx context.Context, req *pbs.UpdateRoleRequest) (*p
|
||||
if authResults.Error != nil {
|
||||
return nil, authResults.Error
|
||||
}
|
||||
r, prs, rgs, err := s.updateInRepo(ctx, authResults.Scope.GetId(), req.GetId(), req.GetUpdateMask().GetPaths(), req.GetItem())
|
||||
r, prs, rgs, grantScopes, err := s.updateInRepo(ctx, authResults.Scope.GetId(), req.GetId(), req.GetUpdateMask().GetPaths(), req.GetItem())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -343,7 +348,7 @@ func (s Service) UpdateRole(ctx context.Context, req *pbs.UpdateRoleRequest) (*p
|
||||
outputOpts = append(outputOpts, handlers.WithAuthorizedActions(authResults.FetchActionSetForId(ctx, r.GetPublicId(), IdActions).Strings()))
|
||||
}
|
||||
|
||||
item, err := toProto(ctx, r, prs, rgs, outputOpts...)
|
||||
item, err := toProto(ctx, r, prs, rgs, grantScopes, outputOpts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -378,7 +383,7 @@ func (s Service) AddRolePrincipals(ctx context.Context, req *pbs.AddRolePrincipa
|
||||
if authResults.Error != nil {
|
||||
return nil, authResults.Error
|
||||
}
|
||||
r, prs, rgs, err := s.addPrinciplesInRepo(ctx, req.GetId(), req.GetPrincipalIds(), req.GetVersion())
|
||||
r, prs, rgs, grantScopes, err := s.addPrincipalsInRepo(ctx, req.GetId(), req.GetPrincipalIds(), req.GetVersion())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -397,7 +402,7 @@ func (s Service) AddRolePrincipals(ctx context.Context, req *pbs.AddRolePrincipa
|
||||
outputOpts = append(outputOpts, handlers.WithAuthorizedActions(authResults.FetchActionSetForId(ctx, r.GetPublicId(), IdActions).Strings()))
|
||||
}
|
||||
|
||||
item, err := toProto(ctx, r, prs, rgs, outputOpts...)
|
||||
item, err := toProto(ctx, r, prs, rgs, grantScopes, outputOpts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -416,7 +421,7 @@ func (s Service) SetRolePrincipals(ctx context.Context, req *pbs.SetRolePrincipa
|
||||
if authResults.Error != nil {
|
||||
return nil, authResults.Error
|
||||
}
|
||||
r, prs, rgs, err := s.setPrinciplesInRepo(ctx, req.GetId(), req.GetPrincipalIds(), req.GetVersion())
|
||||
r, prs, rgs, grantScopes, err := s.setPrincipalsInRepo(ctx, req.GetId(), req.GetPrincipalIds(), req.GetVersion())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -435,7 +440,7 @@ func (s Service) SetRolePrincipals(ctx context.Context, req *pbs.SetRolePrincipa
|
||||
outputOpts = append(outputOpts, handlers.WithAuthorizedActions(authResults.FetchActionSetForId(ctx, r.GetPublicId(), IdActions).Strings()))
|
||||
}
|
||||
|
||||
item, err := toProto(ctx, r, prs, rgs, outputOpts...)
|
||||
item, err := toProto(ctx, r, prs, rgs, grantScopes, outputOpts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -454,7 +459,7 @@ func (s Service) RemoveRolePrincipals(ctx context.Context, req *pbs.RemoveRolePr
|
||||
if authResults.Error != nil {
|
||||
return nil, authResults.Error
|
||||
}
|
||||
r, prs, rgs, err := s.removePrinciplesInRepo(ctx, req.GetId(), req.GetPrincipalIds(), req.GetVersion())
|
||||
r, prs, rgs, grantScopes, err := s.removePrincipalsInRepo(ctx, req.GetId(), req.GetPrincipalIds(), req.GetVersion())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -473,7 +478,7 @@ func (s Service) RemoveRolePrincipals(ctx context.Context, req *pbs.RemoveRolePr
|
||||
outputOpts = append(outputOpts, handlers.WithAuthorizedActions(authResults.FetchActionSetForId(ctx, r.GetPublicId(), IdActions).Strings()))
|
||||
}
|
||||
|
||||
item, err := toProto(ctx, r, prs, rgs, outputOpts...)
|
||||
item, err := toProto(ctx, r, prs, rgs, grantScopes, outputOpts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -492,7 +497,7 @@ func (s Service) AddRoleGrants(ctx context.Context, req *pbs.AddRoleGrantsReques
|
||||
if authResults.Error != nil {
|
||||
return nil, authResults.Error
|
||||
}
|
||||
r, prs, rgs, err := s.addGrantsInRepo(ctx, req.GetId(), req.GetGrantStrings(), req.GetVersion())
|
||||
r, prs, rgs, grantScopes, err := s.addGrantsInRepo(ctx, req.GetId(), req.GetGrantStrings(), req.GetVersion())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -511,7 +516,7 @@ func (s Service) AddRoleGrants(ctx context.Context, req *pbs.AddRoleGrantsReques
|
||||
outputOpts = append(outputOpts, handlers.WithAuthorizedActions(authResults.FetchActionSetForId(ctx, r.GetPublicId(), IdActions).Strings()))
|
||||
}
|
||||
|
||||
item, err := toProto(ctx, r, prs, rgs, outputOpts...)
|
||||
item, err := toProto(ctx, r, prs, rgs, grantScopes, outputOpts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -530,7 +535,7 @@ func (s Service) SetRoleGrants(ctx context.Context, req *pbs.SetRoleGrantsReques
|
||||
if authResults.Error != nil {
|
||||
return nil, authResults.Error
|
||||
}
|
||||
r, prs, rgs, err := s.setGrantsInRepo(ctx, req.GetId(), req.GetGrantStrings(), req.GetVersion())
|
||||
r, prs, rgs, grantScopes, err := s.setGrantsInRepo(ctx, req.GetId(), req.GetGrantStrings(), req.GetVersion())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -549,7 +554,7 @@ func (s Service) SetRoleGrants(ctx context.Context, req *pbs.SetRoleGrantsReques
|
||||
outputOpts = append(outputOpts, handlers.WithAuthorizedActions(authResults.FetchActionSetForId(ctx, r.GetPublicId(), IdActions).Strings()))
|
||||
}
|
||||
|
||||
item, err := toProto(ctx, r, prs, rgs, outputOpts...)
|
||||
item, err := toProto(ctx, r, prs, rgs, grantScopes, outputOpts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -568,7 +573,7 @@ func (s Service) RemoveRoleGrants(ctx context.Context, req *pbs.RemoveRoleGrants
|
||||
if authResults.Error != nil {
|
||||
return nil, authResults.Error
|
||||
}
|
||||
r, prs, rgs, err := s.removeGrantsInRepo(ctx, req.GetId(), req.GetGrantStrings(), req.GetVersion())
|
||||
r, prs, rgs, grantScopes, err := s.removeGrantsInRepo(ctx, req.GetId(), req.GetGrantStrings(), req.GetVersion())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -587,7 +592,7 @@ func (s Service) RemoveRoleGrants(ctx context.Context, req *pbs.RemoveRoleGrants
|
||||
outputOpts = append(outputOpts, handlers.WithAuthorizedActions(authResults.FetchActionSetForId(ctx, r.GetPublicId(), IdActions).Strings()))
|
||||
}
|
||||
|
||||
item, err := toProto(ctx, r, prs, rgs, outputOpts...)
|
||||
item, err := toProto(ctx, r, prs, rgs, grantScopes, outputOpts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -595,25 +600,142 @@ func (s Service) RemoveRoleGrants(ctx context.Context, req *pbs.RemoveRoleGrants
|
||||
return &pbs.RemoveRoleGrantsResponse{Item: item}, nil
|
||||
}
|
||||
|
||||
func (s Service) getFromRepo(ctx context.Context, id string) (*iam.Role, []*iam.PrincipalRole, []*iam.RoleGrant, error) {
|
||||
repo, err := s.repoFn()
|
||||
// AddRoleGrantScopes implements the interface pbs.RoleServiceServer.
|
||||
func (s Service) AddRoleGrantScopes(ctx context.Context, req *pbs.AddRoleGrantScopesRequest) (*pbs.AddRoleGrantScopesResponse, error) {
|
||||
const op = "roles.(Service).AddRoleGrantScopes"
|
||||
|
||||
if err := validateRoleGrantScopesRequest(ctx, req); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
authResults := s.authResult(ctx, req.GetId(), action.AddGrantScopes)
|
||||
if authResults.Error != nil {
|
||||
return nil, authResults.Error
|
||||
}
|
||||
|
||||
r, prs, rgs, grantScopes, err := s.addGrantScopesInRepo(ctx, req)
|
||||
if err != nil {
|
||||
return nil, nil, nil, err
|
||||
return nil, err
|
||||
}
|
||||
out, pr, roleGrants, err := repo.LookupRole(ctx, id)
|
||||
|
||||
outputFields, ok := requests.OutputFields(ctx)
|
||||
if !ok {
|
||||
return nil, errors.New(ctx, errors.Internal, op, "no request context found")
|
||||
}
|
||||
|
||||
outputOpts := make([]handlers.Option, 0, 3)
|
||||
outputOpts = append(outputOpts, handlers.WithOutputFields(outputFields))
|
||||
if outputFields.Has(globals.ScopeField) {
|
||||
outputOpts = append(outputOpts, handlers.WithScope(authResults.Scope))
|
||||
}
|
||||
if outputFields.Has(globals.AuthorizedActionsField) {
|
||||
outputOpts = append(outputOpts, handlers.WithAuthorizedActions(authResults.FetchActionSetForId(ctx, r.GetPublicId(), IdActions).Strings()))
|
||||
}
|
||||
|
||||
item, err := toProto(ctx, r, prs, rgs, grantScopes, outputOpts...)
|
||||
if err != nil {
|
||||
if errors.IsNotFoundError(err) {
|
||||
return nil, nil, nil, handlers.NotFoundErrorf("Role %q doesn't exist.", id)
|
||||
}
|
||||
return nil, nil, nil, err
|
||||
return nil, err
|
||||
}
|
||||
if out == nil {
|
||||
return nil, nil, nil, handlers.NotFoundErrorf("Role %q doesn't exist.", id)
|
||||
}
|
||||
return out, pr, roleGrants, nil
|
||||
|
||||
return &pbs.AddRoleGrantScopesResponse{Item: item}, nil
|
||||
}
|
||||
|
||||
func (s Service) createInRepo(ctx context.Context, scopeId string, item *pb.Role) (*iam.Role, error) {
|
||||
// SetRoleGrantScopes implements the interface pbs.RoleServiceServer.
|
||||
func (s Service) SetRoleGrantScopes(ctx context.Context, req *pbs.SetRoleGrantScopesRequest) (*pbs.SetRoleGrantScopesResponse, error) {
|
||||
const op = "roles.(Service).SetRoleGrantScopes"
|
||||
|
||||
if err := validateRoleGrantScopesRequest(ctx, req); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
authResults := s.authResult(ctx, req.GetId(), action.SetGrantScopes)
|
||||
if authResults.Error != nil {
|
||||
return nil, authResults.Error
|
||||
}
|
||||
|
||||
r, prs, rgs, grantScopes, err := s.setGrantScopesInRepo(ctx, req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
outputFields, ok := requests.OutputFields(ctx)
|
||||
if !ok {
|
||||
return nil, errors.New(ctx, errors.Internal, op, "no request context found")
|
||||
}
|
||||
|
||||
outputOpts := make([]handlers.Option, 0, 3)
|
||||
outputOpts = append(outputOpts, handlers.WithOutputFields(outputFields))
|
||||
if outputFields.Has(globals.ScopeField) {
|
||||
outputOpts = append(outputOpts, handlers.WithScope(authResults.Scope))
|
||||
}
|
||||
if outputFields.Has(globals.AuthorizedActionsField) {
|
||||
outputOpts = append(outputOpts, handlers.WithAuthorizedActions(authResults.FetchActionSetForId(ctx, r.GetPublicId(), IdActions).Strings()))
|
||||
}
|
||||
|
||||
item, err := toProto(ctx, r, prs, rgs, grantScopes, outputOpts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &pbs.SetRoleGrantScopesResponse{Item: item}, nil
|
||||
}
|
||||
|
||||
// RemoveRoleGrantScopes implements the interface pbs.RoleServiceServer.
|
||||
func (s Service) RemoveRoleGrantScopes(ctx context.Context, req *pbs.RemoveRoleGrantScopesRequest) (*pbs.RemoveRoleGrantScopesResponse, error) {
|
||||
const op = "roles.(Service).RemoveRoleGrantScopes"
|
||||
|
||||
if err := validateRoleGrantScopesRequest(ctx, req); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
authResults := s.authResult(ctx, req.GetId(), action.RemoveGrants)
|
||||
if authResults.Error != nil {
|
||||
return nil, authResults.Error
|
||||
}
|
||||
|
||||
r, prs, rgs, grantScopes, err := s.removeGrantScopesInRepo(ctx, req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
outputFields, ok := requests.OutputFields(ctx)
|
||||
if !ok {
|
||||
return nil, errors.New(ctx, errors.Internal, op, "no request context found")
|
||||
}
|
||||
|
||||
outputOpts := make([]handlers.Option, 0, 3)
|
||||
outputOpts = append(outputOpts, handlers.WithOutputFields(outputFields))
|
||||
if outputFields.Has(globals.ScopeField) {
|
||||
outputOpts = append(outputOpts, handlers.WithScope(authResults.Scope))
|
||||
}
|
||||
if outputFields.Has(globals.AuthorizedActionsField) {
|
||||
outputOpts = append(outputOpts, handlers.WithAuthorizedActions(authResults.FetchActionSetForId(ctx, r.GetPublicId(), IdActions).Strings()))
|
||||
}
|
||||
|
||||
item, err := toProto(ctx, r, prs, rgs, grantScopes, outputOpts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &pbs.RemoveRoleGrantScopesResponse{Item: item}, nil
|
||||
}
|
||||
|
||||
func (s Service) getFromRepo(ctx context.Context, id string) (*iam.Role, []*iam.PrincipalRole, []*iam.RoleGrant, []*iam.RoleGrantScope, error) {
|
||||
repo, err := s.repoFn()
|
||||
if err != nil {
|
||||
return nil, nil, nil, nil, err
|
||||
}
|
||||
out, pr, roleGrants, roleGrantScopes, err := repo.LookupRole(ctx, id)
|
||||
if err != nil {
|
||||
if errors.IsNotFoundError(err) {
|
||||
return nil, nil, nil, nil, handlers.NotFoundErrorf("Role %q doesn't exist.", id)
|
||||
}
|
||||
return nil, nil, nil, nil, err
|
||||
}
|
||||
if out == nil {
|
||||
return nil, nil, nil, nil, handlers.NotFoundErrorf("Role %q doesn't exist.", id)
|
||||
}
|
||||
return out, pr, roleGrants, roleGrantScopes, nil
|
||||
}
|
||||
|
||||
func (s Service) createInRepo(ctx context.Context, scopeId string, item *pb.Role) (*iam.Role, []*iam.PrincipalRole, []*iam.RoleGrant, []*iam.RoleGrantScope, error) {
|
||||
const op = "roles.(Service).createInRepo"
|
||||
var opts []iam.Option
|
||||
if item.GetName() != nil {
|
||||
@@ -627,23 +749,23 @@ func (s Service) createInRepo(ctx context.Context, scopeId string, item *pb.Role
|
||||
}
|
||||
u, err := iam.NewRole(ctx, scopeId, opts...)
|
||||
if err != nil {
|
||||
return nil, handlers.ApiErrorWithCodeAndMessage(codes.Internal, "Unable to build role for creation: %v.", err)
|
||||
return nil, nil, nil, nil, handlers.ApiErrorWithCodeAndMessage(codes.Internal, "Unable to build role for creation: %v.", err)
|
||||
}
|
||||
repo, err := s.repoFn()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, nil, nil, nil, err
|
||||
}
|
||||
out, err := repo.CreateRole(ctx, u)
|
||||
out, pr, roleGrants, roleGrantScopes, err := repo.CreateRole(ctx, u, opts...)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(ctx, err, op)
|
||||
return nil, nil, nil, nil, errors.Wrap(ctx, err, op)
|
||||
}
|
||||
if out == nil {
|
||||
return nil, handlers.ApiErrorWithCodeAndMessage(codes.Internal, "Unable to create role but no error returned from repository.")
|
||||
return nil, nil, nil, nil, handlers.ApiErrorWithCodeAndMessage(codes.Internal, "Unable to create role but no error returned from repository.")
|
||||
}
|
||||
return out, nil
|
||||
return out, pr, roleGrants, roleGrantScopes, nil
|
||||
}
|
||||
|
||||
func (s Service) updateInRepo(ctx context.Context, scopeId, id string, mask []string, item *pb.Role) (*iam.Role, []*iam.PrincipalRole, []*iam.RoleGrant, error) {
|
||||
func (s Service) updateInRepo(ctx context.Context, scopeId, id string, mask []string, item *pb.Role) (*iam.Role, []*iam.PrincipalRole, []*iam.RoleGrant, []*iam.RoleGrantScope, error) {
|
||||
const op = "roles.(Service).updateInRepo"
|
||||
var opts []iam.Option
|
||||
if desc := item.GetDescription(); desc != nil {
|
||||
@@ -652,32 +774,54 @@ func (s Service) updateInRepo(ctx context.Context, scopeId, id string, mask []st
|
||||
if name := item.GetName(); name != nil {
|
||||
opts = append(opts, iam.WithName(name.GetValue()))
|
||||
}
|
||||
if grantScopeId := item.GetGrantScopeId(); grantScopeId != nil {
|
||||
opts = append(opts, iam.WithGrantScopeId(grantScopeId.GetValue()))
|
||||
}
|
||||
version := item.GetVersion()
|
||||
|
||||
u, err := iam.NewRole(ctx, scopeId, opts...)
|
||||
if err != nil {
|
||||
return nil, nil, nil, handlers.ApiErrorWithCodeAndMessage(codes.Internal, "Unable to build role for update: %v.", err)
|
||||
return nil, nil, nil, nil, handlers.ApiErrorWithCodeAndMessage(codes.Internal, "Unable to build role for update: %v.", err)
|
||||
}
|
||||
u.PublicId = id
|
||||
dbMask := maskManager.Translate(mask)
|
||||
if len(dbMask) == 0 {
|
||||
return nil, nil, nil, handlers.InvalidArgumentErrorf("No valid fields included in the update mask.", map[string]string{"update_mask": "No valid fields provided in the update mask."})
|
||||
}
|
||||
|
||||
repo, err := s.repoFn()
|
||||
if err != nil {
|
||||
return nil, nil, nil, err
|
||||
return nil, nil, nil, nil, err
|
||||
}
|
||||
out, pr, gr, rowsUpdated, err := repo.UpdateRole(ctx, u, version, dbMask)
|
||||
|
||||
// This has to be separate from Translate since the field only exists on the
|
||||
// API side now.
|
||||
var hasGrantScopeIdMask bool
|
||||
if grantScopeId := item.GetGrantScopeId(); grantScopeId != nil {
|
||||
// Have to manually check the masks, which could be concatenated strings or slices
|
||||
for _, v := range mask {
|
||||
if strutil.StrListContains(strings.Split(v, ","), "grant_scope_id") {
|
||||
opts = append(opts, iam.WithGrantScopeId(grantScopeId.GetValue()))
|
||||
hasGrantScopeIdMask = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if hasGrantScopeIdMask {
|
||||
if err := validateRoleGrantScopesHierarchy(ctx, repo, id, []string{item.GetGrantScopeId().GetValue()}); err != nil {
|
||||
return nil, nil, nil, nil, err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
dbMask := maskManager.Translate(mask)
|
||||
if len(dbMask) == 0 && !hasGrantScopeIdMask {
|
||||
return nil, nil, nil, nil, handlers.InvalidArgumentErrorf("No valid fields provided in the update mask.", map[string]string{"update_mask": "No valid fields provided in the update mask."})
|
||||
}
|
||||
|
||||
out, pr, gr, grantScopes, rowsUpdated, err := repo.UpdateRole(ctx, u, version, dbMask, opts...)
|
||||
if err != nil {
|
||||
return nil, nil, nil, errors.Wrap(ctx, err, op)
|
||||
return nil, nil, nil, nil, errors.Wrap(ctx, err, op)
|
||||
}
|
||||
if rowsUpdated == 0 {
|
||||
return nil, nil, nil, handlers.NotFoundErrorf("Role %q doesn't exist or incorrect version provided.", id)
|
||||
// This is slightly problematic but it's a very unlikely error case and when
|
||||
// we remove the ability to update grant scope ID via here in 0.17 it will
|
||||
// go away.
|
||||
if rowsUpdated == 0 && !hasGrantScopeIdMask {
|
||||
return nil, nil, nil, nil, handlers.NotFoundErrorf("Role %q doesn't exist or incorrect version provided.", id)
|
||||
}
|
||||
return out, pr, gr, nil
|
||||
return out, pr, gr, grantScopes, nil
|
||||
}
|
||||
|
||||
func (s Service) deleteFromRepo(ctx context.Context, id string) (bool, error) {
|
||||
@@ -696,95 +840,95 @@ func (s Service) deleteFromRepo(ctx context.Context, id string) (bool, error) {
|
||||
return rows > 0, nil
|
||||
}
|
||||
|
||||
func (s Service) addPrinciplesInRepo(ctx context.Context, roleId string, principalIds []string, version uint32) (*iam.Role, []*iam.PrincipalRole, []*iam.RoleGrant, error) {
|
||||
func (s Service) addPrincipalsInRepo(ctx context.Context, roleId string, principalIds []string, version uint32) (*iam.Role, []*iam.PrincipalRole, []*iam.RoleGrant, []*iam.RoleGrantScope, error) {
|
||||
const op = "roles.(Service).addPrincpleInRepo"
|
||||
repo, err := s.repoFn()
|
||||
if err != nil {
|
||||
return nil, nil, nil, err
|
||||
return nil, nil, nil, nil, err
|
||||
}
|
||||
_, err = repo.AddPrincipalRoles(ctx, roleId, version, strutil.RemoveDuplicates(principalIds, false))
|
||||
if err != nil {
|
||||
// TODO: Figure out a way to surface more helpful error info beyond the Internal error.
|
||||
return nil, nil, nil, handlers.ApiErrorWithCodeAndMessage(codes.Internal, "Unable to add principals to role: %v.", err)
|
||||
return nil, nil, nil, nil, handlers.ApiErrorWithCodeAndMessage(codes.Internal, "Unable to add principals to role: %v.", err)
|
||||
}
|
||||
out, pr, roleGrants, err := repo.LookupRole(ctx, roleId)
|
||||
out, pr, roleGrants, grantScopes, err := repo.LookupRole(ctx, roleId)
|
||||
if err != nil {
|
||||
return nil, nil, nil, errors.Wrap(ctx, err, op, errors.WithMsg("unable to look up role after adding principals"))
|
||||
return nil, nil, nil, nil, errors.Wrap(ctx, err, op, errors.WithMsg("unable to look up role after adding principals"))
|
||||
}
|
||||
if out == nil {
|
||||
return nil, nil, nil, handlers.ApiErrorWithCodeAndMessage(codes.Internal, "Unable to lookup role after adding principals to it.")
|
||||
return nil, nil, nil, nil, handlers.ApiErrorWithCodeAndMessage(codes.Internal, "Unable to lookup role after adding principals to it.")
|
||||
}
|
||||
return out, pr, roleGrants, nil
|
||||
return out, pr, roleGrants, grantScopes, nil
|
||||
}
|
||||
|
||||
func (s Service) setPrinciplesInRepo(ctx context.Context, roleId string, principalIds []string, version uint32) (*iam.Role, []*iam.PrincipalRole, []*iam.RoleGrant, error) {
|
||||
const op = "roles.(Service).setPrinciplesInRepo"
|
||||
func (s Service) setPrincipalsInRepo(ctx context.Context, roleId string, principalIds []string, version uint32) (*iam.Role, []*iam.PrincipalRole, []*iam.RoleGrant, []*iam.RoleGrantScope, error) {
|
||||
const op = "roles.(Service).setPrincipalsInRepo"
|
||||
repo, err := s.repoFn()
|
||||
if err != nil {
|
||||
return nil, nil, nil, err
|
||||
return nil, nil, nil, nil, err
|
||||
}
|
||||
_, _, err = repo.SetPrincipalRoles(ctx, roleId, version, strutil.RemoveDuplicates(principalIds, false))
|
||||
if err != nil {
|
||||
// TODO: Figure out a way to surface more helpful error info beyond the Internal error.
|
||||
return nil, nil, nil, handlers.ApiErrorWithCodeAndMessage(codes.Internal, "Unable to set principals on role: %v.", err)
|
||||
return nil, nil, nil, nil, handlers.ApiErrorWithCodeAndMessage(codes.Internal, "Unable to set principals on role: %v.", err)
|
||||
}
|
||||
out, pr, roleGrants, err := repo.LookupRole(ctx, roleId)
|
||||
out, pr, roleGrants, grantScopes, err := repo.LookupRole(ctx, roleId)
|
||||
if err != nil {
|
||||
return nil, nil, nil, errors.Wrap(ctx, err, op, errors.WithMsg("unable to look up role after setting principals"))
|
||||
return nil, nil, nil, nil, errors.Wrap(ctx, err, op, errors.WithMsg("unable to look up role after setting principals"))
|
||||
}
|
||||
if out == nil {
|
||||
return nil, nil, nil, handlers.ApiErrorWithCodeAndMessage(codes.Internal, "Unable to lookup role after setting principals for it.")
|
||||
return nil, nil, nil, nil, handlers.ApiErrorWithCodeAndMessage(codes.Internal, "Unable to lookup role after setting principals for it.")
|
||||
}
|
||||
return out, pr, roleGrants, nil
|
||||
return out, pr, roleGrants, grantScopes, nil
|
||||
}
|
||||
|
||||
func (s Service) removePrinciplesInRepo(ctx context.Context, roleId string, principalIds []string, version uint32) (*iam.Role, []*iam.PrincipalRole, []*iam.RoleGrant, error) {
|
||||
const op = "roles.(Service).removePrinciplesInRepo"
|
||||
func (s Service) removePrincipalsInRepo(ctx context.Context, roleId string, principalIds []string, version uint32) (*iam.Role, []*iam.PrincipalRole, []*iam.RoleGrant, []*iam.RoleGrantScope, error) {
|
||||
const op = "roles.(Service).removePrincipalsInRepo"
|
||||
repo, err := s.repoFn()
|
||||
if err != nil {
|
||||
return nil, nil, nil, err
|
||||
return nil, nil, nil, nil, err
|
||||
}
|
||||
_, err = repo.DeletePrincipalRoles(ctx, roleId, version, strutil.RemoveDuplicates(principalIds, false))
|
||||
if err != nil {
|
||||
// TODO: Figure out a way to surface more helpful error info beyond the Internal error.
|
||||
return nil, nil, nil, handlers.ApiErrorWithCodeAndMessage(codes.Internal, "Unable to remove principals from role: %v.", err)
|
||||
return nil, nil, nil, nil, handlers.ApiErrorWithCodeAndMessage(codes.Internal, "Unable to remove principals from role: %v.", err)
|
||||
}
|
||||
out, pr, roleGrants, err := repo.LookupRole(ctx, roleId)
|
||||
out, pr, roleGrants, grantScopes, err := repo.LookupRole(ctx, roleId)
|
||||
if err != nil {
|
||||
return nil, nil, nil, errors.Wrap(ctx, err, op, errors.WithMsg("unable to look up role after removing principals"))
|
||||
return nil, nil, nil, nil, errors.Wrap(ctx, err, op, errors.WithMsg("unable to look up role after removing principals"))
|
||||
}
|
||||
if out == nil {
|
||||
return nil, nil, nil, handlers.ApiErrorWithCodeAndMessage(codes.Internal, "Unable to lookup role after removing principals from it.")
|
||||
return nil, nil, nil, nil, handlers.ApiErrorWithCodeAndMessage(codes.Internal, "Unable to lookup role after removing principals from it.")
|
||||
}
|
||||
return out, pr, roleGrants, nil
|
||||
return out, pr, roleGrants, grantScopes, nil
|
||||
}
|
||||
|
||||
func (s Service) addGrantsInRepo(ctx context.Context, roleId string, grants []string, version uint32) (*iam.Role, []*iam.PrincipalRole, []*iam.RoleGrant, error) {
|
||||
func (s Service) addGrantsInRepo(ctx context.Context, roleId string, grants []string, version uint32) (*iam.Role, []*iam.PrincipalRole, []*iam.RoleGrant, []*iam.RoleGrantScope, error) {
|
||||
const op = "service.(Service).addGrantsInRepo"
|
||||
repo, err := s.repoFn()
|
||||
if err != nil {
|
||||
return nil, nil, nil, err
|
||||
return nil, nil, nil, nil, err
|
||||
}
|
||||
_, err = repo.AddRoleGrants(ctx, roleId, version, strutil.RemoveDuplicates(grants, false))
|
||||
if err != nil {
|
||||
// TODO: Figure out a way to surface more helpful error info beyond the Internal error.
|
||||
return nil, nil, nil, handlers.ApiErrorWithCodeAndMessage(codes.Internal, "Unable to add grants to role: %v.", err)
|
||||
return nil, nil, nil, nil, handlers.ApiErrorWithCodeAndMessage(codes.Internal, "Unable to add grants to role: %v.", err)
|
||||
}
|
||||
out, pr, roleGrants, err := repo.LookupRole(ctx, roleId)
|
||||
out, pr, roleGrants, grantScopes, err := repo.LookupRole(ctx, roleId)
|
||||
if err != nil {
|
||||
return nil, nil, nil, errors.Wrap(ctx, err, op, errors.WithMsg("unable to look up role after adding grants"))
|
||||
return nil, nil, nil, nil, errors.Wrap(ctx, err, op, errors.WithMsg("unable to look up role after adding grants"))
|
||||
}
|
||||
if out == nil {
|
||||
return nil, nil, nil, handlers.ApiErrorWithCodeAndMessage(codes.Internal, "Unable to lookup role after adding grants to it.")
|
||||
return nil, nil, nil, nil, handlers.ApiErrorWithCodeAndMessage(codes.Internal, "Unable to lookup role after adding grants to it.")
|
||||
}
|
||||
return out, pr, roleGrants, nil
|
||||
return out, pr, roleGrants, grantScopes, nil
|
||||
}
|
||||
|
||||
func (s Service) setGrantsInRepo(ctx context.Context, roleId string, grants []string, version uint32) (*iam.Role, []*iam.PrincipalRole, []*iam.RoleGrant, error) {
|
||||
func (s Service) setGrantsInRepo(ctx context.Context, roleId string, grants []string, version uint32) (*iam.Role, []*iam.PrincipalRole, []*iam.RoleGrant, []*iam.RoleGrantScope, error) {
|
||||
const op = "roles.(Service).setGrantsInRepo"
|
||||
repo, err := s.repoFn()
|
||||
if err != nil {
|
||||
return nil, nil, nil, err
|
||||
return nil, nil, nil, nil, err
|
||||
}
|
||||
// If no grant was provided, we clear the grants.
|
||||
if grants == nil {
|
||||
@@ -793,37 +937,115 @@ func (s Service) setGrantsInRepo(ctx context.Context, roleId string, grants []st
|
||||
_, _, err = repo.SetRoleGrants(ctx, roleId, version, strutil.RemoveDuplicates(grants, false))
|
||||
if err != nil {
|
||||
// TODO: Figure out a way to surface more helpful error info beyond the Internal error.
|
||||
return nil, nil, nil, handlers.ApiErrorWithCodeAndMessage(codes.Internal, "Unable to set grants on role: %v.", err)
|
||||
return nil, nil, nil, nil, handlers.ApiErrorWithCodeAndMessage(codes.Internal, "Unable to set grants on role: %v.", err)
|
||||
}
|
||||
out, pr, roleGrants, err := repo.LookupRole(ctx, roleId)
|
||||
out, pr, roleGrants, grantScopes, err := repo.LookupRole(ctx, roleId)
|
||||
if err != nil {
|
||||
return nil, nil, nil, errors.Wrap(ctx, err, op, errors.WithMsg("unable to look up role after setting grants"))
|
||||
return nil, nil, nil, nil, errors.Wrap(ctx, err, op, errors.WithMsg("unable to look up role after setting grants"))
|
||||
}
|
||||
if out == nil {
|
||||
return nil, nil, nil, handlers.ApiErrorWithCodeAndMessage(codes.Internal, "Unable to lookup role after setting grants on it.")
|
||||
return nil, nil, nil, nil, handlers.ApiErrorWithCodeAndMessage(codes.Internal, "Unable to lookup role after setting grants on it.")
|
||||
}
|
||||
return out, pr, roleGrants, nil
|
||||
return out, pr, roleGrants, grantScopes, nil
|
||||
}
|
||||
|
||||
func (s Service) removeGrantsInRepo(ctx context.Context, roleId string, grants []string, version uint32) (*iam.Role, []*iam.PrincipalRole, []*iam.RoleGrant, error) {
|
||||
func (s Service) removeGrantsInRepo(ctx context.Context, roleId string, grants []string, version uint32) (*iam.Role, []*iam.PrincipalRole, []*iam.RoleGrant, []*iam.RoleGrantScope, error) {
|
||||
const op = "roles.(Service).removeGrantsInRepo"
|
||||
repo, err := s.repoFn()
|
||||
if err != nil {
|
||||
return nil, nil, nil, err
|
||||
return nil, nil, nil, nil, err
|
||||
}
|
||||
_, err = repo.DeleteRoleGrants(ctx, roleId, version, strutil.RemoveDuplicates(grants, false))
|
||||
if err != nil {
|
||||
// TODO: Figure out a way to surface more helpful error info beyond the Internal error.
|
||||
return nil, nil, nil, handlers.ApiErrorWithCodeAndMessage(codes.Internal, "Unable to remove grants from role: %v", err)
|
||||
return nil, nil, nil, nil, handlers.ApiErrorWithCodeAndMessage(codes.Internal, "Unable to remove grants from role: %v", err)
|
||||
}
|
||||
out, pr, roleGrants, err := repo.LookupRole(ctx, roleId)
|
||||
out, pr, roleGrants, grantScopes, err := repo.LookupRole(ctx, roleId)
|
||||
if err != nil {
|
||||
return nil, nil, nil, errors.Wrap(ctx, err, op, errors.WithMsg("uable to look up role after removing grant"))
|
||||
return nil, nil, nil, nil, errors.Wrap(ctx, err, op, errors.WithMsg("uable to look up role after removing grant"))
|
||||
}
|
||||
if out == nil {
|
||||
return nil, nil, nil, handlers.ApiErrorWithCodeAndMessage(codes.Internal, "Unable to lookup role after removing grants from it.")
|
||||
return nil, nil, nil, nil, handlers.ApiErrorWithCodeAndMessage(codes.Internal, "Unable to lookup role after removing grants from it.")
|
||||
}
|
||||
return out, pr, roleGrants, nil
|
||||
return out, pr, roleGrants, grantScopes, nil
|
||||
}
|
||||
|
||||
func (s Service) addGrantScopesInRepo(ctx context.Context, req grantScopeRequest) (*iam.Role, []*iam.PrincipalRole, []*iam.RoleGrant, []*iam.RoleGrantScope, error) {
|
||||
const op = "service.(Service).addGrantScopesInRepo"
|
||||
repo, err := s.repoFn()
|
||||
if err != nil {
|
||||
return nil, nil, nil, nil, err
|
||||
}
|
||||
|
||||
deduped := strutil.RemoveDuplicates(req.GetGrantScopeIds(), false)
|
||||
|
||||
if err := validateRoleGrantScopesHierarchy(ctx, repo, req.GetId(), deduped); err != nil {
|
||||
return nil, nil, nil, nil, err
|
||||
}
|
||||
|
||||
_, err = repo.AddRoleGrantScopes(ctx, req.GetId(), req.GetVersion(), deduped)
|
||||
if err != nil {
|
||||
// TODO: Figure out a way to surface more helpful error info beyond the Internal error.
|
||||
return nil, nil, nil, nil, handlers.ApiErrorWithCodeAndMessage(codes.Internal, "Unable to add grant scopes to role: %v.", err)
|
||||
}
|
||||
out, pr, roleGrants, grantScopes, err := repo.LookupRole(ctx, req.GetId())
|
||||
if err != nil {
|
||||
return nil, nil, nil, nil, errors.Wrap(ctx, err, op, errors.WithMsg("unable to look up role after adding grant scopes"))
|
||||
}
|
||||
if out == nil {
|
||||
return nil, nil, nil, nil, handlers.ApiErrorWithCodeAndMessage(codes.Internal, "Unable to lookup role after adding grant scopes to it.")
|
||||
}
|
||||
return out, pr, roleGrants, grantScopes, nil
|
||||
}
|
||||
|
||||
func (s Service) setGrantScopesInRepo(ctx context.Context, req grantScopeRequest) (*iam.Role, []*iam.PrincipalRole, []*iam.RoleGrant, []*iam.RoleGrantScope, error) {
|
||||
const op = "service.(Service).setGrantScopesInRepo"
|
||||
repo, err := s.repoFn()
|
||||
if err != nil {
|
||||
return nil, nil, nil, nil, err
|
||||
}
|
||||
|
||||
deduped := strutil.RemoveDuplicates(req.GetGrantScopeIds(), false)
|
||||
|
||||
if err := validateRoleGrantScopesHierarchy(ctx, repo, req.GetId(), deduped); err != nil {
|
||||
return nil, nil, nil, nil, err
|
||||
}
|
||||
|
||||
_, _, err = repo.SetRoleGrantScopes(ctx, req.GetId(), req.GetVersion(), deduped)
|
||||
if err != nil {
|
||||
// TODO: Figure out a way to surface more helpful error info beyond the Internal error.
|
||||
return nil, nil, nil, nil, handlers.ApiErrorWithCodeAndMessage(codes.Internal, "Unable to set grant scopes on role: %v.", err)
|
||||
}
|
||||
out, pr, roleGrants, grantScopes, err := repo.LookupRole(ctx, req.GetId())
|
||||
if err != nil {
|
||||
return nil, nil, nil, nil, errors.Wrap(ctx, err, op, errors.WithMsg("unable to look up role after setting grant scopes"))
|
||||
}
|
||||
if out == nil {
|
||||
return nil, nil, nil, nil, handlers.ApiErrorWithCodeAndMessage(codes.Internal, "Unable to lookup role after setting grant scopes to it.")
|
||||
}
|
||||
return out, pr, roleGrants, grantScopes, nil
|
||||
}
|
||||
|
||||
func (s Service) removeGrantScopesInRepo(ctx context.Context, req grantScopeRequest) (*iam.Role, []*iam.PrincipalRole, []*iam.RoleGrant, []*iam.RoleGrantScope, error) {
|
||||
const op = "service.(Service).setGrantScopesInRepo"
|
||||
repo, err := s.repoFn()
|
||||
if err != nil {
|
||||
return nil, nil, nil, nil, err
|
||||
}
|
||||
|
||||
_, err = repo.DeleteRoleGrantScopes(ctx, req.GetId(), req.GetVersion(), strutil.RemoveDuplicates(req.GetGrantScopeIds(), false))
|
||||
if err != nil {
|
||||
// TODO: Figure out a way to surface more helpful error info beyond the Internal error.
|
||||
return nil, nil, nil, nil, handlers.ApiErrorWithCodeAndMessage(codes.Internal, "Unable to remove grant scopes from role: %v.", err)
|
||||
}
|
||||
out, pr, roleGrants, grantScopes, err := repo.LookupRole(ctx, req.GetId())
|
||||
if err != nil {
|
||||
return nil, nil, nil, nil, errors.Wrap(ctx, err, op, errors.WithMsg("unable to look up role after removing grant scopes"))
|
||||
}
|
||||
if out == nil {
|
||||
return nil, nil, nil, nil, handlers.ApiErrorWithCodeAndMessage(codes.Internal, "Unable to lookup role after removing grant scopes to it.")
|
||||
}
|
||||
return out, pr, roleGrants, grantScopes, nil
|
||||
}
|
||||
|
||||
func (s Service) authResult(ctx context.Context, id string, a action.Type) auth.VerifyResults {
|
||||
@@ -849,7 +1071,7 @@ func (s Service) authResult(ctx context.Context, id string, a action.Type) auth.
|
||||
return res
|
||||
}
|
||||
default:
|
||||
r, _, _, err := repo.LookupRole(ctx, id)
|
||||
r, _, _, _, err := repo.LookupRole(ctx, id)
|
||||
if err != nil {
|
||||
res.Error = err
|
||||
return res
|
||||
@@ -865,7 +1087,7 @@ func (s Service) authResult(ctx context.Context, id string, a action.Type) auth.
|
||||
return auth.Verify(ctx, opts...)
|
||||
}
|
||||
|
||||
func toProto(ctx context.Context, in *iam.Role, principals []*iam.PrincipalRole, grants []*iam.RoleGrant, opt ...handlers.Option) (*pb.Role, error) {
|
||||
func toProto(ctx context.Context, in *iam.Role, principals []*iam.PrincipalRole, grants []*iam.RoleGrant, grantScopes []*iam.RoleGrantScope, opt ...handlers.Option) (*pb.Role, error) {
|
||||
opts := handlers.GetOpts(opt...)
|
||||
if opts.WithOutputFields == nil {
|
||||
return nil, handlers.ApiErrorWithCodeAndMessage(codes.Internal, "output fields not found when building role proto")
|
||||
@@ -900,14 +1122,20 @@ func toProto(ctx context.Context, in *iam.Role, principals []*iam.PrincipalRole,
|
||||
if outputFields.Has(globals.AuthorizedActionsField) {
|
||||
out.AuthorizedActions = opts.WithAuthorizedActions
|
||||
}
|
||||
if outputFields.Has(globals.GrantScopeIdField) && in.GetGrantScopeId() != "" {
|
||||
out.GrantScopeId = &wrapperspb.StringValue{Value: in.GetGrantScopeId()}
|
||||
}
|
||||
if outputFields.Has(globals.PrincipalIdsField) {
|
||||
for _, p := range principals {
|
||||
out.PrincipalIds = append(out.PrincipalIds, p.GetPrincipalId())
|
||||
}
|
||||
}
|
||||
if outputFields.Has(globals.GrantScopeIdsField) {
|
||||
for _, gs := range grantScopes {
|
||||
out.GrantScopeIds = append(out.GrantScopeIds, gs.GetScopeIdOrSpecial())
|
||||
}
|
||||
sort.Strings(out.GrantScopeIds)
|
||||
}
|
||||
if outputFields.Has(globals.GrantScopeIdField) && len(grantScopes) == 1 {
|
||||
out.GrantScopeId = &wrapperspb.StringValue{Value: grantScopes[0].ScopeIdOrSpecial}
|
||||
}
|
||||
if outputFields.Has(globals.PrincipalsField) {
|
||||
for _, p := range principals {
|
||||
principal := &pb.Principal{
|
||||
@@ -925,7 +1153,7 @@ func toProto(ctx context.Context, in *iam.Role, principals []*iam.PrincipalRole,
|
||||
}
|
||||
if outputFields.Has(globals.GrantsField) {
|
||||
for _, g := range grants {
|
||||
parsed, err := perms.Parse(ctx, in.GetGrantScopeId(), g.GetRawGrant())
|
||||
parsed, err := perms.Parse(ctx, in.GetScopeId(), g.GetRawGrant())
|
||||
if err != nil {
|
||||
// This should never happen as we validate on the way in, but let's
|
||||
// return what we can since we are still returning the raw grant
|
||||
@@ -971,9 +1199,15 @@ func validateCreateRequest(req *pbs.CreateRoleRequest) error {
|
||||
scope.Global.String() != item.GetScopeId() {
|
||||
badFields["scope_id"] = "This field is missing or improperly formatted."
|
||||
}
|
||||
if item.GetGrantScopeId() != nil && handlers.ValidId(handlers.Id(item.GetScopeId()), scope.Project.Prefix()) {
|
||||
if item.GetGrantScopeId().GetValue() != item.GetScopeId() {
|
||||
badFields["grant_scope_id"] = "When the role is in a project scope this value must be that project's scope ID."
|
||||
if item.GetGrantScopeId() != nil {
|
||||
switch {
|
||||
case handlers.ValidId(handlers.Id(item.GetScopeId()), scope.Project.Prefix()):
|
||||
switch item.GetGrantScopeId().GetValue() {
|
||||
case item.GetScopeId(),
|
||||
globals.GrantScopeThis:
|
||||
default:
|
||||
badFields["grant_scope_id"] = "When the role is in a project scope this value must be that project's scope ID or \"this\"."
|
||||
}
|
||||
}
|
||||
}
|
||||
if item.GetPrincipals() != nil {
|
||||
@@ -1001,9 +1235,15 @@ func validateUpdateRequest(req *pbs.UpdateRoleRequest) error {
|
||||
if req.GetItem().GetGrantStrings() != nil {
|
||||
badFields["grant_strings"] = "This is a read only field and cannot be specified in an update request."
|
||||
}
|
||||
if req.GetItem().GetGrantScopeId() != nil && handlers.ValidId(handlers.Id(req.GetItem().GetScopeId()), scope.Project.Prefix()) {
|
||||
if req.GetItem().GetGrantScopeId().GetValue() != req.GetItem().GetScopeId() {
|
||||
badFields["grant_scope_id"] = "When the role is in a project scope this value must be that project's scope ID"
|
||||
if item := req.GetItem(); item != nil {
|
||||
switch {
|
||||
case handlers.ValidId(handlers.Id(item.GetScopeId()), scope.Project.Prefix()):
|
||||
switch item.GetGrantScopeId().GetValue() {
|
||||
case item.GetScopeId(),
|
||||
globals.GrantScopeThis:
|
||||
default:
|
||||
badFields["grant_scope_id"] = "When the role is in a project scope this value must be that project's scope ID or \"this\"."
|
||||
}
|
||||
}
|
||||
}
|
||||
return badFields
|
||||
@@ -1224,6 +1464,113 @@ func validateRemoveRoleGrantsRequest(ctx context.Context, req *pbs.RemoveRoleGra
|
||||
return nil
|
||||
}
|
||||
|
||||
// grantScopeRequest allows us to reuse a few request types in a common way for
|
||||
// grant scope add/set/remove operations
|
||||
type grantScopeRequest interface {
|
||||
GetId() string
|
||||
GetVersion() uint32
|
||||
GetGrantScopeIds() []string
|
||||
}
|
||||
|
||||
func validateRoleGrantScopesRequest(ctx context.Context, req grantScopeRequest) error {
|
||||
badFields := map[string]string{}
|
||||
if !handlers.ValidId(handlers.Id(req.GetId()), globals.RolePrefix) {
|
||||
badFields["id"] = "Incorrectly formatted identifier."
|
||||
}
|
||||
if req.GetVersion() == 0 {
|
||||
badFields["version"] = "Required field."
|
||||
}
|
||||
if len(req.GetGrantScopeIds()) == 0 {
|
||||
// This is actually okay for Set because they could be setting to null,
|
||||
// e.g. removing all grant scope ids
|
||||
if _, ok := req.(*pbs.SetRoleGrantScopesRequest); !ok {
|
||||
badFields["grant_scope_ids"] = "Must be non-empty."
|
||||
}
|
||||
}
|
||||
for _, v := range req.GetGrantScopeIds() {
|
||||
if len(v) == 0 {
|
||||
badFields["grant_scope_ids"] = "Grant scope IDs must not be empty."
|
||||
break
|
||||
}
|
||||
switch {
|
||||
case v == scope.Global.String(),
|
||||
v == globals.GrantScopeThis,
|
||||
v == globals.GrantScopeChildren,
|
||||
v == globals.GrantScopeDescendants:
|
||||
case globals.ResourceInfoFromPrefix(v).Type == resource.Scope:
|
||||
if !handlers.ValidId(handlers.Id(v), globals.ProjectPrefix) &&
|
||||
!handlers.ValidId(handlers.Id(v), globals.OrgPrefix) {
|
||||
badFields["grant_scope_ids"] = fmt.Sprintf("Incorrectly formatted identifier %q.", v)
|
||||
break
|
||||
}
|
||||
default:
|
||||
badFields["grant_scope_ids"] = fmt.Sprintf("Unknown value %q.", v)
|
||||
break
|
||||
}
|
||||
}
|
||||
if len(badFields) > 0 {
|
||||
return handlers.InvalidArgumentErrorf("Errors in provided fields.", badFields)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// validateRoleGrantScopesHierarchy is the companion to the domain-side logic to
|
||||
// validate scopes. It doesn't do all of the same checking but will allow for
|
||||
// better error messages when possible. We perform this check after
|
||||
// authentication to limit the possibility of an anonymous user causing DB load
|
||||
// due to this lookup, which is not a cheap one.
|
||||
func validateRoleGrantScopesHierarchy(ctx context.Context, repo *iam.Repository, roleId string, grantScopes []string) error {
|
||||
const op = "service.(Service).validateRoleGrantScopesHierarchy"
|
||||
// We want to ensure that the values being passed in make sense to whatever
|
||||
// extent we can right now, so we can provide nice errors back instead of DB
|
||||
// errors.
|
||||
role, _, _, _, err := repo.LookupRole(ctx, roleId)
|
||||
if err != nil {
|
||||
return errors.Wrap(ctx, err, op)
|
||||
}
|
||||
switch {
|
||||
case role.ScopeId == scope.Global.String():
|
||||
// Nothing, any grant scope is allowed for global
|
||||
case strings.HasPrefix(role.ScopeId, scope.Project.Prefix()):
|
||||
// In this case only "this" or the same project scope is allowed
|
||||
for _, grantScope := range grantScopes {
|
||||
switch grantScope {
|
||||
case globals.GrantScopeThis, role.ScopeId:
|
||||
default:
|
||||
return handlers.InvalidArgumentErrorf(
|
||||
"Invalid grant scope.",
|
||||
map[string]string{
|
||||
"grant_scope_id": `Project scopes can only have their own scope ID or "this" as a grant scope ID.`,
|
||||
})
|
||||
}
|
||||
}
|
||||
case strings.HasPrefix(role.ScopeId, scope.Org.Prefix()):
|
||||
// Orgs can have "this", its own scope, a project scope, or "children"
|
||||
for _, grantScope := range grantScopes {
|
||||
switch {
|
||||
case grantScope == role.ScopeId,
|
||||
grantScope == globals.GrantScopeThis,
|
||||
grantScope == globals.GrantScopeChildren,
|
||||
strings.HasPrefix(grantScope, scope.Project.Prefix()):
|
||||
default:
|
||||
return handlers.InvalidArgumentErrorf(
|
||||
"Invalid grant scope.",
|
||||
map[string]string{
|
||||
"grant_scope_id": fmt.Sprintf("Grant scope ID %q is not valid to set on an organization role.", grantScope),
|
||||
})
|
||||
}
|
||||
}
|
||||
default:
|
||||
// Should never happen
|
||||
return handlers.InvalidArgumentErrorf(
|
||||
"Improperly formatted identifier.",
|
||||
map[string]string{
|
||||
"grant_scope_id": `Unknown scope prefix type.`,
|
||||
})
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func newOutputOpts(ctx context.Context, item *iam.Role, scopeInfoMap map[string]*scopes.ScopeInfo, authResults auth.VerifyResults) ([]handlers.Option, bool) {
|
||||
res := perms.Resource{
|
||||
Type: resource.Role,
|
||||
|
||||
File diff suppressed because it is too large.
Load diff
@@ -63,7 +63,7 @@ func Test_newRateLimiterConfig(t *testing.T) {
|
||||
ratelimit.DefaultLimiterMaxQuotas(),
|
||||
false,
|
||||
&rateLimiterConfig{
|
||||
maxSize: 316158,
|
||||
maxSize: 322161,
|
||||
configs: nil,
|
||||
disabled: false,
|
||||
limits: defaultLimits,
|
||||
|
||||
+79
-1
@@ -2031,6 +2031,32 @@
|
||||
"unlimited": false
|
||||
}
|
||||
],
|
||||
"add-grant-scopes": [
|
||||
{
|
||||
"action": "add-grant-scopes",
|
||||
"limit": 30000,
|
||||
"per": "ip-address",
|
||||
"period": "30s",
|
||||
"resource": "role",
|
||||
"unlimited": false
|
||||
},
|
||||
{
|
||||
"action": "add-grant-scopes",
|
||||
"limit": 3000,
|
||||
"per": "auth-token",
|
||||
"period": "30s",
|
||||
"resource": "role",
|
||||
"unlimited": false
|
||||
},
|
||||
{
|
||||
"action": "add-grant-scopes",
|
||||
"limit": 30000,
|
||||
"per": "total",
|
||||
"period": "30s",
|
||||
"resource": "role",
|
||||
"unlimited": false
|
||||
}
|
||||
],
|
||||
"add-principals": [
|
||||
{
|
||||
"action": "add-principals",
|
||||
@@ -2213,6 +2239,32 @@
|
||||
"unlimited": false
|
||||
}
|
||||
],
|
||||
"remove-grant-scopes": [
|
||||
{
|
||||
"action": "remove-grant-scopes",
|
||||
"limit": 30000,
|
||||
"per": "total",
|
||||
"period": "30s",
|
||||
"resource": "role",
|
||||
"unlimited": false
|
||||
},
|
||||
{
|
||||
"action": "remove-grant-scopes",
|
||||
"limit": 30000,
|
||||
"per": "ip-address",
|
||||
"period": "30s",
|
||||
"resource": "role",
|
||||
"unlimited": false
|
||||
},
|
||||
{
|
||||
"action": "remove-grant-scopes",
|
||||
"limit": 3000,
|
||||
"per": "auth-token",
|
||||
"period": "30s",
|
||||
"resource": "role",
|
||||
"unlimited": false
|
||||
}
|
||||
],
|
||||
"remove-principals": [
|
||||
{
|
||||
"action": "remove-principals",
|
||||
@@ -2265,6 +2317,32 @@
|
||||
"unlimited": false
|
||||
}
|
||||
],
|
||||
"set-grant-scopes": [
|
||||
{
|
||||
"action": "set-grant-scopes",
|
||||
"limit": 30000,
|
||||
"per": "ip-address",
|
||||
"period": "30s",
|
||||
"resource": "role",
|
||||
"unlimited": false
|
||||
},
|
||||
{
|
||||
"action": "set-grant-scopes",
|
||||
"limit": 3000,
|
||||
"per": "auth-token",
|
||||
"period": "30s",
|
||||
"resource": "role",
|
||||
"unlimited": false
|
||||
},
|
||||
{
|
||||
"action": "set-grant-scopes",
|
||||
"limit": 30000,
|
||||
"per": "total",
|
||||
"period": "30s",
|
||||
"resource": "role",
|
||||
"unlimited": false
|
||||
}
|
||||
],
|
||||
"set-principals": [
|
||||
{
|
||||
"action": "set-principals",
|
||||
@@ -3997,7 +4075,7 @@
|
||||
]
|
||||
}
|
||||
},
|
||||
"max_size": 316158,
|
||||
"max_size": 322161,
|
||||
"msg": "controller api rate limiter"
|
||||
},
|
||||
"op": "controller.(rateLimiterConfig).writeSysEvent",
|
||||
|
||||
+78
@@ -2031,6 +2031,32 @@
|
||||
"unlimited": false
|
||||
}
|
||||
],
|
||||
"add-grant-scopes": [
|
||||
{
|
||||
"action": "add-grant-scopes",
|
||||
"limit": 30000,
|
||||
"per": "ip-address",
|
||||
"period": "30s",
|
||||
"resource": "role",
|
||||
"unlimited": false
|
||||
},
|
||||
{
|
||||
"action": "add-grant-scopes",
|
||||
"limit": 3000,
|
||||
"per": "auth-token",
|
||||
"period": "30s",
|
||||
"resource": "role",
|
||||
"unlimited": false
|
||||
},
|
||||
{
|
||||
"action": "add-grant-scopes",
|
||||
"limit": 30000,
|
||||
"per": "total",
|
||||
"period": "30s",
|
||||
"resource": "role",
|
||||
"unlimited": false
|
||||
}
|
||||
],
|
||||
"add-principals": [
|
||||
{
|
||||
"action": "add-principals",
|
||||
@@ -2213,6 +2239,32 @@
|
||||
"unlimited": false
|
||||
}
|
||||
],
|
||||
"remove-grant-scopes": [
|
||||
{
|
||||
"action": "remove-grant-scopes",
|
||||
"limit": 30000,
|
||||
"per": "total",
|
||||
"period": "30s",
|
||||
"resource": "role",
|
||||
"unlimited": false
|
||||
},
|
||||
{
|
||||
"action": "remove-grant-scopes",
|
||||
"limit": 30000,
|
||||
"per": "ip-address",
|
||||
"period": "30s",
|
||||
"resource": "role",
|
||||
"unlimited": false
|
||||
},
|
||||
{
|
||||
"action": "remove-grant-scopes",
|
||||
"limit": 3000,
|
||||
"per": "auth-token",
|
||||
"period": "30s",
|
||||
"resource": "role",
|
||||
"unlimited": false
|
||||
}
|
||||
],
|
||||
"remove-principals": [
|
||||
{
|
||||
"action": "remove-principals",
|
||||
@@ -2265,6 +2317,32 @@
|
||||
"unlimited": false
|
||||
}
|
||||
],
|
||||
"set-grant-scopes": [
|
||||
{
|
||||
"action": "set-grant-scopes",
|
||||
"limit": 30000,
|
||||
"per": "ip-address",
|
||||
"period": "30s",
|
||||
"resource": "role",
|
||||
"unlimited": false
|
||||
},
|
||||
{
|
||||
"action": "set-grant-scopes",
|
||||
"limit": 3000,
|
||||
"per": "auth-token",
|
||||
"period": "30s",
|
||||
"resource": "role",
|
||||
"unlimited": false
|
||||
},
|
||||
{
|
||||
"action": "set-grant-scopes",
|
||||
"limit": 30000,
|
||||
"per": "total",
|
||||
"period": "30s",
|
||||
"resource": "role",
|
||||
"unlimited": false
|
||||
}
|
||||
],
|
||||
"set-principals": [
|
||||
{
|
||||
"action": "set-principals",
|
||||
|
||||
+79
-1
@@ -2031,6 +2031,32 @@
|
||||
"unlimited": false
|
||||
}
|
||||
],
|
||||
"add-grant-scopes": [
|
||||
{
|
||||
"action": "add-grant-scopes",
|
||||
"limit": 100,
|
||||
"per": "ip-address",
|
||||
"period": "1m0s",
|
||||
"resource": "role",
|
||||
"unlimited": false
|
||||
},
|
||||
{
|
||||
"action": "add-grant-scopes",
|
||||
"limit": 100,
|
||||
"per": "auth-token",
|
||||
"period": "1m0s",
|
||||
"resource": "role",
|
||||
"unlimited": false
|
||||
},
|
||||
{
|
||||
"action": "add-grant-scopes",
|
||||
"limit": 100,
|
||||
"per": "total",
|
||||
"period": "1m0s",
|
||||
"resource": "role",
|
||||
"unlimited": false
|
||||
}
|
||||
],
|
||||
"add-principals": [
|
||||
{
|
||||
"action": "add-principals",
|
||||
@@ -2213,6 +2239,32 @@
|
||||
"unlimited": false
|
||||
}
|
||||
],
|
||||
"remove-grant-scopes": [
|
||||
{
|
||||
"action": "remove-grant-scopes",
|
||||
"limit": 100,
|
||||
"per": "total",
|
||||
"period": "1m0s",
|
||||
"resource": "role",
|
||||
"unlimited": false
|
||||
},
|
||||
{
|
||||
"action": "remove-grant-scopes",
|
||||
"limit": 100,
|
||||
"per": "ip-address",
|
||||
"period": "1m0s",
|
||||
"resource": "role",
|
||||
"unlimited": false
|
||||
},
|
||||
{
|
||||
"action": "remove-grant-scopes",
|
||||
"limit": 100,
|
||||
"per": "auth-token",
|
||||
"period": "1m0s",
|
||||
"resource": "role",
|
||||
"unlimited": false
|
||||
}
|
||||
],
|
||||
"remove-principals": [
|
||||
{
|
||||
"action": "remove-principals",
|
||||
@@ -2265,6 +2317,32 @@
|
||||
"unlimited": false
|
||||
}
|
||||
],
|
||||
"set-grant-scopes": [
|
||||
{
|
||||
"action": "set-grant-scopes",
|
||||
"limit": 100,
|
||||
"per": "ip-address",
|
||||
"period": "1m0s",
|
||||
"resource": "role",
|
||||
"unlimited": false
|
||||
},
|
||||
{
|
||||
"action": "set-grant-scopes",
|
||||
"limit": 100,
|
||||
"per": "auth-token",
|
||||
"period": "1m0s",
|
||||
"resource": "role",
|
||||
"unlimited": false
|
||||
},
|
||||
{
|
||||
"action": "set-grant-scopes",
|
||||
"limit": 100,
|
||||
"per": "total",
|
||||
"period": "1m0s",
|
||||
"resource": "role",
|
||||
"unlimited": false
|
||||
}
|
||||
],
|
||||
"set-principals": [
|
||||
{
|
||||
"action": "set-principals",
|
||||
@@ -3997,7 +4075,7 @@
|
||||
]
|
||||
}
|
||||
},
|
||||
"max_size": 316158,
|
||||
"max_size": 322161,
|
||||
"msg": "controller api rate limiter"
|
||||
},
|
||||
"op": "controller.(rateLimiterConfig).writeSysEvent",
|
||||
|
||||
@@ -370,8 +370,8 @@ type TestControllerOpts struct {
|
||||
// DefaultPassword is the password used when creating the default accounts.
|
||||
DefaultPassword string
|
||||
|
||||
// DisableInitialLoginRoleCreation can be set true to disable creating the
|
||||
// global scope login role automatically.
|
||||
// DisableInitialLoginRoleCreation can be set true to disable creating the global
|
||||
// scope default role automatically.
|
||||
DisableInitialLoginRoleCreation bool
|
||||
|
||||
// DisableAuthMethodCreation can be set true to disable creating an auth
|
||||
@@ -424,6 +424,11 @@ type TestControllerOpts struct {
|
||||
// eventer.
|
||||
EnableEventing bool
|
||||
|
||||
// EventerConfig allows specifying a custom event config. You must not run
|
||||
// the test in parallel (no calls to t.Parallel) since the this option
|
||||
// relies on modifying the system wide default eventer.
|
||||
EventerConfig *event.EventerConfig
|
||||
|
||||
// DisableAuthorizationFailures will still cause authz checks to be
|
||||
// performed but they won't cause 403 Forbidden. Useful for API-level
|
||||
// testing to avoid a lot of faff.
|
||||
@@ -661,12 +666,15 @@ func TestControllerConfig(t testing.TB, ctx context.Context, tc *TestController,
|
||||
opts.Config.Controller.Scheduler.JobRunIntervalDuration = opts.SchedulerRunJobInterval
|
||||
opts.Config.Controller.ApiRateLimiterMaxQuotas = ratelimit.DefaultLimiterMaxQuotas()
|
||||
|
||||
if opts.EnableEventing {
|
||||
opts.Config.Eventing = &event.EventerConfig{
|
||||
AuditEnabled: true,
|
||||
ObservationsEnabled: true,
|
||||
SysEventsEnabled: true,
|
||||
ErrorEventsDisabled: true,
|
||||
if opts.EnableEventing || opts.EventerConfig != nil {
|
||||
opts.Config.Eventing = opts.EventerConfig
|
||||
if opts.Config.Eventing == nil {
|
||||
opts.Config.Eventing = &event.EventerConfig{
|
||||
AuditEnabled: true,
|
||||
ObservationsEnabled: true,
|
||||
SysEventsEnabled: true,
|
||||
ErrorEventsDisabled: true,
|
||||
}
|
||||
}
|
||||
}
|
||||
serverName, err := os.Hostname()
|
||||
@@ -757,6 +765,9 @@ func TestControllerConfig(t testing.TB, ctx context.Context, tc *TestController,
|
||||
if _, err := tc.b.CreateInitialLoginRole(ctx); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if _, err := tc.b.CreateInitialAuthenticatedUserRole(ctx); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if !opts.DisableAuthMethodCreation {
|
||||
if _, _, err := tc.b.CreateInitialPasswordAuthMethod(ctx); err != nil {
|
||||
t.Fatal(err)
|
||||
@@ -791,6 +802,9 @@ func TestControllerConfig(t testing.TB, ctx context.Context, tc *TestController,
|
||||
}
|
||||
} else if !opts.DisableDatabaseCreation {
|
||||
var createOpts []base.Option
|
||||
if opts.DisableInitialLoginRoleCreation {
|
||||
createOpts = append(createOpts, base.WithSkipDefaultRoleCreation())
|
||||
}
|
||||
if opts.DisableAuthMethodCreation {
|
||||
createOpts = append(createOpts, base.WithSkipAuthMethodCreation())
|
||||
}
|
||||
|
||||
@@ -223,6 +223,8 @@ begin
|
||||
end;
|
||||
$$ language plpgsql;
|
||||
|
||||
-- Dropped in 83/01_iam_role_grant_scope since we moved to multiple scopes per
|
||||
-- role
|
||||
create or replace function grant_scope_id_valid() returns trigger
|
||||
as $$
|
||||
declare parent_scope_id text;
|
||||
|
||||
@@ -0,0 +1,210 @@
|
||||
-- Copyright (c) HashiCorp, Inc.
|
||||
-- SPDX-License-Identifier: MPL-2.0
|
||||
|
||||
begin;
|
||||
|
||||
-- This table is a join table to map roles to the various scopes the role
|
||||
-- grants apply to. role_id is a foreign key, but scope_id_or_special is not a
|
||||
-- foreign key to scopes because we support specific special values which are
|
||||
-- checked for in the constraint. We never query by scope_id_or_special so the
|
||||
-- ordering of the primary key should be correct.
|
||||
create table iam_role_grant_scope (
|
||||
create_time wt_timestamp,
|
||||
role_id wt_role_id not null -- pk
|
||||
references iam_role(public_id)
|
||||
on delete cascade
|
||||
on update cascade,
|
||||
scope_id_or_special text not null -- pk
|
||||
constraint scope_id_or_special_is_valid
|
||||
check (
|
||||
length(trim(scope_id_or_special)) = 12
|
||||
or
|
||||
scope_id_or_special in ('global', 'this', 'children', 'descendants')
|
||||
),
|
||||
primary key(role_id, scope_id_or_special)
|
||||
);
|
||||
comment on table iam_role_grant_scope is
|
||||
'table to map roles to the scopes they grant access to';
|
||||
|
||||
insert into oplog_ticket (name, version)
|
||||
values
|
||||
('iam_role_grant_scope', 1);
|
||||
|
||||
create trigger default_create_time_column before insert on iam_role_grant_scope
|
||||
for each row execute procedure default_create_time();
|
||||
|
||||
-- iam_immutable_role_grant_scope() ensures that grant scopes assigned to
|
||||
-- roles are immutable.
|
||||
create function iam_immutable_role_grant_scope() returns trigger
|
||||
as $$
|
||||
begin
|
||||
raise exception 'role grant scopes are immutable';
|
||||
end;
|
||||
$$ language plpgsql;
|
||||
|
||||
create trigger immutable_role_grant_scope before update on iam_role_grant_scope
|
||||
for each row execute procedure iam_immutable_role_grant_scope();
|
||||
|
||||
-- cascade_role_grant_scope_deletion() ensures that grant scopes entries are
|
||||
-- deleted when scopes are deleted
|
||||
create function cascade_role_grant_scope_deletion() returns trigger
|
||||
as $$
|
||||
begin
|
||||
delete from iam_role_grant_scope where scope_id_or_special = old.public_id;
|
||||
return old;
|
||||
end;
|
||||
$$ language plpgsql;
|
||||
|
||||
-- Create a trigger to ensure scope deletion cascades, since we're not using wt_scope_id
|
||||
create trigger cascade_deletion_iam_scope_to_iam_role_grant_scope after delete on iam_scope
|
||||
for each row execute procedure cascade_role_grant_scope_deletion();
|
||||
|
||||
-- role_grant_scope_id_or_special_valid ensures that a given grant scope ID is for a
|
||||
-- scope that exists or one of our known values
|
||||
create function role_grant_scope_id_or_special_valid() returns trigger
|
||||
as $$
|
||||
declare new_scope_type text;
|
||||
declare role_scope_id text;
|
||||
declare parent_scope_id text;
|
||||
declare role_scope_type text;
|
||||
declare validated_scope_id text;
|
||||
declare existing_scope_id_or_special text;
|
||||
begin
|
||||
-- We want to make a few checks based on the role's actual scope so select it
|
||||
select ir.scope_id from iam_role ir where ir.public_id = new.role_id into role_scope_id;
|
||||
-- It's always allowed to have a scope_id_or_special of "this" but don't
|
||||
-- allow it as well as the role's explicit scope ID
|
||||
if new.scope_id_or_special = 'this' then
|
||||
select rgs.scope_id_or_special
|
||||
from iam_role_grant_scope rgs
|
||||
where rgs.role_id = new.role_id and rgs.scope_id_or_special = role_scope_id
|
||||
into existing_scope_id_or_special;
|
||||
if existing_scope_id_or_special is not null then
|
||||
raise exception 'invalid to specify both "this" and a role''s actual scope id as a grant scope';
|
||||
end if;
|
||||
return new;
|
||||
end if;
|
||||
-- Fetch the scope id for the role
|
||||
select ir.scope_id from iam_role ir where ir.public_id = new.role_id into role_scope_id;
|
||||
-- It's always allowed to have the scope_id_or_special be the same as the role's
|
||||
if new.scope_id_or_special = role_scope_id then
|
||||
select rgs.scope_id_or_special
|
||||
from iam_role_grant_scope rgs
|
||||
where rgs.role_id = new.role_id and rgs.scope_id_or_special = 'this'
|
||||
into existing_scope_id_or_special;
|
||||
if existing_scope_id_or_special is not null then
|
||||
raise exception 'invalid to specify both "this" and a role''s actual scope id as a grant scope';
|
||||
end if;
|
||||
return new;
|
||||
end if;
|
||||
|
||||
-- A note about the above: this technically allows us to have grant scope
|
||||
-- IDs defined on projects. The original grant_scope_id logic allowed this
|
||||
-- in the domain layer so long as it referred only to its own scope.
|
||||
-- Accordingly we keep this behavior, even though we could choose to
|
||||
-- disallow this at the API layer.
|
||||
|
||||
-- At this point we've covered the same-as-role-scope and "this" cases
|
||||
-- above. Now, fetch the type of the role's scope, then check two situations
|
||||
-- that are either always or never allowed.
|
||||
select isc.type from iam_scope isc where isc.public_id = role_scope_id into role_scope_type;
|
||||
|
||||
-- Always allowed, because any scope is a child of global, and we've handled
|
||||
-- same-scope-id case above; however we have to check the scope is actually
|
||||
-- valid/known. Distinction check is used in the final case because if it's
|
||||
-- not known it's null.
|
||||
if role_scope_type = 'global' then
|
||||
case
|
||||
when new.scope_id_or_special = 'children' then
|
||||
select rgs.scope_id_or_special
|
||||
from iam_role_grant_scope rgs
|
||||
where rgs.role_id = new.role_id and rgs.scope_id_or_special = 'descendants'
|
||||
into existing_scope_id_or_special;
|
||||
if existing_scope_id_or_special is not null then
|
||||
raise exception 'invalid to specify both "children" and "descendants"as a grant scope';
|
||||
end if;
|
||||
when new.scope_id_or_special = 'descendants' then
|
||||
select rgs.scope_id_or_special
|
||||
from iam_role_grant_scope rgs
|
||||
where rgs.role_id = new.role_id and rgs.scope_id_or_special = 'children'
|
||||
into existing_scope_id_or_special;
|
||||
if existing_scope_id_or_special is not null then
|
||||
raise exception 'invalid to specify both "children" and "descendants"as a grant scope';
|
||||
end if;
|
||||
else
|
||||
select isc.public_id from iam_scope isc where isc.public_id = new.scope_id_or_special into validated_scope_id;
|
||||
if validated_scope_id is distinct from new.scope_id_or_special then
|
||||
raise exception 'invalid grant scope id';
|
||||
end if;
|
||||
end case;
|
||||
return new;
|
||||
end if;
|
||||
|
||||
-- Never allowed, because projects don't have child scopes (and we've
|
||||
-- already allowed same-scope-id above)
|
||||
if role_scope_type = 'project' then
|
||||
raise exception 'invalid to set a grant scope ID to non-same scope_id_or_special when role scope type is project';
|
||||
end if;
|
||||
|
||||
-- Ensure that what remains really is org
|
||||
if role_scope_type != 'org' then
|
||||
raise exception 'unknown scope type';
|
||||
end if;
|
||||
-- If it's "children" then allow it
|
||||
if new.scope_id_or_special = 'children' then
|
||||
return new;
|
||||
end if;
|
||||
-- Make "descendants" an error for orgs
|
||||
if new.scope_id_or_special = 'descendants' then
|
||||
raise exception 'invalid to specify "descendants" as a grant scope when the role''s scope ID is not "global"';
|
||||
end if;
|
||||
|
||||
-- We are now dealing with a bare scope ID and need to ensure that it's a
|
||||
-- child project of the role's org scope. Look up the parent scope ID for
|
||||
-- the grant scope ID given in the row. Allow iff the grant scope ID's
|
||||
-- parent matches the role's scope ID. We know that the role is in an org
|
||||
-- scope, so the only acceptable possibility here is that the new scope ID
|
||||
-- is a project and its parent scope is this org's.
|
||||
|
||||
-- Ensure it exists
|
||||
select isc.public_id from iam_scope isc where isc.public_id = new.scope_id_or_special into validated_scope_id;
|
||||
if validated_scope_id is distinct from new.scope_id_or_special then
|
||||
raise exception 'invalid grant scope id';
|
||||
end if;
|
||||
|
||||
-- Ensure it's a project
|
||||
select isc.type from iam_scope isc where isc.public_id = new.scope_id_or_special into new_scope_type;
|
||||
if new_scope_type != 'project' then
|
||||
raise exception 'expected grant scope id scope type to be project';
|
||||
end if;
|
||||
|
||||
-- Ensure that the parent of the project is the role's org scope
|
||||
select isc.parent_id from iam_scope isc where isc.public_id = new.scope_id_or_special into parent_scope_id;
|
||||
if parent_scope_id != role_scope_id then
|
||||
raise exception 'grant scope id is not a child project of the role''s org scope';
|
||||
end if;
|
||||
|
||||
return new;
|
||||
end;
|
||||
$$ language plpgsql;
|
||||
comment on function role_grant_scope_id_or_special_valid() is
|
||||
'function used to ensure grant scope ids are valid';
|
||||
|
||||
create trigger ensure_role_grant_scope_id_or_special_valid before insert or update on iam_role_grant_scope
|
||||
for each row execute procedure role_grant_scope_id_or_special_valid();
|
||||
|
||||
-- Now perform migrations:
|
||||
|
||||
-- First, copy current grant scope ID values from existing roles to the new
|
||||
-- table and set the grant scope ID value on each role to the scope ID
|
||||
insert into iam_role_grant_scope(role_id, scope_id_or_special)
|
||||
select public_id as role_id, grant_scope_id as scope_id_or_special from iam_role;
|
||||
|
||||
-- Drop the now-unnecessary trigger and function from 0/06_iam
|
||||
drop trigger ensure_grant_scope_id_valid on iam_role;
|
||||
drop function grant_scope_id_valid;
|
||||
|
||||
-- Remove the column from iam_role
|
||||
alter table iam_role drop column grant_scope_id;
|
||||
|
||||
commit;
|
||||
@@ -106,19 +106,33 @@ begin;
|
||||
('g___cg-group', 'u_______cora');
|
||||
|
||||
insert into iam_role
|
||||
(scope_id, grant_scope_id, public_id, name)
|
||||
(scope_id, public_id, name)
|
||||
values
|
||||
('p____bcolors', 'p____bcolors', 'r_pp_bc__mix', 'Color Mixer'),
|
||||
('p____rcolors', 'p____rcolors', 'r_pp_rc__mix', 'Color Mixer'),
|
||||
('p____gcolors', 'p____gcolors', 'r_pp_gc__mix', 'Color Mixer'),
|
||||
('o_____colors', 'p____bcolors', 'r_op_bc__art', 'Blue Color Artist'),
|
||||
('o_____colors', 'p____rcolors', 'r_op_rc__art', 'Red Color Artist'),
|
||||
('o_____colors', 'p____gcolors', 'r_op_gc__art', 'Green Color Artist'),
|
||||
('o_____colors', 'o_____colors', 'r_oo_____art', 'Color Artist'),
|
||||
('global', 'o_____colors', 'r_go____name', 'Color Namer'),
|
||||
('global', 'p____bcolors', 'r_gp____spec', 'Blue Color Inspector'),
|
||||
('global', 'global', 'r_gg_____buy', 'Purchaser'),
|
||||
('global', 'global', 'r_gg____shop', 'Shopper');
|
||||
('p____bcolors', 'r_pp_bc__mix', 'Color Mixer'),
|
||||
('p____rcolors', 'r_pp_rc__mix', 'Color Mixer'),
|
||||
('p____gcolors', 'r_pp_gc__mix', 'Color Mixer'),
|
||||
('o_____colors', 'r_op_bc__art', 'Blue Color Artist'),
|
||||
('o_____colors', 'r_op_rc__art', 'Red Color Artist'),
|
||||
('o_____colors', 'r_op_gc__art', 'Green Color Artist'),
|
||||
('o_____colors', 'r_oo_____art', 'Color Artist'),
|
||||
('global', 'r_go____name', 'Color Namer'),
|
||||
('global', 'r_gp____spec', 'Blue Color Inspector'),
|
||||
('global', 'r_gg_____buy', 'Purchaser'),
|
||||
('global', 'r_gg____shop', 'Shopper');
|
||||
|
||||
insert into iam_role_grant_scope
|
||||
(role_id, scope_id_or_special)
|
||||
values
|
||||
('r_pp_bc__mix', 'this'),
|
||||
('r_pp_rc__mix', 'p____rcolors'),
|
||||
('r_pp_gc__mix', 'this'),
|
||||
('r_op_bc__art', 'p____bcolors'),
|
||||
('r_op_rc__art', 'p____rcolors'),
|
||||
('r_op_gc__art', 'p____gcolors'),
|
||||
('r_go____name', 'o_____colors'),
|
||||
('r_gp____spec', 'p____bcolors'),
|
||||
('r_gg_____buy', 'global'),
|
||||
('r_gg____shop', 'global');
|
||||
|
||||
insert into iam_role_grant
|
||||
(role_id, canonical_grant, raw_grant)
|
||||
|
||||
@@ -55,14 +55,22 @@ begin;
|
||||
('g___ws-group', 'u_____waylon');
|
||||
|
||||
insert into iam_role
|
||||
(scope_id, grant_scope_id, public_id, name)
|
||||
(scope_id, public_id, name)
|
||||
values
|
||||
-- ('global', 'global', 'r_gg_____buy', 'Purchaser'),
|
||||
-- ('global', 'global', 'r_gg____shop', 'Shopper'),
|
||||
('p____bwidget', 'p____bwidget', 'r_pp_bw__bld', 'Widget Builder'),
|
||||
('p____swidget', 'p____swidget', 'r_pp_sw__bld', 'Widget Builder'),
|
||||
('o_____widget', 'p____swidget', 'r_op_sw__eng', 'Small Widget Engineer'),
|
||||
('o_____widget', 'o_____widget', 'r_oo_____eng', 'Widget Engineer');
|
||||
-- ('global', 'r_gg_____buy', 'Purchaser'),
|
||||
-- ('global', 'r_gg____shop', 'Shopper'),
|
||||
('p____bwidget', 'r_pp_bw__bld', 'Widget Builder'),
|
||||
('p____swidget', 'r_pp_sw__bld', 'Widget Builder'),
|
||||
('o_____widget', 'r_op_sw__eng', 'Small Widget Engineer'),
|
||||
('o_____widget', 'r_oo_____eng', 'Widget Engineer');
|
||||
|
||||
insert into iam_role_grant_scope
|
||||
(role_id, scope_id_or_special)
|
||||
values
|
||||
('r_pp_bw__bld', 'p____bwidget'),
|
||||
('r_pp_sw__bld', 'this'),
|
||||
('r_op_sw__eng', 'p____swidget'),
|
||||
('r_oo_____eng', 'o_____widget');
|
||||
|
||||
insert into iam_role_grant
|
||||
(role_id, canonical_grant, raw_grant)
|
||||
|
||||
@@ -107,9 +107,14 @@ begin;
|
||||
|
||||
-- Roles
|
||||
insert into iam_role
|
||||
(scope_id, grant_scope_id, public_id, name)
|
||||
(scope_id, public_id, name)
|
||||
values
|
||||
('p______tacos', 'p______tacos', 'r_pp___tacos', 'Tacos');
|
||||
('p______tacos', 'r_pp___tacos', 'Tacos');
|
||||
|
||||
insert into iam_role_grant_scope
|
||||
(role_id, scope_id_or_special )
|
||||
values
|
||||
('r_pp___tacos', 'p______tacos');
|
||||
|
||||
insert into iam_role_grant
|
||||
(role_id, canonical_grant, raw_grant)
|
||||
|
||||
@@ -2570,6 +2570,54 @@
|
||||
]
|
||||
}
|
||||
},
|
||||
"/v1/roles/{id}:add-grant-scopes": {
|
||||
"post": {
|
||||
"summary": "Adds grant scopes to a Role",
|
||||
"operationId": "RoleService_AddRoleGrantScopes",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/controller.api.resources.roles.v1.Role"
|
||||
}
|
||||
}
|
||||
},
|
||||
"parameters": [
|
||||
{
|
||||
"name": "id",
|
||||
"description": "",
|
||||
"in": "path",
|
||||
"required": true,
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"name": "body",
|
||||
"in": "body",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"version": {
|
||||
"type": "integer",
|
||||
"format": "int64",
|
||||
"description": "Version is used to ensure this resource has not changed.\nThe mutation will fail if the version does not match the latest known good version."
|
||||
},
|
||||
"grant_scope_ids": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"title": ""
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"tags": [
|
||||
"controller.api.services.v1.RoleService"
|
||||
]
|
||||
}
|
||||
},
|
||||
"/v1/roles/{id}:add-grants": {
|
||||
"post": {
|
||||
"summary": "Adds grants to a Role",
|
||||
@@ -2666,6 +2714,54 @@
|
||||
]
|
||||
}
|
||||
},
|
||||
"/v1/roles/{id}:remove-grant-scopes": {
|
||||
"post": {
|
||||
"summary": "Removes grant scopes from a Role.",
|
||||
"operationId": "RoleService_RemoveRoleGrantScopes",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/controller.api.resources.roles.v1.Role"
|
||||
}
|
||||
}
|
||||
},
|
||||
"parameters": [
|
||||
{
|
||||
"name": "id",
|
||||
"description": "",
|
||||
"in": "path",
|
||||
"required": true,
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"name": "body",
|
||||
"in": "body",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"version": {
|
||||
"type": "integer",
|
||||
"format": "int64",
|
||||
"description": "Version is used to ensure this resource has not changed.\nThe mutation will fail if the version does not match the latest known good version."
|
||||
},
|
||||
"grant_scope_ids": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"title": ""
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"tags": [
|
||||
"controller.api.services.v1.RoleService"
|
||||
]
|
||||
}
|
||||
},
|
||||
"/v1/roles/{id}:remove-grants": {
|
||||
"post": {
|
||||
"summary": "Removes grants from a Role.",
|
||||
@@ -2762,6 +2858,54 @@
|
||||
]
|
||||
}
|
||||
},
|
||||
"/v1/roles/{id}:set-grant-scopes": {
|
||||
"post": {
|
||||
"summary": "Set grant scopes for a Role, removing any grant scopes that are not specified in the request.",
|
||||
"operationId": "RoleService_SetRoleGrantScopes",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/controller.api.resources.roles.v1.Role"
|
||||
}
|
||||
}
|
||||
},
|
||||
"parameters": [
|
||||
{
|
||||
"name": "id",
|
||||
"description": "",
|
||||
"in": "path",
|
||||
"required": true,
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"name": "body",
|
||||
"in": "body",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"version": {
|
||||
"type": "integer",
|
||||
"format": "int64",
|
||||
"description": "Version is used to ensure this resource has not changed.\nThe mutation will fail if the version does not match the latest known good version."
|
||||
},
|
||||
"grant_scope_ids": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"title": ""
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"tags": [
|
||||
"controller.api.services.v1.RoleService"
|
||||
]
|
||||
}
|
||||
},
|
||||
"/v1/roles/{id}:set-grants": {
|
||||
"post": {
|
||||
"summary": "Set grants for a Role, removing any grants that are not specified in the request.",
|
||||
@@ -5944,7 +6088,15 @@
|
||||
},
|
||||
"grant_scope_id": {
|
||||
"type": "string",
|
||||
"description": "The Scope the grants will apply to. If the Role is at the global scope, this can be an org or project. If the Role is at an org scope, this can be a project within the org. It is invalid for this to be anything other than the Role's scope when the Role's scope is a project."
|
||||
"description": "The Scope the grants will apply to. If the Role is at the global scope,\nthis can be an org or project. If the Role is at an org scope, this can be\na project within the org. It is invalid for this to be anything other than\nthe Role's scope when the Role's scope is a project.\n\nDeprecated: Use \"grant_scope_ids\" instead."
|
||||
},
|
||||
"grant_scope_ids": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"description": "Output only. The IDs of Scopes the grants will apply to. This can include\nthe role's own scope ID, or \"this\" for the same behavior; specific IDs of\nscopes that are children of the role's scope; the value \"children\" to match\nall direct child scopes of the role's scope; or the value \"descendants\" to\nmatch all descendant scopes (e.g. child scopes, children of child scopes;\nonly valid at \"global\" scope since it is the only one with children of\nchildren).",
|
||||
"readOnly": true
|
||||
},
|
||||
"principal_ids": {
|
||||
"type": "array",
|
||||
@@ -7583,6 +7735,14 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"controller.api.services.v1.AddRoleGrantScopesResponse": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"item": {
|
||||
"$ref": "#/definitions/controller.api.resources.roles.v1.Role"
|
||||
}
|
||||
}
|
||||
},
|
||||
"controller.api.services.v1.AddRoleGrantsResponse": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
@@ -8995,6 +9155,14 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"controller.api.services.v1.RemoveRoleGrantScopesResponse": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"item": {
|
||||
"$ref": "#/definitions/controller.api.resources.roles.v1.Role"
|
||||
}
|
||||
}
|
||||
},
|
||||
"controller.api.services.v1.RemoveRoleGrantsResponse": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
@@ -9083,6 +9251,14 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"controller.api.services.v1.SetRoleGrantScopesResponse": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"item": {
|
||||
"$ref": "#/definitions/controller.api.resources.roles.v1.Role"
|
||||
}
|
||||
}
|
||||
},
|
||||
"controller.api.services.v1.SetRoleGrantsResponse": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
|
||||
@@ -1285,6 +1285,342 @@ func (x *RemoveRoleGrantsResponse) GetItem() *roles.Role {
|
||||
return nil
|
||||
}
|
||||
|
||||
type AddRoleGrantScopesRequest struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty" class:"public"` // @gotags: `class:"public"`
|
||||
// Version is used to ensure this resource has not changed.
|
||||
// The mutation will fail if the version does not match the latest known good version.
|
||||
Version uint32 `protobuf:"varint,2,opt,name=version,proto3" json:"version,omitempty" class:"public"` // @gotags: `class:"public"`
|
||||
GrantScopeIds []string `protobuf:"bytes,3,rep,name=grant_scope_ids,proto3" json:"grant_scope_ids,omitempty" class:"public"` // @gotags: `class:"public"`
|
||||
}
|
||||
|
||||
func (x *AddRoleGrantScopesRequest) Reset() {
|
||||
*x = AddRoleGrantScopesRequest{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_controller_api_services_v1_role_service_proto_msgTypes[22]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *AddRoleGrantScopesRequest) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*AddRoleGrantScopesRequest) ProtoMessage() {}
|
||||
|
||||
func (x *AddRoleGrantScopesRequest) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_controller_api_services_v1_role_service_proto_msgTypes[22]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use AddRoleGrantScopesRequest.ProtoReflect.Descriptor instead.
|
||||
func (*AddRoleGrantScopesRequest) Descriptor() ([]byte, []int) {
|
||||
return file_controller_api_services_v1_role_service_proto_rawDescGZIP(), []int{22}
|
||||
}
|
||||
|
||||
func (x *AddRoleGrantScopesRequest) GetId() string {
|
||||
if x != nil {
|
||||
return x.Id
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *AddRoleGrantScopesRequest) GetVersion() uint32 {
|
||||
if x != nil {
|
||||
return x.Version
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (x *AddRoleGrantScopesRequest) GetGrantScopeIds() []string {
|
||||
if x != nil {
|
||||
return x.GrantScopeIds
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type AddRoleGrantScopesResponse struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
Item *roles.Role `protobuf:"bytes,1,opt,name=item,proto3" json:"item,omitempty"`
|
||||
}
|
||||
|
||||
func (x *AddRoleGrantScopesResponse) Reset() {
|
||||
*x = AddRoleGrantScopesResponse{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_controller_api_services_v1_role_service_proto_msgTypes[23]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *AddRoleGrantScopesResponse) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*AddRoleGrantScopesResponse) ProtoMessage() {}
|
||||
|
||||
func (x *AddRoleGrantScopesResponse) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_controller_api_services_v1_role_service_proto_msgTypes[23]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use AddRoleGrantScopesResponse.ProtoReflect.Descriptor instead.
|
||||
func (*AddRoleGrantScopesResponse) Descriptor() ([]byte, []int) {
|
||||
return file_controller_api_services_v1_role_service_proto_rawDescGZIP(), []int{23}
|
||||
}
|
||||
|
||||
func (x *AddRoleGrantScopesResponse) GetItem() *roles.Role {
|
||||
if x != nil {
|
||||
return x.Item
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type SetRoleGrantScopesRequest struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty" class:"public"` // @gotags: `class:"public"`
|
||||
// Version is used to ensure this resource has not changed.
|
||||
// The mutation will fail if the version does not match the latest known good version.
|
||||
Version uint32 `protobuf:"varint,2,opt,name=version,proto3" json:"version,omitempty" class:"public"` // @gotags: `class:"public"`
|
||||
GrantScopeIds []string `protobuf:"bytes,3,rep,name=grant_scope_ids,proto3" json:"grant_scope_ids,omitempty" class:"public"` // @gotags: `class:"public"`
|
||||
}
|
||||
|
||||
func (x *SetRoleGrantScopesRequest) Reset() {
|
||||
*x = SetRoleGrantScopesRequest{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_controller_api_services_v1_role_service_proto_msgTypes[24]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *SetRoleGrantScopesRequest) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*SetRoleGrantScopesRequest) ProtoMessage() {}
|
||||
|
||||
func (x *SetRoleGrantScopesRequest) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_controller_api_services_v1_role_service_proto_msgTypes[24]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use SetRoleGrantScopesRequest.ProtoReflect.Descriptor instead.
|
||||
func (*SetRoleGrantScopesRequest) Descriptor() ([]byte, []int) {
|
||||
return file_controller_api_services_v1_role_service_proto_rawDescGZIP(), []int{24}
|
||||
}
|
||||
|
||||
func (x *SetRoleGrantScopesRequest) GetId() string {
|
||||
if x != nil {
|
||||
return x.Id
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *SetRoleGrantScopesRequest) GetVersion() uint32 {
|
||||
if x != nil {
|
||||
return x.Version
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (x *SetRoleGrantScopesRequest) GetGrantScopeIds() []string {
|
||||
if x != nil {
|
||||
return x.GrantScopeIds
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type SetRoleGrantScopesResponse struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
Item *roles.Role `protobuf:"bytes,1,opt,name=item,proto3" json:"item,omitempty"`
|
||||
}
|
||||
|
||||
func (x *SetRoleGrantScopesResponse) Reset() {
|
||||
*x = SetRoleGrantScopesResponse{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_controller_api_services_v1_role_service_proto_msgTypes[25]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *SetRoleGrantScopesResponse) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*SetRoleGrantScopesResponse) ProtoMessage() {}
|
||||
|
||||
func (x *SetRoleGrantScopesResponse) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_controller_api_services_v1_role_service_proto_msgTypes[25]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use SetRoleGrantScopesResponse.ProtoReflect.Descriptor instead.
|
||||
func (*SetRoleGrantScopesResponse) Descriptor() ([]byte, []int) {
|
||||
return file_controller_api_services_v1_role_service_proto_rawDescGZIP(), []int{25}
|
||||
}
|
||||
|
||||
func (x *SetRoleGrantScopesResponse) GetItem() *roles.Role {
|
||||
if x != nil {
|
||||
return x.Item
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type RemoveRoleGrantScopesRequest struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty" class:"public"` // @gotags: `class:"public"`
|
||||
// Version is used to ensure this resource has not changed.
|
||||
// The mutation will fail if the version does not match the latest known good version.
|
||||
Version uint32 `protobuf:"varint,2,opt,name=version,proto3" json:"version,omitempty" class:"public"` // @gotags: `class:"public"`
|
||||
GrantScopeIds []string `protobuf:"bytes,3,rep,name=grant_scope_ids,proto3" json:"grant_scope_ids,omitempty" class:"public"` // @gotags: `class:"public"`
|
||||
}
|
||||
|
||||
func (x *RemoveRoleGrantScopesRequest) Reset() {
|
||||
*x = RemoveRoleGrantScopesRequest{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_controller_api_services_v1_role_service_proto_msgTypes[26]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *RemoveRoleGrantScopesRequest) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*RemoveRoleGrantScopesRequest) ProtoMessage() {}
|
||||
|
||||
func (x *RemoveRoleGrantScopesRequest) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_controller_api_services_v1_role_service_proto_msgTypes[26]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use RemoveRoleGrantScopesRequest.ProtoReflect.Descriptor instead.
|
||||
func (*RemoveRoleGrantScopesRequest) Descriptor() ([]byte, []int) {
|
||||
return file_controller_api_services_v1_role_service_proto_rawDescGZIP(), []int{26}
|
||||
}
|
||||
|
||||
func (x *RemoveRoleGrantScopesRequest) GetId() string {
|
||||
if x != nil {
|
||||
return x.Id
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *RemoveRoleGrantScopesRequest) GetVersion() uint32 {
|
||||
if x != nil {
|
||||
return x.Version
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (x *RemoveRoleGrantScopesRequest) GetGrantScopeIds() []string {
|
||||
if x != nil {
|
||||
return x.GrantScopeIds
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type RemoveRoleGrantScopesResponse struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
Item *roles.Role `protobuf:"bytes,1,opt,name=item,proto3" json:"item,omitempty"`
|
||||
}
|
||||
|
||||
func (x *RemoveRoleGrantScopesResponse) Reset() {
|
||||
*x = RemoveRoleGrantScopesResponse{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_controller_api_services_v1_role_service_proto_msgTypes[27]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *RemoveRoleGrantScopesResponse) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*RemoveRoleGrantScopesResponse) ProtoMessage() {}
|
||||
|
||||
func (x *RemoveRoleGrantScopesResponse) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_controller_api_services_v1_role_service_proto_msgTypes[27]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use RemoveRoleGrantScopesResponse.ProtoReflect.Descriptor instead.
|
||||
func (*RemoveRoleGrantScopesResponse) Descriptor() ([]byte, []int) {
|
||||
return file_controller_api_services_v1_role_service_proto_rawDescGZIP(), []int{27}
|
||||
}
|
||||
|
||||
func (x *RemoveRoleGrantScopesResponse) GetItem() *roles.Role {
|
||||
if x != nil {
|
||||
return x.Item
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
var File_controller_api_services_v1_role_service_proto protoreflect.FileDescriptor
|
||||
|
||||
var file_controller_api_services_v1_role_service_proto_rawDesc = []byte{
|
||||
@@ -1441,150 +1777,235 @@ var file_controller_api_services_v1_role_service_proto_rawDesc = []byte{
|
||||
0x69, 0x74, 0x65, 0x6d, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x63, 0x6f, 0x6e,
|
||||
0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x72, 0x65, 0x73, 0x6f,
|
||||
0x75, 0x72, 0x63, 0x65, 0x73, 0x2e, 0x72, 0x6f, 0x6c, 0x65, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x52,
|
||||
0x6f, 0x6c, 0x65, 0x52, 0x04, 0x69, 0x74, 0x65, 0x6d, 0x32, 0x98, 0x11, 0x0a, 0x0b, 0x52, 0x6f,
|
||||
0x6c, 0x65, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x98, 0x01, 0x0a, 0x07, 0x47, 0x65,
|
||||
0x74, 0x52, 0x6f, 0x6c, 0x65, 0x12, 0x2a, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c,
|
||||
0x65, 0x72, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e,
|
||||
0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x52, 0x6f, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73,
|
||||
0x74, 0x1a, 0x2b, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2e, 0x61,
|
||||
0x70, 0x69, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x47,
|
||||
0x65, 0x74, 0x52, 0x6f, 0x6c, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x34,
|
||||
0x92, 0x41, 0x15, 0x12, 0x13, 0x47, 0x65, 0x74, 0x73, 0x20, 0x61, 0x20, 0x73, 0x69, 0x6e, 0x67,
|
||||
0x6c, 0x65, 0x20, 0x52, 0x6f, 0x6c, 0x65, 0x2e, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x16, 0x62, 0x04,
|
||||
0x69, 0x74, 0x65, 0x6d, 0x12, 0x0e, 0x2f, 0x76, 0x31, 0x2f, 0x72, 0x6f, 0x6c, 0x65, 0x73, 0x2f,
|
||||
0x7b, 0x69, 0x64, 0x7d, 0x12, 0x90, 0x01, 0x0a, 0x09, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x6f, 0x6c,
|
||||
0x65, 0x73, 0x12, 0x2c, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2e,
|
||||
0x61, 0x70, 0x69, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x76, 0x31, 0x2e,
|
||||
0x4c, 0x69, 0x73, 0x74, 0x52, 0x6f, 0x6c, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
|
||||
0x1a, 0x2d, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2e, 0x61, 0x70,
|
||||
0x69, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69,
|
||||
0x73, 0x74, 0x52, 0x6f, 0x6c, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22,
|
||||
0x26, 0x92, 0x41, 0x12, 0x12, 0x10, 0x4c, 0x69, 0x73, 0x74, 0x73, 0x20, 0x61, 0x6c, 0x6c, 0x20,
|
||||
0x52, 0x6f, 0x6c, 0x65, 0x73, 0x2e, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x0b, 0x12, 0x09, 0x2f, 0x76,
|
||||
0x31, 0x2f, 0x72, 0x6f, 0x6c, 0x65, 0x73, 0x12, 0xa5, 0x01, 0x0a, 0x0a, 0x43, 0x72, 0x65, 0x61,
|
||||
0x74, 0x65, 0x52, 0x6f, 0x6c, 0x65, 0x12, 0x2d, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c,
|
||||
0x6c, 0x65, 0x72, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73,
|
||||
0x2e, 0x76, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x6f, 0x6c, 0x65, 0x52, 0x65,
|
||||
0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2e, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c,
|
||||
0x65, 0x72, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e,
|
||||
0x76, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x6f, 0x6c, 0x65, 0x52, 0x65, 0x73,
|
||||
0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x38, 0x92, 0x41, 0x18, 0x12, 0x16, 0x43, 0x72, 0x65, 0x61,
|
||||
0x74, 0x65, 0x73, 0x20, 0x61, 0x20, 0x73, 0x69, 0x6e, 0x67, 0x6c, 0x65, 0x20, 0x52, 0x6f, 0x6c,
|
||||
0x65, 0x2e, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x17, 0x3a, 0x04, 0x69, 0x74, 0x65, 0x6d, 0x62, 0x04,
|
||||
0x69, 0x74, 0x65, 0x6d, 0x22, 0x09, 0x2f, 0x76, 0x31, 0x2f, 0x72, 0x6f, 0x6c, 0x65, 0x73, 0x12,
|
||||
0xa3, 0x01, 0x0a, 0x0a, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, 0x6f, 0x6c, 0x65, 0x12, 0x2d,
|
||||
0x6f, 0x6c, 0x65, 0x52, 0x04, 0x69, 0x74, 0x65, 0x6d, 0x22, 0x6f, 0x0a, 0x19, 0x41, 0x64, 0x64,
|
||||
0x52, 0x6f, 0x6c, 0x65, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x53, 0x63, 0x6f, 0x70, 0x65, 0x73, 0x52,
|
||||
0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01,
|
||||
0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f,
|
||||
0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e,
|
||||
0x12, 0x28, 0x0a, 0x0f, 0x67, 0x72, 0x61, 0x6e, 0x74, 0x5f, 0x73, 0x63, 0x6f, 0x70, 0x65, 0x5f,
|
||||
0x69, 0x64, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0f, 0x67, 0x72, 0x61, 0x6e, 0x74,
|
||||
0x5f, 0x73, 0x63, 0x6f, 0x70, 0x65, 0x5f, 0x69, 0x64, 0x73, 0x22, 0x59, 0x0a, 0x1a, 0x41, 0x64,
|
||||
0x64, 0x52, 0x6f, 0x6c, 0x65, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x53, 0x63, 0x6f, 0x70, 0x65, 0x73,
|
||||
0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3b, 0x0a, 0x04, 0x69, 0x74, 0x65, 0x6d,
|
||||
0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c,
|
||||
0x6c, 0x65, 0x72, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65,
|
||||
0x73, 0x2e, 0x72, 0x6f, 0x6c, 0x65, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x6f, 0x6c, 0x65, 0x52,
|
||||
0x04, 0x69, 0x74, 0x65, 0x6d, 0x22, 0x6f, 0x0a, 0x19, 0x53, 0x65, 0x74, 0x52, 0x6f, 0x6c, 0x65,
|
||||
0x47, 0x72, 0x61, 0x6e, 0x74, 0x53, 0x63, 0x6f, 0x70, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65,
|
||||
0x73, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02,
|
||||
0x69, 0x64, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20,
|
||||
0x01, 0x28, 0x0d, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x28, 0x0a, 0x0f,
|
||||
0x67, 0x72, 0x61, 0x6e, 0x74, 0x5f, 0x73, 0x63, 0x6f, 0x70, 0x65, 0x5f, 0x69, 0x64, 0x73, 0x18,
|
||||
0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0f, 0x67, 0x72, 0x61, 0x6e, 0x74, 0x5f, 0x73, 0x63, 0x6f,
|
||||
0x70, 0x65, 0x5f, 0x69, 0x64, 0x73, 0x22, 0x59, 0x0a, 0x1a, 0x53, 0x65, 0x74, 0x52, 0x6f, 0x6c,
|
||||
0x65, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x53, 0x63, 0x6f, 0x70, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70,
|
||||
0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3b, 0x0a, 0x04, 0x69, 0x74, 0x65, 0x6d, 0x18, 0x01, 0x20, 0x01,
|
||||
0x28, 0x0b, 0x32, 0x27, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2e,
|
||||
0x61, 0x70, 0x69, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x2e, 0x72, 0x6f,
|
||||
0x6c, 0x65, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x6f, 0x6c, 0x65, 0x52, 0x04, 0x69, 0x74, 0x65,
|
||||
0x6d, 0x22, 0x72, 0x0a, 0x1c, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x52, 0x6f, 0x6c, 0x65, 0x47,
|
||||
0x72, 0x61, 0x6e, 0x74, 0x53, 0x63, 0x6f, 0x70, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73,
|
||||
0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69,
|
||||
0x64, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01,
|
||||
0x28, 0x0d, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x28, 0x0a, 0x0f, 0x67,
|
||||
0x72, 0x61, 0x6e, 0x74, 0x5f, 0x73, 0x63, 0x6f, 0x70, 0x65, 0x5f, 0x69, 0x64, 0x73, 0x18, 0x03,
|
||||
0x20, 0x03, 0x28, 0x09, 0x52, 0x0f, 0x67, 0x72, 0x61, 0x6e, 0x74, 0x5f, 0x73, 0x63, 0x6f, 0x70,
|
||||
0x65, 0x5f, 0x69, 0x64, 0x73, 0x22, 0x5c, 0x0a, 0x1d, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x52,
|
||||
0x6f, 0x6c, 0x65, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x53, 0x63, 0x6f, 0x70, 0x65, 0x73, 0x52, 0x65,
|
||||
0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3b, 0x0a, 0x04, 0x69, 0x74, 0x65, 0x6d, 0x18, 0x01,
|
||||
0x20, 0x01, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65,
|
||||
0x72, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x2e,
|
||||
0x72, 0x6f, 0x6c, 0x65, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x6f, 0x6c, 0x65, 0x52, 0x04, 0x69,
|
||||
0x74, 0x65, 0x6d, 0x32, 0xf5, 0x16, 0x0a, 0x0b, 0x52, 0x6f, 0x6c, 0x65, 0x53, 0x65, 0x72, 0x76,
|
||||
0x69, 0x63, 0x65, 0x12, 0x98, 0x01, 0x0a, 0x07, 0x47, 0x65, 0x74, 0x52, 0x6f, 0x6c, 0x65, 0x12,
|
||||
0x2a, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2e, 0x61, 0x70, 0x69,
|
||||
0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74,
|
||||
0x52, 0x6f, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2b, 0x2e, 0x63, 0x6f,
|
||||
0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x73, 0x65, 0x72,
|
||||
0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x52, 0x6f, 0x6c, 0x65,
|
||||
0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x34, 0x92, 0x41, 0x15, 0x12, 0x13, 0x47,
|
||||
0x65, 0x74, 0x73, 0x20, 0x61, 0x20, 0x73, 0x69, 0x6e, 0x67, 0x6c, 0x65, 0x20, 0x52, 0x6f, 0x6c,
|
||||
0x65, 0x2e, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x16, 0x62, 0x04, 0x69, 0x74, 0x65, 0x6d, 0x12, 0x0e,
|
||||
0x2f, 0x76, 0x31, 0x2f, 0x72, 0x6f, 0x6c, 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x64, 0x7d, 0x12, 0x90,
|
||||
0x01, 0x0a, 0x09, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x6f, 0x6c, 0x65, 0x73, 0x12, 0x2c, 0x2e, 0x63,
|
||||
0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x73, 0x65,
|
||||
0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x6f,
|
||||
0x6c, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2d, 0x2e, 0x63, 0x6f, 0x6e,
|
||||
0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x73, 0x65, 0x72, 0x76,
|
||||
0x69, 0x63, 0x65, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x6f, 0x6c, 0x65,
|
||||
0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x26, 0x92, 0x41, 0x12, 0x12, 0x10,
|
||||
0x4c, 0x69, 0x73, 0x74, 0x73, 0x20, 0x61, 0x6c, 0x6c, 0x20, 0x52, 0x6f, 0x6c, 0x65, 0x73, 0x2e,
|
||||
0x82, 0xd3, 0xe4, 0x93, 0x02, 0x0b, 0x12, 0x09, 0x2f, 0x76, 0x31, 0x2f, 0x72, 0x6f, 0x6c, 0x65,
|
||||
0x73, 0x12, 0xa5, 0x01, 0x0a, 0x0a, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x6f, 0x6c, 0x65,
|
||||
0x12, 0x2d, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2e, 0x61, 0x70,
|
||||
0x69, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x72,
|
||||
0x65, 0x61, 0x74, 0x65, 0x52, 0x6f, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a,
|
||||
0x2e, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2e, 0x61, 0x70, 0x69,
|
||||
0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x72, 0x65,
|
||||
0x61, 0x74, 0x65, 0x52, 0x6f, 0x6c, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22,
|
||||
0x38, 0x92, 0x41, 0x18, 0x12, 0x16, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x73, 0x20, 0x61, 0x20,
|
||||
0x73, 0x69, 0x6e, 0x67, 0x6c, 0x65, 0x20, 0x52, 0x6f, 0x6c, 0x65, 0x2e, 0x82, 0xd3, 0xe4, 0x93,
|
||||
0x02, 0x17, 0x3a, 0x04, 0x69, 0x74, 0x65, 0x6d, 0x62, 0x04, 0x69, 0x74, 0x65, 0x6d, 0x22, 0x09,
|
||||
0x2f, 0x76, 0x31, 0x2f, 0x72, 0x6f, 0x6c, 0x65, 0x73, 0x12, 0xa3, 0x01, 0x0a, 0x0a, 0x55, 0x70,
|
||||
0x64, 0x61, 0x74, 0x65, 0x52, 0x6f, 0x6c, 0x65, 0x12, 0x2d, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72,
|
||||
0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63,
|
||||
0x65, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, 0x6f, 0x6c, 0x65,
|
||||
0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2e, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f,
|
||||
0x6c, 0x6c, 0x65, 0x72, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65,
|
||||
0x73, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, 0x6f, 0x6c, 0x65, 0x52,
|
||||
0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x36, 0x92, 0x41, 0x11, 0x12, 0x0f, 0x55, 0x70,
|
||||
0x64, 0x61, 0x74, 0x65, 0x73, 0x20, 0x61, 0x20, 0x52, 0x6f, 0x6c, 0x65, 0x2e, 0x82, 0xd3, 0xe4,
|
||||
0x93, 0x02, 0x1c, 0x3a, 0x04, 0x69, 0x74, 0x65, 0x6d, 0x62, 0x04, 0x69, 0x74, 0x65, 0x6d, 0x32,
|
||||
0x0e, 0x2f, 0x76, 0x31, 0x2f, 0x72, 0x6f, 0x6c, 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x64, 0x7d, 0x12,
|
||||
0x97, 0x01, 0x0a, 0x0a, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x6f, 0x6c, 0x65, 0x12, 0x2d,
|
||||
0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2e, 0x61, 0x70, 0x69, 0x2e,
|
||||
0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x70, 0x64, 0x61,
|
||||
0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, 0x6c, 0x65,
|
||||
0x74, 0x65, 0x52, 0x6f, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2e, 0x2e,
|
||||
0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x73,
|
||||
0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74,
|
||||
0x65, 0x52, 0x6f, 0x6c, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x36, 0x92,
|
||||
0x41, 0x11, 0x12, 0x0f, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x73, 0x20, 0x61, 0x20, 0x52, 0x6f,
|
||||
0x6c, 0x65, 0x2e, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1c, 0x3a, 0x04, 0x69, 0x74, 0x65, 0x6d, 0x62,
|
||||
0x04, 0x69, 0x74, 0x65, 0x6d, 0x32, 0x0e, 0x2f, 0x76, 0x31, 0x2f, 0x72, 0x6f, 0x6c, 0x65, 0x73,
|
||||
0x2f, 0x7b, 0x69, 0x64, 0x7d, 0x12, 0x97, 0x01, 0x0a, 0x0a, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65,
|
||||
0x52, 0x6f, 0x6c, 0x65, 0x12, 0x2d, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65,
|
||||
0x72, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x76,
|
||||
0x31, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x6f, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75,
|
||||
0x65, 0x73, 0x74, 0x1a, 0x2e, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72,
|
||||
0x2e, 0x61, 0x70, 0x69, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x76, 0x31,
|
||||
0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x6f, 0x6c, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f,
|
||||
0x6e, 0x73, 0x65, 0x22, 0x2a, 0x92, 0x41, 0x11, 0x12, 0x0f, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65,
|
||||
0x73, 0x20, 0x61, 0x20, 0x52, 0x6f, 0x6c, 0x65, 0x2e, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x10, 0x2a,
|
||||
0x0e, 0x2f, 0x76, 0x31, 0x2f, 0x72, 0x6f, 0x6c, 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x64, 0x7d, 0x12,
|
||||
0xd8, 0x01, 0x0a, 0x11, 0x41, 0x64, 0x64, 0x52, 0x6f, 0x6c, 0x65, 0x50, 0x72, 0x69, 0x6e, 0x63,
|
||||
0x69, 0x70, 0x61, 0x6c, 0x73, 0x12, 0x34, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c,
|
||||
0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74,
|
||||
0x65, 0x52, 0x6f, 0x6c, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x2a, 0x92,
|
||||
0x41, 0x11, 0x12, 0x0f, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x73, 0x20, 0x61, 0x20, 0x52, 0x6f,
|
||||
0x6c, 0x65, 0x2e, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x10, 0x2a, 0x0e, 0x2f, 0x76, 0x31, 0x2f, 0x72,
|
||||
0x6f, 0x6c, 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x64, 0x7d, 0x12, 0xd8, 0x01, 0x0a, 0x11, 0x41, 0x64,
|
||||
0x64, 0x52, 0x6f, 0x6c, 0x65, 0x50, 0x72, 0x69, 0x6e, 0x63, 0x69, 0x70, 0x61, 0x6c, 0x73, 0x12,
|
||||
0x34, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2e, 0x61, 0x70, 0x69,
|
||||
0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x64, 0x64,
|
||||
0x52, 0x6f, 0x6c, 0x65, 0x50, 0x72, 0x69, 0x6e, 0x63, 0x69, 0x70, 0x61, 0x6c, 0x73, 0x52, 0x65,
|
||||
0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x35, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c,
|
||||
0x65, 0x72, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e,
|
||||
0x76, 0x31, 0x2e, 0x41, 0x64, 0x64, 0x52, 0x6f, 0x6c, 0x65, 0x50, 0x72, 0x69, 0x6e, 0x63, 0x69,
|
||||
0x70, 0x61, 0x6c, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x35, 0x2e, 0x63, 0x6f,
|
||||
0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x73, 0x65, 0x72,
|
||||
0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x64, 0x64, 0x52, 0x6f, 0x6c, 0x65,
|
||||
0x50, 0x72, 0x69, 0x6e, 0x63, 0x69, 0x70, 0x61, 0x6c, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e,
|
||||
0x73, 0x65, 0x22, 0x56, 0x92, 0x41, 0x25, 0x12, 0x23, 0x41, 0x64, 0x64, 0x73, 0x20, 0x55, 0x73,
|
||||
0x65, 0x72, 0x73, 0x20, 0x61, 0x6e, 0x64, 0x2f, 0x6f, 0x72, 0x20, 0x47, 0x72, 0x6f, 0x75, 0x70,
|
||||
0x73, 0x20, 0x74, 0x6f, 0x20, 0x61, 0x20, 0x52, 0x6f, 0x6c, 0x65, 0x2e, 0x82, 0xd3, 0xe4, 0x93,
|
||||
0x02, 0x28, 0x3a, 0x01, 0x2a, 0x62, 0x04, 0x69, 0x74, 0x65, 0x6d, 0x22, 0x1d, 0x2f, 0x76, 0x31,
|
||||
0x2f, 0x72, 0x6f, 0x6c, 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x64, 0x7d, 0x3a, 0x61, 0x64, 0x64, 0x2d,
|
||||
0x70, 0x72, 0x69, 0x6e, 0x63, 0x69, 0x70, 0x61, 0x6c, 0x73, 0x12, 0x97, 0x02, 0x0a, 0x11, 0x53,
|
||||
0x65, 0x74, 0x52, 0x6f, 0x6c, 0x65, 0x50, 0x72, 0x69, 0x6e, 0x63, 0x69, 0x70, 0x61, 0x6c, 0x73,
|
||||
0x12, 0x34, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2e, 0x61, 0x70,
|
||||
0x70, 0x61, 0x6c, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x56, 0x92, 0x41,
|
||||
0x25, 0x12, 0x23, 0x41, 0x64, 0x64, 0x73, 0x20, 0x55, 0x73, 0x65, 0x72, 0x73, 0x20, 0x61, 0x6e,
|
||||
0x64, 0x2f, 0x6f, 0x72, 0x20, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x20, 0x74, 0x6f, 0x20, 0x61,
|
||||
0x20, 0x52, 0x6f, 0x6c, 0x65, 0x2e, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x28, 0x3a, 0x01, 0x2a, 0x62,
|
||||
0x04, 0x69, 0x74, 0x65, 0x6d, 0x22, 0x1d, 0x2f, 0x76, 0x31, 0x2f, 0x72, 0x6f, 0x6c, 0x65, 0x73,
|
||||
0x2f, 0x7b, 0x69, 0x64, 0x7d, 0x3a, 0x61, 0x64, 0x64, 0x2d, 0x70, 0x72, 0x69, 0x6e, 0x63, 0x69,
|
||||
0x70, 0x61, 0x6c, 0x73, 0x12, 0x97, 0x02, 0x0a, 0x11, 0x53, 0x65, 0x74, 0x52, 0x6f, 0x6c, 0x65,
|
||||
0x50, 0x72, 0x69, 0x6e, 0x63, 0x69, 0x70, 0x61, 0x6c, 0x73, 0x12, 0x34, 0x2e, 0x63, 0x6f, 0x6e,
|
||||
0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x73, 0x65, 0x72, 0x76,
|
||||
0x69, 0x63, 0x65, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x65, 0x74, 0x52, 0x6f, 0x6c, 0x65, 0x50,
|
||||
0x72, 0x69, 0x6e, 0x63, 0x69, 0x70, 0x61, 0x6c, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
|
||||
0x1a, 0x35, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2e, 0x61, 0x70,
|
||||
0x69, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x65,
|
||||
0x74, 0x52, 0x6f, 0x6c, 0x65, 0x50, 0x72, 0x69, 0x6e, 0x63, 0x69, 0x70, 0x61, 0x6c, 0x73, 0x52,
|
||||
0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x35, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c,
|
||||
0x6c, 0x65, 0x72, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73,
|
||||
0x2e, 0x76, 0x31, 0x2e, 0x53, 0x65, 0x74, 0x52, 0x6f, 0x6c, 0x65, 0x50, 0x72, 0x69, 0x6e, 0x63,
|
||||
0x69, 0x70, 0x61, 0x6c, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x94, 0x01,
|
||||
0x92, 0x41, 0x63, 0x12, 0x61, 0x53, 0x65, 0x74, 0x20, 0x55, 0x73, 0x65, 0x72, 0x73, 0x20, 0x61,
|
||||
0x6e, 0x64, 0x2f, 0x6f, 0x72, 0x20, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x20, 0x74, 0x6f, 0x20,
|
||||
0x61, 0x20, 0x52, 0x6f, 0x6c, 0x65, 0x2c, 0x20, 0x72, 0x65, 0x6d, 0x6f, 0x76, 0x69, 0x6e, 0x67,
|
||||
0x20, 0x61, 0x6e, 0x79, 0x20, 0x70, 0x72, 0x69, 0x6e, 0x63, 0x69, 0x70, 0x61, 0x6c, 0x73, 0x20,
|
||||
0x74, 0x68, 0x61, 0x74, 0x20, 0x61, 0x72, 0x65, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x73, 0x70, 0x65,
|
||||
0x63, 0x69, 0x66, 0x69, 0x65, 0x64, 0x20, 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x72, 0x65,
|
||||
0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x28, 0x3a, 0x01, 0x2a, 0x62,
|
||||
0x04, 0x69, 0x74, 0x65, 0x6d, 0x22, 0x1d, 0x2f, 0x76, 0x31, 0x2f, 0x72, 0x6f, 0x6c, 0x65, 0x73,
|
||||
0x2f, 0x7b, 0x69, 0x64, 0x7d, 0x3a, 0x73, 0x65, 0x74, 0x2d, 0x70, 0x72, 0x69, 0x6e, 0x63, 0x69,
|
||||
0x70, 0x61, 0x6c, 0x73, 0x12, 0xf7, 0x01, 0x0a, 0x14, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x52,
|
||||
0x6f, 0x6c, 0x65, 0x50, 0x72, 0x69, 0x6e, 0x63, 0x69, 0x70, 0x61, 0x6c, 0x73, 0x12, 0x37, 0x2e,
|
||||
0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x73,
|
||||
0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x6d, 0x6f, 0x76,
|
||||
0x65, 0x52, 0x6f, 0x6c, 0x65, 0x50, 0x72, 0x69, 0x6e, 0x63, 0x69, 0x70, 0x61, 0x6c, 0x73, 0x52,
|
||||
0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x38, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c,
|
||||
0x6c, 0x65, 0x72, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73,
|
||||
0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x52, 0x6f, 0x6c, 0x65, 0x50, 0x72,
|
||||
0x69, 0x6e, 0x63, 0x69, 0x70, 0x61, 0x6c, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65,
|
||||
0x22, 0x6c, 0x92, 0x41, 0x38, 0x12, 0x36, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x73, 0x20, 0x74,
|
||||
0x68, 0x65, 0x20, 0x73, 0x70, 0x65, 0x63, 0x69, 0x66, 0x69, 0x65, 0x64, 0x20, 0x55, 0x73, 0x65,
|
||||
0x72, 0x73, 0x20, 0x61, 0x6e, 0x64, 0x2f, 0x6f, 0x72, 0x20, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x73,
|
||||
0x20, 0x66, 0x72, 0x6f, 0x6d, 0x20, 0x61, 0x20, 0x52, 0x6f, 0x6c, 0x65, 0x2e, 0x82, 0xd3, 0xe4,
|
||||
0x93, 0x02, 0x2b, 0x3a, 0x01, 0x2a, 0x62, 0x04, 0x69, 0x74, 0x65, 0x6d, 0x22, 0x20, 0x2f, 0x76,
|
||||
0x31, 0x2f, 0x72, 0x6f, 0x6c, 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x64, 0x7d, 0x3a, 0x72, 0x65, 0x6d,
|
||||
0x6f, 0x76, 0x65, 0x2d, 0x70, 0x72, 0x69, 0x6e, 0x63, 0x69, 0x70, 0x61, 0x6c, 0x73, 0x12, 0xba,
|
||||
0x01, 0x0a, 0x0d, 0x41, 0x64, 0x64, 0x52, 0x6f, 0x6c, 0x65, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x73,
|
||||
0x12, 0x30, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2e, 0x61, 0x70,
|
||||
0x69, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x64,
|
||||
0x64, 0x52, 0x6f, 0x6c, 0x65, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65,
|
||||
0x73, 0x74, 0x1a, 0x31, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2e,
|
||||
0x61, 0x70, 0x69, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x76, 0x31, 0x2e,
|
||||
0x41, 0x64, 0x64, 0x52, 0x6f, 0x6c, 0x65, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x73,
|
||||
0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x44, 0x92, 0x41, 0x17, 0x12, 0x15, 0x41, 0x64, 0x64, 0x73,
|
||||
0x20, 0x67, 0x72, 0x61, 0x6e, 0x74, 0x73, 0x20, 0x74, 0x6f, 0x20, 0x61, 0x20, 0x52, 0x6f, 0x6c,
|
||||
0x65, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x24, 0x3a, 0x01, 0x2a, 0x62, 0x04, 0x69, 0x74, 0x65, 0x6d,
|
||||
0x22, 0x19, 0x2f, 0x76, 0x31, 0x2f, 0x72, 0x6f, 0x6c, 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x64, 0x7d,
|
||||
0x3a, 0x61, 0x64, 0x64, 0x2d, 0x67, 0x72, 0x61, 0x6e, 0x74, 0x73, 0x12, 0xf7, 0x01, 0x0a, 0x0d,
|
||||
0x53, 0x65, 0x74, 0x52, 0x6f, 0x6c, 0x65, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x73, 0x12, 0x30, 0x2e,
|
||||
0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x94, 0x01, 0x92, 0x41, 0x63, 0x12, 0x61, 0x53,
|
||||
0x65, 0x74, 0x20, 0x55, 0x73, 0x65, 0x72, 0x73, 0x20, 0x61, 0x6e, 0x64, 0x2f, 0x6f, 0x72, 0x20,
|
||||
0x47, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x20, 0x74, 0x6f, 0x20, 0x61, 0x20, 0x52, 0x6f, 0x6c, 0x65,
|
||||
0x2c, 0x20, 0x72, 0x65, 0x6d, 0x6f, 0x76, 0x69, 0x6e, 0x67, 0x20, 0x61, 0x6e, 0x79, 0x20, 0x70,
|
||||
0x72, 0x69, 0x6e, 0x63, 0x69, 0x70, 0x61, 0x6c, 0x73, 0x20, 0x74, 0x68, 0x61, 0x74, 0x20, 0x61,
|
||||
0x72, 0x65, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x73, 0x70, 0x65, 0x63, 0x69, 0x66, 0x69, 0x65, 0x64,
|
||||
0x20, 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e,
|
||||
0x82, 0xd3, 0xe4, 0x93, 0x02, 0x28, 0x3a, 0x01, 0x2a, 0x62, 0x04, 0x69, 0x74, 0x65, 0x6d, 0x22,
|
||||
0x1d, 0x2f, 0x76, 0x31, 0x2f, 0x72, 0x6f, 0x6c, 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x64, 0x7d, 0x3a,
|
||||
0x73, 0x65, 0x74, 0x2d, 0x70, 0x72, 0x69, 0x6e, 0x63, 0x69, 0x70, 0x61, 0x6c, 0x73, 0x12, 0xf7,
|
||||
0x01, 0x0a, 0x14, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x52, 0x6f, 0x6c, 0x65, 0x50, 0x72, 0x69,
|
||||
0x6e, 0x63, 0x69, 0x70, 0x61, 0x6c, 0x73, 0x12, 0x37, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f,
|
||||
0x6c, 0x6c, 0x65, 0x72, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65,
|
||||
0x73, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x52, 0x6f, 0x6c, 0x65, 0x50,
|
||||
0x72, 0x69, 0x6e, 0x63, 0x69, 0x70, 0x61, 0x6c, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
|
||||
0x1a, 0x38, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2e, 0x61, 0x70,
|
||||
0x69, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65,
|
||||
0x6d, 0x6f, 0x76, 0x65, 0x52, 0x6f, 0x6c, 0x65, 0x50, 0x72, 0x69, 0x6e, 0x63, 0x69, 0x70, 0x61,
|
||||
0x6c, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x6c, 0x92, 0x41, 0x38, 0x12,
|
||||
0x36, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x73, 0x20, 0x74, 0x68, 0x65, 0x20, 0x73, 0x70, 0x65,
|
||||
0x63, 0x69, 0x66, 0x69, 0x65, 0x64, 0x20, 0x55, 0x73, 0x65, 0x72, 0x73, 0x20, 0x61, 0x6e, 0x64,
|
||||
0x2f, 0x6f, 0x72, 0x20, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x20, 0x66, 0x72, 0x6f, 0x6d, 0x20,
|
||||
0x61, 0x20, 0x52, 0x6f, 0x6c, 0x65, 0x2e, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x2b, 0x3a, 0x01, 0x2a,
|
||||
0x62, 0x04, 0x69, 0x74, 0x65, 0x6d, 0x22, 0x20, 0x2f, 0x76, 0x31, 0x2f, 0x72, 0x6f, 0x6c, 0x65,
|
||||
0x73, 0x2f, 0x7b, 0x69, 0x64, 0x7d, 0x3a, 0x72, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x2d, 0x70, 0x72,
|
||||
0x69, 0x6e, 0x63, 0x69, 0x70, 0x61, 0x6c, 0x73, 0x12, 0xba, 0x01, 0x0a, 0x0d, 0x41, 0x64, 0x64,
|
||||
0x52, 0x6f, 0x6c, 0x65, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x73, 0x12, 0x30, 0x2e, 0x63, 0x6f, 0x6e,
|
||||
0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x73, 0x65, 0x72, 0x76,
|
||||
0x69, 0x63, 0x65, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x64, 0x64, 0x52, 0x6f, 0x6c, 0x65, 0x47,
|
||||
0x72, 0x61, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x31, 0x2e, 0x63,
|
||||
0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x73, 0x65,
|
||||
0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x64, 0x64, 0x52, 0x6f, 0x6c,
|
||||
0x65, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22,
|
||||
0x44, 0x92, 0x41, 0x17, 0x12, 0x15, 0x41, 0x64, 0x64, 0x73, 0x20, 0x67, 0x72, 0x61, 0x6e, 0x74,
|
||||
0x73, 0x20, 0x74, 0x6f, 0x20, 0x61, 0x20, 0x52, 0x6f, 0x6c, 0x65, 0x82, 0xd3, 0xe4, 0x93, 0x02,
|
||||
0x24, 0x3a, 0x01, 0x2a, 0x62, 0x04, 0x69, 0x74, 0x65, 0x6d, 0x22, 0x19, 0x2f, 0x76, 0x31, 0x2f,
|
||||
0x72, 0x6f, 0x6c, 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x64, 0x7d, 0x3a, 0x61, 0x64, 0x64, 0x2d, 0x67,
|
||||
0x72, 0x61, 0x6e, 0x74, 0x73, 0x12, 0xf7, 0x01, 0x0a, 0x0d, 0x53, 0x65, 0x74, 0x52, 0x6f, 0x6c,
|
||||
0x65, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x73, 0x12, 0x30, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f,
|
||||
0x6c, 0x6c, 0x65, 0x72, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65,
|
||||
0x73, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x65, 0x74, 0x52, 0x6f, 0x6c, 0x65, 0x47, 0x72, 0x61, 0x6e,
|
||||
0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x31, 0x2e, 0x63, 0x6f, 0x6e, 0x74,
|
||||
0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69,
|
||||
0x63, 0x65, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x65, 0x74, 0x52, 0x6f, 0x6c, 0x65, 0x47, 0x72,
|
||||
0x61, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x80, 0x01, 0x92,
|
||||
0x41, 0x53, 0x12, 0x51, 0x53, 0x65, 0x74, 0x20, 0x67, 0x72, 0x61, 0x6e, 0x74, 0x73, 0x20, 0x66,
|
||||
0x6f, 0x72, 0x20, 0x61, 0x20, 0x52, 0x6f, 0x6c, 0x65, 0x2c, 0x20, 0x72, 0x65, 0x6d, 0x6f, 0x76,
|
||||
0x69, 0x6e, 0x67, 0x20, 0x61, 0x6e, 0x79, 0x20, 0x67, 0x72, 0x61, 0x6e, 0x74, 0x73, 0x20, 0x74,
|
||||
0x68, 0x61, 0x74, 0x20, 0x61, 0x72, 0x65, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x73, 0x70, 0x65, 0x63,
|
||||
0x69, 0x66, 0x69, 0x65, 0x64, 0x20, 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x72, 0x65, 0x71,
|
||||
0x75, 0x65, 0x73, 0x74, 0x2e, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x24, 0x3a, 0x01, 0x2a, 0x62, 0x04,
|
||||
0x69, 0x74, 0x65, 0x6d, 0x22, 0x19, 0x2f, 0x76, 0x31, 0x2f, 0x72, 0x6f, 0x6c, 0x65, 0x73, 0x2f,
|
||||
0x7b, 0x69, 0x64, 0x7d, 0x3a, 0x73, 0x65, 0x74, 0x2d, 0x67, 0x72, 0x61, 0x6e, 0x74, 0x73, 0x12,
|
||||
0xcc, 0x01, 0x0a, 0x10, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x52, 0x6f, 0x6c, 0x65, 0x47, 0x72,
|
||||
0x61, 0x6e, 0x74, 0x73, 0x12, 0x33, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65,
|
||||
0x72, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x76,
|
||||
0x31, 0x2e, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x52, 0x6f, 0x6c, 0x65, 0x47, 0x72, 0x61, 0x6e,
|
||||
0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x34, 0x2e, 0x63, 0x6f, 0x6e, 0x74,
|
||||
0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69,
|
||||
0x63, 0x65, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x52, 0x6f, 0x6c,
|
||||
0x65, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22,
|
||||
0x4d, 0x92, 0x41, 0x1d, 0x12, 0x1b, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x73, 0x20, 0x67, 0x72,
|
||||
0x61, 0x6e, 0x74, 0x73, 0x20, 0x66, 0x72, 0x6f, 0x6d, 0x20, 0x61, 0x20, 0x52, 0x6f, 0x6c, 0x65,
|
||||
0x2e, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x27, 0x3a, 0x01, 0x2a, 0x62, 0x04, 0x69, 0x74, 0x65, 0x6d,
|
||||
0x22, 0x1c, 0x2f, 0x76, 0x31, 0x2f, 0x72, 0x6f, 0x6c, 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x64, 0x7d,
|
||||
0x3a, 0x72, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x2d, 0x67, 0x72, 0x61, 0x6e, 0x74, 0x73, 0x12, 0xd5,
|
||||
0x01, 0x0a, 0x12, 0x41, 0x64, 0x64, 0x52, 0x6f, 0x6c, 0x65, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x53,
|
||||
0x63, 0x6f, 0x70, 0x65, 0x73, 0x12, 0x35, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c,
|
||||
0x65, 0x72, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e,
|
||||
0x76, 0x31, 0x2e, 0x41, 0x64, 0x64, 0x52, 0x6f, 0x6c, 0x65, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x53,
|
||||
0x63, 0x6f, 0x70, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x36, 0x2e, 0x63,
|
||||
0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x73, 0x65,
|
||||
0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x64, 0x64, 0x52, 0x6f, 0x6c,
|
||||
0x65, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x53, 0x63, 0x6f, 0x70, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70,
|
||||
0x6f, 0x6e, 0x73, 0x65, 0x22, 0x50, 0x92, 0x41, 0x1d, 0x12, 0x1b, 0x41, 0x64, 0x64, 0x73, 0x20,
|
||||
0x67, 0x72, 0x61, 0x6e, 0x74, 0x20, 0x73, 0x63, 0x6f, 0x70, 0x65, 0x73, 0x20, 0x74, 0x6f, 0x20,
|
||||
0x61, 0x20, 0x52, 0x6f, 0x6c, 0x65, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x2a, 0x3a, 0x01, 0x2a, 0x62,
|
||||
0x04, 0x69, 0x74, 0x65, 0x6d, 0x22, 0x1f, 0x2f, 0x76, 0x31, 0x2f, 0x72, 0x6f, 0x6c, 0x65, 0x73,
|
||||
0x2f, 0x7b, 0x69, 0x64, 0x7d, 0x3a, 0x61, 0x64, 0x64, 0x2d, 0x67, 0x72, 0x61, 0x6e, 0x74, 0x2d,
|
||||
0x73, 0x63, 0x6f, 0x70, 0x65, 0x73, 0x12, 0x98, 0x02, 0x0a, 0x12, 0x53, 0x65, 0x74, 0x52, 0x6f,
|
||||
0x6c, 0x65, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x53, 0x63, 0x6f, 0x70, 0x65, 0x73, 0x12, 0x35, 0x2e,
|
||||
0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x73,
|
||||
0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x65, 0x74, 0x52, 0x6f,
|
||||
0x6c, 0x65, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a,
|
||||
0x31, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2e, 0x61, 0x70, 0x69,
|
||||
0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x65, 0x74,
|
||||
0x52, 0x6f, 0x6c, 0x65, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e,
|
||||
0x73, 0x65, 0x22, 0x80, 0x01, 0x92, 0x41, 0x53, 0x12, 0x51, 0x53, 0x65, 0x74, 0x20, 0x67, 0x72,
|
||||
0x61, 0x6e, 0x74, 0x73, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x61, 0x20, 0x52, 0x6f, 0x6c, 0x65, 0x2c,
|
||||
0x6c, 0x65, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x53, 0x63, 0x6f, 0x70, 0x65, 0x73, 0x52, 0x65, 0x71,
|
||||
0x75, 0x65, 0x73, 0x74, 0x1a, 0x36, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65,
|
||||
0x72, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x76,
|
||||
0x31, 0x2e, 0x53, 0x65, 0x74, 0x52, 0x6f, 0x6c, 0x65, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x53, 0x63,
|
||||
0x6f, 0x70, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x92, 0x01, 0x92,
|
||||
0x41, 0x5f, 0x12, 0x5d, 0x53, 0x65, 0x74, 0x20, 0x67, 0x72, 0x61, 0x6e, 0x74, 0x20, 0x73, 0x63,
|
||||
0x6f, 0x70, 0x65, 0x73, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x61, 0x20, 0x52, 0x6f, 0x6c, 0x65, 0x2c,
|
||||
0x20, 0x72, 0x65, 0x6d, 0x6f, 0x76, 0x69, 0x6e, 0x67, 0x20, 0x61, 0x6e, 0x79, 0x20, 0x67, 0x72,
|
||||
0x61, 0x6e, 0x74, 0x73, 0x20, 0x74, 0x68, 0x61, 0x74, 0x20, 0x61, 0x72, 0x65, 0x20, 0x6e, 0x6f,
|
||||
0x74, 0x20, 0x73, 0x70, 0x65, 0x63, 0x69, 0x66, 0x69, 0x65, 0x64, 0x20, 0x69, 0x6e, 0x20, 0x74,
|
||||
0x68, 0x65, 0x20, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x82, 0xd3, 0xe4, 0x93, 0x02,
|
||||
0x24, 0x3a, 0x01, 0x2a, 0x62, 0x04, 0x69, 0x74, 0x65, 0x6d, 0x22, 0x19, 0x2f, 0x76, 0x31, 0x2f,
|
||||
0x72, 0x6f, 0x6c, 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x64, 0x7d, 0x3a, 0x73, 0x65, 0x74, 0x2d, 0x67,
|
||||
0x72, 0x61, 0x6e, 0x74, 0x73, 0x12, 0xcc, 0x01, 0x0a, 0x10, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65,
|
||||
0x52, 0x6f, 0x6c, 0x65, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x73, 0x12, 0x33, 0x2e, 0x63, 0x6f, 0x6e,
|
||||
0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x73, 0x65, 0x72, 0x76,
|
||||
0x69, 0x63, 0x65, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x52, 0x6f,
|
||||
0x6c, 0x65, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a,
|
||||
0x34, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2e, 0x61, 0x70, 0x69,
|
||||
0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x6d,
|
||||
0x6f, 0x76, 0x65, 0x52, 0x6f, 0x6c, 0x65, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x73,
|
||||
0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x4d, 0x92, 0x41, 0x1d, 0x12, 0x1b, 0x52, 0x65, 0x6d, 0x6f,
|
||||
0x76, 0x65, 0x73, 0x20, 0x67, 0x72, 0x61, 0x6e, 0x74, 0x73, 0x20, 0x66, 0x72, 0x6f, 0x6d, 0x20,
|
||||
0x61, 0x20, 0x52, 0x6f, 0x6c, 0x65, 0x2e, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x27, 0x3a, 0x01, 0x2a,
|
||||
0x62, 0x04, 0x69, 0x74, 0x65, 0x6d, 0x22, 0x1c, 0x2f, 0x76, 0x31, 0x2f, 0x72, 0x6f, 0x6c, 0x65,
|
||||
0x73, 0x2f, 0x7b, 0x69, 0x64, 0x7d, 0x3a, 0x72, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x2d, 0x67, 0x72,
|
||||
0x61, 0x6e, 0x74, 0x73, 0x42, 0x4d, 0x5a, 0x4b, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63,
|
||||
0x6f, 0x6d, 0x2f, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2f, 0x62, 0x6f, 0x75,
|
||||
0x6e, 0x64, 0x61, 0x72, 0x79, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x67,
|
||||
0x65, 0x6e, 0x2f, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2f, 0x61, 0x70,
|
||||
0x69, 0x2f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x3b, 0x73, 0x65, 0x72, 0x76, 0x69,
|
||||
0x63, 0x65, 0x73, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
|
||||
0x61, 0x6e, 0x74, 0x20, 0x73, 0x63, 0x6f, 0x70, 0x65, 0x73, 0x20, 0x74, 0x68, 0x61, 0x74, 0x20,
|
||||
0x61, 0x72, 0x65, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x73, 0x70, 0x65, 0x63, 0x69, 0x66, 0x69, 0x65,
|
||||
0x64, 0x20, 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
|
||||
0x2e, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x2a, 0x3a, 0x01, 0x2a, 0x62, 0x04, 0x69, 0x74, 0x65, 0x6d,
|
||||
0x22, 0x1f, 0x2f, 0x76, 0x31, 0x2f, 0x72, 0x6f, 0x6c, 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x64, 0x7d,
|
||||
0x3a, 0x73, 0x65, 0x74, 0x2d, 0x67, 0x72, 0x61, 0x6e, 0x74, 0x2d, 0x73, 0x63, 0x6f, 0x70, 0x65,
|
||||
0x73, 0x12, 0xe7, 0x01, 0x0a, 0x15, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x52, 0x6f, 0x6c, 0x65,
|
||||
0x47, 0x72, 0x61, 0x6e, 0x74, 0x53, 0x63, 0x6f, 0x70, 0x65, 0x73, 0x12, 0x38, 0x2e, 0x63, 0x6f,
|
||||
0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x73, 0x65, 0x72,
|
||||
0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x52,
|
||||
0x6f, 0x6c, 0x65, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x53, 0x63, 0x6f, 0x70, 0x65, 0x73, 0x52, 0x65,
|
||||
0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x39, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c,
|
||||
0x65, 0x72, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e,
|
||||
0x76, 0x31, 0x2e, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x52, 0x6f, 0x6c, 0x65, 0x47, 0x72, 0x61,
|
||||
0x6e, 0x74, 0x53, 0x63, 0x6f, 0x70, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65,
|
||||
0x22, 0x59, 0x92, 0x41, 0x23, 0x12, 0x21, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x73, 0x20, 0x67,
|
||||
0x72, 0x61, 0x6e, 0x74, 0x20, 0x73, 0x63, 0x6f, 0x70, 0x65, 0x73, 0x20, 0x66, 0x72, 0x6f, 0x6d,
|
||||
0x20, 0x61, 0x20, 0x52, 0x6f, 0x6c, 0x65, 0x2e, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x2d, 0x3a, 0x01,
|
||||
0x2a, 0x62, 0x04, 0x69, 0x74, 0x65, 0x6d, 0x22, 0x22, 0x2f, 0x76, 0x31, 0x2f, 0x72, 0x6f, 0x6c,
|
||||
0x65, 0x73, 0x2f, 0x7b, 0x69, 0x64, 0x7d, 0x3a, 0x72, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x2d, 0x67,
|
||||
0x72, 0x61, 0x6e, 0x74, 0x2d, 0x73, 0x63, 0x6f, 0x70, 0x65, 0x73, 0x42, 0x4d, 0x5a, 0x4b, 0x67,
|
||||
0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63,
|
||||
0x6f, 0x72, 0x70, 0x2f, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x61, 0x72, 0x79, 0x2f, 0x69, 0x6e, 0x74,
|
||||
0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x67, 0x65, 0x6e, 0x2f, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f,
|
||||
0x6c, 0x6c, 0x65, 0x72, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65,
|
||||
0x73, 0x3b, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74,
|
||||
0x6f, 0x33,
|
||||
}
|
||||
|
||||
var (
|
||||
@@ -1599,74 +2020,89 @@ func file_controller_api_services_v1_role_service_proto_rawDescGZIP() []byte {
|
||||
return file_controller_api_services_v1_role_service_proto_rawDescData
|
||||
}
|
||||
|
||||
var file_controller_api_services_v1_role_service_proto_msgTypes = make([]protoimpl.MessageInfo, 22)
|
||||
var file_controller_api_services_v1_role_service_proto_msgTypes = make([]protoimpl.MessageInfo, 28)
|
||||
var file_controller_api_services_v1_role_service_proto_goTypes = []interface{}{
|
||||
(*GetRoleRequest)(nil), // 0: controller.api.services.v1.GetRoleRequest
|
||||
(*GetRoleResponse)(nil), // 1: controller.api.services.v1.GetRoleResponse
|
||||
(*ListRolesRequest)(nil), // 2: controller.api.services.v1.ListRolesRequest
|
||||
(*ListRolesResponse)(nil), // 3: controller.api.services.v1.ListRolesResponse
|
||||
(*CreateRoleRequest)(nil), // 4: controller.api.services.v1.CreateRoleRequest
|
||||
(*CreateRoleResponse)(nil), // 5: controller.api.services.v1.CreateRoleResponse
|
||||
(*UpdateRoleRequest)(nil), // 6: controller.api.services.v1.UpdateRoleRequest
|
||||
(*UpdateRoleResponse)(nil), // 7: controller.api.services.v1.UpdateRoleResponse
|
||||
(*DeleteRoleRequest)(nil), // 8: controller.api.services.v1.DeleteRoleRequest
|
||||
(*DeleteRoleResponse)(nil), // 9: controller.api.services.v1.DeleteRoleResponse
|
||||
(*AddRolePrincipalsRequest)(nil), // 10: controller.api.services.v1.AddRolePrincipalsRequest
|
||||
(*AddRolePrincipalsResponse)(nil), // 11: controller.api.services.v1.AddRolePrincipalsResponse
|
||||
(*SetRolePrincipalsRequest)(nil), // 12: controller.api.services.v1.SetRolePrincipalsRequest
|
||||
(*SetRolePrincipalsResponse)(nil), // 13: controller.api.services.v1.SetRolePrincipalsResponse
|
||||
(*RemoveRolePrincipalsRequest)(nil), // 14: controller.api.services.v1.RemoveRolePrincipalsRequest
|
||||
(*RemoveRolePrincipalsResponse)(nil), // 15: controller.api.services.v1.RemoveRolePrincipalsResponse
|
||||
(*AddRoleGrantsRequest)(nil), // 16: controller.api.services.v1.AddRoleGrantsRequest
|
||||
(*AddRoleGrantsResponse)(nil), // 17: controller.api.services.v1.AddRoleGrantsResponse
|
||||
(*SetRoleGrantsRequest)(nil), // 18: controller.api.services.v1.SetRoleGrantsRequest
|
||||
(*SetRoleGrantsResponse)(nil), // 19: controller.api.services.v1.SetRoleGrantsResponse
|
||||
(*RemoveRoleGrantsRequest)(nil), // 20: controller.api.services.v1.RemoveRoleGrantsRequest
|
||||
(*RemoveRoleGrantsResponse)(nil), // 21: controller.api.services.v1.RemoveRoleGrantsResponse
|
||||
(*roles.Role)(nil), // 22: controller.api.resources.roles.v1.Role
|
||||
(*fieldmaskpb.FieldMask)(nil), // 23: google.protobuf.FieldMask
|
||||
(*GetRoleRequest)(nil), // 0: controller.api.services.v1.GetRoleRequest
|
||||
(*GetRoleResponse)(nil), // 1: controller.api.services.v1.GetRoleResponse
|
||||
(*ListRolesRequest)(nil), // 2: controller.api.services.v1.ListRolesRequest
|
||||
(*ListRolesResponse)(nil), // 3: controller.api.services.v1.ListRolesResponse
|
||||
(*CreateRoleRequest)(nil), // 4: controller.api.services.v1.CreateRoleRequest
|
||||
(*CreateRoleResponse)(nil), // 5: controller.api.services.v1.CreateRoleResponse
|
||||
(*UpdateRoleRequest)(nil), // 6: controller.api.services.v1.UpdateRoleRequest
|
||||
(*UpdateRoleResponse)(nil), // 7: controller.api.services.v1.UpdateRoleResponse
|
||||
(*DeleteRoleRequest)(nil), // 8: controller.api.services.v1.DeleteRoleRequest
|
||||
(*DeleteRoleResponse)(nil), // 9: controller.api.services.v1.DeleteRoleResponse
|
||||
(*AddRolePrincipalsRequest)(nil), // 10: controller.api.services.v1.AddRolePrincipalsRequest
|
||||
(*AddRolePrincipalsResponse)(nil), // 11: controller.api.services.v1.AddRolePrincipalsResponse
|
||||
(*SetRolePrincipalsRequest)(nil), // 12: controller.api.services.v1.SetRolePrincipalsRequest
|
||||
(*SetRolePrincipalsResponse)(nil), // 13: controller.api.services.v1.SetRolePrincipalsResponse
|
||||
(*RemoveRolePrincipalsRequest)(nil), // 14: controller.api.services.v1.RemoveRolePrincipalsRequest
|
||||
(*RemoveRolePrincipalsResponse)(nil), // 15: controller.api.services.v1.RemoveRolePrincipalsResponse
|
||||
(*AddRoleGrantsRequest)(nil), // 16: controller.api.services.v1.AddRoleGrantsRequest
|
||||
(*AddRoleGrantsResponse)(nil), // 17: controller.api.services.v1.AddRoleGrantsResponse
|
||||
(*SetRoleGrantsRequest)(nil), // 18: controller.api.services.v1.SetRoleGrantsRequest
|
||||
(*SetRoleGrantsResponse)(nil), // 19: controller.api.services.v1.SetRoleGrantsResponse
|
||||
(*RemoveRoleGrantsRequest)(nil), // 20: controller.api.services.v1.RemoveRoleGrantsRequest
|
||||
(*RemoveRoleGrantsResponse)(nil), // 21: controller.api.services.v1.RemoveRoleGrantsResponse
|
||||
(*AddRoleGrantScopesRequest)(nil), // 22: controller.api.services.v1.AddRoleGrantScopesRequest
|
||||
(*AddRoleGrantScopesResponse)(nil), // 23: controller.api.services.v1.AddRoleGrantScopesResponse
|
||||
(*SetRoleGrantScopesRequest)(nil), // 24: controller.api.services.v1.SetRoleGrantScopesRequest
|
||||
(*SetRoleGrantScopesResponse)(nil), // 25: controller.api.services.v1.SetRoleGrantScopesResponse
|
||||
(*RemoveRoleGrantScopesRequest)(nil), // 26: controller.api.services.v1.RemoveRoleGrantScopesRequest
|
||||
(*RemoveRoleGrantScopesResponse)(nil), // 27: controller.api.services.v1.RemoveRoleGrantScopesResponse
|
||||
(*roles.Role)(nil), // 28: controller.api.resources.roles.v1.Role
|
||||
(*fieldmaskpb.FieldMask)(nil), // 29: google.protobuf.FieldMask
|
||||
}
|
||||
var file_controller_api_services_v1_role_service_proto_depIdxs = []int32{
|
||||
22, // 0: controller.api.services.v1.GetRoleResponse.item:type_name -> controller.api.resources.roles.v1.Role
|
||||
22, // 1: controller.api.services.v1.ListRolesResponse.items:type_name -> controller.api.resources.roles.v1.Role
|
||||
22, // 2: controller.api.services.v1.CreateRoleRequest.item:type_name -> controller.api.resources.roles.v1.Role
|
||||
22, // 3: controller.api.services.v1.CreateRoleResponse.item:type_name -> controller.api.resources.roles.v1.Role
|
||||
22, // 4: controller.api.services.v1.UpdateRoleRequest.item:type_name -> controller.api.resources.roles.v1.Role
|
||||
23, // 5: controller.api.services.v1.UpdateRoleRequest.update_mask:type_name -> google.protobuf.FieldMask
|
||||
22, // 6: controller.api.services.v1.UpdateRoleResponse.item:type_name -> controller.api.resources.roles.v1.Role
|
||||
22, // 7: controller.api.services.v1.AddRolePrincipalsResponse.item:type_name -> controller.api.resources.roles.v1.Role
|
||||
22, // 8: controller.api.services.v1.SetRolePrincipalsResponse.item:type_name -> controller.api.resources.roles.v1.Role
|
||||
22, // 9: controller.api.services.v1.RemoveRolePrincipalsResponse.item:type_name -> controller.api.resources.roles.v1.Role
|
||||
22, // 10: controller.api.services.v1.AddRoleGrantsResponse.item:type_name -> controller.api.resources.roles.v1.Role
|
||||
22, // 11: controller.api.services.v1.SetRoleGrantsResponse.item:type_name -> controller.api.resources.roles.v1.Role
|
||||
22, // 12: controller.api.services.v1.RemoveRoleGrantsResponse.item:type_name -> controller.api.resources.roles.v1.Role
|
||||
0, // 13: controller.api.services.v1.RoleService.GetRole:input_type -> controller.api.services.v1.GetRoleRequest
|
||||
2, // 14: controller.api.services.v1.RoleService.ListRoles:input_type -> controller.api.services.v1.ListRolesRequest
|
||||
4, // 15: controller.api.services.v1.RoleService.CreateRole:input_type -> controller.api.services.v1.CreateRoleRequest
|
||||
6, // 16: controller.api.services.v1.RoleService.UpdateRole:input_type -> controller.api.services.v1.UpdateRoleRequest
|
||||
8, // 17: controller.api.services.v1.RoleService.DeleteRole:input_type -> controller.api.services.v1.DeleteRoleRequest
|
||||
10, // 18: controller.api.services.v1.RoleService.AddRolePrincipals:input_type -> controller.api.services.v1.AddRolePrincipalsRequest
|
||||
12, // 19: controller.api.services.v1.RoleService.SetRolePrincipals:input_type -> controller.api.services.v1.SetRolePrincipalsRequest
|
||||
14, // 20: controller.api.services.v1.RoleService.RemoveRolePrincipals:input_type -> controller.api.services.v1.RemoveRolePrincipalsRequest
|
||||
16, // 21: controller.api.services.v1.RoleService.AddRoleGrants:input_type -> controller.api.services.v1.AddRoleGrantsRequest
|
||||
18, // 22: controller.api.services.v1.RoleService.SetRoleGrants:input_type -> controller.api.services.v1.SetRoleGrantsRequest
|
||||
20, // 23: controller.api.services.v1.RoleService.RemoveRoleGrants:input_type -> controller.api.services.v1.RemoveRoleGrantsRequest
|
||||
1, // 24: controller.api.services.v1.RoleService.GetRole:output_type -> controller.api.services.v1.GetRoleResponse
|
||||
3, // 25: controller.api.services.v1.RoleService.ListRoles:output_type -> controller.api.services.v1.ListRolesResponse
|
||||
5, // 26: controller.api.services.v1.RoleService.CreateRole:output_type -> controller.api.services.v1.CreateRoleResponse
|
||||
7, // 27: controller.api.services.v1.RoleService.UpdateRole:output_type -> controller.api.services.v1.UpdateRoleResponse
|
||||
9, // 28: controller.api.services.v1.RoleService.DeleteRole:output_type -> controller.api.services.v1.DeleteRoleResponse
|
||||
11, // 29: controller.api.services.v1.RoleService.AddRolePrincipals:output_type -> controller.api.services.v1.AddRolePrincipalsResponse
|
||||
13, // 30: controller.api.services.v1.RoleService.SetRolePrincipals:output_type -> controller.api.services.v1.SetRolePrincipalsResponse
|
||||
15, // 31: controller.api.services.v1.RoleService.RemoveRolePrincipals:output_type -> controller.api.services.v1.RemoveRolePrincipalsResponse
|
||||
17, // 32: controller.api.services.v1.RoleService.AddRoleGrants:output_type -> controller.api.services.v1.AddRoleGrantsResponse
|
||||
19, // 33: controller.api.services.v1.RoleService.SetRoleGrants:output_type -> controller.api.services.v1.SetRoleGrantsResponse
|
||||
21, // 34: controller.api.services.v1.RoleService.RemoveRoleGrants:output_type -> controller.api.services.v1.RemoveRoleGrantsResponse
|
||||
24, // [24:35] is the sub-list for method output_type
|
||||
13, // [13:24] is the sub-list for method input_type
|
||||
13, // [13:13] is the sub-list for extension type_name
|
||||
13, // [13:13] is the sub-list for extension extendee
|
||||
0, // [0:13] is the sub-list for field type_name
|
||||
28, // 0: controller.api.services.v1.GetRoleResponse.item:type_name -> controller.api.resources.roles.v1.Role
|
||||
28, // 1: controller.api.services.v1.ListRolesResponse.items:type_name -> controller.api.resources.roles.v1.Role
|
||||
28, // 2: controller.api.services.v1.CreateRoleRequest.item:type_name -> controller.api.resources.roles.v1.Role
|
||||
28, // 3: controller.api.services.v1.CreateRoleResponse.item:type_name -> controller.api.resources.roles.v1.Role
|
||||
28, // 4: controller.api.services.v1.UpdateRoleRequest.item:type_name -> controller.api.resources.roles.v1.Role
|
||||
29, // 5: controller.api.services.v1.UpdateRoleRequest.update_mask:type_name -> google.protobuf.FieldMask
|
||||
28, // 6: controller.api.services.v1.UpdateRoleResponse.item:type_name -> controller.api.resources.roles.v1.Role
|
||||
28, // 7: controller.api.services.v1.AddRolePrincipalsResponse.item:type_name -> controller.api.resources.roles.v1.Role
|
||||
28, // 8: controller.api.services.v1.SetRolePrincipalsResponse.item:type_name -> controller.api.resources.roles.v1.Role
|
||||
28, // 9: controller.api.services.v1.RemoveRolePrincipalsResponse.item:type_name -> controller.api.resources.roles.v1.Role
|
||||
28, // 10: controller.api.services.v1.AddRoleGrantsResponse.item:type_name -> controller.api.resources.roles.v1.Role
|
||||
28, // 11: controller.api.services.v1.SetRoleGrantsResponse.item:type_name -> controller.api.resources.roles.v1.Role
|
||||
28, // 12: controller.api.services.v1.RemoveRoleGrantsResponse.item:type_name -> controller.api.resources.roles.v1.Role
|
||||
28, // 13: controller.api.services.v1.AddRoleGrantScopesResponse.item:type_name -> controller.api.resources.roles.v1.Role
|
||||
28, // 14: controller.api.services.v1.SetRoleGrantScopesResponse.item:type_name -> controller.api.resources.roles.v1.Role
|
||||
28, // 15: controller.api.services.v1.RemoveRoleGrantScopesResponse.item:type_name -> controller.api.resources.roles.v1.Role
|
||||
0, // 16: controller.api.services.v1.RoleService.GetRole:input_type -> controller.api.services.v1.GetRoleRequest
|
||||
2, // 17: controller.api.services.v1.RoleService.ListRoles:input_type -> controller.api.services.v1.ListRolesRequest
|
||||
4, // 18: controller.api.services.v1.RoleService.CreateRole:input_type -> controller.api.services.v1.CreateRoleRequest
|
||||
6, // 19: controller.api.services.v1.RoleService.UpdateRole:input_type -> controller.api.services.v1.UpdateRoleRequest
|
||||
8, // 20: controller.api.services.v1.RoleService.DeleteRole:input_type -> controller.api.services.v1.DeleteRoleRequest
|
||||
10, // 21: controller.api.services.v1.RoleService.AddRolePrincipals:input_type -> controller.api.services.v1.AddRolePrincipalsRequest
|
||||
12, // 22: controller.api.services.v1.RoleService.SetRolePrincipals:input_type -> controller.api.services.v1.SetRolePrincipalsRequest
|
||||
14, // 23: controller.api.services.v1.RoleService.RemoveRolePrincipals:input_type -> controller.api.services.v1.RemoveRolePrincipalsRequest
|
||||
16, // 24: controller.api.services.v1.RoleService.AddRoleGrants:input_type -> controller.api.services.v1.AddRoleGrantsRequest
|
||||
18, // 25: controller.api.services.v1.RoleService.SetRoleGrants:input_type -> controller.api.services.v1.SetRoleGrantsRequest
|
||||
20, // 26: controller.api.services.v1.RoleService.RemoveRoleGrants:input_type -> controller.api.services.v1.RemoveRoleGrantsRequest
|
||||
22, // 27: controller.api.services.v1.RoleService.AddRoleGrantScopes:input_type -> controller.api.services.v1.AddRoleGrantScopesRequest
|
||||
24, // 28: controller.api.services.v1.RoleService.SetRoleGrantScopes:input_type -> controller.api.services.v1.SetRoleGrantScopesRequest
|
||||
26, // 29: controller.api.services.v1.RoleService.RemoveRoleGrantScopes:input_type -> controller.api.services.v1.RemoveRoleGrantScopesRequest
|
||||
1, // 30: controller.api.services.v1.RoleService.GetRole:output_type -> controller.api.services.v1.GetRoleResponse
|
||||
3, // 31: controller.api.services.v1.RoleService.ListRoles:output_type -> controller.api.services.v1.ListRolesResponse
|
||||
5, // 32: controller.api.services.v1.RoleService.CreateRole:output_type -> controller.api.services.v1.CreateRoleResponse
|
||||
7, // 33: controller.api.services.v1.RoleService.UpdateRole:output_type -> controller.api.services.v1.UpdateRoleResponse
|
||||
9, // 34: controller.api.services.v1.RoleService.DeleteRole:output_type -> controller.api.services.v1.DeleteRoleResponse
|
||||
11, // 35: controller.api.services.v1.RoleService.AddRolePrincipals:output_type -> controller.api.services.v1.AddRolePrincipalsResponse
|
||||
13, // 36: controller.api.services.v1.RoleService.SetRolePrincipals:output_type -> controller.api.services.v1.SetRolePrincipalsResponse
|
||||
15, // 37: controller.api.services.v1.RoleService.RemoveRolePrincipals:output_type -> controller.api.services.v1.RemoveRolePrincipalsResponse
|
||||
17, // 38: controller.api.services.v1.RoleService.AddRoleGrants:output_type -> controller.api.services.v1.AddRoleGrantsResponse
|
||||
19, // 39: controller.api.services.v1.RoleService.SetRoleGrants:output_type -> controller.api.services.v1.SetRoleGrantsResponse
|
||||
21, // 40: controller.api.services.v1.RoleService.RemoveRoleGrants:output_type -> controller.api.services.v1.RemoveRoleGrantsResponse
|
||||
23, // 41: controller.api.services.v1.RoleService.AddRoleGrantScopes:output_type -> controller.api.services.v1.AddRoleGrantScopesResponse
|
||||
25, // 42: controller.api.services.v1.RoleService.SetRoleGrantScopes:output_type -> controller.api.services.v1.SetRoleGrantScopesResponse
|
||||
27, // 43: controller.api.services.v1.RoleService.RemoveRoleGrantScopes:output_type -> controller.api.services.v1.RemoveRoleGrantScopesResponse
|
||||
30, // [30:44] is the sub-list for method output_type
|
||||
16, // [16:30] is the sub-list for method input_type
|
||||
16, // [16:16] is the sub-list for extension type_name
|
||||
16, // [16:16] is the sub-list for extension extendee
|
||||
0, // [0:16] is the sub-list for field type_name
|
||||
}
|
||||
|
||||
func init() { file_controller_api_services_v1_role_service_proto_init() }
|
||||
@@ -1939,6 +2375,78 @@ func file_controller_api_services_v1_role_service_proto_init() {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_controller_api_services_v1_role_service_proto_msgTypes[22].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*AddRoleGrantScopesRequest); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_controller_api_services_v1_role_service_proto_msgTypes[23].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*AddRoleGrantScopesResponse); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_controller_api_services_v1_role_service_proto_msgTypes[24].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*SetRoleGrantScopesRequest); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_controller_api_services_v1_role_service_proto_msgTypes[25].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*SetRoleGrantScopesResponse); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_controller_api_services_v1_role_service_proto_msgTypes[26].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*RemoveRoleGrantScopesRequest); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_controller_api_services_v1_role_service_proto_msgTypes[27].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*RemoveRoleGrantScopesResponse); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
}
|
||||
type x struct{}
|
||||
out := protoimpl.TypeBuilder{
|
||||
@@ -1946,7 +2454,7 @@ func file_controller_api_services_v1_role_service_proto_init() {
|
||||
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
||||
RawDescriptor: file_controller_api_services_v1_role_service_proto_rawDesc,
|
||||
NumEnums: 0,
|
||||
NumMessages: 22,
|
||||
NumMessages: 28,
|
||||
NumExtensions: 0,
|
||||
NumServices: 1,
|
||||
},
|
||||
|
||||
@@ -713,6 +713,210 @@ func local_request_RoleService_RemoveRoleGrants_0(ctx context.Context, marshaler
|
||||
|
||||
}
|
||||
|
||||
func request_RoleService_AddRoleGrantScopes_0(ctx context.Context, marshaler runtime.Marshaler, client RoleServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
|
||||
var protoReq AddRoleGrantScopesRequest
|
||||
var metadata runtime.ServerMetadata
|
||||
|
||||
newReader, berr := utilities.IOReaderFactory(req.Body)
|
||||
if berr != nil {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr)
|
||||
}
|
||||
if err := marshaler.NewDecoder(newReader()).Decode(&protoReq); err != nil && err != io.EOF {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
|
||||
}
|
||||
|
||||
var (
|
||||
val string
|
||||
ok bool
|
||||
err error
|
||||
_ = err
|
||||
)
|
||||
|
||||
val, ok = pathParams["id"]
|
||||
if !ok {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "id")
|
||||
}
|
||||
|
||||
protoReq.Id, err = runtime.String(val)
|
||||
if err != nil {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "id", err)
|
||||
}
|
||||
|
||||
msg, err := client.AddRoleGrantScopes(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
|
||||
return msg, metadata, err
|
||||
|
||||
}
|
||||
|
||||
func local_request_RoleService_AddRoleGrantScopes_0(ctx context.Context, marshaler runtime.Marshaler, server RoleServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
|
||||
var protoReq AddRoleGrantScopesRequest
|
||||
var metadata runtime.ServerMetadata
|
||||
|
||||
newReader, berr := utilities.IOReaderFactory(req.Body)
|
||||
if berr != nil {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr)
|
||||
}
|
||||
if err := marshaler.NewDecoder(newReader()).Decode(&protoReq); err != nil && err != io.EOF {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
|
||||
}
|
||||
|
||||
var (
|
||||
val string
|
||||
ok bool
|
||||
err error
|
||||
_ = err
|
||||
)
|
||||
|
||||
val, ok = pathParams["id"]
|
||||
if !ok {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "id")
|
||||
}
|
||||
|
||||
protoReq.Id, err = runtime.String(val)
|
||||
if err != nil {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "id", err)
|
||||
}
|
||||
|
||||
msg, err := server.AddRoleGrantScopes(ctx, &protoReq)
|
||||
return msg, metadata, err
|
||||
|
||||
}
|
||||
|
||||
func request_RoleService_SetRoleGrantScopes_0(ctx context.Context, marshaler runtime.Marshaler, client RoleServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
|
||||
var protoReq SetRoleGrantScopesRequest
|
||||
var metadata runtime.ServerMetadata
|
||||
|
||||
newReader, berr := utilities.IOReaderFactory(req.Body)
|
||||
if berr != nil {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr)
|
||||
}
|
||||
if err := marshaler.NewDecoder(newReader()).Decode(&protoReq); err != nil && err != io.EOF {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
|
||||
}
|
||||
|
||||
var (
|
||||
val string
|
||||
ok bool
|
||||
err error
|
||||
_ = err
|
||||
)
|
||||
|
||||
val, ok = pathParams["id"]
|
||||
if !ok {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "id")
|
||||
}
|
||||
|
||||
protoReq.Id, err = runtime.String(val)
|
||||
if err != nil {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "id", err)
|
||||
}
|
||||
|
||||
msg, err := client.SetRoleGrantScopes(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
|
||||
return msg, metadata, err
|
||||
|
||||
}
|
||||
|
||||
func local_request_RoleService_SetRoleGrantScopes_0(ctx context.Context, marshaler runtime.Marshaler, server RoleServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
|
||||
var protoReq SetRoleGrantScopesRequest
|
||||
var metadata runtime.ServerMetadata
|
||||
|
||||
newReader, berr := utilities.IOReaderFactory(req.Body)
|
||||
if berr != nil {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr)
|
||||
}
|
||||
if err := marshaler.NewDecoder(newReader()).Decode(&protoReq); err != nil && err != io.EOF {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
|
||||
}
|
||||
|
||||
var (
|
||||
val string
|
||||
ok bool
|
||||
err error
|
||||
_ = err
|
||||
)
|
||||
|
||||
val, ok = pathParams["id"]
|
||||
if !ok {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "id")
|
||||
}
|
||||
|
||||
protoReq.Id, err = runtime.String(val)
|
||||
if err != nil {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "id", err)
|
||||
}
|
||||
|
||||
msg, err := server.SetRoleGrantScopes(ctx, &protoReq)
|
||||
return msg, metadata, err
|
||||
|
||||
}
|
||||
|
||||
func request_RoleService_RemoveRoleGrantScopes_0(ctx context.Context, marshaler runtime.Marshaler, client RoleServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
|
||||
var protoReq RemoveRoleGrantScopesRequest
|
||||
var metadata runtime.ServerMetadata
|
||||
|
||||
newReader, berr := utilities.IOReaderFactory(req.Body)
|
||||
if berr != nil {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr)
|
||||
}
|
||||
if err := marshaler.NewDecoder(newReader()).Decode(&protoReq); err != nil && err != io.EOF {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
|
||||
}
|
||||
|
||||
var (
|
||||
val string
|
||||
ok bool
|
||||
err error
|
||||
_ = err
|
||||
)
|
||||
|
||||
val, ok = pathParams["id"]
|
||||
if !ok {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "id")
|
||||
}
|
||||
|
||||
protoReq.Id, err = runtime.String(val)
|
||||
if err != nil {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "id", err)
|
||||
}
|
||||
|
||||
msg, err := client.RemoveRoleGrantScopes(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
|
||||
return msg, metadata, err
|
||||
|
||||
}
|
||||
|
||||
func local_request_RoleService_RemoveRoleGrantScopes_0(ctx context.Context, marshaler runtime.Marshaler, server RoleServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
|
||||
var protoReq RemoveRoleGrantScopesRequest
|
||||
var metadata runtime.ServerMetadata
|
||||
|
||||
newReader, berr := utilities.IOReaderFactory(req.Body)
|
||||
if berr != nil {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr)
|
||||
}
|
||||
if err := marshaler.NewDecoder(newReader()).Decode(&protoReq); err != nil && err != io.EOF {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
|
||||
}
|
||||
|
||||
var (
|
||||
val string
|
||||
ok bool
|
||||
err error
|
||||
_ = err
|
||||
)
|
||||
|
||||
val, ok = pathParams["id"]
|
||||
if !ok {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "id")
|
||||
}
|
||||
|
||||
protoReq.Id, err = runtime.String(val)
|
||||
if err != nil {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "id", err)
|
||||
}
|
||||
|
||||
msg, err := server.RemoveRoleGrantScopes(ctx, &protoReq)
|
||||
return msg, metadata, err
|
||||
|
||||
}
|
||||
|
||||
// RegisterRoleServiceHandlerServer registers the http handlers for service RoleService to "mux".
|
||||
// UnaryRPC :call RoleServiceServer directly.
|
||||
// StreamingRPC :currently unsupported pending https://github.com/grpc/grpc-go/issues/906.
|
||||
@@ -994,6 +1198,81 @@ func RegisterRoleServiceHandlerServer(ctx context.Context, mux *runtime.ServeMux
|
||||
|
||||
})
|
||||
|
||||
mux.Handle("POST", pattern_RoleService_AddRoleGrantScopes_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
|
||||
ctx, cancel := context.WithCancel(req.Context())
|
||||
defer cancel()
|
||||
var stream runtime.ServerTransportStream
|
||||
ctx = grpc.NewContextWithServerTransportStream(ctx, &stream)
|
||||
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
|
||||
var err error
|
||||
var annotatedContext context.Context
|
||||
annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/controller.api.services.v1.RoleService/AddRoleGrantScopes", runtime.WithHTTPPathPattern("/v1/roles/{id}:add-grant-scopes"))
|
||||
if err != nil {
|
||||
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
resp, md, err := local_request_RoleService_AddRoleGrantScopes_0(annotatedContext, inboundMarshaler, server, req, pathParams)
|
||||
md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer())
|
||||
annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md)
|
||||
if err != nil {
|
||||
runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
|
||||
forward_RoleService_AddRoleGrantScopes_0(annotatedContext, mux, outboundMarshaler, w, req, response_RoleService_AddRoleGrantScopes_0{resp}, mux.GetForwardResponseOptions()...)
|
||||
|
||||
})
|
||||
|
||||
mux.Handle("POST", pattern_RoleService_SetRoleGrantScopes_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
|
||||
ctx, cancel := context.WithCancel(req.Context())
|
||||
defer cancel()
|
||||
var stream runtime.ServerTransportStream
|
||||
ctx = grpc.NewContextWithServerTransportStream(ctx, &stream)
|
||||
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
|
||||
var err error
|
||||
var annotatedContext context.Context
|
||||
annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/controller.api.services.v1.RoleService/SetRoleGrantScopes", runtime.WithHTTPPathPattern("/v1/roles/{id}:set-grant-scopes"))
|
||||
if err != nil {
|
||||
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
resp, md, err := local_request_RoleService_SetRoleGrantScopes_0(annotatedContext, inboundMarshaler, server, req, pathParams)
|
||||
md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer())
|
||||
annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md)
|
||||
if err != nil {
|
||||
runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
|
||||
forward_RoleService_SetRoleGrantScopes_0(annotatedContext, mux, outboundMarshaler, w, req, response_RoleService_SetRoleGrantScopes_0{resp}, mux.GetForwardResponseOptions()...)
|
||||
|
||||
})
|
||||
|
||||
mux.Handle("POST", pattern_RoleService_RemoveRoleGrantScopes_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
|
||||
ctx, cancel := context.WithCancel(req.Context())
|
||||
defer cancel()
|
||||
var stream runtime.ServerTransportStream
|
||||
ctx = grpc.NewContextWithServerTransportStream(ctx, &stream)
|
||||
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
|
||||
var err error
|
||||
var annotatedContext context.Context
|
||||
annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/controller.api.services.v1.RoleService/RemoveRoleGrantScopes", runtime.WithHTTPPathPattern("/v1/roles/{id}:remove-grant-scopes"))
|
||||
if err != nil {
|
||||
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
resp, md, err := local_request_RoleService_RemoveRoleGrantScopes_0(annotatedContext, inboundMarshaler, server, req, pathParams)
|
||||
md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer())
|
||||
annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md)
|
||||
if err != nil {
|
||||
runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
|
||||
forward_RoleService_RemoveRoleGrantScopes_0(annotatedContext, mux, outboundMarshaler, w, req, response_RoleService_RemoveRoleGrantScopes_0{resp}, mux.GetForwardResponseOptions()...)
|
||||
|
||||
})
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -1277,6 +1556,72 @@ func RegisterRoleServiceHandlerClient(ctx context.Context, mux *runtime.ServeMux
|
||||
|
||||
})
|
||||
|
||||
mux.Handle("POST", pattern_RoleService_AddRoleGrantScopes_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
|
||||
ctx, cancel := context.WithCancel(req.Context())
|
||||
defer cancel()
|
||||
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
|
||||
var err error
|
||||
var annotatedContext context.Context
|
||||
annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/controller.api.services.v1.RoleService/AddRoleGrantScopes", runtime.WithHTTPPathPattern("/v1/roles/{id}:add-grant-scopes"))
|
||||
if err != nil {
|
||||
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
resp, md, err := request_RoleService_AddRoleGrantScopes_0(annotatedContext, inboundMarshaler, client, req, pathParams)
|
||||
annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md)
|
||||
if err != nil {
|
||||
runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
|
||||
forward_RoleService_AddRoleGrantScopes_0(annotatedContext, mux, outboundMarshaler, w, req, response_RoleService_AddRoleGrantScopes_0{resp}, mux.GetForwardResponseOptions()...)
|
||||
|
||||
})
|
||||
|
||||
mux.Handle("POST", pattern_RoleService_SetRoleGrantScopes_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
|
||||
ctx, cancel := context.WithCancel(req.Context())
|
||||
defer cancel()
|
||||
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
|
||||
var err error
|
||||
var annotatedContext context.Context
|
||||
annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/controller.api.services.v1.RoleService/SetRoleGrantScopes", runtime.WithHTTPPathPattern("/v1/roles/{id}:set-grant-scopes"))
|
||||
if err != nil {
|
||||
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
resp, md, err := request_RoleService_SetRoleGrantScopes_0(annotatedContext, inboundMarshaler, client, req, pathParams)
|
||||
annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md)
|
||||
if err != nil {
|
||||
runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
|
||||
forward_RoleService_SetRoleGrantScopes_0(annotatedContext, mux, outboundMarshaler, w, req, response_RoleService_SetRoleGrantScopes_0{resp}, mux.GetForwardResponseOptions()...)
|
||||
|
||||
})
|
||||
|
||||
mux.Handle("POST", pattern_RoleService_RemoveRoleGrantScopes_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
|
||||
ctx, cancel := context.WithCancel(req.Context())
|
||||
defer cancel()
|
||||
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
|
||||
var err error
|
||||
var annotatedContext context.Context
|
||||
annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/controller.api.services.v1.RoleService/RemoveRoleGrantScopes", runtime.WithHTTPPathPattern("/v1/roles/{id}:remove-grant-scopes"))
|
||||
if err != nil {
|
||||
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
resp, md, err := request_RoleService_RemoveRoleGrantScopes_0(annotatedContext, inboundMarshaler, client, req, pathParams)
|
||||
annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md)
|
||||
if err != nil {
|
||||
runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
|
||||
forward_RoleService_RemoveRoleGrantScopes_0(annotatedContext, mux, outboundMarshaler, w, req, response_RoleService_RemoveRoleGrantScopes_0{resp}, mux.GetForwardResponseOptions()...)
|
||||
|
||||
})
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -1361,6 +1706,33 @@ func (m response_RoleService_RemoveRoleGrants_0) XXX_ResponseBody() interface{}
|
||||
return response.Item
|
||||
}
|
||||
|
||||
type response_RoleService_AddRoleGrantScopes_0 struct {
|
||||
proto.Message
|
||||
}
|
||||
|
||||
func (m response_RoleService_AddRoleGrantScopes_0) XXX_ResponseBody() interface{} {
|
||||
response := m.Message.(*AddRoleGrantScopesResponse)
|
||||
return response.Item
|
||||
}
|
||||
|
||||
type response_RoleService_SetRoleGrantScopes_0 struct {
|
||||
proto.Message
|
||||
}
|
||||
|
||||
func (m response_RoleService_SetRoleGrantScopes_0) XXX_ResponseBody() interface{} {
|
||||
response := m.Message.(*SetRoleGrantScopesResponse)
|
||||
return response.Item
|
||||
}
|
||||
|
||||
type response_RoleService_RemoveRoleGrantScopes_0 struct {
|
||||
proto.Message
|
||||
}
|
||||
|
||||
func (m response_RoleService_RemoveRoleGrantScopes_0) XXX_ResponseBody() interface{} {
|
||||
response := m.Message.(*RemoveRoleGrantScopesResponse)
|
||||
return response.Item
|
||||
}
|
||||
|
||||
var (
|
||||
pattern_RoleService_GetRole_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 1, 0, 4, 1, 5, 2}, []string{"v1", "roles", "id"}, ""))
|
||||
|
||||
@@ -1383,6 +1755,12 @@ var (
|
||||
pattern_RoleService_SetRoleGrants_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 1, 0, 4, 1, 5, 2}, []string{"v1", "roles", "id"}, "set-grants"))
|
||||
|
||||
pattern_RoleService_RemoveRoleGrants_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 1, 0, 4, 1, 5, 2}, []string{"v1", "roles", "id"}, "remove-grants"))
|
||||
|
||||
pattern_RoleService_AddRoleGrantScopes_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 1, 0, 4, 1, 5, 2}, []string{"v1", "roles", "id"}, "add-grant-scopes"))
|
||||
|
||||
pattern_RoleService_SetRoleGrantScopes_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 1, 0, 4, 1, 5, 2}, []string{"v1", "roles", "id"}, "set-grant-scopes"))
|
||||
|
||||
pattern_RoleService_RemoveRoleGrantScopes_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 1, 0, 4, 1, 5, 2}, []string{"v1", "roles", "id"}, "remove-grant-scopes"))
|
||||
)
|
||||
|
||||
var (
|
||||
@@ -1407,4 +1785,10 @@ var (
|
||||
forward_RoleService_SetRoleGrants_0 = runtime.ForwardResponseMessage
|
||||
|
||||
forward_RoleService_RemoveRoleGrants_0 = runtime.ForwardResponseMessage
|
||||
|
||||
forward_RoleService_AddRoleGrantScopes_0 = runtime.ForwardResponseMessage
|
||||
|
||||
forward_RoleService_SetRoleGrantScopes_0 = runtime.ForwardResponseMessage
|
||||
|
||||
forward_RoleService_RemoveRoleGrantScopes_0 = runtime.ForwardResponseMessage
|
||||
)
|
||||
@@ -22,17 +22,20 @@ import (
|
||||
const _ = grpc.SupportPackageIsVersion7
|
||||
|
||||
const (
|
||||
RoleService_GetRole_FullMethodName = "/controller.api.services.v1.RoleService/GetRole"
|
||||
RoleService_ListRoles_FullMethodName = "/controller.api.services.v1.RoleService/ListRoles"
|
||||
RoleService_CreateRole_FullMethodName = "/controller.api.services.v1.RoleService/CreateRole"
|
||||
RoleService_UpdateRole_FullMethodName = "/controller.api.services.v1.RoleService/UpdateRole"
|
||||
RoleService_DeleteRole_FullMethodName = "/controller.api.services.v1.RoleService/DeleteRole"
|
||||
RoleService_AddRolePrincipals_FullMethodName = "/controller.api.services.v1.RoleService/AddRolePrincipals"
|
||||
RoleService_SetRolePrincipals_FullMethodName = "/controller.api.services.v1.RoleService/SetRolePrincipals"
|
||||
RoleService_RemoveRolePrincipals_FullMethodName = "/controller.api.services.v1.RoleService/RemoveRolePrincipals"
|
||||
RoleService_AddRoleGrants_FullMethodName = "/controller.api.services.v1.RoleService/AddRoleGrants"
|
||||
RoleService_SetRoleGrants_FullMethodName = "/controller.api.services.v1.RoleService/SetRoleGrants"
|
||||
RoleService_RemoveRoleGrants_FullMethodName = "/controller.api.services.v1.RoleService/RemoveRoleGrants"
|
||||
RoleService_GetRole_FullMethodName = "/controller.api.services.v1.RoleService/GetRole"
|
||||
RoleService_ListRoles_FullMethodName = "/controller.api.services.v1.RoleService/ListRoles"
|
||||
RoleService_CreateRole_FullMethodName = "/controller.api.services.v1.RoleService/CreateRole"
|
||||
RoleService_UpdateRole_FullMethodName = "/controller.api.services.v1.RoleService/UpdateRole"
|
||||
RoleService_DeleteRole_FullMethodName = "/controller.api.services.v1.RoleService/DeleteRole"
|
||||
RoleService_AddRolePrincipals_FullMethodName = "/controller.api.services.v1.RoleService/AddRolePrincipals"
|
||||
RoleService_SetRolePrincipals_FullMethodName = "/controller.api.services.v1.RoleService/SetRolePrincipals"
|
||||
RoleService_RemoveRolePrincipals_FullMethodName = "/controller.api.services.v1.RoleService/RemoveRolePrincipals"
|
||||
RoleService_AddRoleGrants_FullMethodName = "/controller.api.services.v1.RoleService/AddRoleGrants"
|
||||
RoleService_SetRoleGrants_FullMethodName = "/controller.api.services.v1.RoleService/SetRoleGrants"
|
||||
RoleService_RemoveRoleGrants_FullMethodName = "/controller.api.services.v1.RoleService/RemoveRoleGrants"
|
||||
RoleService_AddRoleGrantScopes_FullMethodName = "/controller.api.services.v1.RoleService/AddRoleGrantScopes"
|
||||
RoleService_SetRoleGrantScopes_FullMethodName = "/controller.api.services.v1.RoleService/SetRoleGrantScopes"
|
||||
RoleService_RemoveRoleGrantScopes_FullMethodName = "/controller.api.services.v1.RoleService/RemoveRoleGrantScopes"
|
||||
)
|
||||
|
||||
// RoleServiceClient is the client API for RoleService service.
|
||||
@@ -100,6 +103,22 @@ type RoleServiceClient interface {
|
||||
// grants will be removed. If missing, malformed, or references a non-existing
|
||||
// resource, an error is returned.
|
||||
RemoveRoleGrants(ctx context.Context, in *RemoveRoleGrantsRequest, opts ...grpc.CallOption) (*RemoveRoleGrantsResponse, error)
|
||||
// AddRoleGrantScopes adds grants scopes to a Role. The provided request must
|
||||
// include the Role id which the grant scopes will be added to. An error is
|
||||
// returned if the provided id is malformed or references a non-existing
|
||||
// resource.
|
||||
AddRoleGrantScopes(ctx context.Context, in *AddRoleGrantScopesRequest, opts ...grpc.CallOption) (*AddRoleGrantScopesResponse, error)
|
||||
// SetRoleGrants sets the Role's grant scopes. Any existing grant scopes on
|
||||
// the Role are deleted if they are not included in this request. The provided
|
||||
// request must include the Role ID on which the grants will be set. If
|
||||
// missing, malformed, or referencing a non-existing resource, an error is
|
||||
// returned.
|
||||
SetRoleGrantScopes(ctx context.Context, in *SetRoleGrantScopesRequest, opts ...grpc.CallOption) (*SetRoleGrantScopesResponse, error)
|
||||
// RemoveRoleGrantScopes removes the grant scopes from the specified Role. The
|
||||
// provided request must include the Role IDs from which the grants will be
|
||||
// removed. If missing, malformed, or references a non-existing resource, an
|
||||
// error is returned.
|
||||
RemoveRoleGrantScopes(ctx context.Context, in *RemoveRoleGrantScopesRequest, opts ...grpc.CallOption) (*RemoveRoleGrantScopesResponse, error)
|
||||
}
|
||||
|
||||
type roleServiceClient struct {
|
||||
@@ -209,6 +228,33 @@ func (c *roleServiceClient) RemoveRoleGrants(ctx context.Context, in *RemoveRole
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *roleServiceClient) AddRoleGrantScopes(ctx context.Context, in *AddRoleGrantScopesRequest, opts ...grpc.CallOption) (*AddRoleGrantScopesResponse, error) {
|
||||
out := new(AddRoleGrantScopesResponse)
|
||||
err := c.cc.Invoke(ctx, RoleService_AddRoleGrantScopes_FullMethodName, in, out, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *roleServiceClient) SetRoleGrantScopes(ctx context.Context, in *SetRoleGrantScopesRequest, opts ...grpc.CallOption) (*SetRoleGrantScopesResponse, error) {
|
||||
out := new(SetRoleGrantScopesResponse)
|
||||
err := c.cc.Invoke(ctx, RoleService_SetRoleGrantScopes_FullMethodName, in, out, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *roleServiceClient) RemoveRoleGrantScopes(ctx context.Context, in *RemoveRoleGrantScopesRequest, opts ...grpc.CallOption) (*RemoveRoleGrantScopesResponse, error) {
|
||||
out := new(RemoveRoleGrantScopesResponse)
|
||||
err := c.cc.Invoke(ctx, RoleService_RemoveRoleGrantScopes_FullMethodName, in, out, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
// RoleServiceServer is the server API for RoleService service.
|
||||
// All implementations must embed UnimplementedRoleServiceServer
|
||||
// for forward compatibility
|
||||
@@ -274,6 +320,22 @@ type RoleServiceServer interface {
|
||||
// grants will be removed. If missing, malformed, or references a non-existing
|
||||
// resource, an error is returned.
|
||||
RemoveRoleGrants(context.Context, *RemoveRoleGrantsRequest) (*RemoveRoleGrantsResponse, error)
|
||||
// AddRoleGrantScopes adds grants scopes to a Role. The provided request must
|
||||
// include the Role id which the grant scopes will be added to. An error is
|
||||
// returned if the provided id is malformed or references a non-existing
|
||||
// resource.
|
||||
AddRoleGrantScopes(context.Context, *AddRoleGrantScopesRequest) (*AddRoleGrantScopesResponse, error)
|
||||
// SetRoleGrants sets the Role's grant scopes. Any existing grant scopes on
|
||||
// the Role are deleted if they are not included in this request. The provided
|
||||
// request must include the Role ID on which the grants will be set. If
|
||||
// missing, malformed, or referencing a non-existing resource, an error is
|
||||
// returned.
|
||||
SetRoleGrantScopes(context.Context, *SetRoleGrantScopesRequest) (*SetRoleGrantScopesResponse, error)
|
||||
// RemoveRoleGrantScopes removes the grant scopes from the specified Role. The
|
||||
// provided request must include the Role IDs from which the grants will be
|
||||
// removed. If missing, malformed, or references a non-existing resource, an
|
||||
// error is returned.
|
||||
RemoveRoleGrantScopes(context.Context, *RemoveRoleGrantScopesRequest) (*RemoveRoleGrantScopesResponse, error)
|
||||
mustEmbedUnimplementedRoleServiceServer()
|
||||
}
|
||||
|
||||
@@ -314,6 +376,15 @@ func (UnimplementedRoleServiceServer) SetRoleGrants(context.Context, *SetRoleGra
|
||||
func (UnimplementedRoleServiceServer) RemoveRoleGrants(context.Context, *RemoveRoleGrantsRequest) (*RemoveRoleGrantsResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method RemoveRoleGrants not implemented")
|
||||
}
|
||||
func (UnimplementedRoleServiceServer) AddRoleGrantScopes(context.Context, *AddRoleGrantScopesRequest) (*AddRoleGrantScopesResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method AddRoleGrantScopes not implemented")
|
||||
}
|
||||
func (UnimplementedRoleServiceServer) SetRoleGrantScopes(context.Context, *SetRoleGrantScopesRequest) (*SetRoleGrantScopesResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method SetRoleGrantScopes not implemented")
|
||||
}
|
||||
func (UnimplementedRoleServiceServer) RemoveRoleGrantScopes(context.Context, *RemoveRoleGrantScopesRequest) (*RemoveRoleGrantScopesResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method RemoveRoleGrantScopes not implemented")
|
||||
}
|
||||
func (UnimplementedRoleServiceServer) mustEmbedUnimplementedRoleServiceServer() {}
|
||||
|
||||
// UnsafeRoleServiceServer may be embedded to opt out of forward compatibility for this service.
|
||||
@@ -525,6 +596,60 @@ func _RoleService_RemoveRoleGrants_Handler(srv interface{}, ctx context.Context,
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _RoleService_AddRoleGrantScopes_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(AddRoleGrantScopesRequest)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(RoleServiceServer).AddRoleGrantScopes(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: RoleService_AddRoleGrantScopes_FullMethodName,
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(RoleServiceServer).AddRoleGrantScopes(ctx, req.(*AddRoleGrantScopesRequest))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _RoleService_SetRoleGrantScopes_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(SetRoleGrantScopesRequest)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(RoleServiceServer).SetRoleGrantScopes(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: RoleService_SetRoleGrantScopes_FullMethodName,
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(RoleServiceServer).SetRoleGrantScopes(ctx, req.(*SetRoleGrantScopesRequest))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _RoleService_RemoveRoleGrantScopes_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(RemoveRoleGrantScopesRequest)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(RoleServiceServer).RemoveRoleGrantScopes(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: RoleService_RemoveRoleGrantScopes_FullMethodName,
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(RoleServiceServer).RemoveRoleGrantScopes(ctx, req.(*RemoveRoleGrantScopesRequest))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
// RoleService_ServiceDesc is the grpc.ServiceDesc for RoleService service.
|
||||
// It's only intended for direct use with grpc.RegisterService,
|
||||
// and not to be introspected or modified (even as a copy)
|
||||
@@ -576,6 +701,18 @@ var RoleService_ServiceDesc = grpc.ServiceDesc{
|
||||
MethodName: "RemoveRoleGrants",
|
||||
Handler: _RoleService_RemoveRoleGrants_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "AddRoleGrantScopes",
|
||||
Handler: _RoleService_AddRoleGrantScopes_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "SetRoleGrantScopes",
|
||||
Handler: _RoleService_SetRoleGrantScopes_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "RemoveRoleGrantScopes",
|
||||
Handler: _RoleService_RemoveRoleGrantScopes_Handler,
|
||||
},
|
||||
},
|
||||
Streams: []grpc.StreamDesc{},
|
||||
Metadata: "controller/api/services/v1/role_service.proto",
|
||||
|
||||
@@ -78,7 +78,7 @@ func (g *Group) VetForWrite(ctx context.Context, r db.Reader, opType db.OpType,
|
||||
return nil
|
||||
}
|
||||
|
||||
func (u *Group) validScopeTypes() []scope.Type {
|
||||
func (g *Group) validScopeTypes() []scope.Type {
|
||||
return []scope.Type{scope.Global, scope.Org, scope.Project}
|
||||
}
|
||||
|
||||
|
||||
+34
-4
@@ -6,6 +6,7 @@ package iam
|
||||
import (
|
||||
"io"
|
||||
|
||||
"github.com/hashicorp/boundary/internal/db"
|
||||
"github.com/hashicorp/boundary/internal/pagination"
|
||||
)
|
||||
|
||||
@@ -13,7 +14,9 @@ import (
|
||||
func getOpts(opt ...Option) options {
|
||||
opts := getDefaultOptions()
|
||||
for _, o := range opt {
|
||||
o(&opts)
|
||||
if o != nil {
|
||||
o(&opts)
|
||||
}
|
||||
}
|
||||
return opts
|
||||
}
|
||||
@@ -27,7 +30,8 @@ type options struct {
|
||||
withName string
|
||||
withDescription string
|
||||
withLimit int
|
||||
withGrantScopeId string
|
||||
withGrantScopeId *string
|
||||
withGrantScopeIds []string
|
||||
withSkipVetForWrite bool
|
||||
withDisassociate bool
|
||||
withSkipAdminRoleCreation bool
|
||||
@@ -36,6 +40,8 @@ type options struct {
|
||||
withRandomReader io.Reader
|
||||
withAccountIds []string
|
||||
withPrimaryAuthMethodId string
|
||||
withReader db.Reader
|
||||
withWriter db.Writer
|
||||
withStartPageAfterItem pagination.Item
|
||||
}
|
||||
|
||||
@@ -45,7 +51,6 @@ func getDefaultOptions() options {
|
||||
withName: "",
|
||||
withDescription: "",
|
||||
withLimit: 0,
|
||||
withGrantScopeId: "",
|
||||
withSkipVetForWrite: false,
|
||||
}
|
||||
}
|
||||
@@ -84,7 +89,20 @@ func WithLimit(limit int) Option {
|
||||
// roles.
|
||||
func WithGrantScopeId(id string) Option {
|
||||
return func(o *options) {
|
||||
o.withGrantScopeId = id
|
||||
if o.withGrantScopeId == nil {
|
||||
o.withGrantScopeId = new(string)
|
||||
}
|
||||
*o.withGrantScopeId = id
|
||||
}
|
||||
}
|
||||
|
||||
// WithGrantScopeIds provides an option to specify the scope ID for grants in
|
||||
// roles. In most tests this is likely the option to use, however, for tests
|
||||
// that call repo functions instead of test functions the other option is still
|
||||
// correct to specify a grant scope at creation time.
|
||||
func WithGrantScopeIds(ids []string) Option {
|
||||
return func(o *options) {
|
||||
o.withGrantScopeIds = ids
|
||||
}
|
||||
}
|
||||
|
||||
@@ -150,6 +168,18 @@ func WithPrimaryAuthMethodId(id string) Option {
|
||||
}
|
||||
}
|
||||
|
||||
// WithReaderWriter allows the caller to pass an inflight transaction to be used
|
||||
// for all database operations. If WithReaderWriter(...) is used, then the
|
||||
// caller is responsible for managing the transaction. The purpose of the
|
||||
// WithReaderWriter(...) option is to allow the caller to create the scope and
|
||||
// all of its keys in the same transaction.
|
||||
func WithReaderWriter(r db.Reader, w db.Writer) Option {
|
||||
return func(o *options) {
|
||||
o.withReader = r
|
||||
o.withWriter = w
|
||||
}
|
||||
}
|
||||
|
||||
// WithStartPageAfterItem is used to paginate over the results.
|
||||
// The next page will start after the provided item.
|
||||
func WithStartPageAfterItem(item pagination.Item) Option {
|
||||
|
||||
@@ -63,9 +63,11 @@ func Test_GetOpts(t *testing.T) {
|
||||
})
|
||||
t.Run("WithGrantScopeId", func(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
opts := getOpts(WithGrantScopeId("o_1234"))
|
||||
str := "o_1234"
|
||||
opts := getOpts(WithGrantScopeId(str))
|
||||
testOpts := getDefaultOptions()
|
||||
testOpts.withGrantScopeId = "o_1234"
|
||||
|
||||
testOpts.withGrantScopeId = &str
|
||||
assert.Equal(opts, testOpts)
|
||||
})
|
||||
t.Run("WithDisassociate", func(t *testing.T) {
|
||||
|
||||
+125
-64
@@ -112,70 +112,131 @@ const (
|
||||
order by action, member_id;
|
||||
`
|
||||
|
||||
grantsQuery = `
|
||||
with
|
||||
users (id) as (
|
||||
select public_id
|
||||
from iam_user
|
||||
%s -- anonUser || authUser
|
||||
),
|
||||
user_groups (id) as (
|
||||
select group_id
|
||||
from iam_group_member_user
|
||||
where member_id in (select id from users)
|
||||
),
|
||||
user_accounts (id) as (
|
||||
select public_id
|
||||
from auth_account
|
||||
where iam_user_id in (select id from users)
|
||||
),
|
||||
user_managed_groups (id) as (
|
||||
select managed_group_id
|
||||
from auth_managed_group_member_account
|
||||
where member_id in (select id from user_accounts)
|
||||
),
|
||||
managed_group_roles (role_id) as (
|
||||
select role_id
|
||||
from iam_managed_group_role
|
||||
where principal_id in (select id from user_managed_groups)
|
||||
),
|
||||
group_roles (role_id) as (
|
||||
select role_id
|
||||
from iam_group_role
|
||||
where principal_id in (select id from user_groups)
|
||||
),
|
||||
user_roles (role_id) as (
|
||||
select role_id
|
||||
from iam_user_role
|
||||
where principal_id in (select id from users)
|
||||
),
|
||||
user_group_roles (role_id) as (
|
||||
select role_id
|
||||
from group_roles
|
||||
union
|
||||
select role_id
|
||||
from user_roles
|
||||
union
|
||||
select role_id
|
||||
from managed_group_roles
|
||||
),
|
||||
roles (role_id, grant_scope_id) as (
|
||||
select iam_role.public_id,
|
||||
iam_role.grant_scope_id
|
||||
from iam_role
|
||||
where public_id in (select role_id from user_group_roles)
|
||||
),
|
||||
final (role_id, role_scope, role_grant) as (
|
||||
select roles.role_id,
|
||||
roles.grant_scope_id,
|
||||
iam_role_grant.canonical_grant
|
||||
from roles
|
||||
inner join iam_role_grant
|
||||
on roles.role_id = iam_role_grant.role_id
|
||||
-- only retrieves roles with a grant! there can be roles that don't have grants (it's a valid state in boundary)
|
||||
)
|
||||
select role_id as role_id, role_scope as scope_id, role_grant as grant from final;
|
||||
`
|
||||
grantsForUserQuery = `
|
||||
with
|
||||
users (id) as (
|
||||
select public_id
|
||||
from iam_user
|
||||
%s -- anonUser || authUser
|
||||
),
|
||||
user_groups (id) as (
|
||||
select group_id
|
||||
from iam_group_member_user
|
||||
where member_id in (select id from users)
|
||||
),
|
||||
user_accounts (id) as (
|
||||
select public_id
|
||||
from auth_account
|
||||
where iam_user_id in (select id from users)
|
||||
),
|
||||
user_managed_groups (id) as (
|
||||
select managed_group_id
|
||||
from auth_managed_group_member_account
|
||||
where member_id in (select id from user_accounts)
|
||||
),
|
||||
managed_group_roles (role_id) as (
|
||||
select role_id
|
||||
from iam_managed_group_role
|
||||
where principal_id in (select id from user_managed_groups)
|
||||
),
|
||||
group_roles (role_id) as (
|
||||
select role_id
|
||||
from iam_group_role
|
||||
where principal_id in (select id from user_groups)
|
||||
),
|
||||
user_roles (role_id) as (
|
||||
select role_id
|
||||
from iam_user_role
|
||||
where principal_id in (select id from users)
|
||||
),
|
||||
user_group_roles (role_id) as (
|
||||
select role_id
|
||||
from group_roles
|
||||
union
|
||||
select role_id
|
||||
from user_roles
|
||||
union
|
||||
select role_id
|
||||
from managed_group_roles
|
||||
),
|
||||
roles (role_id, role_scope_id) as (
|
||||
select iam_role.public_id,
|
||||
iam_role.scope_id
|
||||
from iam_role
|
||||
where public_id in (select role_id from user_group_roles)
|
||||
),
|
||||
role_grant_scopes (role_id, role_scope_id, grant_scope_id) as (
|
||||
select roles.role_id,
|
||||
roles.role_scope_id,
|
||||
iam_role_grant_scope.scope_id_or_special
|
||||
from roles
|
||||
inner join iam_role_grant_scope
|
||||
on roles.role_id = iam_role_grant_scope.role_id
|
||||
),
|
||||
-- For all role_ids with a special scope_id of 'descendants', we want to
|
||||
-- perform a cartesian product to pair the role_id with all non-global scopes.
|
||||
descendant_grant_scopes (role_id, grant_scope_id) as (
|
||||
select role_grant_scopes.role_id as role_id,
|
||||
iam_scope.public_id as grant_scope_id
|
||||
from role_grant_scopes,
|
||||
iam_scope
|
||||
where iam_scope.public_id != 'global'
|
||||
and role_grant_scopes.grant_scope_id = 'descendants'
|
||||
),
|
||||
children_grant_scopes (role_id, grant_scope_id) as (
|
||||
select role_grant_scopes.role_id as role_id,
|
||||
iam_scope.public_id as grant_scope_id
|
||||
from role_grant_scopes
|
||||
join iam_scope
|
||||
on iam_scope.parent_id = role_grant_scopes.role_scope_id
|
||||
where role_grant_scopes.grant_scope_id = 'children'
|
||||
),
|
||||
this_grant_scopes (role_id, grant_scope_id) as (
|
||||
select role_grant_scopes.role_id as role_id,
|
||||
role_grant_scopes.role_scope_id as grant_scope_id
|
||||
from role_grant_scopes
|
||||
where role_grant_scopes.grant_scope_id = 'this'
|
||||
),
|
||||
direct_grant_scopes (role_id, grant_scope_id) as (
|
||||
select role_grant_scopes.role_id as role_id,
|
||||
role_grant_scopes.grant_scope_id as grant_scope_id
|
||||
from role_grant_scopes
|
||||
where role_grant_scopes.grant_scope_id not in ('descendants', 'children', 'this')
|
||||
),
|
||||
grant_scopes (role_id, grant_scope_id) as (
|
||||
select
|
||||
role_id as role_id,
|
||||
grant_scope_id as grant_scope_id
|
||||
from descendant_grant_scopes
|
||||
union
|
||||
select
|
||||
role_id as role_id,
|
||||
grant_scope_id as grant_scope_id
|
||||
from children_grant_scopes
|
||||
union
|
||||
select
|
||||
role_id as role_id,
|
||||
grant_scope_id as grant_scope_id
|
||||
from this_grant_scopes
|
||||
union
|
||||
select
|
||||
role_id as role_id,
|
||||
grant_scope_id as grant_scope_id
|
||||
from direct_grant_scopes
|
||||
),
|
||||
final (role_id, grant_scope_id, canonical_grant) as (
|
||||
select grant_scopes.role_id,
|
||||
grant_scopes.grant_scope_id,
|
||||
iam_role_grant.canonical_grant
|
||||
from grant_scopes
|
||||
join iam_role_grant
|
||||
on grant_scopes.role_id = iam_role_grant.role_id
|
||||
)
|
||||
select role_id as role_id,
|
||||
grant_scope_id as scope_id,
|
||||
canonical_grant as grant
|
||||
from final;
|
||||
`
|
||||
|
||||
estimateCountRoles = `
|
||||
select reltuples::bigint as estimate from pg_class where oid in ('iam_role'::regclass)
|
||||
|
||||
+67
-43
@@ -55,6 +55,8 @@ func NewRepository(ctx context.Context, r db.Reader, w db.Writer, kms *kms.Kms,
|
||||
|
||||
// list will return a listing of resources and honor the WithLimit option or the
|
||||
// repo defaultLimit
|
||||
//
|
||||
// Supported options: WithLimit, WithReaderWriter
|
||||
func (r *Repository) list(ctx context.Context, resources any, where string, args []any, opt ...Option) error {
|
||||
opts := getOpts(opt...)
|
||||
limit := r.defaultLimit
|
||||
@@ -62,11 +64,17 @@ func (r *Repository) list(ctx context.Context, resources any, where string, args
|
||||
// non-zero signals an override of the default limit for the repo.
|
||||
limit = opts.withLimit
|
||||
}
|
||||
return r.reader.SearchWhere(ctx, resources, where, args, db.WithLimit(limit))
|
||||
reader := r.reader
|
||||
if opts.withReader != nil {
|
||||
reader = opts.withReader
|
||||
}
|
||||
return reader.SearchWhere(ctx, resources, where, args, db.WithLimit(limit))
|
||||
}
|
||||
|
||||
// create will create a new iam resource in the db repository with an oplog entry
|
||||
func (r *Repository) create(ctx context.Context, resource Resource, _ ...Option) (Resource, error) {
|
||||
//
|
||||
// Supported options: WithReaderWriter
|
||||
func (r *Repository) create(ctx context.Context, resource Resource, opt ...Option) (Resource, error) {
|
||||
const op = "iam.(Repository).create"
|
||||
if resource == nil {
|
||||
return nil, errors.New(ctx, errors.InvalidParameter, op, "missing resource")
|
||||
@@ -90,24 +98,20 @@ func (r *Repository) create(ctx context.Context, resource Resource, _ ...Option)
|
||||
return nil, errors.Wrap(ctx, err, op, errors.WithMsg("unable to get oplog wrapper"))
|
||||
}
|
||||
|
||||
var returnedResource any
|
||||
_, err = r.writer.DoTx(
|
||||
ctx,
|
||||
db.StdRetryCnt,
|
||||
db.ExpBackoff{},
|
||||
func(_ db.Reader, w db.Writer) error {
|
||||
returnedResource = resourceCloner.Clone()
|
||||
err := w.Create(
|
||||
ctx,
|
||||
returnedResource,
|
||||
db.WithOplog(oplogWrapper, metadata),
|
||||
)
|
||||
if err != nil {
|
||||
return errors.Wrap(ctx, err, op)
|
||||
}
|
||||
return nil
|
||||
},
|
||||
)
|
||||
returnedResource := resourceCloner.Clone()
|
||||
opts := getOpts(opt...)
|
||||
if opts.withWriter != nil {
|
||||
err = opts.withWriter.Create(ctx, returnedResource, db.WithOplog(oplogWrapper, metadata))
|
||||
} else {
|
||||
_, err = r.writer.DoTx(
|
||||
ctx,
|
||||
db.StdRetryCnt,
|
||||
db.ExpBackoff{},
|
||||
func(_ db.Reader, w db.Writer) error {
|
||||
return w.Create(ctx, returnedResource, db.WithOplog(oplogWrapper, metadata))
|
||||
},
|
||||
)
|
||||
}
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(ctx, err, op)
|
||||
}
|
||||
@@ -115,6 +119,8 @@ func (r *Repository) create(ctx context.Context, resource Resource, _ ...Option)
|
||||
}
|
||||
|
||||
// update will update an iam resource in the db repository with an oplog entry
|
||||
//
|
||||
// Supported options: WithReaderWriter
|
||||
func (r *Repository) update(ctx context.Context, resource Resource, version uint32, fieldMaskPaths []string, setToNullPaths []string, opt ...Option) (Resource, int, error) {
|
||||
const op = "iam.(Repository).update"
|
||||
if version == 0 {
|
||||
@@ -141,6 +147,18 @@ func (r *Repository) update(ctx context.Context, resource Resource, version uint
|
||||
dbOpts = append(dbOpts, db.WithSkipVetForWrite(true))
|
||||
}
|
||||
|
||||
reader := r.reader
|
||||
writer := r.writer
|
||||
needFreshReaderWriter := true
|
||||
if opts.withReader != nil && opts.withWriter != nil {
|
||||
reader = opts.withReader
|
||||
writer = opts.withWriter
|
||||
if !writer.IsTx(ctx) {
|
||||
return nil, db.NoRowsAffected, errors.New(ctx, errors.Internal, op, "writer is not in transaction")
|
||||
}
|
||||
needFreshReaderWriter = false
|
||||
}
|
||||
|
||||
var scope *Scope
|
||||
switch t := resource.(type) {
|
||||
case *Scope:
|
||||
@@ -159,29 +177,35 @@ func (r *Repository) update(ctx context.Context, resource Resource, version uint
|
||||
|
||||
var rowsUpdated int
|
||||
var returnedResource any
|
||||
_, err = r.writer.DoTx(
|
||||
ctx,
|
||||
db.StdRetryCnt,
|
||||
db.ExpBackoff{},
|
||||
func(_ db.Reader, w db.Writer) error {
|
||||
returnedResource = resourceCloner.Clone()
|
||||
rowsUpdated, err = w.Update(
|
||||
ctx,
|
||||
returnedResource,
|
||||
fieldMaskPaths,
|
||||
setToNullPaths,
|
||||
dbOpts...,
|
||||
)
|
||||
if err != nil {
|
||||
return errors.Wrap(ctx, err, op)
|
||||
}
|
||||
if rowsUpdated > 1 {
|
||||
// return err, which will result in a rollback of the update
|
||||
return errors.New(ctx, errors.MultipleRecords, op, "more than 1 resource would have been updated")
|
||||
}
|
||||
return nil
|
||||
},
|
||||
)
|
||||
txFunc := func(rdr db.Reader, wtr db.Writer) error {
|
||||
returnedResource = resourceCloner.Clone()
|
||||
rowsUpdated, err = wtr.Update(
|
||||
ctx,
|
||||
returnedResource,
|
||||
fieldMaskPaths,
|
||||
setToNullPaths,
|
||||
dbOpts...,
|
||||
)
|
||||
if err != nil {
|
||||
return errors.Wrap(ctx, err, op)
|
||||
}
|
||||
if rowsUpdated > 1 {
|
||||
// return err, which will result in a rollback of the update
|
||||
return errors.New(ctx, errors.MultipleRecords, op, "more than 1 resource would have been updated")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
if !needFreshReaderWriter {
|
||||
err = txFunc(reader, writer)
|
||||
} else {
|
||||
_, err = r.writer.DoTx(
|
||||
ctx,
|
||||
db.StdRetryCnt,
|
||||
db.ExpBackoff{},
|
||||
txFunc,
|
||||
)
|
||||
}
|
||||
if err != nil {
|
||||
return nil, db.NoRowsAffected, errors.Wrap(ctx, err, op)
|
||||
}
|
||||
|
||||
@@ -0,0 +1,385 @@
|
||||
// Copyright (c) HashiCorp, Inc.
|
||||
// SPDX-License-Identifier: MPL-2.0
|
||||
|
||||
package iam
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/hashicorp/boundary/internal/db"
|
||||
"github.com/hashicorp/boundary/internal/errors"
|
||||
"github.com/hashicorp/boundary/internal/kms"
|
||||
"github.com/hashicorp/boundary/internal/oplog"
|
||||
)
|
||||
|
||||
// AddRoleGrantScopes will add role grant scopes associated with the role ID in
|
||||
// the repository. No options are currently supported. Zero is not a valid value
|
||||
// for the WithVersion option and will return an error.
|
||||
func (r *Repository) AddRoleGrantScopes(ctx context.Context, roleId string, roleVersion uint32, grantScopes []string, _ ...Option) ([]*RoleGrantScope, error) {
|
||||
const op = "iam.(Repository).AddRoleGrantScopes"
|
||||
if roleId == "" {
|
||||
return nil, errors.New(ctx, errors.InvalidParameter, op, "missing role id")
|
||||
}
|
||||
if len(grantScopes) == 0 {
|
||||
return nil, errors.New(ctx, errors.InvalidParameter, op, "missing grant scopes")
|
||||
}
|
||||
if roleVersion == 0 {
|
||||
return nil, errors.New(ctx, errors.InvalidParameter, op, "missing version")
|
||||
}
|
||||
|
||||
role := allocRole()
|
||||
role.PublicId = roleId
|
||||
|
||||
scope, err := role.GetScope(ctx, r.reader)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(ctx, err, op, errors.WithMsg(fmt.Sprintf("unable to get role %s scope", roleId)))
|
||||
}
|
||||
role.ScopeId = scope.PublicId
|
||||
|
||||
// Find existing grant scopes
|
||||
roleGrantScopes := []*RoleGrantScope{}
|
||||
if err := r.reader.SearchWhere(ctx, &roleGrantScopes, "role_id = ?", []any{roleId}); err != nil {
|
||||
return nil, errors.Wrap(ctx, err, op, errors.WithMsg("unable to search for grant scopes"))
|
||||
}
|
||||
found := map[string]*RoleGrantScope{}
|
||||
for _, rgs := range roleGrantScopes {
|
||||
found[rgs.ScopeIdOrSpecial] = rgs
|
||||
}
|
||||
|
||||
// Check incoming grant scopes to see if they exist so we don't try to add
|
||||
// again and cause an integrity error
|
||||
addRoleGrantScopes := make([]any, 0, len(grantScopes))
|
||||
for _, grantScope := range grantScopes {
|
||||
if _, ok := found[grantScope]; !ok {
|
||||
addRoleGrantScopes = append(addRoleGrantScopes, grantScope)
|
||||
}
|
||||
}
|
||||
|
||||
newRoleGrantScopes := make([]any, 0, len(addRoleGrantScopes))
|
||||
for _, grantScope := range grantScopes {
|
||||
roleGrantScope, err := NewRoleGrantScope(ctx, role.GetPublicId(), grantScope)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(ctx, err, op, errors.WithMsg("unable to create in memory role grant scope"))
|
||||
}
|
||||
newRoleGrantScopes = append(newRoleGrantScopes, roleGrantScope)
|
||||
}
|
||||
|
||||
oplogWrapper, err := r.kms.GetWrapper(ctx, role.GetScopeId(), kms.KeyPurposeOplog)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(ctx, err, op, errors.WithMsg("unable to get oplog wrapper"))
|
||||
}
|
||||
|
||||
_, err = r.writer.DoTx(
|
||||
ctx,
|
||||
db.StdRetryCnt,
|
||||
db.ExpBackoff{},
|
||||
func(reader db.Reader, w db.Writer) error {
|
||||
msgs := make([]*oplog.Message, 0, 2)
|
||||
roleTicket, err := w.GetTicket(ctx, &role)
|
||||
if err != nil {
|
||||
return errors.Wrap(ctx, err, op, errors.WithMsg("unable to get ticket"))
|
||||
}
|
||||
|
||||
// We need to update the role version as that's the aggregate
|
||||
updatedRole := allocRole()
|
||||
updatedRole.PublicId = role.GetPublicId()
|
||||
updatedRole.Version = uint32(roleVersion + 1)
|
||||
var roleOplogMsg oplog.Message
|
||||
rowsUpdated, err := w.Update(ctx, &updatedRole, []string{"Version"}, nil, db.NewOplogMsg(&roleOplogMsg), db.WithVersion(&roleVersion))
|
||||
if err != nil {
|
||||
return errors.Wrap(ctx, err, op, errors.WithMsg("unable to update role version"))
|
||||
}
|
||||
if rowsUpdated != 1 {
|
||||
return errors.New(ctx, errors.MultipleRecords, op, fmt.Sprintf("updated role and %d rows updated", rowsUpdated))
|
||||
}
|
||||
msgs = append(msgs, &roleOplogMsg)
|
||||
roleGrantScopesOplogMsgs := make([]*oplog.Message, 0, len(newRoleGrantScopes))
|
||||
if err := w.CreateItems(ctx, newRoleGrantScopes, db.NewOplogMsgs(&roleGrantScopesOplogMsgs)); err != nil {
|
||||
return errors.Wrap(ctx, err, op, errors.WithMsg("unable to add grants"))
|
||||
}
|
||||
msgs = append(msgs, roleGrantScopesOplogMsgs...)
|
||||
|
||||
metadata := oplog.Metadata{
|
||||
"op-type": []string{oplog.OpType_OP_TYPE_CREATE.String()},
|
||||
"scope-id": []string{scope.PublicId},
|
||||
"scope-type": []string{scope.Type},
|
||||
"resource-public-id": []string{role.PublicId},
|
||||
}
|
||||
if err := w.WriteOplogEntryWith(ctx, oplogWrapper, roleTicket, metadata, msgs); err != nil {
|
||||
return errors.Wrap(ctx, err, op, errors.WithMsg("unable to write oplog"))
|
||||
}
|
||||
|
||||
return nil
|
||||
},
|
||||
)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(ctx, err, op)
|
||||
}
|
||||
roleGrantScopes = make([]*RoleGrantScope, 0, len(newRoleGrantScopes))
|
||||
for _, grantScope := range newRoleGrantScopes {
|
||||
roleGrantScopes = append(roleGrantScopes, grantScope.(*RoleGrantScope))
|
||||
}
|
||||
return roleGrantScopes, nil
|
||||
}
|
||||
|
||||
// DeleteRoleGrantScopes will delete role grant scopes associated with the role ID in
|
||||
// the repository. No options are currently supported. Zero is not a valid value
|
||||
// for the WithVersion option and will return an error.
|
||||
func (r *Repository) DeleteRoleGrantScopes(ctx context.Context, roleId string, roleVersion uint32, grantScopes []string, _ ...Option) (int, error) {
|
||||
const op = "iam.(Repository).DeleteRoleGrantScopes"
|
||||
if roleId == "" {
|
||||
return db.NoRowsAffected, errors.New(ctx, errors.InvalidParameter, op, "missing role id")
|
||||
}
|
||||
if len(grantScopes) == 0 {
|
||||
return db.NoRowsAffected, errors.New(ctx, errors.InvalidParameter, op, "missing grant scopes")
|
||||
}
|
||||
if roleVersion == 0 {
|
||||
return db.NoRowsAffected, errors.New(ctx, errors.InvalidParameter, op, "missing version")
|
||||
}
|
||||
|
||||
role := allocRole()
|
||||
role.PublicId = roleId
|
||||
|
||||
scope, err := role.GetScope(ctx, r.reader)
|
||||
if err != nil {
|
||||
return db.NoRowsAffected, errors.Wrap(ctx, err, op, errors.WithMsg(fmt.Sprintf("unable to get role %s scope", roleId)))
|
||||
}
|
||||
role.ScopeId = scope.PublicId
|
||||
|
||||
oplogWrapper, err := r.kms.GetWrapper(ctx, role.GetScopeId(), kms.KeyPurposeOplog)
|
||||
if err != nil {
|
||||
return db.NoRowsAffected, errors.Wrap(ctx, err, op, errors.WithMsg("unable to get oplog wrapper"))
|
||||
}
|
||||
|
||||
var totalRowsDeleted int
|
||||
_, err = r.writer.DoTx(
|
||||
ctx,
|
||||
db.StdRetryCnt,
|
||||
db.ExpBackoff{},
|
||||
func(reader db.Reader, w db.Writer) error {
|
||||
msgs := make([]*oplog.Message, 0, 2)
|
||||
roleTicket, err := w.GetTicket(ctx, &role)
|
||||
if err != nil {
|
||||
return errors.Wrap(ctx, err, op, errors.WithMsg("unable to get ticket"))
|
||||
}
|
||||
|
||||
// We need to update the role version as that's the aggregate
|
||||
updatedRole := allocRole()
|
||||
updatedRole.PublicId = role.GetPublicId()
|
||||
updatedRole.Version = uint32(roleVersion + 1)
|
||||
var roleOplogMsg oplog.Message
|
||||
rowsUpdated, err := w.Update(ctx, &updatedRole, []string{"Version"}, nil, db.NewOplogMsg(&roleOplogMsg), db.WithVersion(&roleVersion))
|
||||
if err != nil {
|
||||
return errors.Wrap(ctx, err, op, errors.WithMsg("unable to update role version"))
|
||||
}
|
||||
if rowsUpdated != 1 {
|
||||
return errors.New(ctx, errors.MultipleRecords, op, fmt.Sprintf("updated role and %d rows updated", rowsUpdated))
|
||||
}
|
||||
msgs = append(msgs, &roleOplogMsg)
|
||||
|
||||
deleteRoleGrantScopes := make([]any, 0, len(grantScopes))
|
||||
for _, grantScope := range grantScopes {
|
||||
roleGrantScope, err := NewRoleGrantScope(ctx, roleId, grantScope)
|
||||
if err != nil {
|
||||
return errors.Wrap(ctx, err, op, errors.WithMsg("unable to create in memory role grant scope"))
|
||||
}
|
||||
deleteRoleGrantScopes = append(deleteRoleGrantScopes, roleGrantScope)
|
||||
}
|
||||
|
||||
if len(deleteRoleGrantScopes) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
roleGrantScopesOplogMsgs := make([]*oplog.Message, 0, len(deleteRoleGrantScopes))
|
||||
rowsDeleted, err := w.DeleteItems(ctx, deleteRoleGrantScopes, db.NewOplogMsgs(&roleGrantScopesOplogMsgs))
|
||||
if err != nil {
|
||||
return errors.Wrap(ctx, err, op, errors.WithMsg("unable to add grants"))
|
||||
}
|
||||
totalRowsDeleted = rowsDeleted
|
||||
msgs = append(msgs, roleGrantScopesOplogMsgs...)
|
||||
|
||||
metadata := oplog.Metadata{
|
||||
"op-type": []string{oplog.OpType_OP_TYPE_CREATE.String()},
|
||||
"scope-id": []string{scope.PublicId},
|
||||
"scope-type": []string{scope.Type},
|
||||
"resource-public-id": []string{role.PublicId},
|
||||
}
|
||||
if err := w.WriteOplogEntryWith(ctx, oplogWrapper, roleTicket, metadata, msgs); err != nil {
|
||||
return errors.Wrap(ctx, err, op, errors.WithMsg("unable to write oplog"))
|
||||
}
|
||||
|
||||
return nil
|
||||
},
|
||||
)
|
||||
if err != nil {
|
||||
return db.NoRowsAffected, errors.Wrap(ctx, err, op)
|
||||
}
|
||||
return totalRowsDeleted, nil
|
||||
}
|
||||
|
||||
// SetRoleGrantScopes sets grant scopes on a role (roleId). The role's current
|
||||
// db version
|
||||
// must match the roleVersion or an error will be returned. Zero is not a valid
|
||||
// value for the WithVersion option and will return an error.
|
||||
func (r *Repository) SetRoleGrantScopes(ctx context.Context, roleId string, roleVersion uint32, grantScopes []string, opt ...Option) ([]*RoleGrantScope, int, error) {
|
||||
const op = "iam.(Repository).SetRoleGrantScopes"
|
||||
if roleId == "" {
|
||||
return nil, db.NoRowsAffected, errors.New(ctx, errors.InvalidParameter, op, "missing role id")
|
||||
}
|
||||
if roleVersion == 0 {
|
||||
return nil, db.NoRowsAffected, errors.New(ctx, errors.InvalidParameter, op, "missing version")
|
||||
}
|
||||
|
||||
// Explicitly set to zero clears, but treat nil as a mistake
|
||||
if grantScopes == nil {
|
||||
return nil, db.NoRowsAffected, errors.New(ctx, errors.InvalidParameter, op, "missing grants")
|
||||
}
|
||||
|
||||
reader := r.reader
|
||||
writer := r.writer
|
||||
needFreshReaderWriter := true
|
||||
opts := getOpts(opt...)
|
||||
if opts.withReader != nil && opts.withWriter != nil {
|
||||
reader = opts.withReader
|
||||
writer = opts.withWriter
|
||||
needFreshReaderWriter = false
|
||||
}
|
||||
|
||||
role := allocRole()
|
||||
role.PublicId = roleId
|
||||
|
||||
// NOTE: Set calculation can safely take place out of the transaction since
|
||||
// we are using roleVersion to ensure that we end up operating on the same
|
||||
// set of data from this query to the final set in the transaction function
|
||||
|
||||
// Find existing grant scopes
|
||||
roleGrantScopes := []*RoleGrantScope{}
|
||||
if err := reader.SearchWhere(ctx, &roleGrantScopes, "role_id = ?", []any{roleId}); err != nil {
|
||||
return nil, db.NoRowsAffected, errors.Wrap(ctx, err, op, errors.WithMsg("unable to search for grant scopes"))
|
||||
}
|
||||
found := map[string]*RoleGrantScope{}
|
||||
for _, rgs := range roleGrantScopes {
|
||||
found[rgs.ScopeIdOrSpecial] = rgs
|
||||
}
|
||||
|
||||
// Check incoming grant scopes to see if they exist and if so act appropriately
|
||||
currentRoleGrantScopes := make([]*RoleGrantScope, 0, len(grantScopes)+len(found))
|
||||
addRoleGrantScopes := make([]any, 0, len(grantScopes))
|
||||
deleteRoleGrantScopes := make([]any, 0, len(grantScopes))
|
||||
for _, grantScope := range grantScopes {
|
||||
rgs, ok := found[grantScope]
|
||||
if ok {
|
||||
// If we have an exact match, do nothing, we want to keep
|
||||
// it, but remove from found
|
||||
currentRoleGrantScopes = append(currentRoleGrantScopes, rgs)
|
||||
delete(found, grantScope)
|
||||
continue
|
||||
}
|
||||
|
||||
// Not found, so add
|
||||
rgs, err := NewRoleGrantScope(ctx, roleId, grantScope)
|
||||
if err != nil {
|
||||
return nil, db.NoRowsAffected, errors.Wrap(ctx, err, op, errors.WithMsg("unable to create in memory role grant"))
|
||||
}
|
||||
addRoleGrantScopes = append(addRoleGrantScopes, rgs)
|
||||
currentRoleGrantScopes = append(currentRoleGrantScopes, rgs)
|
||||
}
|
||||
|
||||
if len(found) > 0 {
|
||||
for _, rgs := range found {
|
||||
deleteRoleGrantScopes = append(deleteRoleGrantScopes, rgs)
|
||||
}
|
||||
}
|
||||
|
||||
if len(addRoleGrantScopes) == 0 && len(deleteRoleGrantScopes) == 0 {
|
||||
return currentRoleGrantScopes, db.NoRowsAffected, nil
|
||||
}
|
||||
|
||||
scope, err := role.GetScope(ctx, reader)
|
||||
if err != nil {
|
||||
return nil, db.NoRowsAffected, errors.Wrap(ctx, err, op, errors.WithMsg(fmt.Sprintf("unable to get role %s scope", roleId)))
|
||||
}
|
||||
oplogWrapper, err := r.kms.GetWrapper(ctx, scope.GetPublicId(), kms.KeyPurposeOplog)
|
||||
if err != nil {
|
||||
return nil, db.NoRowsAffected, errors.Wrap(ctx, err, op, errors.WithMsg("unable to get oplog wrapper"))
|
||||
}
|
||||
|
||||
var totalRowsDeleted int
|
||||
currentRoleGrantScopes = currentRoleGrantScopes[:0]
|
||||
txFunc := func(rdr db.Reader, wtr db.Writer) error {
|
||||
msgs := make([]*oplog.Message, 0, 2)
|
||||
roleTicket, err := wtr.GetTicket(ctx, &role)
|
||||
if err != nil {
|
||||
return errors.Wrap(ctx, err, op, errors.WithMsg("unable to get ticket"))
|
||||
}
|
||||
updatedRole := allocRole()
|
||||
updatedRole.PublicId = roleId
|
||||
updatedRole.Version = roleVersion + 1
|
||||
var roleOplogMsg oplog.Message
|
||||
rowsUpdated, err := wtr.Update(ctx, &updatedRole, []string{"Version"}, nil, db.NewOplogMsg(&roleOplogMsg), db.WithVersion(&roleVersion))
|
||||
if err != nil {
|
||||
return errors.Wrap(ctx, err, op, errors.WithMsg("unable to update role version"))
|
||||
}
|
||||
if rowsUpdated != 1 {
|
||||
return errors.New(ctx, errors.MultipleRecords, op, fmt.Sprintf("updated role and %d rows updated", rowsUpdated))
|
||||
}
|
||||
msgs = append(msgs, &roleOplogMsg)
|
||||
|
||||
// Anything we didn't take out of found needs to be removed. This needs
|
||||
// to come before writing in new ones because otherwise we may hit some
|
||||
// validation issues.
|
||||
if len(deleteRoleGrantScopes) > 0 {
|
||||
roleGrantScopeOplogMsgs := make([]*oplog.Message, 0, len(deleteRoleGrantScopes))
|
||||
rowsDeleted, err := wtr.DeleteItems(ctx, deleteRoleGrantScopes, db.NewOplogMsgs(&roleGrantScopeOplogMsgs))
|
||||
if err != nil {
|
||||
return errors.Wrap(ctx, err, op, errors.WithMsg("unable to delete role grant scope"))
|
||||
}
|
||||
if rowsDeleted != len(deleteRoleGrantScopes) {
|
||||
return errors.New(ctx, errors.MultipleRecords, op, fmt.Sprintf("role grant scope deleted %d did not match request for %d", rowsDeleted, len(deleteRoleGrantScopes)))
|
||||
}
|
||||
totalRowsDeleted = rowsDeleted
|
||||
msgs = append(msgs, roleGrantScopeOplogMsgs...)
|
||||
}
|
||||
|
||||
// Write the new ones in
|
||||
if len(addRoleGrantScopes) > 0 {
|
||||
roleGrantScopeOplogMsgs := make([]*oplog.Message, 0, len(addRoleGrantScopes))
|
||||
if err := wtr.CreateItems(ctx, addRoleGrantScopes, db.NewOplogMsgs(&roleGrantScopeOplogMsgs)); err != nil {
|
||||
return errors.Wrap(ctx, err, op, errors.WithMsg("unable to add grant scope during set"))
|
||||
}
|
||||
msgs = append(msgs, roleGrantScopeOplogMsgs...)
|
||||
}
|
||||
|
||||
metadata := oplog.Metadata{
|
||||
"op-type": []string{oplog.OpType_OP_TYPE_DELETE.String(), oplog.OpType_OP_TYPE_CREATE.String()},
|
||||
"scope-id": []string{scope.PublicId},
|
||||
"scope-type": []string{scope.Type},
|
||||
"resource-public-id": []string{roleId},
|
||||
}
|
||||
if err := wtr.WriteOplogEntryWith(ctx, oplogWrapper, roleTicket, metadata, msgs); err != nil {
|
||||
return errors.Wrap(ctx, err, op, errors.WithMsg("unable to write oplog"))
|
||||
}
|
||||
|
||||
if err := r.list(ctx, ¤tRoleGrantScopes, "role_id = ?", []any{roleId}, opt...); err != nil {
|
||||
return errors.Wrap(ctx, err, op, errors.WithMsg("unable to retrieve current role grant scopes after set"))
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
if !needFreshReaderWriter {
|
||||
err = txFunc(reader, writer)
|
||||
} else {
|
||||
_, err = r.writer.DoTx(
|
||||
ctx,
|
||||
db.StdRetryCnt,
|
||||
db.ExpBackoff{},
|
||||
txFunc,
|
||||
)
|
||||
}
|
||||
if err != nil {
|
||||
return nil, db.NoRowsAffected, errors.Wrap(ctx, err, op)
|
||||
}
|
||||
return currentRoleGrantScopes, totalRowsDeleted, nil
|
||||
}
|
||||
@@ -135,7 +135,7 @@ func TestRepository_AddPrincipalRoles(t *testing.T) {
|
||||
var userIds, groupIds []string
|
||||
|
||||
for _, roleId := range []string{orgRole.PublicId, projRole.PublicId} {
|
||||
origRole, _, _, err := repo.LookupRole(context.Background(), roleId)
|
||||
origRole, _, _, _, err := repo.LookupRole(context.Background(), roleId)
|
||||
require.NoError(err)
|
||||
|
||||
if tt.args.wantUserIds {
|
||||
@@ -187,7 +187,7 @@ func TestRepository_AddPrincipalRoles(t *testing.T) {
|
||||
assert.Equal(gotPrincipal[principalId].GetType(), r.GetType())
|
||||
}
|
||||
|
||||
r, _, _, err := repo.LookupRole(context.Background(), roleId)
|
||||
r, _, _, _, err := repo.LookupRole(context.Background(), roleId)
|
||||
require.NoError(err)
|
||||
assert.Equal(tt.args.roleVersion+1, r.Version)
|
||||
assert.Equal(origRole.Version, r.Version-1)
|
||||
@@ -646,7 +646,7 @@ func TestRepository_SetPrincipalRoles(t *testing.T) {
|
||||
if tt.args.addToOrigGrps {
|
||||
tt.args.groupIds = append(tt.args.groupIds, origGrps...)
|
||||
}
|
||||
origRole, _, _, err := repo.LookupRole(context.Background(), tt.args.role.PublicId)
|
||||
origRole, _, _, _, err := repo.LookupRole(context.Background(), tt.args.role.PublicId)
|
||||
require.NoError(err)
|
||||
|
||||
principalIds := append(tt.args.userIds, tt.args.groupIds...)
|
||||
@@ -671,7 +671,7 @@ func TestRepository_SetPrincipalRoles(t *testing.T) {
|
||||
sort.Strings(gotIds)
|
||||
assert.Equal(wantIds, gotIds)
|
||||
|
||||
r, _, _, err := repo.LookupRole(context.Background(), tt.args.role.PublicId)
|
||||
r, _, _, _, err := repo.LookupRole(context.Background(), tt.args.role.PublicId)
|
||||
require.NoError(err)
|
||||
if tt.name != "no change" {
|
||||
assert.Equalf(tt.args.roleVersion+1, r.Version, "%s unexpected version: %d/%d", tt.name, tt.args.roleVersion+1, r.Version)
|
||||
|
||||
+136
-63
@@ -10,6 +10,7 @@ import (
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/hashicorp/boundary/globals"
|
||||
"github.com/hashicorp/boundary/internal/db"
|
||||
"github.com/hashicorp/boundary/internal/db/timestamp"
|
||||
"github.com/hashicorp/boundary/internal/errors"
|
||||
@@ -18,34 +19,70 @@ import (
|
||||
|
||||
// CreateRole will create a role in the repository and return the written
|
||||
// role. No options are currently supported.
|
||||
func (r *Repository) CreateRole(ctx context.Context, role *Role, _ ...Option) (*Role, error) {
|
||||
func (r *Repository) CreateRole(ctx context.Context, role *Role, opt ...Option) (*Role, []*PrincipalRole, []*RoleGrant, []*RoleGrantScope, error) {
|
||||
const op = "iam.(Repository).CreateRole"
|
||||
if role == nil {
|
||||
return nil, errors.New(ctx, errors.InvalidParameter, op, "missing role")
|
||||
return nil, nil, nil, nil, errors.New(ctx, errors.InvalidParameter, op, "missing role")
|
||||
}
|
||||
if role.Role == nil {
|
||||
return nil, errors.New(ctx, errors.InvalidParameter, op, "missing role store")
|
||||
return nil, nil, nil, nil, errors.New(ctx, errors.InvalidParameter, op, "missing role store")
|
||||
}
|
||||
if role.PublicId != "" {
|
||||
return nil, errors.New(ctx, errors.InvalidParameter, op, "public id not empty")
|
||||
return nil, nil, nil, nil, errors.New(ctx, errors.InvalidParameter, op, "public id not empty")
|
||||
}
|
||||
if role.ScopeId == "" {
|
||||
return nil, errors.New(ctx, errors.InvalidParameter, op, "missing scope id")
|
||||
return nil, nil, nil, nil, errors.New(ctx, errors.InvalidParameter, op, "missing scope id")
|
||||
}
|
||||
id, err := newRoleId(ctx)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(ctx, err, op)
|
||||
return nil, nil, nil, nil, errors.Wrap(ctx, err, op)
|
||||
}
|
||||
c := role.Clone().(*Role)
|
||||
c.PublicId = id
|
||||
resource, err := r.create(ctx, c)
|
||||
|
||||
opts := getOpts(opt...)
|
||||
|
||||
var initialScope string
|
||||
switch {
|
||||
case opts.withGrantScopeId == nil:
|
||||
initialScope = globals.GrantScopeThis
|
||||
case *opts.withGrantScopeId == "":
|
||||
initialScope = globals.GrantScopeThis
|
||||
default:
|
||||
initialScope = *opts.withGrantScopeId
|
||||
}
|
||||
|
||||
var resource Resource
|
||||
var pr []*PrincipalRole
|
||||
var rg []*RoleGrant
|
||||
var grantScopes []*RoleGrantScope
|
||||
_, err = r.writer.DoTx(
|
||||
ctx,
|
||||
db.StdRetryCnt,
|
||||
db.ExpBackoff{},
|
||||
func(reader db.Reader, writer db.Writer) error {
|
||||
resource, err = r.create(ctx, c, WithReaderWriter(reader, writer))
|
||||
if err != nil {
|
||||
return errors.Wrap(ctx, err, op, errors.WithMsg("while creating role"))
|
||||
}
|
||||
_, _, err = r.SetRoleGrantScopes(ctx, id, resource.(*Role).Version, []string{initialScope}, WithReaderWriter(reader, writer))
|
||||
if err != nil {
|
||||
return errors.Wrap(ctx, err, op, errors.WithMsg("while setting grant scopes"))
|
||||
}
|
||||
// Do a fresh lookup to get all return values
|
||||
resource, pr, rg, grantScopes, err = r.LookupRole(ctx, resource.(*Role).PublicId, WithReaderWriter(reader, writer))
|
||||
if err != nil {
|
||||
return errors.Wrap(ctx, err, op)
|
||||
}
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
if errors.IsUniqueError(err) {
|
||||
return nil, errors.New(ctx, errors.NotUnique, op, fmt.Sprintf("role %s already exists in scope %s", role.Name, role.ScopeId))
|
||||
return nil, nil, nil, nil, errors.New(ctx, errors.NotUnique, op, fmt.Sprintf("role %s already exists in scope %s", role.Name, role.ScopeId))
|
||||
}
|
||||
return nil, errors.Wrap(ctx, err, op, errors.WithMsg(fmt.Sprintf("for %s", c.PublicId)))
|
||||
return nil, nil, nil, nil, errors.Wrap(ctx, err, op, errors.WithMsg(fmt.Sprintf("for %s", c.PublicId)))
|
||||
}
|
||||
return resource.(*Role), nil
|
||||
return resource.(*Role), pr, rg, grantScopes, nil
|
||||
}
|
||||
|
||||
// UpdateRole will update a role in the repository and return the written role.
|
||||
@@ -54,43 +91,56 @@ func (r *Repository) CreateRole(ctx context.Context, role *Role, _ ...Option) (*
|
||||
// included in fieldMask. Name, Description, and GrantScopeId are the only
|
||||
// updatable fields, If no updatable fields are included in the fieldMaskPaths,
|
||||
// then an error is returned.
|
||||
func (r *Repository) UpdateRole(ctx context.Context, role *Role, version uint32, fieldMaskPaths []string, _ ...Option) (*Role, []*PrincipalRole, []*RoleGrant, int, error) {
|
||||
func (r *Repository) UpdateRole(ctx context.Context, role *Role, version uint32, fieldMaskPaths []string, opt ...Option) (*Role, []*PrincipalRole, []*RoleGrant, []*RoleGrantScope, int, error) {
|
||||
const op = "iam.(Repository).UpdateRole"
|
||||
if role == nil {
|
||||
return nil, nil, nil, db.NoRowsAffected, errors.New(ctx, errors.InvalidParameter, op, "missing role")
|
||||
return nil, nil, nil, nil, db.NoRowsAffected, errors.New(ctx, errors.InvalidParameter, op, "missing role")
|
||||
}
|
||||
if role.Role == nil {
|
||||
return nil, nil, nil, db.NoRowsAffected, errors.New(ctx, errors.InvalidParameter, op, "missing role store")
|
||||
return nil, nil, nil, nil, db.NoRowsAffected, errors.New(ctx, errors.InvalidParameter, op, "missing role store")
|
||||
}
|
||||
if role.PublicId == "" {
|
||||
return nil, nil, nil, db.NoRowsAffected, errors.New(ctx, errors.InvalidParameter, op, "missing public id")
|
||||
return nil, nil, nil, nil, db.NoRowsAffected, errors.New(ctx, errors.InvalidParameter, op, "missing public id")
|
||||
}
|
||||
|
||||
for _, f := range fieldMaskPaths {
|
||||
switch {
|
||||
case strings.EqualFold("name", f):
|
||||
case strings.EqualFold("description", f):
|
||||
case strings.EqualFold("grantscopeid", f):
|
||||
default:
|
||||
return nil, nil, nil, db.NoRowsAffected, errors.New(ctx, errors.InvalidFieldMask, op, fmt.Sprintf("invalid field mask: %s", f))
|
||||
return nil, nil, nil, nil, db.NoRowsAffected, errors.New(ctx, errors.InvalidFieldMask, op, fmt.Sprintf("invalid field mask: %s", f))
|
||||
}
|
||||
}
|
||||
|
||||
opts := getOpts(opt...)
|
||||
var grantScopeIdToSet []string
|
||||
if opts.withGrantScopeId != nil {
|
||||
// If the value is empty, they're trying to clear it (e.g. a
|
||||
// null field), which is represented by an empty slice in
|
||||
// SetRoleGrantScopes
|
||||
grantScopeIdToSet = make([]string, 0, 1)
|
||||
if *opts.withGrantScopeId != "" {
|
||||
grantScopeIdToSet = append(grantScopeIdToSet, *opts.withGrantScopeId)
|
||||
}
|
||||
}
|
||||
|
||||
var dbMask, nullFields []string
|
||||
dbMask, nullFields = dbw.BuildUpdatePaths(
|
||||
map[string]any{
|
||||
"name": role.Name,
|
||||
"description": role.Description,
|
||||
"GrantScopeId": role.GrantScopeId,
|
||||
"name": role.Name,
|
||||
"description": role.Description,
|
||||
},
|
||||
fieldMaskPaths,
|
||||
nil,
|
||||
)
|
||||
if len(dbMask) == 0 && len(nullFields) == 0 {
|
||||
return nil, nil, nil, db.NoRowsAffected, errors.E(ctx, errors.WithCode(errors.EmptyFieldMask), errors.WithOp(op))
|
||||
if len(dbMask) == 0 && len(nullFields) == 0 && grantScopeIdToSet == nil {
|
||||
return nil, nil, nil, nil, db.NoRowsAffected, errors.E(ctx, errors.WithCode(errors.EmptyFieldMask), errors.WithOp(op))
|
||||
}
|
||||
var resource Resource
|
||||
var rowsUpdated int
|
||||
var pr []*PrincipalRole
|
||||
var rg []*RoleGrant
|
||||
var grantScopes []*RoleGrantScope
|
||||
_, err := r.writer.DoTx(
|
||||
ctx,
|
||||
db.StdRetryCnt,
|
||||
@@ -98,19 +148,23 @@ func (r *Repository) UpdateRole(ctx context.Context, role *Role, version uint32,
|
||||
func(read db.Reader, w db.Writer) error {
|
||||
var err error
|
||||
c := role.Clone().(*Role)
|
||||
resource, rowsUpdated, err = r.update(ctx, c, version, dbMask, nullFields)
|
||||
if err != nil {
|
||||
return errors.Wrap(ctx, err, op)
|
||||
resource = c // If we don't have dbMask or nullFields, we'll return this
|
||||
if len(dbMask) > 0 || len(nullFields) > 0 {
|
||||
resource, rowsUpdated, err = r.update(ctx, c, version, dbMask, nullFields, WithReaderWriter(read, w))
|
||||
if err != nil {
|
||||
return errors.Wrap(ctx, err, op)
|
||||
}
|
||||
version = resource.(*Role).Version
|
||||
}
|
||||
repo, err := NewRepository(ctx, read, w, r.kms)
|
||||
if err != nil {
|
||||
return errors.Wrap(ctx, err, op)
|
||||
if grantScopeIdToSet != nil {
|
||||
_, _, err = r.SetRoleGrantScopes(ctx, role.PublicId, version, grantScopeIdToSet, WithReaderWriter(read, w))
|
||||
if err != nil {
|
||||
return errors.Wrap(ctx, err, op, errors.WithMsg("while setting grant scopes"))
|
||||
}
|
||||
}
|
||||
pr, err = repo.ListPrincipalRoles(ctx, role.PublicId)
|
||||
if err != nil {
|
||||
return errors.Wrap(ctx, err, op)
|
||||
}
|
||||
rg, err = repo.ListRoleGrants(ctx, role.PublicId)
|
||||
// Do a fresh lookup since version may have gone up by 1 or 2 based
|
||||
// on grant scope id
|
||||
resource, pr, rg, grantScopes, err = r.LookupRole(ctx, role.PublicId, WithReaderWriter(read, w))
|
||||
if err != nil {
|
||||
return errors.Wrap(ctx, err, op)
|
||||
}
|
||||
@@ -119,54 +173,73 @@ func (r *Repository) UpdateRole(ctx context.Context, role *Role, version uint32,
|
||||
)
|
||||
if err != nil {
|
||||
if errors.IsUniqueError(err) {
|
||||
return nil, nil, nil, db.NoRowsAffected, errors.New(ctx, errors.NotUnique, op, fmt.Sprintf("role %s already exists in org %s", role.Name, role.ScopeId))
|
||||
return nil, nil, nil, nil, db.NoRowsAffected, errors.New(ctx, errors.NotUnique, op, fmt.Sprintf("role %s already exists in org %s", role.Name, role.ScopeId))
|
||||
}
|
||||
return nil, nil, nil, db.NoRowsAffected, errors.Wrap(ctx, err, op, errors.WithMsg(fmt.Sprintf("for %s", role.PublicId)))
|
||||
return nil, nil, nil, nil, db.NoRowsAffected, errors.Wrap(ctx, err, op, errors.WithMsg(fmt.Sprintf("for %s", role.PublicId)))
|
||||
}
|
||||
return resource.(*Role), pr, rg, rowsUpdated, nil
|
||||
return resource.(*Role), pr, rg, grantScopes, rowsUpdated, nil
|
||||
}
|
||||
|
||||
// LookupRole will look up a role in the repository. If the role is not
|
||||
// found, it will return nil, nil.
|
||||
func (r *Repository) LookupRole(ctx context.Context, withPublicId string, _ ...Option) (*Role, []*PrincipalRole, []*RoleGrant, error) {
|
||||
//
|
||||
// Supported options: WithReaderWriter
|
||||
func (r *Repository) LookupRole(ctx context.Context, withPublicId string, opt ...Option) (*Role, []*PrincipalRole, []*RoleGrant, []*RoleGrantScope, error) {
|
||||
const op = "iam.(Repository).LookupRole"
|
||||
if withPublicId == "" {
|
||||
return nil, nil, nil, errors.New(ctx, errors.InvalidParameter, op, "missing public id")
|
||||
return nil, nil, nil, nil, errors.New(ctx, errors.InvalidParameter, op, "missing public id")
|
||||
}
|
||||
opts := getOpts(opt...)
|
||||
role := allocRole()
|
||||
role.PublicId = withPublicId
|
||||
var pr []*PrincipalRole
|
||||
var rg []*RoleGrant
|
||||
_, err := r.writer.DoTx(
|
||||
ctx,
|
||||
db.StdRetryCnt,
|
||||
db.ExpBackoff{},
|
||||
func(read db.Reader, w db.Writer) error {
|
||||
if err := read.LookupByPublicId(ctx, &role); err != nil {
|
||||
return errors.Wrap(ctx, err, op)
|
||||
}
|
||||
repo, err := NewRepository(ctx, read, w, r.kms)
|
||||
if err != nil {
|
||||
return errors.Wrap(ctx, err, op)
|
||||
}
|
||||
pr, err = repo.ListPrincipalRoles(ctx, withPublicId)
|
||||
if err != nil {
|
||||
return errors.Wrap(ctx, err, op)
|
||||
}
|
||||
rg, err = repo.ListRoleGrants(ctx, withPublicId)
|
||||
if err != nil {
|
||||
return errors.Wrap(ctx, err, op)
|
||||
}
|
||||
return nil
|
||||
},
|
||||
)
|
||||
var rgs []*RoleGrantScope
|
||||
|
||||
lookupFunc := func(read db.Reader, w db.Writer) error {
|
||||
if err := read.LookupByPublicId(ctx, &role); err != nil {
|
||||
return errors.Wrap(ctx, err, op)
|
||||
}
|
||||
repo, err := NewRepository(ctx, read, w, r.kms)
|
||||
if err != nil {
|
||||
return errors.Wrap(ctx, err, op)
|
||||
}
|
||||
pr, err = repo.ListPrincipalRoles(ctx, withPublicId)
|
||||
if err != nil {
|
||||
return errors.Wrap(ctx, err, op)
|
||||
}
|
||||
rg, err = repo.ListRoleGrants(ctx, withPublicId)
|
||||
if err != nil {
|
||||
return errors.Wrap(ctx, err, op)
|
||||
}
|
||||
rgs, err = repo.ListRoleGrantScopes(ctx, withPublicId)
|
||||
if err != nil {
|
||||
return errors.Wrap(ctx, err, op)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
var err error
|
||||
if opts.withReader != nil && opts.withWriter != nil {
|
||||
if !opts.withWriter.IsTx(ctx) {
|
||||
return nil, nil, nil, nil, errors.New(ctx, errors.Internal, op, "writer is not in transaction")
|
||||
}
|
||||
err = lookupFunc(opts.withReader, opts.withWriter)
|
||||
} else {
|
||||
_, err = r.writer.DoTx(
|
||||
ctx,
|
||||
db.StdRetryCnt,
|
||||
db.ExpBackoff{},
|
||||
lookupFunc,
|
||||
)
|
||||
}
|
||||
if err != nil {
|
||||
if errors.IsNotFoundError(err) {
|
||||
return nil, nil, nil, nil
|
||||
return nil, nil, nil, nil, nil
|
||||
}
|
||||
return nil, nil, nil, errors.Wrap(ctx, err, op, errors.WithMsg(fmt.Sprintf("for %s", withPublicId)))
|
||||
return nil, nil, nil, nil, errors.Wrap(ctx, err, op, errors.WithMsg(fmt.Sprintf("for %s", withPublicId)))
|
||||
}
|
||||
return &role, pr, rg, nil
|
||||
return &role, pr, rg, rgs, nil
|
||||
}
|
||||
|
||||
// DeleteRole will delete a role from the repository.
|
||||
|
||||
@@ -389,6 +389,20 @@ func (r *Repository) ListRoleGrants(ctx context.Context, roleId string, opt ...O
|
||||
return roleGrants, nil
|
||||
}
|
||||
|
||||
// ListRoleGrantScopes returns the grant scopes for the roleId and supports the WithLimit
|
||||
// option.
|
||||
func (r *Repository) ListRoleGrantScopes(ctx context.Context, roleId string, opt ...Option) ([]*RoleGrantScope, error) {
|
||||
const op = "iam.(Repository).ListRoleGrantScopes"
|
||||
if roleId == "" {
|
||||
return nil, errors.New(ctx, errors.InvalidParameter, op, "missing role id")
|
||||
}
|
||||
var roleGrantScopes []*RoleGrantScope
|
||||
if err := r.list(ctx, &roleGrantScopes, "role_id = ?", []any{roleId}, opt...); err != nil {
|
||||
return nil, errors.Wrap(ctx, err, op, errors.WithMsg("unable to lookup role grant scopes"))
|
||||
}
|
||||
return roleGrantScopes, nil
|
||||
}
|
||||
|
||||
func (r *Repository) GrantsForUser(ctx context.Context, userId string, _ ...Option) ([]perms.GrantTuple, error) {
|
||||
const op = "iam.(Repository).GrantsForUser"
|
||||
if userId == "" {
|
||||
@@ -403,9 +417,9 @@ func (r *Repository) GrantsForUser(ctx context.Context, userId string, _ ...Opti
|
||||
var query string
|
||||
switch userId {
|
||||
case globals.AnonymousUserId:
|
||||
query = fmt.Sprintf(grantsQuery, anonUser)
|
||||
query = fmt.Sprintf(grantsForUserQuery, anonUser)
|
||||
default:
|
||||
query = fmt.Sprintf(grantsQuery, authUser)
|
||||
query = fmt.Sprintf(grantsForUserQuery, authUser)
|
||||
}
|
||||
|
||||
var grants []perms.GrantTuple
|
||||
@@ -415,11 +429,9 @@ func (r *Repository) GrantsForUser(ctx context.Context, userId string, _ ...Opti
|
||||
}
|
||||
defer rows.Close()
|
||||
for rows.Next() {
|
||||
var g perms.GrantTuple
|
||||
if err := r.reader.ScanRows(ctx, rows, &g); err != nil {
|
||||
if err := r.reader.ScanRows(ctx, rows, &grants); err != nil {
|
||||
return nil, errors.Wrap(ctx, err, op)
|
||||
}
|
||||
grants = append(grants, g)
|
||||
}
|
||||
if err := rows.Err(); err != nil {
|
||||
return nil, errors.Wrap(ctx, err, op)
|
||||
|
||||
@@ -10,6 +10,7 @@ import (
|
||||
mathrand "math/rand"
|
||||
"testing"
|
||||
|
||||
"github.com/hashicorp/boundary/globals"
|
||||
"github.com/hashicorp/boundary/internal/auth/ldap"
|
||||
"github.com/hashicorp/boundary/internal/auth/ldap/store"
|
||||
"github.com/hashicorp/boundary/internal/auth/oidc"
|
||||
@@ -23,6 +24,43 @@ import (
|
||||
)
|
||||
|
||||
func TestGrantsForUser(t *testing.T) {
|
||||
conn, _ := db.TestSetup(t, "postgres")
|
||||
wrap := db.TestWrapper(t)
|
||||
|
||||
iamRepo := iam.TestRepo(t, conn, wrap)
|
||||
user := iam.TestUser(t, iamRepo, "global")
|
||||
org1, proj1 := iam.TestScopes(
|
||||
t,
|
||||
iamRepo,
|
||||
iam.WithSkipAdminRoleCreation(true),
|
||||
iam.WithSkipDefaultRoleCreation(true),
|
||||
)
|
||||
org2, proj2 := iam.TestScopes(
|
||||
t,
|
||||
iamRepo,
|
||||
iam.WithSkipAdminRoleCreation(true),
|
||||
iam.WithSkipDefaultRoleCreation(true),
|
||||
)
|
||||
t.Log("org1", org1.GetPublicId(), "proj1", proj1.GetPublicId(), "org2", org2.GetPublicId(), "proj2", proj2.GetPublicId())
|
||||
org1Proj1Role := iam.TestRole(t, conn, org1.GetPublicId(), iam.WithGrantScopeId(proj1.PublicId))
|
||||
org2Proj2Role := iam.TestRole(t, conn, org2.GetPublicId(), iam.WithGrantScopeIds([]string{globals.GrantScopeThis, globals.GrantScopeChildren}))
|
||||
globalRole := iam.TestRole(t, conn, scope.Global.String(), iam.WithGrantScopeIds([]string{globals.GrantScopeDescendants}))
|
||||
iam.TestUserRole(t, conn, org1Proj1Role.PublicId, user.PublicId)
|
||||
iam.TestUserRole(t, conn, org2Proj2Role.PublicId, user.PublicId)
|
||||
iam.TestUserRole(t, conn, globalRole.PublicId, user.PublicId)
|
||||
iam.TestRoleGrant(t, conn, org1Proj1Role.PublicId, "id=*;type=*;actions=read")
|
||||
iam.TestRoleGrant(t, conn, org2Proj2Role.PublicId, "id=*;type=*;actions=create")
|
||||
iam.TestRoleGrant(t, conn, org2Proj2Role.PublicId, "id=*;type=*;actions=list,no-op")
|
||||
iam.TestRoleGrant(t, conn, globalRole.PublicId, "id=*;type=auth-method;actions=update")
|
||||
iam.TestRoleGrant(t, conn, globalRole.PublicId, "id=*;type=credential-store;actions=list,no-op")
|
||||
// time.Sleep(10000 * time.Second)
|
||||
// ctx := context.Background()
|
||||
// grantTuples, err := iamRepo.GrantsForUser(ctx, user.PublicId)
|
||||
// require.NoError(t, err)
|
||||
// t.Log(pretty.Sprint(grantTuples))
|
||||
}
|
||||
|
||||
func TestGrantsForUserRandomized(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
conn, _ := db.TestSetup(t, "postgres")
|
||||
wrap := db.TestWrapper(t)
|
||||
|
||||
@@ -151,11 +151,11 @@ func TestRepository_CreateRole(t *testing.T) {
|
||||
if tt.wantDup {
|
||||
dup, err := NewRole(ctx, org.PublicId, tt.args.opt...)
|
||||
assert.NoError(err)
|
||||
dup, err = repo.CreateRole(context.Background(), dup, tt.args.opt...)
|
||||
dup, _, _, _, err = repo.CreateRole(context.Background(), dup, tt.args.opt...)
|
||||
assert.NoError(err)
|
||||
assert.NotNil(dup)
|
||||
}
|
||||
grp, err := repo.CreateRole(context.Background(), tt.args.role, tt.args.opt...)
|
||||
grp, _, _, _, err := repo.CreateRole(context.Background(), tt.args.role, tt.args.opt...)
|
||||
if tt.wantErr {
|
||||
assert.Error(err)
|
||||
assert.Nil(grp)
|
||||
@@ -167,7 +167,7 @@ func TestRepository_CreateRole(t *testing.T) {
|
||||
assert.NotNil(grp.CreateTime)
|
||||
assert.NotNil(grp.UpdateTime)
|
||||
|
||||
foundGrp, _, _, err := repo.LookupRole(context.Background(), grp.PublicId)
|
||||
foundGrp, _, _, _, err := repo.LookupRole(context.Background(), grp.PublicId)
|
||||
assert.NoError(err)
|
||||
assert.True(proto.Equal(foundGrp, grp))
|
||||
|
||||
@@ -395,7 +395,7 @@ func TestRepository_UpdateRole(t *testing.T) {
|
||||
_ = TestUserRole(t, conn, r.GetPublicId(), u.GetPublicId())
|
||||
_ = TestRoleGrant(t, conn, r.GetPublicId(), "ids=*;type=*;actions=*")
|
||||
r.Name = tt.args.name
|
||||
_, _, _, _, err := repo.UpdateRole(context.Background(), r, r.Version, tt.args.fieldMaskPaths, tt.args.opt...)
|
||||
_, _, _, _, _, err := repo.UpdateRole(context.Background(), r, r.Version, tt.args.fieldMaskPaths, tt.args.opt...)
|
||||
assert.NoError(err)
|
||||
}
|
||||
|
||||
@@ -427,7 +427,7 @@ func TestRepository_UpdateRole(t *testing.T) {
|
||||
updateRole.Name = tt.args.name
|
||||
updateRole.Description = tt.args.description
|
||||
|
||||
roleAfterUpdate, principals, grants, updatedRows, err := repo.UpdateRole(context.Background(), &updateRole, r.Version, tt.args.fieldMaskPaths, tt.args.opt...)
|
||||
roleAfterUpdate, principals, grants, _, updatedRows, err := repo.UpdateRole(context.Background(), &updateRole, r.Version, tt.args.fieldMaskPaths, tt.args.opt...)
|
||||
if tt.wantErr {
|
||||
assert.Error(err)
|
||||
assert.True(errors.Match(errors.T(tt.wantIsError), err))
|
||||
@@ -450,7 +450,7 @@ func TestRepository_UpdateRole(t *testing.T) {
|
||||
default:
|
||||
assert.NotEqual(r.UpdateTime, roleAfterUpdate.UpdateTime)
|
||||
}
|
||||
foundRole, _, _, err := repo.LookupRole(context.Background(), r.PublicId)
|
||||
foundRole, _, _, _, err := repo.LookupRole(context.Background(), r.PublicId)
|
||||
assert.NoError(err)
|
||||
assert.True(proto.Equal(roleAfterUpdate, foundRole))
|
||||
underlyingDB, err := conn.SqlDB(ctx)
|
||||
@@ -544,7 +544,7 @@ func TestRepository_DeleteRole(t *testing.T) {
|
||||
}
|
||||
assert.NoError(err)
|
||||
assert.Equal(tt.wantRowsDeleted, deletedRows)
|
||||
foundRole, _, _, err := repo.LookupRole(ctx, tt.args.role.PublicId)
|
||||
foundRole, _, _, _, err := repo.LookupRole(ctx, tt.args.role.PublicId)
|
||||
assert.NoError(err)
|
||||
assert.Nil(foundRole)
|
||||
|
||||
|
||||
@@ -209,7 +209,7 @@ func (r *Repository) CreateScope(ctx context.Context, s *Scope, userId string, o
|
||||
|
||||
adminRole = adminRoleRaw.(*Role)
|
||||
|
||||
msgs := make([]*oplog.Message, 0, 3)
|
||||
msgs := make([]*oplog.Message, 0, 4)
|
||||
roleTicket, err := w.GetTicket(ctx, adminRole)
|
||||
if err != nil {
|
||||
return errors.Wrap(ctx, err, op, errors.WithMsg("unable to get ticket"))
|
||||
@@ -237,6 +237,16 @@ func (r *Repository) CreateScope(ctx context.Context, s *Scope, userId string, o
|
||||
}
|
||||
msgs = append(msgs, roleGrantOplogMsgs...)
|
||||
|
||||
roleGrantScope, err := NewRoleGrantScope(ctx, adminRolePublicId, globals.GrantScopeThis)
|
||||
if err != nil {
|
||||
return errors.Wrap(ctx, err, op, errors.WithMsg("unable to create in memory role grant scope"))
|
||||
}
|
||||
roleGrantScopeOplogMsgs := make([]*oplog.Message, 0, 1)
|
||||
if err := w.CreateItems(ctx, []any{roleGrantScope}, db.NewOplogMsgs(&roleGrantScopeOplogMsgs)); err != nil {
|
||||
return errors.Wrap(ctx, err, op, errors.WithMsg("unable to add grant scope"))
|
||||
}
|
||||
msgs = append(msgs, roleGrantScopeOplogMsgs...)
|
||||
|
||||
rolePrincipal, err := NewUserRole(ctx, adminRolePublicId, userId)
|
||||
if err != nil {
|
||||
return errors.Wrap(ctx, err, op, errors.WithMsg("unable to create in memory role user"))
|
||||
@@ -272,7 +282,7 @@ func (r *Repository) CreateScope(ctx context.Context, s *Scope, userId string, o
|
||||
|
||||
defaultRole = defaultRoleRaw.(*Role)
|
||||
|
||||
msgs := make([]*oplog.Message, 0, 6)
|
||||
msgs := make([]*oplog.Message, 0, 7)
|
||||
roleTicket, err := w.GetTicket(ctx, defaultRole)
|
||||
if err != nil {
|
||||
return errors.Wrap(ctx, err, op, errors.WithMsg("unable to get ticket"))
|
||||
@@ -360,6 +370,16 @@ func (r *Repository) CreateScope(ctx context.Context, s *Scope, userId string, o
|
||||
msgs = append(msgs, roleUserOplogMsgs...)
|
||||
}
|
||||
|
||||
roleGrantScope, err := NewRoleGrantScope(ctx, defaultRolePublicId, globals.GrantScopeThis)
|
||||
if err != nil {
|
||||
return errors.Wrap(ctx, err, op, errors.WithMsg("unable to create in memory role grant scope"))
|
||||
}
|
||||
roleGrantScopeOplogMsgs := make([]*oplog.Message, 0, 1)
|
||||
if err := w.CreateItems(ctx, []any{roleGrantScope}, db.NewOplogMsgs(&roleGrantScopeOplogMsgs)); err != nil {
|
||||
return errors.Wrap(ctx, err, op, errors.WithMsg("unable to add grant scope"))
|
||||
}
|
||||
msgs = append(msgs, roleGrantScopeOplogMsgs...)
|
||||
|
||||
metadata := oplog.Metadata{
|
||||
"op-type": []string{oplog.OpType_OP_TYPE_CREATE.String()},
|
||||
"scope-id": []string{s.PublicId},
|
||||
|
||||
@@ -703,7 +703,7 @@ func TestRepository_ListUsers_Multiple_Scopes(t *testing.T) {
|
||||
})
|
||||
|
||||
const numPerScope = 10
|
||||
var total int = 3 // anon, auth, recovery
|
||||
total := 3 // anon, auth, recovery
|
||||
for i := 0; i < numPerScope; i++ {
|
||||
iam.TestUser(t, repo, "global")
|
||||
total++
|
||||
|
||||
+12
-13
@@ -34,7 +34,7 @@ var (
|
||||
)
|
||||
|
||||
// NewRole creates a new in memory role with a scope (project/org)
|
||||
// allowed options include: withDescripion, WithName, withGrantScopeId.
|
||||
// allowed options include: withDescripion, WithName.
|
||||
func NewRole(ctx context.Context, scopeId string, opt ...Option) (*Role, error) {
|
||||
const op = "iam.NewRole"
|
||||
if scopeId == "" {
|
||||
@@ -43,10 +43,9 @@ func NewRole(ctx context.Context, scopeId string, opt ...Option) (*Role, error)
|
||||
opts := getOpts(opt...)
|
||||
r := &Role{
|
||||
Role: &store.Role{
|
||||
ScopeId: scopeId,
|
||||
Name: opts.withName,
|
||||
Description: opts.withDescription,
|
||||
GrantScopeId: opts.withGrantScopeId,
|
||||
ScopeId: scopeId,
|
||||
Name: opts.withName,
|
||||
Description: opts.withDescription,
|
||||
},
|
||||
}
|
||||
return r, nil
|
||||
@@ -59,8 +58,8 @@ func allocRole() Role {
|
||||
}
|
||||
|
||||
// Clone creates a clone of the Role.
|
||||
func (r *Role) Clone() any {
|
||||
cp := proto.Clone(r.Role)
|
||||
func (role *Role) Clone() any {
|
||||
cp := proto.Clone(role.Role)
|
||||
return &Role{
|
||||
Role: cp.(*store.Role),
|
||||
}
|
||||
@@ -78,7 +77,7 @@ func (role *Role) VetForWrite(ctx context.Context, r db.Reader, opType db.OpType
|
||||
return nil
|
||||
}
|
||||
|
||||
func (u *Role) validScopeTypes() []scope.Type {
|
||||
func (role *Role) validScopeTypes() []scope.Type {
|
||||
return []scope.Type{scope.Global, scope.Org, scope.Project}
|
||||
}
|
||||
|
||||
@@ -103,9 +102,9 @@ func (*Role) Actions() map[string]action.Type {
|
||||
}
|
||||
|
||||
// TableName returns the tablename to override the default gorm table name.
|
||||
func (r *Role) TableName() string {
|
||||
if r.tableName != "" {
|
||||
return r.tableName
|
||||
func (role *Role) TableName() string {
|
||||
if role.tableName != "" {
|
||||
return role.tableName
|
||||
}
|
||||
return defaultRoleTableName
|
||||
}
|
||||
@@ -113,8 +112,8 @@ func (r *Role) TableName() string {
|
||||
// SetTableName sets the tablename and satisfies the ReplayableMessage
|
||||
// interface. If the caller attempts to set the name to "" the name will be
|
||||
// reset to the default name.
|
||||
func (r *Role) SetTableName(n string) {
|
||||
r.tableName = n
|
||||
func (role *Role) SetTableName(n string) {
|
||||
role.tableName = n
|
||||
}
|
||||
|
||||
type deletedRole struct {
|
||||
|
||||
@@ -0,0 +1,111 @@
|
||||
// Copyright (c) HashiCorp, Inc.
|
||||
// SPDX-License-Identifier: MPL-2.0
|
||||
|
||||
package iam
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/hashicorp/boundary/globals"
|
||||
"github.com/hashicorp/boundary/internal/db"
|
||||
"github.com/hashicorp/boundary/internal/errors"
|
||||
"github.com/hashicorp/boundary/internal/iam/store"
|
||||
"github.com/hashicorp/boundary/internal/types/resource"
|
||||
"github.com/hashicorp/boundary/internal/types/scope"
|
||||
"google.golang.org/protobuf/proto"
|
||||
)
|
||||
|
||||
const defaultRoleGrantScopeTable = "iam_role_grant_scope"
|
||||
|
||||
// RoleGrantScope defines the grant scopes that are assigned to a role
|
||||
type RoleGrantScope struct {
|
||||
*store.RoleGrantScope
|
||||
tableName string `gorm:"-"`
|
||||
}
|
||||
|
||||
// ensure that RoleGrantScope implements the interfaces of: Cloneable and db.VetForWriter
|
||||
var (
|
||||
_ Cloneable = (*RoleGrantScope)(nil)
|
||||
_ db.VetForWriter = (*RoleGrantScope)(nil)
|
||||
)
|
||||
|
||||
// NewRoleGrantScope creates a new in memory role grant scope
|
||||
func NewRoleGrantScope(ctx context.Context, roleId string, grantScope string, _ ...Option) (*RoleGrantScope, error) {
|
||||
const op = "iam.NewRoleGrantScope"
|
||||
if roleId == "" {
|
||||
return nil, errors.New(ctx, errors.InvalidParameter, op, "missing role id")
|
||||
}
|
||||
if grantScope == "" {
|
||||
return nil, errors.New(ctx, errors.InvalidParameter, op, "missing grant scope")
|
||||
}
|
||||
|
||||
switch {
|
||||
case grantScope == scope.Global.String(),
|
||||
grantScope == globals.GrantScopeThis,
|
||||
grantScope == globals.GrantScopeChildren,
|
||||
grantScope == globals.GrantScopeDescendants:
|
||||
case globals.ResourceInfoFromPrefix(grantScope).Type == resource.Scope:
|
||||
default:
|
||||
return nil, errors.New(ctx, errors.InvalidParameter, op, fmt.Sprintf("unknown grant scope id %q", grantScope))
|
||||
}
|
||||
rgs := &RoleGrantScope{
|
||||
RoleGrantScope: &store.RoleGrantScope{
|
||||
RoleId: roleId,
|
||||
ScopeIdOrSpecial: grantScope,
|
||||
},
|
||||
}
|
||||
return rgs, nil
|
||||
}
|
||||
|
||||
func allocRoleGrantScope() RoleGrantScope {
|
||||
return RoleGrantScope{
|
||||
RoleGrantScope: &store.RoleGrantScope{},
|
||||
}
|
||||
}
|
||||
|
||||
// Clone creates a clone of the RoleGrantScope
|
||||
func (g *RoleGrantScope) Clone() any {
|
||||
cp := proto.Clone(g.RoleGrantScope)
|
||||
return &RoleGrantScope{
|
||||
RoleGrantScope: cp.(*store.RoleGrantScope),
|
||||
}
|
||||
}
|
||||
|
||||
// VetForWrite implements db.VetForWrite() interface
|
||||
func (g *RoleGrantScope) VetForWrite(ctx context.Context, _ db.Reader, _ db.OpType, _ ...db.Option) error {
|
||||
const op = "iam.(RoleGrantScope).VetForWrite"
|
||||
if g.RoleId == "" {
|
||||
return errors.New(ctx, errors.InvalidParameter, op, "missing role id")
|
||||
}
|
||||
if g.ScopeIdOrSpecial == "" {
|
||||
return errors.New(ctx, errors.InvalidParameter, op, "missing scope id")
|
||||
}
|
||||
|
||||
switch {
|
||||
case g.ScopeIdOrSpecial == scope.Global.String(),
|
||||
g.ScopeIdOrSpecial == globals.GrantScopeThis,
|
||||
g.ScopeIdOrSpecial == globals.GrantScopeChildren,
|
||||
g.ScopeIdOrSpecial == globals.GrantScopeDescendants:
|
||||
case globals.ResourceInfoFromPrefix(g.ScopeIdOrSpecial).Type == resource.Scope:
|
||||
default:
|
||||
return errors.New(ctx, errors.InvalidParameter, op, fmt.Sprintf("unknown grant scope id %q", g.ScopeIdOrSpecial))
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// TableName returns the tablename to override the default gorm table name
|
||||
func (g *RoleGrantScope) TableName() string {
|
||||
if g.tableName != "" {
|
||||
return g.tableName
|
||||
}
|
||||
return defaultRoleGrantScopeTable
|
||||
}
|
||||
|
||||
// SetTableName sets the tablename and satisfies the ReplayableMessage
|
||||
// interface. If the caller attempts to set the name to "" the name will be
|
||||
// reset to the default name.
|
||||
func (g *RoleGrantScope) SetTableName(n string) {
|
||||
g.tableName = n
|
||||
}
|
||||
@@ -219,7 +219,6 @@ func Test_RoleUpdate(t *testing.T) {
|
||||
repo := TestRepo(t, conn, wrapper)
|
||||
id := testId(t)
|
||||
org, proj := TestScopes(t, repo)
|
||||
org2, proj2 := TestScopes(t, repo)
|
||||
rw := db.New(conn)
|
||||
type args struct {
|
||||
name string
|
||||
@@ -227,7 +226,6 @@ func Test_RoleUpdate(t *testing.T) {
|
||||
fieldMaskPaths []string
|
||||
nullPaths []string
|
||||
scopeId string
|
||||
grantScopeId string
|
||||
scopeIdOverride string
|
||||
opts []db.Option
|
||||
}
|
||||
@@ -325,80 +323,6 @@ func Test_RoleUpdate(t *testing.T) {
|
||||
wantErr: false,
|
||||
wantRowsUpdate: 1,
|
||||
},
|
||||
{
|
||||
name: "set grant scope in project with same scope",
|
||||
args: args{
|
||||
name: "set grant scope in project with same scope",
|
||||
fieldMaskPaths: []string{"Name", "GrantScopeId"},
|
||||
scopeId: proj.PublicId,
|
||||
grantScopeId: proj.PublicId,
|
||||
},
|
||||
wantRowsUpdate: 1,
|
||||
},
|
||||
{
|
||||
name: "set grant scope in org with same scope",
|
||||
args: args{
|
||||
name: "set grant scope in org with same scope",
|
||||
fieldMaskPaths: []string{"Name", "GrantScopeId"},
|
||||
scopeId: org2.PublicId,
|
||||
grantScopeId: org2.PublicId,
|
||||
},
|
||||
wantRowsUpdate: 1,
|
||||
},
|
||||
{
|
||||
name: "set grant scope in project with different scope",
|
||||
args: args{
|
||||
name: "set grant scope in project with different scope",
|
||||
fieldMaskPaths: []string{"GrantScopeId"},
|
||||
scopeId: proj.PublicId,
|
||||
grantScopeId: proj2.PublicId,
|
||||
},
|
||||
wantErr: true,
|
||||
wantErrMsg: "db.Update: invalid to set grant_scope_id to non-same scope_id when role scope type is project: integrity violation: error #1104",
|
||||
},
|
||||
{
|
||||
name: "set grant scope in org",
|
||||
args: args{
|
||||
name: "set grant scope in org",
|
||||
fieldMaskPaths: []string{"Name", "GrantScopeId"},
|
||||
scopeId: org2.PublicId,
|
||||
grantScopeId: proj2.PublicId,
|
||||
},
|
||||
wantRowsUpdate: 1,
|
||||
},
|
||||
{
|
||||
name: "set grant scope in external project",
|
||||
args: args{
|
||||
name: "set grant scope in external project",
|
||||
fieldMaskPaths: []string{"GrantScopeId"},
|
||||
scopeId: org.PublicId,
|
||||
grantScopeId: proj2.PublicId,
|
||||
},
|
||||
wantErr: true,
|
||||
wantErrMsg: "db.Update: grant_scope_id is not a child project of the role scope: integrity violation: error #1104",
|
||||
},
|
||||
{
|
||||
name: "set grant scope in global",
|
||||
args: args{
|
||||
name: "set grant scope in global",
|
||||
fieldMaskPaths: []string{"GrantScopeId"},
|
||||
scopeId: org.PublicId,
|
||||
grantScopeId: "global",
|
||||
},
|
||||
wantErr: true,
|
||||
wantErrMsg: "db.Update: grant_scope_id is not a child project of the role scope: integrity violation: error #1104",
|
||||
},
|
||||
{
|
||||
name: "set grant scope to parent",
|
||||
args: args{
|
||||
name: "set grant scope to parent",
|
||||
fieldMaskPaths: []string{"GrantScopeId"},
|
||||
scopeId: proj2.PublicId,
|
||||
grantScopeId: org2.PublicId,
|
||||
},
|
||||
wantErr: true,
|
||||
wantErrMsg: "db.Update: invalid to set grant_scope_id to non-same scope_id when role scope type is project: integrity violation: error #1104",
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
@@ -424,7 +348,6 @@ func Test_RoleUpdate(t *testing.T) {
|
||||
}
|
||||
updateRole.Name = tt.args.name
|
||||
updateRole.Description = tt.args.description
|
||||
updateRole.GrantScopeId = tt.args.grantScopeId
|
||||
|
||||
updatedRows, err := rw.Update(context.Background(), &updateRole, tt.args.fieldMaskPaths, tt.args.nullPaths, tt.args.opts...)
|
||||
if tt.wantErr {
|
||||
@@ -443,9 +366,6 @@ func Test_RoleUpdate(t *testing.T) {
|
||||
foundRole.PublicId = role.GetPublicId()
|
||||
err = rw.LookupByPublicId(context.Background(), &foundRole)
|
||||
require.NoError(err)
|
||||
if tt.args.grantScopeId == "" {
|
||||
updateRole.GrantScopeId = role.ScopeId
|
||||
}
|
||||
assert.True(proto.Equal(updateRole, foundRole))
|
||||
if len(tt.args.nullPaths) != 0 {
|
||||
underlyingDB, err := conn.SqlDB(ctx)
|
||||
|
||||
@@ -53,10 +53,6 @@ type Role struct {
|
||||
// itself and when modifying dependent items like principal roles.
|
||||
// @inject_tag: `gorm:"default:null"`
|
||||
Version uint32 `protobuf:"varint,70,opt,name=version,proto3" json:"version,omitempty" gorm:"default:null"`
|
||||
// grant_scope_id is used for delegating access; it defines a scope other than
|
||||
// the role's scope that is used when compiling these grants into an ACL
|
||||
// @inject_tag: `gorm:"default:null"`
|
||||
GrantScopeId string `protobuf:"bytes,80,opt,name=grant_scope_id,json=grantScopeId,proto3" json:"grant_scope_id,omitempty" gorm:"default:null"`
|
||||
}
|
||||
|
||||
func (x *Role) Reset() {
|
||||
@@ -140,13 +136,6 @@ func (x *Role) GetVersion() uint32 {
|
||||
return 0
|
||||
}
|
||||
|
||||
func (x *Role) GetGrantScopeId() string {
|
||||
if x != nil {
|
||||
return x.GrantScopeId
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
var File_controller_storage_iam_store_v1_role_proto protoreflect.FileDescriptor
|
||||
|
||||
var file_controller_storage_iam_store_v1_role_proto_rawDesc = []byte{
|
||||
@@ -160,7 +149,7 @@ var file_controller_storage_iam_store_v1_role_proto_rawDesc = []byte{
|
||||
0x6f, 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x2f, 0x63, 0x6f, 0x6e, 0x74, 0x72,
|
||||
0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2f, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x2f, 0x74, 0x69,
|
||||
0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x2f, 0x76, 0x31, 0x2f, 0x74, 0x69, 0x6d, 0x65, 0x73,
|
||||
0x74, 0x61, 0x6d, 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xa4, 0x03, 0x0a, 0x04, 0x52,
|
||||
0x74, 0x61, 0x6d, 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xe0, 0x02, 0x0a, 0x04, 0x52,
|
||||
0x6f, 0x6c, 0x65, 0x12, 0x1b, 0x0a, 0x09, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x5f, 0x69, 0x64,
|
||||
0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x49, 0x64,
|
||||
0x12, 0x19, 0x0a, 0x08, 0x73, 0x63, 0x6f, 0x70, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x14, 0x20, 0x01,
|
||||
@@ -182,16 +171,11 @@ var file_controller_storage_iam_store_v1_role_proto_rawDesc = []byte{
|
||||
0x74, 0x61, 0x6d, 0x70, 0x2e, 0x76, 0x31, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d,
|
||||
0x70, 0x52, 0x0a, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x18, 0x0a,
|
||||
0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x46, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x07,
|
||||
0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x48, 0x0a, 0x0e, 0x67, 0x72, 0x61, 0x6e, 0x74,
|
||||
0x5f, 0x73, 0x63, 0x6f, 0x70, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x50, 0x20, 0x01, 0x28, 0x09, 0x42,
|
||||
0x22, 0xc2, 0xdd, 0x29, 0x1e, 0x0a, 0x0c, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x53, 0x63, 0x6f, 0x70,
|
||||
0x65, 0x49, 0x64, 0x12, 0x0e, 0x67, 0x72, 0x61, 0x6e, 0x74, 0x5f, 0x73, 0x63, 0x6f, 0x70, 0x65,
|
||||
0x5f, 0x69, 0x64, 0x52, 0x0c, 0x67, 0x72, 0x61, 0x6e, 0x74, 0x53, 0x63, 0x6f, 0x70, 0x65, 0x49,
|
||||
0x64, 0x42, 0x38, 0x5a, 0x36, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f,
|
||||
0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2f, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x61,
|
||||
0x72, 0x79, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x69, 0x61, 0x6d, 0x2f,
|
||||
0x73, 0x74, 0x6f, 0x72, 0x65, 0x3b, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x62, 0x06, 0x70, 0x72, 0x6f,
|
||||
0x74, 0x6f, 0x33,
|
||||
0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x4a, 0x04, 0x08, 0x50, 0x10, 0x51, 0x42, 0x38, 0x5a,
|
||||
0x36, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x68, 0x61, 0x73, 0x68,
|
||||
0x69, 0x63, 0x6f, 0x72, 0x70, 0x2f, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x61, 0x72, 0x79, 0x2f, 0x69,
|
||||
0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x69, 0x61, 0x6d, 0x2f, 0x73, 0x74, 0x6f, 0x72,
|
||||
0x65, 0x3b, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
|
||||
}
|
||||
|
||||
var (
|
||||
|
||||
@@ -33,14 +33,14 @@ type RoleGrant struct {
|
||||
// @inject_tag: `gorm:"default:current_timestamp"`
|
||||
CreateTime *timestamp.Timestamp `protobuf:"bytes,1,opt,name=create_time,json=createTime,proto3" json:"create_time,omitempty" gorm:"default:current_timestamp"`
|
||||
// role_id is the ID of the role this is a part of
|
||||
// @inject_tag: gorm:"primary_key"
|
||||
// @inject_tag: `gorm:"primary_key"`
|
||||
RoleId string `protobuf:"bytes,2,opt,name=role_id,json=roleId,proto3" json:"role_id,omitempty" gorm:"primary_key"`
|
||||
// raw_grant is the string grant value as provided by the user
|
||||
// @inject_tag: `gorm:"default:null"`
|
||||
RawGrant string `protobuf:"bytes,3,opt,name=raw_grant,json=rawGrant,proto3" json:"raw_grant,omitempty" gorm:"default:null"`
|
||||
// canonical_grant is the canonical string representation of the grant value.
|
||||
// We use this as the unique constraint.
|
||||
// @inject_tag: gorm:"primary_key"
|
||||
// @inject_tag: `gorm:"primary_key"`
|
||||
CanonicalGrant string `protobuf:"bytes,4,opt,name=canonical_grant,json=canonicalGrant,proto3" json:"canonical_grant,omitempty" gorm:"primary_key"`
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,190 @@
|
||||
// Copyright (c) HashiCorp, Inc.
|
||||
// SPDX-License-Identifier: MPL-2.0
|
||||
|
||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||
// versions:
|
||||
// protoc-gen-go v1.31.0
|
||||
// protoc (unknown)
|
||||
// source: controller/storage/iam/store/v1/role_grant_scope.proto
|
||||
|
||||
package store
|
||||
|
||||
import (
|
||||
timestamp "github.com/hashicorp/boundary/internal/db/timestamp"
|
||||
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
|
||||
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
|
||||
reflect "reflect"
|
||||
sync "sync"
|
||||
)
|
||||
|
||||
const (
|
||||
// Verify that this generated code is sufficiently up-to-date.
|
||||
_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
|
||||
// Verify that runtime/protoimpl is sufficiently up-to-date.
|
||||
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
|
||||
)
|
||||
|
||||
type RoleGrantScope struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
// create_time from the RDBMS
|
||||
// @inject_tag: `gorm:"default:current_timestamp"`
|
||||
CreateTime *timestamp.Timestamp `protobuf:"bytes,1,opt,name=create_time,json=createTime,proto3" json:"create_time,omitempty" gorm:"default:current_timestamp"`
|
||||
// role_id is the ID of the role this is a part of
|
||||
// @inject_tag: `gorm:"primary_key"`
|
||||
RoleId string `protobuf:"bytes,2,opt,name=role_id,json=roleId,proto3" json:"role_id,omitempty" gorm:"primary_key"`
|
||||
// scope_id_or_special is the string grant scope value as provided by the
|
||||
// user, which may be one of a few special values as well
|
||||
//
|
||||
// @inject_tag: `gorm:"primary_key"`
|
||||
ScopeIdOrSpecial string `protobuf:"bytes,3,opt,name=scope_id_or_special,json=scopeIdOrSpecial,proto3" json:"scope_id_or_special,omitempty" gorm:"primary_key"`
|
||||
}
|
||||
|
||||
func (x *RoleGrantScope) Reset() {
|
||||
*x = RoleGrantScope{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_controller_storage_iam_store_v1_role_grant_scope_proto_msgTypes[0]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *RoleGrantScope) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*RoleGrantScope) ProtoMessage() {}
|
||||
|
||||
func (x *RoleGrantScope) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_controller_storage_iam_store_v1_role_grant_scope_proto_msgTypes[0]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use RoleGrantScope.ProtoReflect.Descriptor instead.
|
||||
func (*RoleGrantScope) Descriptor() ([]byte, []int) {
|
||||
return file_controller_storage_iam_store_v1_role_grant_scope_proto_rawDescGZIP(), []int{0}
|
||||
}
|
||||
|
||||
func (x *RoleGrantScope) GetCreateTime() *timestamp.Timestamp {
|
||||
if x != nil {
|
||||
return x.CreateTime
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *RoleGrantScope) GetRoleId() string {
|
||||
if x != nil {
|
||||
return x.RoleId
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *RoleGrantScope) GetScopeIdOrSpecial() string {
|
||||
if x != nil {
|
||||
return x.ScopeIdOrSpecial
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
var File_controller_storage_iam_store_v1_role_grant_scope_proto protoreflect.FileDescriptor
|
||||
|
||||
var file_controller_storage_iam_store_v1_role_grant_scope_proto_rawDesc = []byte{
|
||||
0x0a, 0x36, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2f, 0x73, 0x74, 0x6f,
|
||||
0x72, 0x61, 0x67, 0x65, 0x2f, 0x69, 0x61, 0x6d, 0x2f, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x2f, 0x76,
|
||||
0x31, 0x2f, 0x72, 0x6f, 0x6c, 0x65, 0x5f, 0x67, 0x72, 0x61, 0x6e, 0x74, 0x5f, 0x73, 0x63, 0x6f,
|
||||
0x70, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x1f, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f,
|
||||
0x6c, 0x6c, 0x65, 0x72, 0x2e, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x2e, 0x69, 0x61, 0x6d,
|
||||
0x2e, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x2e, 0x76, 0x31, 0x1a, 0x2f, 0x63, 0x6f, 0x6e, 0x74, 0x72,
|
||||
0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2f, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x2f, 0x74, 0x69,
|
||||
0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x2f, 0x76, 0x31, 0x2f, 0x74, 0x69, 0x6d, 0x65, 0x73,
|
||||
0x74, 0x61, 0x6d, 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xa5, 0x01, 0x0a, 0x0e, 0x52,
|
||||
0x6f, 0x6c, 0x65, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x53, 0x63, 0x6f, 0x70, 0x65, 0x12, 0x4b, 0x0a,
|
||||
0x0b, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01,
|
||||
0x28, 0x0b, 0x32, 0x2a, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2e,
|
||||
0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x2e, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d,
|
||||
0x70, 0x2e, 0x76, 0x31, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x0a,
|
||||
0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x17, 0x0a, 0x07, 0x72, 0x6f,
|
||||
0x6c, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x72, 0x6f, 0x6c,
|
||||
0x65, 0x49, 0x64, 0x12, 0x2d, 0x0a, 0x13, 0x73, 0x63, 0x6f, 0x70, 0x65, 0x5f, 0x69, 0x64, 0x5f,
|
||||
0x6f, 0x72, 0x5f, 0x73, 0x70, 0x65, 0x63, 0x69, 0x61, 0x6c, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09,
|
||||
0x52, 0x10, 0x73, 0x63, 0x6f, 0x70, 0x65, 0x49, 0x64, 0x4f, 0x72, 0x53, 0x70, 0x65, 0x63, 0x69,
|
||||
0x61, 0x6c, 0x42, 0x38, 0x5a, 0x36, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d,
|
||||
0x2f, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2f, 0x62, 0x6f, 0x75, 0x6e, 0x64,
|
||||
0x61, 0x72, 0x79, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x69, 0x61, 0x6d,
|
||||
0x2f, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x3b, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x62, 0x06, 0x70, 0x72,
|
||||
0x6f, 0x74, 0x6f, 0x33,
|
||||
}
|
||||
|
||||
var (
|
||||
file_controller_storage_iam_store_v1_role_grant_scope_proto_rawDescOnce sync.Once
|
||||
file_controller_storage_iam_store_v1_role_grant_scope_proto_rawDescData = file_controller_storage_iam_store_v1_role_grant_scope_proto_rawDesc
|
||||
)
|
||||
|
||||
func file_controller_storage_iam_store_v1_role_grant_scope_proto_rawDescGZIP() []byte {
|
||||
file_controller_storage_iam_store_v1_role_grant_scope_proto_rawDescOnce.Do(func() {
|
||||
file_controller_storage_iam_store_v1_role_grant_scope_proto_rawDescData = protoimpl.X.CompressGZIP(file_controller_storage_iam_store_v1_role_grant_scope_proto_rawDescData)
|
||||
})
|
||||
return file_controller_storage_iam_store_v1_role_grant_scope_proto_rawDescData
|
||||
}
|
||||
|
||||
var file_controller_storage_iam_store_v1_role_grant_scope_proto_msgTypes = make([]protoimpl.MessageInfo, 1)
|
||||
var file_controller_storage_iam_store_v1_role_grant_scope_proto_goTypes = []interface{}{
|
||||
(*RoleGrantScope)(nil), // 0: controller.storage.iam.store.v1.RoleGrantScope
|
||||
(*timestamp.Timestamp)(nil), // 1: controller.storage.timestamp.v1.Timestamp
|
||||
}
|
||||
var file_controller_storage_iam_store_v1_role_grant_scope_proto_depIdxs = []int32{
|
||||
1, // 0: controller.storage.iam.store.v1.RoleGrantScope.create_time:type_name -> controller.storage.timestamp.v1.Timestamp
|
||||
1, // [1:1] is the sub-list for method output_type
|
||||
1, // [1:1] is the sub-list for method input_type
|
||||
1, // [1:1] is the sub-list for extension type_name
|
||||
1, // [1:1] is the sub-list for extension extendee
|
||||
0, // [0:1] is the sub-list for field type_name
|
||||
}
|
||||
|
||||
func init() { file_controller_storage_iam_store_v1_role_grant_scope_proto_init() }
|
||||
func file_controller_storage_iam_store_v1_role_grant_scope_proto_init() {
|
||||
if File_controller_storage_iam_store_v1_role_grant_scope_proto != nil {
|
||||
return
|
||||
}
|
||||
if !protoimpl.UnsafeEnabled {
|
||||
file_controller_storage_iam_store_v1_role_grant_scope_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*RoleGrantScope); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
}
|
||||
type x struct{}
|
||||
out := protoimpl.TypeBuilder{
|
||||
File: protoimpl.DescBuilder{
|
||||
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
||||
RawDescriptor: file_controller_storage_iam_store_v1_role_grant_scope_proto_rawDesc,
|
||||
NumEnums: 0,
|
||||
NumMessages: 1,
|
||||
NumExtensions: 0,
|
||||
NumServices: 0,
|
||||
},
|
||||
GoTypes: file_controller_storage_iam_store_v1_role_grant_scope_proto_goTypes,
|
||||
DependencyIndexes: file_controller_storage_iam_store_v1_role_grant_scope_proto_depIdxs,
|
||||
MessageInfos: file_controller_storage_iam_store_v1_role_grant_scope_proto_msgTypes,
|
||||
}.Build()
|
||||
File_controller_storage_iam_store_v1_role_grant_scope_proto = out.File
|
||||
file_controller_storage_iam_store_v1_role_grant_scope_proto_rawDesc = nil
|
||||
file_controller_storage_iam_store_v1_role_grant_scope_proto_goTypes = nil
|
||||
file_controller_storage_iam_store_v1_role_grant_scope_proto_depIdxs = nil
|
||||
}
|
||||
+42
-4
@@ -8,6 +8,7 @@ import (
|
||||
"crypto/rand"
|
||||
"testing"
|
||||
|
||||
"github.com/hashicorp/boundary/globals"
|
||||
"github.com/hashicorp/boundary/internal/auth/store"
|
||||
"github.com/hashicorp/boundary/internal/db"
|
||||
dbassert "github.com/hashicorp/boundary/internal/db/assert"
|
||||
@@ -185,9 +186,16 @@ func TestUser(t testing.TB, repo *Repository, scopeId string, opt ...Option) *Us
|
||||
return user
|
||||
}
|
||||
|
||||
// TestRole creates a role suitable for testing.
|
||||
// TestRole creates a role suitable for testing. It will use a default grant
|
||||
// scope ID unless WithGrantScopeId is used. To prevent a grant scope from being
|
||||
// created, pass in a grant scope ID option with the value "testing-none".
|
||||
func TestRole(t testing.TB, conn *db.DB, scopeId string, opt ...Option) *Role {
|
||||
t.Helper()
|
||||
opts := getOpts(opt...)
|
||||
if opts.withGrantScopeId != nil && *opts.withGrantScopeId != "" && len(opts.withGrantScopeIds) > 0 {
|
||||
require.FailNow(t, "cannot specify both withGrantScopeId and withGrantScopeIds")
|
||||
}
|
||||
|
||||
ctx := context.Background()
|
||||
require := require.New(t)
|
||||
rw := db.New(conn)
|
||||
@@ -197,11 +205,30 @@ func TestRole(t testing.TB, conn *db.DB, scopeId string, opt ...Option) *Role {
|
||||
id, err := newRoleId(ctx)
|
||||
require.NoError(err)
|
||||
role.PublicId = id
|
||||
err = rw.Create(ctx, role)
|
||||
require.NoError(err)
|
||||
require.NoError(rw.Create(ctx, role))
|
||||
require.NotEmpty(role.PublicId)
|
||||
|
||||
opts := getOpts(opt...)
|
||||
grantScopeIds := opts.withGrantScopeIds
|
||||
if len(grantScopeIds) == 0 {
|
||||
var scpId string
|
||||
switch {
|
||||
case opts.withGrantScopeId == nil:
|
||||
scpId = globals.GrantScopeThis
|
||||
case *opts.withGrantScopeId == "":
|
||||
scpId = globals.GrantScopeThis
|
||||
default:
|
||||
scpId = *opts.withGrantScopeId
|
||||
}
|
||||
grantScopeIds = []string{scpId}
|
||||
}
|
||||
for _, gsi := range grantScopeIds {
|
||||
if gsi == "testing-none" {
|
||||
continue
|
||||
}
|
||||
gs, err := NewRoleGrantScope(ctx, id, gsi)
|
||||
require.NoError(err)
|
||||
require.NoError(rw.Create(ctx, gs))
|
||||
}
|
||||
require.Equal(opts.withDescription, role.Description)
|
||||
require.Equal(opts.withName, role.Name)
|
||||
return role
|
||||
@@ -219,6 +246,17 @@ func TestRoleGrant(t testing.TB, conn *db.DB, roleId, grant string, opt ...Optio
|
||||
return g
|
||||
}
|
||||
|
||||
func TestRoleGrantScope(t testing.TB, conn *db.DB, roleId, grantScopeId string, opt ...Option) *RoleGrantScope {
|
||||
t.Helper()
|
||||
require := require.New(t)
|
||||
rw := db.New(conn)
|
||||
|
||||
gs, err := NewRoleGrantScope(context.Background(), roleId, grantScopeId, opt...)
|
||||
require.NoError(err)
|
||||
require.NoError(rw.Create(context.Background(), gs))
|
||||
return gs
|
||||
}
|
||||
|
||||
// TestGroup creates a group suitable for testing.
|
||||
func TestGroup(t testing.TB, conn *db.DB, scopeId string, opt ...Option) *Group {
|
||||
t.Helper()
|
||||
|
||||
@@ -932,7 +932,7 @@ func Test_AnonRestrictions(t *testing.T) {
|
||||
if i == resource.Controller || i == resource.Worker {
|
||||
continue
|
||||
}
|
||||
for j := action.Type(1); j <= action.ReApplyStoragePolicy; j++ {
|
||||
for j := action.Type(1); j <= action.RemoveGrantScopes; j++ {
|
||||
id := "foobar"
|
||||
prefixes := globals.ResourcePrefixesFromType(resource.Type(i))
|
||||
if len(prefixes) > 0 {
|
||||
|
||||
@@ -88,16 +88,27 @@ message Role {
|
||||
// The mutation will fail if the version does not match the latest known good version.
|
||||
uint32 version = 80; // @gotags: `class:"public"`
|
||||
|
||||
// The Scope the grants will apply to. If the Role is at the global scope, this can be an org or project. If the Role is at an org scope, this can be a project within the org. It is invalid for this to be anything other than the Role's scope when the Role's scope is a project.
|
||||
// The Scope the grants will apply to. If the Role is at the global scope,
|
||||
// this can be an org or project. If the Role is at an org scope, this can be
|
||||
// a project within the org. It is invalid for this to be anything other than
|
||||
// the Role's scope when the Role's scope is a project.
|
||||
//
|
||||
// Deprecated: Use "grant_scope_ids" instead.
|
||||
google.protobuf.StringValue grant_scope_id = 90 [
|
||||
json_name = "grant_scope_id",
|
||||
(custom_options.v1.generate_sdk_option) = true,
|
||||
(custom_options.v1.mask_mapping) = {
|
||||
this: "grant_scope_id"
|
||||
that: "GrantScopeId"
|
||||
}
|
||||
deprecated = true,
|
||||
(custom_options.v1.generate_sdk_option) = true
|
||||
]; // @gotags: `class:"public" eventstream:"observation"`
|
||||
|
||||
// Output only. The IDs of Scopes the grants will apply to. This can include
|
||||
// the role's own scope ID, or "this" for the same behavior; specific IDs of
|
||||
// scopes that are children of the role's scope; the value "children" to match
|
||||
// all direct child scopes of the role's scope; or the value "descendants" to
|
||||
// match all descendant scopes (e.g. child scopes, children of child scopes;
|
||||
// only valid at "global" scope since it is the only one with children of
|
||||
// children).
|
||||
repeated string grant_scope_ids = 91 [json_name = "grant_scope_ids"]; // @gotags: `class:"public"`
|
||||
|
||||
// Output only. The IDs (only) of principals that are assigned to this role.
|
||||
repeated string principal_ids = 100 [json_name = "principal_ids"]; // @gotags: `class:"public" eventstream:"observation"`
|
||||
|
||||
|
||||
@@ -152,6 +152,46 @@ service RoleService {
|
||||
};
|
||||
option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = {summary: "Removes grants from a Role."};
|
||||
}
|
||||
|
||||
// AddRoleGrantScopes adds grants scopes to a Role. The provided request must
|
||||
// include the Role id which the grant scopes will be added to. An error is
|
||||
// returned if the provided id is malformed or references a non-existing
|
||||
// resource.
|
||||
rpc AddRoleGrantScopes(AddRoleGrantScopesRequest) returns (AddRoleGrantScopesResponse) {
|
||||
option (google.api.http) = {
|
||||
post: "/v1/roles/{id}:add-grant-scopes"
|
||||
body: "*"
|
||||
response_body: "item"
|
||||
};
|
||||
option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = {summary: "Adds grant scopes to a Role"};
|
||||
}
|
||||
|
||||
// SetRoleGrants sets the Role's grant scopes. Any existing grant scopes on
|
||||
// the Role are deleted if they are not included in this request. The provided
|
||||
// request must include the Role ID on which the grants will be set. If
|
||||
// missing, malformed, or referencing a non-existing resource, an error is
|
||||
// returned.
|
||||
rpc SetRoleGrantScopes(SetRoleGrantScopesRequest) returns (SetRoleGrantScopesResponse) {
|
||||
option (google.api.http) = {
|
||||
post: "/v1/roles/{id}:set-grant-scopes"
|
||||
body: "*"
|
||||
response_body: "item"
|
||||
};
|
||||
option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = {summary: "Set grant scopes for a Role, removing any grant scopes that are not specified in the request."};
|
||||
}
|
||||
|
||||
// RemoveRoleGrantScopes removes the grant scopes from the specified Role. The
|
||||
// provided request must include the Role IDs from which the grants will be
|
||||
// removed. If missing, malformed, or references a non-existing resource, an
|
||||
// error is returned.
|
||||
rpc RemoveRoleGrantScopes(RemoveRoleGrantScopesRequest) returns (RemoveRoleGrantScopesResponse) {
|
||||
option (google.api.http) = {
|
||||
post: "/v1/roles/{id}:remove-grant-scopes"
|
||||
body: "*"
|
||||
response_body: "item"
|
||||
};
|
||||
option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = {summary: "Removes grant scopes from a Role."};
|
||||
}
|
||||
}
|
||||
|
||||
message GetRoleRequest {
|
||||
@@ -305,3 +345,39 @@ message RemoveRoleGrantsRequest {
|
||||
message RemoveRoleGrantsResponse {
|
||||
resources.roles.v1.Role item = 1;
|
||||
}
|
||||
|
||||
message AddRoleGrantScopesRequest {
|
||||
string id = 1; // @gotags: `class:"public"`
|
||||
// Version is used to ensure this resource has not changed.
|
||||
// The mutation will fail if the version does not match the latest known good version.
|
||||
uint32 version = 2; // @gotags: `class:"public"`
|
||||
repeated string grant_scope_ids = 3 [json_name = "grant_scope_ids"]; // @gotags: `class:"public"`
|
||||
}
|
||||
|
||||
message AddRoleGrantScopesResponse {
|
||||
resources.roles.v1.Role item = 1;
|
||||
}
|
||||
|
||||
message SetRoleGrantScopesRequest {
|
||||
string id = 1; // @gotags: `class:"public"`
|
||||
// Version is used to ensure this resource has not changed.
|
||||
// The mutation will fail if the version does not match the latest known good version.
|
||||
uint32 version = 2; // @gotags: `class:"public"`
|
||||
repeated string grant_scope_ids = 3 [json_name = "grant_scope_ids"]; // @gotags: `class:"public"`
|
||||
}
|
||||
|
||||
message SetRoleGrantScopesResponse {
|
||||
resources.roles.v1.Role item = 1;
|
||||
}
|
||||
|
||||
message RemoveRoleGrantScopesRequest {
|
||||
string id = 1; // @gotags: `class:"public"`
|
||||
// Version is used to ensure this resource has not changed.
|
||||
// The mutation will fail if the version does not match the latest known good version.
|
||||
uint32 version = 2; // @gotags: `class:"public"`
|
||||
repeated string grant_scope_ids = 3 [json_name = "grant_scope_ids"]; // @gotags: `class:"public"`
|
||||
}
|
||||
|
||||
message RemoveRoleGrantScopesResponse {
|
||||
resources.roles.v1.Role item = 1;
|
||||
}
|
||||
@@ -47,11 +47,6 @@ message Role {
|
||||
// @inject_tag: `gorm:"default:null"`
|
||||
uint32 version = 70;
|
||||
|
||||
// grant_scope_id is used for delegating access; it defines a scope other than
|
||||
// the role's scope that is used when compiling these grants into an ACL
|
||||
// @inject_tag: `gorm:"default:null"`
|
||||
string grant_scope_id = 80 [(custom_options.v1.mask_mapping) = {
|
||||
this: "GrantScopeId"
|
||||
that: "grant_scope_id"
|
||||
}];
|
||||
// Previously grant_scope_id
|
||||
reserved 80;
|
||||
}
|
||||
@@ -15,7 +15,7 @@ message RoleGrant {
|
||||
timestamp.v1.Timestamp create_time = 1;
|
||||
|
||||
// role_id is the ID of the role this is a part of
|
||||
// @inject_tag: gorm:"primary_key"
|
||||
// @inject_tag: `gorm:"primary_key"`
|
||||
string role_id = 2;
|
||||
|
||||
// raw_grant is the string grant value as provided by the user
|
||||
@@ -24,6 +24,6 @@ message RoleGrant {
|
||||
|
||||
// canonical_grant is the canonical string representation of the grant value.
|
||||
// We use this as the unique constraint.
|
||||
// @inject_tag: gorm:"primary_key"
|
||||
// @inject_tag: `gorm:"primary_key"`
|
||||
string canonical_grant = 4;
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
// Copyright (c) HashiCorp, Inc.
|
||||
// SPDX-License-Identifier: MPL-2.0
|
||||
|
||||
syntax = "proto3";
|
||||
|
||||
package controller.storage.iam.store.v1;
|
||||
|
||||
import "controller/storage/timestamp/v1/timestamp.proto";
|
||||
|
||||
option go_package = "github.com/hashicorp/boundary/internal/iam/store;store";
|
||||
|
||||
message RoleGrantScope {
|
||||
// create_time from the RDBMS
|
||||
// @inject_tag: `gorm:"default:current_timestamp"`
|
||||
timestamp.v1.Timestamp create_time = 1;
|
||||
|
||||
// role_id is the ID of the role this is a part of
|
||||
// @inject_tag: `gorm:"primary_key"`
|
||||
string role_id = 2;
|
||||
|
||||
// scope_id_or_special is the string grant scope value as provided by the
|
||||
// user, which may be one of a few special values as well
|
||||
//
|
||||
// @inject_tag: `gorm:"primary_key"`
|
||||
string scope_id_or_special = 3;
|
||||
}
|
||||
@@ -147,18 +147,23 @@ func TestCrud(t *testing.T) {
|
||||
hcClient := hostcatalogs.NewClient(client)
|
||||
|
||||
hc, err := hcClient.Create(tc.Context(), "static", proj.GetPublicId(), hostcatalogs.WithName("foo"))
|
||||
require.NoError(err)
|
||||
checkCatalog("create", hc.Item, err, "foo", 1)
|
||||
|
||||
hc, err = hcClient.Read(tc.Context(), hc.Item.Id)
|
||||
require.NoError(err)
|
||||
checkCatalog("read", hc.Item, err, "foo", 1)
|
||||
|
||||
hc, err = hcClient.Update(tc.Context(), hc.Item.Id, hc.Item.Version, hostcatalogs.WithName("foo"))
|
||||
require.NoError(err)
|
||||
checkCatalog("update", hc.Item, err, "foo", 1)
|
||||
|
||||
hc, err = hcClient.Update(tc.Context(), hc.Item.Id, hc.Item.Version, hostcatalogs.WithName("bar"))
|
||||
require.NoError(err)
|
||||
checkCatalog("update", hc.Item, err, "bar", 2)
|
||||
|
||||
hc, err = hcClient.Update(tc.Context(), hc.Item.Id, hc.Item.Version, hostcatalogs.DefaultName())
|
||||
require.NoError(err)
|
||||
checkCatalog("update", hc.Item, err, "", 3)
|
||||
|
||||
_, err = hcClient.Delete(tc.Context(), hc.Item.Id)
|
||||
|
||||
@@ -9,6 +9,7 @@ import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/hashicorp/boundary/globals"
|
||||
"github.com/hashicorp/boundary/sdk/pbs/controller/api"
|
||||
pb "github.com/hashicorp/boundary/sdk/pbs/controller/api/resources/roles"
|
||||
"github.com/hashicorp/boundary/sdk/pbs/controller/api/resources/scopes"
|
||||
@@ -53,6 +54,10 @@ func TestRoles(t *testing.T) {
|
||||
UpdatedTime: pbNow,
|
||||
Version: 0,
|
||||
GrantScopeId: &wrapperspb.StringValue{Value: "grant-scope-id"},
|
||||
GrantScopeIds: []string{
|
||||
globals.GrantScopeThis,
|
||||
"grant-scope-id",
|
||||
},
|
||||
PrincipalIds: []string{
|
||||
"principal-id",
|
||||
},
|
||||
@@ -99,6 +104,10 @@ func TestRoles(t *testing.T) {
|
||||
UpdatedTime: pbNow,
|
||||
Version: 0,
|
||||
GrantScopeId: &wrapperspb.StringValue{Value: "grant-scope-id"},
|
||||
GrantScopeIds: []string{
|
||||
globals.GrantScopeThis,
|
||||
"grant-scope-id",
|
||||
},
|
||||
PrincipalIds: []string{
|
||||
"principal-id",
|
||||
},
|
||||
|
||||
@@ -69,7 +69,7 @@ func TestCustom(t *testing.T) {
|
||||
require.NotNil(g)
|
||||
|
||||
rc := roles.NewClient(client)
|
||||
var version uint32 = 1
|
||||
var version uint32 = 2
|
||||
|
||||
r, err := rc.Create(tc.Context(), tt.scopeId, roles.WithName("foo"))
|
||||
require.NoError(err)
|
||||
@@ -241,16 +241,16 @@ func TestCrud(t *testing.T) {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
roleClient := roles.NewClient(client)
|
||||
g, err := roleClient.Create(tc.Context(), tt.scopeId, roles.WithName("foo"))
|
||||
checkRole("create", g.Item, err, "foo", 1)
|
||||
checkRole("create", g.Item, err, "foo", 2)
|
||||
|
||||
g, err = roleClient.Read(tc.Context(), g.Item.Id)
|
||||
checkRole("read", g.Item, err, "foo", 1)
|
||||
checkRole("read", g.Item, err, "foo", 2)
|
||||
|
||||
g, err = roleClient.Update(tc.Context(), g.Item.Id, g.Item.Version, roles.WithName("bar"))
|
||||
checkRole("update", g.Item, err, "bar", 2)
|
||||
checkRole("update", g.Item, err, "bar", 3)
|
||||
|
||||
g, err = roleClient.Update(tc.Context(), g.Item.Id, g.Item.Version, roles.DefaultName())
|
||||
checkRole("update", g.Item, err, "", 3)
|
||||
checkRole("update", g.Item, err, "", 4)
|
||||
|
||||
_, err = roleClient.Delete(tc.Context(), g.Item.Id)
|
||||
require.NoError(err)
|
||||
|
||||
@@ -32,9 +32,9 @@ load _target_host_sources
|
||||
[ "$status" -eq 0 ]
|
||||
}
|
||||
|
||||
@test "boundary/target: unpriv user can not read default target" {
|
||||
@test "boundary/target: unpriv user can read default target" {
|
||||
run read_target $DEFAULT_TARGET
|
||||
[ "$status" -eq 1 ]
|
||||
[ "$status" -eq 0 ]
|
||||
}
|
||||
|
||||
@test "boundary/login: login back in as admin user" {
|
||||
|
||||
@@ -27,6 +27,14 @@ func TestListAnonymousRecursing(t *testing.T) {
|
||||
rolesClient := rolesapi.NewClient(client)
|
||||
orgScopeId := "o_1234567890"
|
||||
|
||||
// Create a custom role in org scope
|
||||
customRole, err := rolesClient.Create(tc.Context(), orgScopeId)
|
||||
require.NoError(err)
|
||||
customRole, err = rolesClient.AddPrincipals(tc.Context(), customRole.Item.Id, customRole.Item.Version, []string{"u_anon"})
|
||||
require.NoError(err)
|
||||
_, err = rolesClient.AddGrants(tc.Context(), customRole.Item.Id, customRole.Item.Version, []string{"id=*;type=auth-method;actions=list,authenticate"})
|
||||
require.NoError(err)
|
||||
|
||||
// Create an auth method in org scope for the test
|
||||
am, err := amClient.Create(tc.Context(), "password", orgScopeId)
|
||||
require.NoError(err)
|
||||
@@ -49,18 +57,19 @@ func TestListAnonymousRecursing(t *testing.T) {
|
||||
rl, err := rolesClient.List(tc.Context(), scope.Global.String())
|
||||
require.NoError(err)
|
||||
require.NotNil(rl)
|
||||
require.Len(rl.GetItems(), 2)
|
||||
require.Len(rl.GetItems(), 3)
|
||||
|
||||
// Find the non-admin one and delete that first
|
||||
adminIdx := 0
|
||||
defaultIdx := 1
|
||||
roles := rl.GetItems()
|
||||
if strings.Contains(roles[0].Name, "Default") {
|
||||
adminIdx, defaultIdx = 1, 0
|
||||
adminRoleId := ""
|
||||
for _, role := range rl.GetItems() {
|
||||
if strings.Contains(role.Name, "Admin") {
|
||||
adminRoleId = role.Id
|
||||
} else {
|
||||
_, err = rolesClient.Delete(tc.Context(), role.Id)
|
||||
require.NoError(err)
|
||||
}
|
||||
}
|
||||
_, err = rolesClient.Delete(tc.Context(), roles[defaultIdx].Id)
|
||||
require.NoError(err)
|
||||
_, err = rolesClient.Delete(tc.Context(), roles[adminIdx].Id)
|
||||
_, err = rolesClient.Delete(tc.Context(), adminRoleId)
|
||||
require.NoError(err)
|
||||
|
||||
// Make sure we can't list in global
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
package cluster
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"os"
|
||||
"path"
|
||||
@@ -15,6 +16,7 @@ import (
|
||||
"github.com/hashicorp/boundary/internal/cmd/config"
|
||||
"github.com/hashicorp/boundary/internal/daemon/controller"
|
||||
"github.com/hashicorp/boundary/internal/daemon/worker"
|
||||
"github.com/hashicorp/boundary/internal/event"
|
||||
"github.com/hashicorp/boundary/internal/tests/helper"
|
||||
"github.com/hashicorp/go-hclog"
|
||||
"github.com/stretchr/testify/require"
|
||||
@@ -22,6 +24,7 @@ import (
|
||||
|
||||
func TestUnixListener(t *testing.T) {
|
||||
require := require.New(t)
|
||||
buf := new(bytes.Buffer)
|
||||
logger := hclog.New(&hclog.LoggerOptions{
|
||||
Level: hclog.Trace,
|
||||
})
|
||||
@@ -52,6 +55,23 @@ func TestUnixListener(t *testing.T) {
|
||||
Config: conf,
|
||||
Logger: logger.Named("c1"),
|
||||
DisableOidcAuthMethodCreation: true,
|
||||
EventerConfig: &event.EventerConfig{
|
||||
ObservationsEnabled: true,
|
||||
SysEventsEnabled: true,
|
||||
Sinks: []*event.SinkConfig{
|
||||
{
|
||||
Name: "output",
|
||||
Type: event.WriterSink,
|
||||
EventTypes: []event.Type{
|
||||
event.EveryType,
|
||||
},
|
||||
WriterConfig: &event.WriterSinkTypeConfig{
|
||||
Writer: buf,
|
||||
},
|
||||
Format: event.TextHclogSinkFormat,
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
defer c1.Shutdown()
|
||||
|
||||
@@ -80,6 +100,23 @@ func TestUnixListener(t *testing.T) {
|
||||
Config: conf,
|
||||
Logger: logger.Named("c1"),
|
||||
DisableOidcAuthMethodCreation: true,
|
||||
EventerConfig: &event.EventerConfig{
|
||||
ObservationsEnabled: true,
|
||||
SysEventsEnabled: true,
|
||||
Sinks: []*event.SinkConfig{
|
||||
{
|
||||
Name: "output",
|
||||
Type: event.WriterSink,
|
||||
EventTypes: []event.Type{
|
||||
event.EveryType,
|
||||
},
|
||||
WriterConfig: &event.WriterSinkTypeConfig{
|
||||
Writer: buf,
|
||||
},
|
||||
Format: event.TextHclogSinkFormat,
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
defer c1.Shutdown()
|
||||
|
||||
|
||||
@@ -71,6 +71,9 @@ const (
|
||||
AttachStoragePolicy Type = 57
|
||||
DetachStoragePolicy Type = 58
|
||||
ReApplyStoragePolicy Type = 59
|
||||
AddGrantScopes Type = 60
|
||||
SetGrantScopes Type = 61
|
||||
RemoveGrantScopes Type = 62
|
||||
|
||||
// When adding new actions, be sure to update:
|
||||
//
|
||||
@@ -138,6 +141,9 @@ var Map = map[string]Type{
|
||||
AttachStoragePolicy.String(): AttachStoragePolicy,
|
||||
DetachStoragePolicy.String(): DetachStoragePolicy,
|
||||
ReApplyStoragePolicy.String(): ReApplyStoragePolicy,
|
||||
AddGrantScopes.String(): AddGrantScopes,
|
||||
SetGrantScopes.String(): SetGrantScopes,
|
||||
RemoveGrantScopes.String(): RemoveGrantScopes,
|
||||
}
|
||||
|
||||
var DeprecatedMap = map[string]Type{
|
||||
@@ -211,6 +217,9 @@ func (a Type) String() string {
|
||||
"attach-storage-policy",
|
||||
"detach-storage-policy",
|
||||
"reapply-storage-policy",
|
||||
"add-grant-scopes",
|
||||
"set-grant-scopes",
|
||||
"remove-grant-scopes",
|
||||
}[a]
|
||||
}
|
||||
|
||||
|
||||
@@ -261,8 +261,23 @@ type Role struct {
|
||||
// Version is used in mutation requests, after the initial creation, to ensure this resource has not changed.
|
||||
// The mutation will fail if the version does not match the latest known good version.
|
||||
Version uint32 `protobuf:"varint,80,opt,name=version,proto3" json:"version,omitempty" class:"public"` // @gotags: `class:"public"`
|
||||
// The Scope the grants will apply to. If the Role is at the global scope, this can be an org or project. If the Role is at an org scope, this can be a project within the org. It is invalid for this to be anything other than the Role's scope when the Role's scope is a project.
|
||||
// The Scope the grants will apply to. If the Role is at the global scope,
|
||||
// this can be an org or project. If the Role is at an org scope, this can be
|
||||
// a project within the org. It is invalid for this to be anything other than
|
||||
// the Role's scope when the Role's scope is a project.
|
||||
//
|
||||
// Deprecated: Use "grant_scope_ids" instead.
|
||||
//
|
||||
// Deprecated: Marked as deprecated in controller/api/resources/roles/v1/role.proto.
|
||||
GrantScopeId *wrapperspb.StringValue `protobuf:"bytes,90,opt,name=grant_scope_id,proto3" json:"grant_scope_id,omitempty" class:"public" eventstream:"observation"` // @gotags: `class:"public" eventstream:"observation"`
|
||||
// Output only. The IDs of Scopes the grants will apply to. This can include
|
||||
// the role's own scope ID, or "this" for the same behavior; specific IDs of
|
||||
// scopes that are children of the role's scope; the value "children" to match
|
||||
// all direct child scopes of the role's scope; or the value "descendants" to
|
||||
// match all descendant scopes (e.g. child scopes, children of child scopes;
|
||||
// only valid at "global" scope since it is the only one with children of
|
||||
// children).
|
||||
GrantScopeIds []string `protobuf:"bytes,91,rep,name=grant_scope_ids,proto3" json:"grant_scope_ids,omitempty" class:"public"` // @gotags: `class:"public"`
|
||||
// Output only. The IDs (only) of principals that are assigned to this role.
|
||||
PrincipalIds []string `protobuf:"bytes,100,rep,name=principal_ids,proto3" json:"principal_ids,omitempty" class:"public" eventstream:"observation"` // @gotags: `class:"public" eventstream:"observation"`
|
||||
// Output only. The principals that are assigned to this role.
|
||||
@@ -363,6 +378,7 @@ func (x *Role) GetVersion() uint32 {
|
||||
return 0
|
||||
}
|
||||
|
||||
// Deprecated: Marked as deprecated in controller/api/resources/roles/v1/role.proto.
|
||||
func (x *Role) GetGrantScopeId() *wrapperspb.StringValue {
|
||||
if x != nil {
|
||||
return x.GrantScopeId
|
||||
@@ -370,6 +386,13 @@ func (x *Role) GetGrantScopeId() *wrapperspb.StringValue {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *Role) GetGrantScopeIds() []string {
|
||||
if x != nil {
|
||||
return x.GrantScopeIds
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *Role) GetPrincipalIds() []string {
|
||||
if x != nil {
|
||||
return x.PrincipalIds
|
||||
@@ -441,7 +464,7 @@ var file_controller_api_resources_roles_v1_role_proto_rawDesc = []byte{
|
||||
0x01, 0x28, 0x0b, 0x32, 0x2c, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72,
|
||||
0x2e, 0x61, 0x70, 0x69, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x2e, 0x72,
|
||||
0x6f, 0x6c, 0x65, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x4a, 0x73, 0x6f,
|
||||
0x6e, 0x52, 0x04, 0x6a, 0x73, 0x6f, 0x6e, 0x22, 0xb9, 0x06, 0x0a, 0x04, 0x52, 0x6f, 0x6c, 0x65,
|
||||
0x6e, 0x52, 0x04, 0x6a, 0x73, 0x6f, 0x6e, 0x22, 0xc3, 0x06, 0x0a, 0x04, 0x52, 0x6f, 0x6c, 0x65,
|
||||
0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64,
|
||||
0x12, 0x1a, 0x0a, 0x08, 0x73, 0x63, 0x6f, 0x70, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x14, 0x20, 0x01,
|
||||
0x28, 0x09, 0x52, 0x08, 0x73, 0x63, 0x6f, 0x70, 0x65, 0x5f, 0x69, 0x64, 0x12, 0x43, 0x0a, 0x05,
|
||||
@@ -469,36 +492,37 @@ var file_controller_api_resources_roles_v1_role_proto_rawDesc = []byte{
|
||||
0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52,
|
||||
0x0c, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x12, 0x18, 0x0a,
|
||||
0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x50, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x07,
|
||||
0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x6c, 0x0a, 0x0e, 0x67, 0x72, 0x61, 0x6e, 0x74,
|
||||
0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x4c, 0x0a, 0x0e, 0x67, 0x72, 0x61, 0x6e, 0x74,
|
||||
0x5f, 0x73, 0x63, 0x6f, 0x70, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x5a, 0x20, 0x01, 0x28, 0x0b, 0x32,
|
||||
0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75,
|
||||
0x66, 0x2e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x42, 0x26, 0xa0,
|
||||
0xda, 0x29, 0x01, 0xc2, 0xdd, 0x29, 0x1e, 0x0a, 0x0e, 0x67, 0x72, 0x61, 0x6e, 0x74, 0x5f, 0x73,
|
||||
0x63, 0x6f, 0x70, 0x65, 0x5f, 0x69, 0x64, 0x12, 0x0c, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x53, 0x63,
|
||||
0x6f, 0x70, 0x65, 0x49, 0x64, 0x52, 0x0e, 0x67, 0x72, 0x61, 0x6e, 0x74, 0x5f, 0x73, 0x63, 0x6f,
|
||||
0x70, 0x65, 0x5f, 0x69, 0x64, 0x12, 0x24, 0x0a, 0x0d, 0x70, 0x72, 0x69, 0x6e, 0x63, 0x69, 0x70,
|
||||
0x61, 0x6c, 0x5f, 0x69, 0x64, 0x73, 0x18, 0x64, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0d, 0x70, 0x72,
|
||||
0x69, 0x6e, 0x63, 0x69, 0x70, 0x61, 0x6c, 0x5f, 0x69, 0x64, 0x73, 0x12, 0x4c, 0x0a, 0x0a, 0x70,
|
||||
0x72, 0x69, 0x6e, 0x63, 0x69, 0x70, 0x61, 0x6c, 0x73, 0x18, 0x6e, 0x20, 0x03, 0x28, 0x0b, 0x32,
|
||||
0x2c, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2e, 0x61, 0x70, 0x69,
|
||||
0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x2e, 0x72, 0x6f, 0x6c, 0x65, 0x73,
|
||||
0x2e, 0x76, 0x31, 0x2e, 0x50, 0x72, 0x69, 0x6e, 0x63, 0x69, 0x70, 0x61, 0x6c, 0x52, 0x0a, 0x70,
|
||||
0x72, 0x69, 0x6e, 0x63, 0x69, 0x70, 0x61, 0x6c, 0x73, 0x12, 0x24, 0x0a, 0x0d, 0x67, 0x72, 0x61,
|
||||
0x6e, 0x74, 0x5f, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x73, 0x18, 0x78, 0x20, 0x03, 0x28, 0x09,
|
||||
0x52, 0x0d, 0x67, 0x72, 0x61, 0x6e, 0x74, 0x5f, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x73, 0x12,
|
||||
0x41, 0x0a, 0x06, 0x67, 0x72, 0x61, 0x6e, 0x74, 0x73, 0x18, 0x82, 0x01, 0x20, 0x03, 0x28, 0x0b,
|
||||
0x32, 0x28, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2e, 0x61, 0x70,
|
||||
0x69, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x2e, 0x72, 0x6f, 0x6c, 0x65,
|
||||
0x73, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x52, 0x06, 0x67, 0x72, 0x61, 0x6e,
|
||||
0x74, 0x73, 0x12, 0x2f, 0x0a, 0x12, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x64,
|
||||
0x5f, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0xac, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52,
|
||||
0x12, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x64, 0x5f, 0x61, 0x63, 0x74, 0x69,
|
||||
0x6f, 0x6e, 0x73, 0x42, 0x4c, 0x5a, 0x4a, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f,
|
||||
0x6d, 0x2f, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2f, 0x62, 0x6f, 0x75, 0x6e,
|
||||
0x64, 0x61, 0x72, 0x79, 0x2f, 0x73, 0x64, 0x6b, 0x2f, 0x70, 0x62, 0x73, 0x2f, 0x63, 0x6f, 0x6e,
|
||||
0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x72, 0x65, 0x73, 0x6f,
|
||||
0x75, 0x72, 0x63, 0x65, 0x73, 0x2f, 0x72, 0x6f, 0x6c, 0x65, 0x73, 0x3b, 0x72, 0x6f, 0x6c, 0x65,
|
||||
0x73, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
|
||||
0x66, 0x2e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x42, 0x06, 0xa0,
|
||||
0xda, 0x29, 0x01, 0x18, 0x01, 0x52, 0x0e, 0x67, 0x72, 0x61, 0x6e, 0x74, 0x5f, 0x73, 0x63, 0x6f,
|
||||
0x70, 0x65, 0x5f, 0x69, 0x64, 0x12, 0x28, 0x0a, 0x0f, 0x67, 0x72, 0x61, 0x6e, 0x74, 0x5f, 0x73,
|
||||
0x63, 0x6f, 0x70, 0x65, 0x5f, 0x69, 0x64, 0x73, 0x18, 0x5b, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0f,
|
||||
0x67, 0x72, 0x61, 0x6e, 0x74, 0x5f, 0x73, 0x63, 0x6f, 0x70, 0x65, 0x5f, 0x69, 0x64, 0x73, 0x12,
|
||||
0x24, 0x0a, 0x0d, 0x70, 0x72, 0x69, 0x6e, 0x63, 0x69, 0x70, 0x61, 0x6c, 0x5f, 0x69, 0x64, 0x73,
|
||||
0x18, 0x64, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0d, 0x70, 0x72, 0x69, 0x6e, 0x63, 0x69, 0x70, 0x61,
|
||||
0x6c, 0x5f, 0x69, 0x64, 0x73, 0x12, 0x4c, 0x0a, 0x0a, 0x70, 0x72, 0x69, 0x6e, 0x63, 0x69, 0x70,
|
||||
0x61, 0x6c, 0x73, 0x18, 0x6e, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2c, 0x2e, 0x63, 0x6f, 0x6e, 0x74,
|
||||
0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75,
|
||||
0x72, 0x63, 0x65, 0x73, 0x2e, 0x72, 0x6f, 0x6c, 0x65, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x72,
|
||||
0x69, 0x6e, 0x63, 0x69, 0x70, 0x61, 0x6c, 0x52, 0x0a, 0x70, 0x72, 0x69, 0x6e, 0x63, 0x69, 0x70,
|
||||
0x61, 0x6c, 0x73, 0x12, 0x24, 0x0a, 0x0d, 0x67, 0x72, 0x61, 0x6e, 0x74, 0x5f, 0x73, 0x74, 0x72,
|
||||
0x69, 0x6e, 0x67, 0x73, 0x18, 0x78, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0d, 0x67, 0x72, 0x61, 0x6e,
|
||||
0x74, 0x5f, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x73, 0x12, 0x41, 0x0a, 0x06, 0x67, 0x72, 0x61,
|
||||
0x6e, 0x74, 0x73, 0x18, 0x82, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x28, 0x2e, 0x63, 0x6f, 0x6e,
|
||||
0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x72, 0x65, 0x73, 0x6f,
|
||||
0x75, 0x72, 0x63, 0x65, 0x73, 0x2e, 0x72, 0x6f, 0x6c, 0x65, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x47,
|
||||
0x72, 0x61, 0x6e, 0x74, 0x52, 0x06, 0x67, 0x72, 0x61, 0x6e, 0x74, 0x73, 0x12, 0x2f, 0x0a, 0x12,
|
||||
0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x64, 0x5f, 0x61, 0x63, 0x74, 0x69, 0x6f,
|
||||
0x6e, 0x73, 0x18, 0xac, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x12, 0x61, 0x75, 0x74, 0x68, 0x6f,
|
||||
0x72, 0x69, 0x7a, 0x65, 0x64, 0x5f, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x42, 0x4c, 0x5a,
|
||||
0x4a, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x68, 0x61, 0x73, 0x68,
|
||||
0x69, 0x63, 0x6f, 0x72, 0x70, 0x2f, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x61, 0x72, 0x79, 0x2f, 0x73,
|
||||
0x64, 0x6b, 0x2f, 0x70, 0x62, 0x73, 0x2f, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65,
|
||||
0x72, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x2f,
|
||||
0x72, 0x6f, 0x6c, 0x65, 0x73, 0x3b, 0x72, 0x6f, 0x6c, 0x65, 0x73, 0x62, 0x06, 0x70, 0x72, 0x6f,
|
||||
0x74, 0x6f, 0x33,
|
||||
}
|
||||
|
||||
var (
|
||||
|
||||
Reference in new issue
Block a user