Create a default role on new scope creation (#265)
This commit is contained in:
1 parent
e89e9d1349
commit
bb6b189513
10 files changed
+264
-70
No files matched your search
@@ -180,10 +180,10 @@ func TestRole_List(t *testing.T) {
|
||||
assert.Nil(apiErr)
|
||||
var defaultRoleIds []string
|
||||
if tt.name == "org" {
|
||||
require.True(2 == len(p1))
|
||||
require.True(len(p1) == 2)
|
||||
defaultRoleIds = []string{p1[0].Id, p1[1].Id}
|
||||
} else {
|
||||
require.Empty(p1)
|
||||
require.Len(p1, 0)
|
||||
}
|
||||
|
||||
var expected []*roles.Role
|
||||
|
||||
@@ -45,6 +45,7 @@ type RequestInfo struct {
|
||||
|
||||
// This is used for operations on the scopes collection
|
||||
scopeIdOverride string
|
||||
userIdOverride string
|
||||
|
||||
// The following are useful for tests
|
||||
DisableAuthzFailures bool
|
||||
@@ -96,6 +97,7 @@ func Verify(ctx context.Context, opt ...Option) (ret VerifyResults) {
|
||||
// context we won't catch in tests
|
||||
panic("no verifier information found in context")
|
||||
}
|
||||
opts := getOpts(opt...)
|
||||
ret.Scope = new(scopes.ScopeInfo)
|
||||
if v.requestInfo.DisableAuthEntirely {
|
||||
ret.Scope.Id = v.requestInfo.scopeIdOverride
|
||||
@@ -107,11 +109,11 @@ func Verify(ctx context.Context, opt ...Option) (ret VerifyResults) {
|
||||
case strings.HasPrefix(ret.Scope.Id, scope.Project.Prefix()):
|
||||
ret.Scope.Type = scope.Project.String()
|
||||
}
|
||||
ret.UserId = v.requestInfo.userIdOverride
|
||||
ret.Valid = true
|
||||
return
|
||||
}
|
||||
v.ctx = ctx
|
||||
opts := getOpts(opt...)
|
||||
v.requestInfo.scopeIdOverride = opts.withScopeId
|
||||
if err := v.parseAuthParams(); err != nil {
|
||||
v.logger.Trace("error reading auth parameters from URL", "url", v.requestInfo.Path, "method", v.requestInfo.Method, "error", err)
|
||||
|
||||
@@ -14,11 +14,13 @@ type Option func(*options)
|
||||
// options = how options are represented
|
||||
type options struct {
|
||||
withScopeId string
|
||||
withUserId string
|
||||
}
|
||||
|
||||
func getDefaultOptions() options {
|
||||
return options{
|
||||
withScopeId: "",
|
||||
withUserId: "",
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,3 +29,9 @@ func WithScopeId(id string) Option {
|
||||
o.withScopeId = id
|
||||
}
|
||||
}
|
||||
|
||||
func WithUserId(id string) Option {
|
||||
return func(o *options) {
|
||||
o.withUserId = id
|
||||
}
|
||||
}
|
||||
@@ -7,5 +7,6 @@ func DisabledAuthTestContext(opt ...Option) context.Context {
|
||||
reqInfo := RequestInfo{DisableAuthEntirely: true}
|
||||
opts := getOpts(opt...)
|
||||
reqInfo.scopeIdOverride = opts.withScopeId
|
||||
reqInfo.userIdOverride = opts.withUserId
|
||||
return NewVerifierContext(context.Background(), nil, nil, nil, reqInfo)
|
||||
}
|
||||
@@ -457,7 +457,7 @@ func (b *Server) CreateDevDatabase(dialect string) error {
|
||||
if err != nil {
|
||||
return fmt.Errorf("error creating new org scope: %w", err)
|
||||
}
|
||||
orgScope, err = repo.CreateScope(ctx, orgScope, iam.WithPublicId(b.DefaultOrgId))
|
||||
orgScope, err = repo.CreateScope(ctx, orgScope, "", iam.WithPublicId(b.DefaultOrgId))
|
||||
if err != nil {
|
||||
return fmt.Errorf("error persisting new org scope: %w", err)
|
||||
}
|
||||
|
||||
@@ -8,12 +8,14 @@ import (
|
||||
|
||||
"github.com/hashicorp/boundary/internal/db"
|
||||
dbcommon "github.com/hashicorp/boundary/internal/db/common"
|
||||
"github.com/hashicorp/boundary/internal/oplog"
|
||||
"github.com/hashicorp/boundary/internal/types/resource"
|
||||
"github.com/hashicorp/boundary/internal/types/scope"
|
||||
)
|
||||
|
||||
// CreateScope will create a scope in the repository and return the written
|
||||
// scope. Supported options include: WithPublicId.
|
||||
func (r *Repository) CreateScope(ctx context.Context, s *Scope, opt ...Option) (*Scope, error) {
|
||||
func (r *Repository) CreateScope(ctx context.Context, s *Scope, userId string, opt ...Option) (*Scope, error) {
|
||||
if s == nil {
|
||||
return nil, fmt.Errorf("create scope: missing scope %w", db.ErrNilParameter)
|
||||
}
|
||||
@@ -29,31 +31,162 @@ func (r *Repository) CreateScope(ctx context.Context, s *Scope, opt ...Option) (
|
||||
case scope.Global.String():
|
||||
return nil, fmt.Errorf("create scope: invalid type: %w", db.ErrInvalidParameter)
|
||||
}
|
||||
|
||||
opts := getOpts(opt...)
|
||||
var publicId string
|
||||
t := scope.Map[s.Type]
|
||||
if opts.withPublicId != "" {
|
||||
if !strings.HasPrefix(opts.withPublicId, t.Prefix()+"_") {
|
||||
return nil, fmt.Errorf("create scope: passed-in public ID %q has wrong prefix for type %q which uses prefix %q", opts.withPublicId, t.String(), t.Prefix())
|
||||
|
||||
var err error
|
||||
var scopePublicId string
|
||||
var scopeMetadata oplog.Metadata
|
||||
var scopeRaw interface{}
|
||||
{
|
||||
scopeType := scope.Map[s.Type]
|
||||
if opts.withPublicId != "" {
|
||||
if !strings.HasPrefix(opts.withPublicId, scopeType.Prefix()+"_") {
|
||||
return nil, fmt.Errorf("create scope: passed-in public ID %q has wrong prefix for type %q which uses prefix %q", opts.withPublicId, scopeType.String(), scopeType.Prefix())
|
||||
}
|
||||
scopePublicId = opts.withPublicId
|
||||
} else {
|
||||
scopePublicId, err = newScopeId(scopeType)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("create scope: error generating public id for new scope: %w", err)
|
||||
}
|
||||
}
|
||||
publicId = opts.withPublicId
|
||||
} else {
|
||||
var err error
|
||||
publicId, err = newScopeId(t)
|
||||
sc := s.Clone().(*Scope)
|
||||
sc.PublicId = scopePublicId
|
||||
scopeRaw = sc
|
||||
scopeMetadata, err = r.stdMetadata(ctx, sc)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("create scope: error generating public id %w for new scope", err)
|
||||
return nil, fmt.Errorf("create scope: error getting metadata for scope create: %w", err)
|
||||
}
|
||||
scopeMetadata["op-type"] = []string{oplog.OpType_OP_TYPE_CREATE.String()}
|
||||
}
|
||||
|
||||
var rolePublicId string
|
||||
var roleMetadata oplog.Metadata
|
||||
var role *Role
|
||||
var roleRaw interface{}
|
||||
switch userId {
|
||||
case "", "u_anon", "u_auth":
|
||||
// TODO: Cause a log entry. The repo doesn't have a logger right now,
|
||||
// and ideally we will be using context to pass around log info scoped
|
||||
// to this request for grouped display in the server log. The only
|
||||
// reason this should ever happen anyways is via the administrative
|
||||
// recovery workflow so it's already a special case.
|
||||
|
||||
// Also, stop linter from complaining
|
||||
_ = role
|
||||
|
||||
default:
|
||||
role, err = NewRole(scopePublicId)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("create scope: error instantiating new role: %w", err)
|
||||
}
|
||||
rolePublicId, err = newRoleId()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("create scope: error generating public id for new role: %w", err)
|
||||
}
|
||||
role.PublicId = rolePublicId
|
||||
role.Name = "on-scope-creation"
|
||||
role.Description = fmt.Sprintf("Role created for administration of scope %s at its creation time", scopePublicId)
|
||||
roleRaw = role
|
||||
roleMetadata = oplog.Metadata{
|
||||
"resource-public-id": []string{rolePublicId},
|
||||
"scope-id": []string{scopePublicId},
|
||||
"scope-type": []string{s.Type},
|
||||
"resource-type": []string{resource.Role.String()},
|
||||
"op-type": []string{oplog.OpType_OP_TYPE_CREATE.String()},
|
||||
}
|
||||
}
|
||||
sc := s.Clone().(*Scope)
|
||||
sc.PublicId = publicId
|
||||
resource, err := r.create(ctx, sc)
|
||||
|
||||
_, err = r.writer.DoTx(
|
||||
ctx,
|
||||
db.StdRetryCnt,
|
||||
db.ExpBackoff{},
|
||||
func(_ db.Reader, w db.Writer) error {
|
||||
if err := w.Create(
|
||||
ctx,
|
||||
scopeRaw,
|
||||
db.WithOplog(r.wrapper, scopeMetadata),
|
||||
); err != nil {
|
||||
return fmt.Errorf("error creating scope: %w", err)
|
||||
}
|
||||
|
||||
// We create a new role, then set grants and principals on it. This
|
||||
// turns into a bunch of stuff sadly because the role is the
|
||||
// aggregate.
|
||||
if roleRaw != nil {
|
||||
if err := w.Create(
|
||||
ctx,
|
||||
roleRaw,
|
||||
db.WithOplog(r.wrapper, roleMetadata),
|
||||
); err != nil {
|
||||
return fmt.Errorf("error creating role: %w", err)
|
||||
}
|
||||
|
||||
role = roleRaw.(*Role)
|
||||
|
||||
msgs := make([]*oplog.Message, 0, 3)
|
||||
roleTicket, err := w.GetTicket(role)
|
||||
if err != nil {
|
||||
return fmt.Errorf("unable to get ticket: %w", err)
|
||||
}
|
||||
|
||||
// We need to update the role version as that's the aggregate
|
||||
var roleOplogMsg oplog.Message
|
||||
rowsUpdated, err := w.Update(ctx, role, []string{"Version"}, nil, db.NewOplogMsg(&roleOplogMsg), db.WithVersion(&role.Version))
|
||||
if err != nil {
|
||||
return fmt.Errorf("unable to update role version for adding grant: %w", err)
|
||||
}
|
||||
if rowsUpdated != 1 {
|
||||
return fmt.Errorf("updated role but %d rows updated", rowsUpdated)
|
||||
}
|
||||
|
||||
msgs = append(msgs, &roleOplogMsg)
|
||||
|
||||
roleGrant, err := NewRoleGrant(rolePublicId, "id=*;actions=*")
|
||||
if err != nil {
|
||||
return fmt.Errorf("unable to create in memory role grant: %w", err)
|
||||
}
|
||||
roleGrantOplogMsgs := make([]*oplog.Message, 0, 1)
|
||||
if err := w.CreateItems(ctx, []interface{}{roleGrant}, db.NewOplogMsgs(&roleGrantOplogMsgs)); err != nil {
|
||||
return fmt.Errorf("unable to add grants: %w", err)
|
||||
}
|
||||
msgs = append(msgs, roleGrantOplogMsgs...)
|
||||
|
||||
rolePrincipal, err := NewUserRole(rolePublicId, userId)
|
||||
if err != nil {
|
||||
return fmt.Errorf("unable to create in memory role user: %w", err)
|
||||
}
|
||||
roleUserOplogMsgs := make([]*oplog.Message, 0, 1)
|
||||
if err := w.CreateItems(ctx, []interface{}{rolePrincipal}, db.NewOplogMsgs(&roleUserOplogMsgs)); err != nil {
|
||||
return fmt.Errorf("unable to add grants: %w", err)
|
||||
}
|
||||
msgs = append(msgs, roleUserOplogMsgs...)
|
||||
|
||||
s := scopeRaw.(*Scope)
|
||||
|
||||
metadata := oplog.Metadata{
|
||||
"op-type": []string{oplog.OpType_OP_TYPE_CREATE.String()},
|
||||
"scope-id": []string{s.PublicId},
|
||||
"scope-type": []string{s.Type},
|
||||
"resource-public-id": []string{role.PublicId},
|
||||
}
|
||||
if err := w.WriteOplogEntryWith(ctx, r.wrapper, roleTicket, metadata, msgs); err != nil {
|
||||
return fmt.Errorf("unable to write oplog: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
},
|
||||
)
|
||||
|
||||
if err != nil {
|
||||
if db.IsUniqueError(err) {
|
||||
return nil, fmt.Errorf("create scope: scope %s/%s already exists: %w", sc.PublicId, sc.Name, db.ErrNotUnique)
|
||||
return nil, fmt.Errorf("create scope: scope %s/%s already exists: %w", scopePublicId, s.Name, db.ErrNotUnique)
|
||||
}
|
||||
return nil, fmt.Errorf("create scope: %w for %s", err, sc.PublicId)
|
||||
return nil, fmt.Errorf("create scope: id %s got error: %w", scopePublicId, err)
|
||||
}
|
||||
return resource.(*Scope), nil
|
||||
return scopeRaw.(*Scope), nil
|
||||
}
|
||||
|
||||
// UpdateScope will update a scope in the repository and return the written
|
||||
|
||||
@@ -30,7 +30,7 @@ func Test_Repository_Scope_Create(t *testing.T) {
|
||||
|
||||
s, err := NewOrg(WithName(id))
|
||||
require.NoError(err)
|
||||
s, err = repo.CreateScope(context.Background(), s)
|
||||
s, err = repo.CreateScope(context.Background(), s, "")
|
||||
require.NoError(err)
|
||||
require.NotNil(s)
|
||||
assert.NotEmpty(s.GetPublicId())
|
||||
@@ -53,7 +53,7 @@ func Test_Repository_Scope_Create(t *testing.T) {
|
||||
require.NoError(err)
|
||||
s, err := NewOrg()
|
||||
require.NoError(err)
|
||||
s, err = repo.CreateScope(context.Background(), s, WithPublicId(publicId))
|
||||
s, err = repo.CreateScope(context.Background(), s, "", WithPublicId(publicId))
|
||||
require.NoError(err)
|
||||
require.NotNil(s)
|
||||
assert.Equal(publicId, s.GetPublicId())
|
||||
@@ -74,7 +74,7 @@ func Test_Repository_Scope_Create(t *testing.T) {
|
||||
|
||||
s, err := NewOrg(WithName(id))
|
||||
require.NoError(err)
|
||||
s, err = repo.CreateScope(context.Background(), s)
|
||||
s, err = repo.CreateScope(context.Background(), s, "")
|
||||
require.NoError(err)
|
||||
require.NotNil(s)
|
||||
assert.NotEmpty(s.GetPublicId())
|
||||
@@ -82,7 +82,7 @@ func Test_Repository_Scope_Create(t *testing.T) {
|
||||
|
||||
s2, err := NewOrg(WithName(id))
|
||||
require.NoError(err)
|
||||
s2, err = repo.CreateScope(context.Background(), s2)
|
||||
s2, err = repo.CreateScope(context.Background(), s2, "")
|
||||
require.Error(err)
|
||||
assert.Nil(s2)
|
||||
})
|
||||
@@ -96,7 +96,7 @@ func Test_Repository_Scope_Create(t *testing.T) {
|
||||
|
||||
s, err := NewOrg(WithName(id))
|
||||
require.NoError(err)
|
||||
s, err = repo.CreateScope(context.Background(), s)
|
||||
s, err = repo.CreateScope(context.Background(), s, "")
|
||||
require.NoError(err)
|
||||
require.NotNil(s)
|
||||
assert.NotEmpty(s.GetPublicId())
|
||||
@@ -104,13 +104,13 @@ func Test_Repository_Scope_Create(t *testing.T) {
|
||||
|
||||
p, err := NewProject(s.PublicId, WithName(id))
|
||||
require.NoError(err)
|
||||
p, err = repo.CreateScope(context.Background(), p)
|
||||
p, err = repo.CreateScope(context.Background(), p, "")
|
||||
require.NoError(err)
|
||||
require.NotEmpty(p.PublicId)
|
||||
|
||||
p2, err := NewProject(s.PublicId, WithName(id))
|
||||
require.NoError(err)
|
||||
p2, err = repo.CreateScope(context.Background(), p2)
|
||||
p2, err = repo.CreateScope(context.Background(), p2, "")
|
||||
assert.Error(err)
|
||||
assert.Nil(p2)
|
||||
})
|
||||
@@ -178,7 +178,7 @@ func Test_Repository_Scope_Update(t *testing.T) {
|
||||
|
||||
project, err := NewProject(s.PublicId)
|
||||
require.NoError(err)
|
||||
project, err = repo.CreateScope(context.Background(), project)
|
||||
project, err = repo.CreateScope(context.Background(), project, "")
|
||||
require.NoError(err)
|
||||
require.NotNil(project)
|
||||
|
||||
|
||||
@@ -24,14 +24,14 @@ func TestScopes(t *testing.T, conn *gorm.DB) (org *Scope, prj *Scope) {
|
||||
|
||||
org, err = NewOrg()
|
||||
require.NoError(err)
|
||||
org, err = repo.CreateScope(context.Background(), org)
|
||||
org, err = repo.CreateScope(context.Background(), org, "")
|
||||
require.NoError(err)
|
||||
require.NotNil(org)
|
||||
require.NotEmpty(org.GetPublicId())
|
||||
|
||||
prj, err = NewProject(org.GetPublicId())
|
||||
require.NoError(err)
|
||||
prj, err = repo.CreateScope(context.Background(), prj)
|
||||
prj, err = repo.CreateScope(context.Background(), prj, "")
|
||||
require.NoError(err)
|
||||
require.NotNil(prj)
|
||||
require.NotEmpty(prj.GetPublicId())
|
||||
@@ -49,7 +49,7 @@ func testOrg(t *testing.T, conn *gorm.DB, name, description string) (org *Scope)
|
||||
|
||||
o, err := NewOrg(WithDescription(description), WithName(name))
|
||||
require.NoError(err)
|
||||
o, err = repo.CreateScope(context.Background(), o)
|
||||
o, err = repo.CreateScope(context.Background(), o, "")
|
||||
require.NoError(err)
|
||||
require.NotNil(o)
|
||||
require.NotEmpty(o.GetPublicId())
|
||||
@@ -66,7 +66,7 @@ func testProject(t *testing.T, conn *gorm.DB, orgId string, opt ...Option) *Scop
|
||||
|
||||
p, err := NewProject(orgId, opt...)
|
||||
require.NoError(err)
|
||||
p, err = repo.CreateScope(context.Background(), p)
|
||||
p, err = repo.CreateScope(context.Background(), p, "")
|
||||
require.NoError(err)
|
||||
require.NotNil(p)
|
||||
require.NotEmpty(p.GetPublicId())
|
||||
|
||||
@@ -106,7 +106,7 @@ func (s Service) CreateScope(ctx context.Context, req *pbs.CreateScopeRequest) (
|
||||
if err := validateCreateRequest(req); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
p, err := s.createInRepo(ctx, authResults.Scope, req.GetItem())
|
||||
p, err := s.createInRepo(ctx, authResults, req.GetItem())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -162,7 +162,7 @@ func (s Service) getFromRepo(ctx context.Context, id string) (*pb.Scope, error)
|
||||
return ToProto(p), nil
|
||||
}
|
||||
|
||||
func (s Service) createInRepo(ctx context.Context, parentScope *scopes.ScopeInfo, item *pb.Scope) (*pb.Scope, error) {
|
||||
func (s Service) createInRepo(ctx context.Context, authResults auth.VerifyResults, item *pb.Scope) (*pb.Scope, error) {
|
||||
var opts []iam.Option
|
||||
if item.GetName() != nil {
|
||||
opts = append(opts, iam.WithName(item.GetName().GetValue()))
|
||||
@@ -171,6 +171,7 @@ func (s Service) createInRepo(ctx context.Context, parentScope *scopes.ScopeInfo
|
||||
opts = append(opts, iam.WithDescription(item.GetDescription().GetValue()))
|
||||
}
|
||||
|
||||
parentScope := authResults.Scope
|
||||
var iamScope *iam.Scope
|
||||
var err error
|
||||
switch parentScope.GetType() {
|
||||
@@ -186,7 +187,7 @@ func (s Service) createInRepo(ctx context.Context, parentScope *scopes.ScopeInfo
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
out, err := repo.CreateScope(ctx, iamScope)
|
||||
out, err := repo.CreateScope(ctx, iamScope, authResults.UserId)
|
||||
if err != nil {
|
||||
return nil, status.Errorf(codes.Internal, "Unable to create scope: %v.", err)
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ package scopes_test
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
@@ -211,7 +212,7 @@ func TestList(t *testing.T) {
|
||||
for i := 0; i < 10; i++ {
|
||||
newO, err := iam.NewOrg()
|
||||
require.NoError(t, err)
|
||||
o, err := repo.CreateScope(context.Background(), newO)
|
||||
o, err := repo.CreateScope(context.Background(), newO, "")
|
||||
require.NoError(t, err)
|
||||
wantOrgs = append(wantOrgs, &pb.Scope{
|
||||
Id: o.GetPublicId(),
|
||||
@@ -228,7 +229,7 @@ func TestList(t *testing.T) {
|
||||
for i := 0; i < 10; i++ {
|
||||
newP, err := iam.NewProject(oWithProjects.GetPublicId())
|
||||
require.NoError(t, err)
|
||||
p, err := repo.CreateScope(context.Background(), newP)
|
||||
p, err := repo.CreateScope(context.Background(), newP, "")
|
||||
require.NoError(t, err)
|
||||
wantProjects = append(wantProjects, &pb.Scope{
|
||||
Id: p.GetPublicId(),
|
||||
@@ -393,12 +394,24 @@ func TestDelete_twice(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestCreate(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
require := require.New(t)
|
||||
defaultOrg, defaultProj, repo := createDefaultScopesAndRepo(t)
|
||||
defaultOrg, defaultProj, repoFn := createDefaultScopesAndRepo(t)
|
||||
defaultProjCreated, err := ptypes.Timestamp(defaultProj.GetCreateTime().GetTimestamp())
|
||||
require.NoError(err, "Error converting proto to timestamp.")
|
||||
toMerge := &pbs.CreateScopeRequest{}
|
||||
|
||||
repo, err := repoFn()
|
||||
require.NoError(err)
|
||||
globalUser, err := iam.NewUser(scope.Global.String())
|
||||
require.NoError(err)
|
||||
globalUser, err = repo.CreateUser(ctx, globalUser)
|
||||
require.NoError(err)
|
||||
orgUser, err := iam.NewUser(defaultOrg.GetPublicId())
|
||||
require.NoError(err)
|
||||
orgUser, err = repo.CreateUser(ctx, orgUser)
|
||||
require.NoError(err)
|
||||
|
||||
cases := []struct {
|
||||
name string
|
||||
scopeId string
|
||||
@@ -477,39 +490,75 @@ func TestCreate(t *testing.T) {
|
||||
},
|
||||
}
|
||||
for _, tc := range cases {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
req := proto.Clone(toMerge).(*pbs.CreateScopeRequest)
|
||||
proto.Merge(req, tc.req)
|
||||
|
||||
s, err := scopes.NewService(repo)
|
||||
require.NoError(err, "Error when getting new project service.")
|
||||
|
||||
got, gErr := s.CreateScope(auth.DisabledAuthTestContext(auth.WithScopeId(tc.scopeId)), req)
|
||||
assert.Equal(tc.errCode, status.Code(gErr), "CreateScope(%+v) got error %v, wanted %v", req, gErr, tc.errCode)
|
||||
if got != nil {
|
||||
assert.Contains(got.GetUri(), tc.res.Uri)
|
||||
switch tc.scopeId {
|
||||
case "global":
|
||||
assert.True(strings.HasPrefix(got.GetItem().GetId(), "o_"))
|
||||
default:
|
||||
assert.True(strings.HasPrefix(got.GetItem().GetId(), "p_"))
|
||||
for _, withUserId := range []bool{false, true} {
|
||||
t.Run(fmt.Sprintf("%s-userid-%t", tc.name, withUserId), func(t *testing.T) {
|
||||
var name string
|
||||
if tc.req != nil && tc.req.GetItem() != nil && tc.req.GetItem().GetName() != nil {
|
||||
name = tc.req.GetItem().GetName().GetValue()
|
||||
localName := name
|
||||
defer func() {
|
||||
tc.res.GetItem().GetName().Value = localName
|
||||
}()
|
||||
}
|
||||
gotCreateTime, err := ptypes.Timestamp(got.GetItem().GetCreatedTime())
|
||||
require.NoError(err, "Error converting proto to timestamp.")
|
||||
gotUpdateTime, err := ptypes.Timestamp(got.GetItem().GetUpdatedTime())
|
||||
require.NoError(err, "Error converting proto to timestamp.")
|
||||
// Verify it is a project created after the test setup's default project
|
||||
assert.True(gotCreateTime.After(defaultProjCreated), "New scope should have been created after default project. Was created %v, which is after %v", gotCreateTime, defaultProjCreated)
|
||||
assert.True(gotUpdateTime.After(defaultProjCreated), "New scope should have been updated after default project. Was updated %v, which is after %v", gotUpdateTime, defaultProjCreated)
|
||||
assert := assert.New(t)
|
||||
req := proto.Clone(toMerge).(*pbs.CreateScopeRequest)
|
||||
proto.Merge(req, tc.req)
|
||||
|
||||
// Clear all values which are hard to compare against.
|
||||
got.Uri, tc.res.Uri = "", ""
|
||||
got.Item.Id, tc.res.Item.Id = "", ""
|
||||
got.Item.CreatedTime, got.Item.UpdatedTime, tc.res.Item.CreatedTime, tc.res.Item.UpdatedTime = nil, nil, nil, nil
|
||||
}
|
||||
assert.Empty(cmp.Diff(got, tc.res, protocmp.Transform()), "CreateScope(%q) got response %q, wanted %q", req, got, tc.res)
|
||||
})
|
||||
s, err := scopes.NewService(repoFn)
|
||||
require.NoError(err, "Error when getting new project service.")
|
||||
|
||||
if name != "" {
|
||||
name = fmt.Sprintf("%s-%t", name, withUserId)
|
||||
req.GetItem().GetName().Value = name
|
||||
}
|
||||
var userId string
|
||||
if withUserId {
|
||||
if tc.scopeId == scope.Global.String() {
|
||||
userId = globalUser.GetPublicId()
|
||||
} else {
|
||||
userId = orgUser.GetPublicId()
|
||||
}
|
||||
assert.NotEmpty(userId)
|
||||
}
|
||||
got, gErr := s.CreateScope(auth.DisabledAuthTestContext(auth.WithScopeId(tc.scopeId), auth.WithUserId(userId)), req)
|
||||
assert.Equal(tc.errCode, status.Code(gErr), "CreateScope(%+v) got error %v, wanted %v", req, gErr, tc.errCode)
|
||||
if got != nil {
|
||||
assert.Contains(got.GetUri(), tc.res.Uri)
|
||||
switch tc.scopeId {
|
||||
case "global":
|
||||
assert.True(strings.HasPrefix(got.GetItem().GetId(), "o_"))
|
||||
default:
|
||||
assert.True(strings.HasPrefix(got.GetItem().GetId(), "p_"))
|
||||
}
|
||||
gotCreateTime, err := ptypes.Timestamp(got.GetItem().GetCreatedTime())
|
||||
require.NoError(err, "Error converting proto to timestamp.")
|
||||
gotUpdateTime, err := ptypes.Timestamp(got.GetItem().GetUpdatedTime())
|
||||
require.NoError(err, "Error converting proto to timestamp.")
|
||||
// Verify it is a project created after the test setup's default project
|
||||
assert.True(gotCreateTime.After(defaultProjCreated), "New scope should have been created after default project. Was created %v, which is after %v", gotCreateTime, defaultProjCreated)
|
||||
assert.True(gotUpdateTime.After(defaultProjCreated), "New scope should have been updated after default project. Was updated %v, which is after %v", gotUpdateTime, defaultProjCreated)
|
||||
|
||||
if withUserId {
|
||||
repo, err := repoFn()
|
||||
require.NoError(err)
|
||||
roles, err := repo.ListRoles(ctx, got.GetItem().GetId())
|
||||
require.NoError(err)
|
||||
require.Len(roles, 1)
|
||||
role := roles[0]
|
||||
assert.Equal("on-scope-creation", role.GetName())
|
||||
assert.Equal(fmt.Sprintf("Role created for administration of scope %s at its creation time", got.GetItem().GetId()), role.GetDescription())
|
||||
}
|
||||
|
||||
// Clear all values which are hard to compare against.
|
||||
assert.Equal(name, got.GetItem().GetName().GetValue())
|
||||
got.Item.Name = tc.res.GetItem().GetName()
|
||||
got.Uri, tc.res.Uri = "", ""
|
||||
got.Item.Id, tc.res.Item.Id = "", ""
|
||||
got.Item.CreatedTime, got.Item.UpdatedTime, tc.res.Item.CreatedTime, tc.res.Item.UpdatedTime = nil, nil, nil, nil
|
||||
}
|
||||
assert.Empty(cmp.Diff(tc.res, got, protocmp.Transform()), "CreateScope(%q) got response %q, wanted %q", req, got, tc.res)
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user