Scopes type field and types in updates allowed (#335)

pull/339/head
Todd Knight 6 years ago committed by GitHub
parent c3ecea172d
commit 99d5456d7a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -22,6 +22,7 @@ type Scope struct {
CreatedTime time.Time `json:"created_time,omitempty"`
UpdatedTime time.Time `json:"updated_time,omitempty"`
Version uint32 `json:"version,omitempty"`
Type string `json:"type,omitempty"`
}
// Client is a client for this collection

@ -4686,6 +4686,10 @@
"format": "int64",
"description": "The version can be used in subsequent write requests to ensure this\nresource has not changed and to fail the write if it has.\nOutput only.",
"readOnly": true
},
"type": {
"type": "string",
"title": "The type of the resource"
}
},
"title": "Scope contains all fields related to a Scope resource"

@ -145,6 +145,8 @@ type Scope struct {
// resource has not changed and to fail the write if it has.
// Output only.
Version uint32 `protobuf:"varint,80,opt,name=version,proto3" json:"version,omitempty"`
// The type of the resource
Type string `protobuf:"bytes,90,opt,name=type,proto3" json:"type,omitempty"`
}
func (x *Scope) Reset() {
@ -235,6 +237,13 @@ func (x *Scope) GetVersion() uint32 {
return 0
}
func (x *Scope) GetType() string {
if x != nil {
return x.Type
}
return ""
}
var File_controller_api_resources_scopes_v1_scope_proto protoreflect.FileDescriptor
var file_controller_api_resources_scopes_v1_scope_proto_rawDesc = []byte{
@ -259,7 +268,7 @@ var file_controller_api_resources_scopes_v1_scope_proto_rawDesc = []byte{
0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x28, 0x0a, 0x0f, 0x70, 0x61, 0x72,
0x65, 0x6e, 0x74, 0x5f, 0x73, 0x63, 0x6f, 0x70, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x05, 0x20, 0x01,
0x28, 0x09, 0x52, 0x0f, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x5f, 0x73, 0x63, 0x6f, 0x70, 0x65,
0x5f, 0x69, 0x64, 0x22, 0xbe, 0x03, 0x0a, 0x05, 0x53, 0x63, 0x6f, 0x70, 0x65, 0x12, 0x0e, 0x0a,
0x5f, 0x69, 0x64, 0x22, 0xd2, 0x03, 0x0a, 0x05, 0x53, 0x63, 0x6f, 0x70, 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, 0x73, 0x63, 0x6f,
@ -287,13 +296,14 @@ var file_controller_api_resources_scopes_v1_scope_proto_rawDesc = []byte{
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, 0x42, 0x53, 0x5a, 0x51, 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, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x2f, 0x73, 0x63, 0x6f, 0x70,
0x65, 0x73, 0x3b, 0x73, 0x63, 0x6f, 0x70, 0x65, 0x73, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f,
0x33,
0x73, 0x69, 0x6f, 0x6e, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x5a, 0x20, 0x01,
0x28, 0x09, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x42, 0x53, 0x5a, 0x51, 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, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x2f,
0x73, 0x63, 0x6f, 0x70, 0x65, 0x73, 0x3b, 0x73, 0x63, 0x6f, 0x70, 0x65, 0x73, 0x62, 0x06, 0x70,
0x72, 0x6f, 0x74, 0x6f, 0x33,
}
var (

@ -61,4 +61,7 @@ message Scope {
// resource has not changed and to fail the write if it has.
// Output only.
uint32 version = 80;
// The type of the resource
string type = 90;
}

@ -419,7 +419,20 @@ func validateCreateRequest(req *pbs.CreateAccountRequest) error {
}
func validateUpdateRequest(req *pbs.UpdateAccountRequest) error {
return handlers.ValidateUpdateRequest(password.AccountPrefix, req, req.GetItem(), handlers.NoopValidatorFn)
return handlers.ValidateUpdateRequest(password.AccountPrefix, req, req.GetItem(), func() map[string]string {
badFields := map[string]string{}
switch auth.SubtypeFromId(req.GetId()) {
case auth.PasswordSubtype:
if req.GetItem().GetType() != "" && req.GetItem().GetType() != auth.PasswordSubtype.String() {
badFields["type"] = "Cannot modify resource type."
}
pwAttrs := &pb.PasswordAccountAttributes{}
if err := handlers.StructToProto(req.GetItem().GetAttributes(), pwAttrs); err != nil {
badFields["attributes"] = "Attribute fields do not match the expected format."
}
}
return badFields
})
}
func validateDeleteRequest(req *pbs.DeleteAccountRequest) error {

@ -517,6 +517,7 @@ func TestUpdate(t *testing.T) {
Item: &pb.Account{
Name: &wrapperspb.StringValue{Value: "new"},
Description: &wrapperspb.StringValue{Value: "desc"},
Type: "password",
},
},
res: &pbs.UpdateAccountResponse{
@ -540,6 +541,7 @@ func TestUpdate(t *testing.T) {
Item: &pb.Account{
Name: &wrapperspb.StringValue{Value: "new"},
Description: &wrapperspb.StringValue{Value: "desc"},
Type: "password",
},
},
res: &pbs.UpdateAccountResponse{
@ -565,6 +567,19 @@ func TestUpdate(t *testing.T) {
},
errCode: codes.InvalidArgument,
},
{
name: "Cant change type",
req: &pbs.UpdateAccountRequest{
UpdateMask: &field_mask.FieldMask{
Paths: []string{"name"},
},
Item: &pb.Account{
Name: &wrapperspb.StringValue{Value: ""},
Type: "oidc",
},
},
errCode: codes.InvalidArgument,
},
{
name: "No Paths in Mask",
req: &pbs.UpdateAccountRequest{

@ -362,8 +362,17 @@ func validateCreateRequest(req *pbs.CreateAuthMethodRequest) error {
func validateUpdateRequest(req *pbs.UpdateAuthMethodRequest) error {
return handlers.ValidateUpdateRequest(password.AuthMethodPrefix, req, req.GetItem(), func() map[string]string {
badFields := map[string]string{}
if req.GetItem().GetType() != "" {
badFields["type"] = "This is a read only field and cannot be specified in an update request."
switch auth.SubtypeFromId(req.GetId()) {
case auth.PasswordSubtype:
if req.GetItem().GetType() != "" && auth.SubtypeFromType(req.GetItem().GetType()) != auth.PasswordSubtype {
badFields["type"] = "Cannot modify resource type."
}
pwAttrs := &pb.PasswordAuthMethodAttributes{}
if err := handlers.StructToProto(req.GetItem().GetAttributes(), pwAttrs); err != nil {
badFields["attributes"] = "Attribute fields do not match the expected format."
}
default:
badFields["id"] = "Incorrectly formatted identifier."
}
return badFields
})

@ -529,6 +529,7 @@ func TestUpdate(t *testing.T) {
Item: &pb.AuthMethod{
Name: &wrapperspb.StringValue{Value: "new"},
Description: &wrapperspb.StringValue{Value: "desc"},
Type: "password",
},
},
res: &pbs.UpdateAuthMethodResponse{
@ -550,11 +551,12 @@ func TestUpdate(t *testing.T) {
name: "Multiple Paths in single string",
req: &pbs.UpdateAuthMethodRequest{
UpdateMask: &field_mask.FieldMask{
Paths: []string{"name,description"},
Paths: []string{"name,description,type"},
},
Item: &pb.AuthMethod{
Name: &wrapperspb.StringValue{Value: "new"},
Description: &wrapperspb.StringValue{Value: "desc"},
Type: "password",
},
},
res: &pbs.UpdateAuthMethodResponse{
@ -604,6 +606,17 @@ func TestUpdate(t *testing.T) {
},
errCode: codes.InvalidArgument,
},
{
name: "Cant change type",
req: &pbs.UpdateAuthMethodRequest{
UpdateMask: &field_mask.FieldMask{Paths: []string{"name", "type"}},
Item: &pb.AuthMethod{
Name: &wrapperspb.StringValue{Value: "updated name"},
Type: "oidc",
},
},
errCode: codes.InvalidArgument,
},
{
name: "Unset Name",
req: &pbs.UpdateAuthMethodRequest{

@ -14,6 +14,7 @@ import (
"github.com/hashicorp/boundary/internal/servers/controller/handlers"
"github.com/hashicorp/boundary/internal/types/action"
"github.com/hashicorp/boundary/internal/types/resource"
"github.com/hashicorp/boundary/internal/types/scope"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
"google.golang.org/protobuf/types/known/wrapperspb"
@ -314,6 +315,9 @@ func validateGetRequest(req *pbs.GetHostCatalogRequest) error {
func validateCreateRequest(req *pbs.CreateHostCatalogRequest) error {
return handlers.ValidateCreateRequest(req.GetItem(), func() map[string]string {
badFields := map[string]string{}
if !handlers.ValidId(scope.Project.Prefix(), req.GetItem().GetScopeId()) {
badFields["scope_id"] = "This field must be a valid project scope id."
}
switch host.SubtypeFromType(req.GetItem().GetType()) {
case host.StaticSubtype:
default:
@ -326,8 +330,11 @@ func validateCreateRequest(req *pbs.CreateHostCatalogRequest) error {
func validateUpdateRequest(req *pbs.UpdateHostCatalogRequest) error {
return handlers.ValidateUpdateRequest(static.HostCatalogPrefix, req, req.GetItem(), func() map[string]string {
badFields := map[string]string{}
if req.GetItem().GetType() != "" {
badFields["type"] = "This is a read only field and cannot be specified in an update request."
switch host.SubtypeFromId(req.GetId()) {
case host.StaticSubtype:
if req.GetItem().GetType() != "" && host.SubtypeFromType(req.GetItem().GetType()) != host.StaticSubtype {
badFields["type"] = "Cannot modify resource type."
}
}
return badFields
})
@ -339,6 +346,9 @@ func validateDeleteRequest(req *pbs.DeleteHostCatalogRequest) error {
func validateListRequest(req *pbs.ListHostCatalogsRequest) error {
badFields := map[string]string{}
if !handlers.ValidId(scope.Project.Prefix(), req.GetScopeId()) {
badFields["scope_id"] = "This field must be a valid project scope id."
}
if len(badFields) > 0 {
return handlers.InvalidArgumentErrorf("Improperly formatted identifier.", badFields)
}

@ -198,6 +198,11 @@ func TestList(t *testing.T) {
scopeId: scope.Project.Prefix() + "_DoesntExis",
errCode: codes.PermissionDenied,
},
{
name: "Bad scope level",
scopeId: scope.Global.String(),
errCode: codes.InvalidArgument,
},
}
for _, tc := range cases {
t.Run(tc.name, func(t *testing.T) {
@ -318,6 +323,26 @@ func TestCreate(t *testing.T) {
},
errCode: codes.OK,
},
{
name: "Cant create in org",
req: &pbs.CreateHostCatalogRequest{Item: &pb.HostCatalog{
ScopeId: proj.GetParentId(),
Name: &wrappers.StringValue{Value: "name"},
Description: &wrappers.StringValue{Value: "desc"},
Type: "static",
}},
errCode: codes.InvalidArgument,
},
{
name: "Cant create in global",
req: &pbs.CreateHostCatalogRequest{Item: &pb.HostCatalog{
ScopeId: scope.Global.String(),
Name: &wrappers.StringValue{Value: "name"},
Description: &wrappers.StringValue{Value: "desc"},
Type: "static",
}},
errCode: codes.InvalidArgument,
},
{
name: "Create with unknown type",
req: &pbs.CreateHostCatalogRequest{Item: &pb.HostCatalog{
@ -433,6 +458,7 @@ func TestUpdate(t *testing.T) {
Item: &pb.HostCatalog{
Name: &wrappers.StringValue{Value: "new"},
Description: &wrappers.StringValue{Value: "desc"},
Type: "static",
},
},
res: &pbs.UpdateHostCatalogResponse{
@ -457,6 +483,7 @@ func TestUpdate(t *testing.T) {
Item: &pb.HostCatalog{
Name: &wrappers.StringValue{Value: "new"},
Description: &wrappers.StringValue{Value: "desc"},
Type: "static",
},
},
res: &pbs.UpdateHostCatalogResponse{
@ -596,6 +623,19 @@ func TestUpdate(t *testing.T) {
},
errCode: codes.OK,
},
{
name: "Cant change type",
req: &pbs.UpdateHostCatalogRequest{
UpdateMask: &field_mask.FieldMask{
Paths: []string{"name", "type"},
},
Item: &pb.HostCatalog{
Name: &wrappers.StringValue{Value: "updated name"},
Type: "ec2",
},
},
errCode: codes.InvalidArgument,
},
{
name: "Update a Non Existing HostCatalog",
req: &pbs.UpdateHostCatalogRequest{

@ -430,8 +430,11 @@ func validateCreateRequest(req *pbs.CreateHostSetRequest) error {
func validateUpdateRequest(req *pbs.UpdateHostSetRequest) error {
return handlers.ValidateUpdateRequest(static.HostSetPrefix, req, req.GetItem(), func() map[string]string {
badFields := map[string]string{}
if req.GetItem().GetType() != "" {
badFields["type"] = "This is a read only field and cannot be specified in an update request."
switch host.SubtypeFromId(req.GetId()) {
case host.StaticSubtype:
if req.GetItem().GetType() != "" && req.GetItem().GetType() != host.StaticSubtype.String() {
badFields["type"] = "Cannot modify the resource type."
}
}
return badFields
})

@ -462,11 +462,12 @@ func TestUpdate(t *testing.T) {
name: "Update an Existing Host",
req: &pbs.UpdateHostSetRequest{
UpdateMask: &field_mask.FieldMask{
Paths: []string{"name", "description"},
Paths: []string{"name", "description", "type"},
},
Item: &pb.HostSet{
Name: &wrappers.StringValue{Value: "new"},
Description: &wrappers.StringValue{Value: "desc"},
Type: "static",
},
},
res: &pbs.UpdateHostSetResponse{
@ -487,11 +488,12 @@ func TestUpdate(t *testing.T) {
name: "Multiple Paths in single string",
req: &pbs.UpdateHostSetRequest{
UpdateMask: &field_mask.FieldMask{
Paths: []string{"name,description"},
Paths: []string{"name,description,type"},
},
Item: &pb.HostSet{
Name: &wrappers.StringValue{Value: "new"},
Description: &wrappers.StringValue{Value: "desc"},
Type: "static",
},
},
res: &pbs.UpdateHostSetResponse{
@ -508,6 +510,20 @@ func TestUpdate(t *testing.T) {
},
errCode: codes.OK,
},
{
name: "Cant modify type",
req: &pbs.UpdateHostSetRequest{
UpdateMask: &field_mask.FieldMask{
Paths: []string{"name,type"},
},
Item: &pb.HostSet{
Name: &wrappers.StringValue{Value: "updated name"},
Description: &wrappers.StringValue{Value: "updated desc"},
Type: "ec2",
},
},
errCode: codes.InvalidArgument,
},
{
name: "No Update Mask",
req: &pbs.UpdateHostSetRequest{

@ -362,13 +362,14 @@ func validateCreateRequest(req *pbs.CreateHostRequest) error {
func validateUpdateRequest(req *pbs.UpdateHostRequest) error {
return handlers.ValidateUpdateRequest(static.HostPrefix, req, req.GetItem(), func() map[string]string {
badFields := map[string]string{}
ct := host.SubtypeFromId(req.GetId())
if ct == host.UnknownSubtype {
switch host.SubtypeFromId(req.GetId()) {
case host.StaticSubtype:
if req.GetItem().GetType() != "" && req.GetItem().GetType() != host.StaticSubtype.String() {
badFields["type"] = "Cannot modify the resource type."
}
default:
badFields["id"] = "Improperly formatted identifier used."
}
if req.GetItem().GetType() != "" {
badFields["type"] = "This is a read only field and cannot be specified in an update request."
}
return badFields
})
}

@ -464,11 +464,12 @@ func TestUpdate(t *testing.T) {
name: "Update an Existing Host",
req: &pbs.UpdateHostRequest{
UpdateMask: &field_mask.FieldMask{
Paths: []string{"name", "description"},
Paths: []string{"name", "description", "type"},
},
Item: &pb.Host{
Name: &wrappers.StringValue{Value: "new"},
Description: &wrappers.StringValue{Value: "desc"},
Type: "static",
},
},
res: &pbs.UpdateHostResponse{
@ -491,11 +492,12 @@ func TestUpdate(t *testing.T) {
name: "Multiple Paths in single string",
req: &pbs.UpdateHostRequest{
UpdateMask: &field_mask.FieldMask{
Paths: []string{"name,description"},
Paths: []string{"name,description,type"},
},
Item: &pb.Host{
Name: &wrappers.StringValue{Value: "new"},
Description: &wrappers.StringValue{Value: "desc"},
Type: "static",
},
},
res: &pbs.UpdateHostResponse{
@ -524,6 +526,19 @@ func TestUpdate(t *testing.T) {
},
errCode: codes.InvalidArgument,
},
{
name: "No Update Mask",
req: &pbs.UpdateHostRequest{
UpdateMask: &field_mask.FieldMask{
Paths: []string{"name,type"},
},
Item: &pb.Host{
Name: &wrappers.StringValue{Value: "updated name"},
Type: "ec2",
},
},
errCode: codes.InvalidArgument,
},
{
name: "Empty Path",
req: &pbs.UpdateHostRequest{

@ -324,6 +324,7 @@ func ToProto(in *iam.Scope) *pb.Scope {
CreatedTime: in.GetCreateTime().GetTimestamp(),
UpdatedTime: in.GetUpdateTime().GetTimestamp(),
Version: in.GetVersion(),
Type: in.GetType(),
}
if in.GetDescription() != "" {
out.Description = &wrapperspb.StringValue{Value: in.GetDescription()}
@ -365,7 +366,19 @@ func validateCreateRequest(req *pbs.CreateScopeRequest) error {
badFields := map[string]string{}
item := req.GetItem()
if item.GetScopeId() == "" {
badFields["scope_id"] = "Missing value for scope_id"
badFields["scope_id"] = "Missing value for scope_id."
}
switch item.GetType() {
case scope.Global.String():
badFields["type"] = "Cannot create a global scope."
case scope.Org.String():
if !strings.EqualFold(scope.Global.String(), item.GetScopeId()) {
badFields["type"] = "Org scopes can only be created under the global scope."
}
case scope.Project.String():
if !handlers.ValidId(scope.Org.Prefix(), item.GetScopeId()) {
badFields["type"] = "Project scopes can only be created under an org scope."
}
}
if item.GetId() != "" {
badFields["id"] = "This is a read only field."
@ -394,10 +407,16 @@ func validateUpdateRequest(req *pbs.UpdateScopeRequest) error {
if !handlers.ValidId(scope.Org.Prefix(), id) {
badFields["id"] = "Invalidly formatted scope id."
}
if req.GetItem().GetType() != "" && !strings.EqualFold(scope.Org.String(), req.GetItem().GetType()) {
badFields["type"] = "Cannot modify the resource type."
}
case strings.HasPrefix(id, scope.Project.Prefix()):
if !handlers.ValidId(scope.Project.Prefix(), id) {
badFields["id"] = "Invalidly formatted scope id."
}
if req.GetItem().GetType() != "" && !strings.EqualFold(scope.Project.String(), req.GetItem().GetType()) {
badFields["type"] = "Cannot modify the resource type."
}
default:
badFields["id"] = "Invalidly formatted scope id."
}

@ -69,6 +69,7 @@ func TestGet(t *testing.T) {
CreatedTime: org.CreateTime.GetTimestamp(),
UpdatedTime: org.UpdateTime.GetTimestamp(),
Version: 2,
Type: scope.Org.String(),
}
pScope := &pb.Scope{
@ -80,6 +81,7 @@ func TestGet(t *testing.T) {
CreatedTime: proj.CreateTime.GetTimestamp(),
UpdatedTime: proj.UpdateTime.GetTimestamp(),
Version: 2,
Type: scope.Project.String(),
}
cases := []struct {
@ -223,6 +225,7 @@ func TestList(t *testing.T) {
CreatedTime: o.GetCreateTime().GetTimestamp(),
UpdatedTime: o.GetUpdateTime().GetTimestamp(),
Version: 1,
Type: scope.Org.String(),
})
}
wantOrgs = append(wantOrgs, initialOrgs...)
@ -241,6 +244,7 @@ func TestList(t *testing.T) {
CreatedTime: p.GetCreateTime().GetTimestamp(),
UpdatedTime: p.GetUpdateTime().GetTimestamp(),
Version: 1,
Type: scope.Project.String(),
})
}
scopes.SortScopes(wantProjects)
@ -393,22 +397,21 @@ func TestDelete_twice(t *testing.T) {
func TestCreate(t *testing.T) {
ctx := context.Background()
require := require.New(t)
defaultOrg, defaultProj, repoFn := createDefaultScopesAndRepo(t)
defaultProjCreated, err := ptypes.Timestamp(defaultProj.GetCreateTime().GetTimestamp())
require.NoError(err, "Error converting proto to timestamp.")
require.NoError(t, err, "Error converting proto to timestamp.")
toMerge := &pbs.CreateScopeRequest{}
repo, err := repoFn()
require.NoError(err)
require.NoError(t, err)
globalUser, err := iam.NewUser(scope.Global.String())
require.NoError(err)
require.NoError(t, err)
globalUser, err = repo.CreateUser(ctx, globalUser)
require.NoError(err)
require.NoError(t, err)
orgUser, err := iam.NewUser(defaultOrg.GetPublicId())
require.NoError(err)
require.NoError(t, err)
orgUser, err = repo.CreateUser(ctx, orgUser)
require.NoError(err)
require.NoError(t, err)
cases := []struct {
name string
@ -435,6 +438,7 @@ func TestCreate(t *testing.T) {
Name: &wrapperspb.StringValue{Value: "name"},
Description: &wrapperspb.StringValue{Value: "desc"},
Version: 1,
Type: scope.Project.String(),
},
},
errCode: codes.OK,
@ -457,10 +461,79 @@ func TestCreate(t *testing.T) {
Name: &wrapperspb.StringValue{Value: "name"},
Description: &wrapperspb.StringValue{Value: "desc"},
Version: 1,
Type: scope.Org.String(),
},
},
errCode: codes.OK,
},
{
name: "Create a valid Project with type specified",
scopeId: defaultOrg.GetPublicId(),
req: &pbs.CreateScopeRequest{
Item: &pb.Scope{
ScopeId: defaultOrg.GetPublicId(),
Description: &wrapperspb.StringValue{Value: "desc"},
Type: scope.Project.String(),
},
},
res: &pbs.CreateScopeResponse{
Uri: "scopes/p_",
Item: &pb.Scope{
ScopeId: defaultOrg.GetPublicId(),
Scope: &pb.ScopeInfo{Id: defaultOrg.GetPublicId(), Type: scope.Org.String()},
Description: &wrapperspb.StringValue{Value: "desc"},
Version: 1,
Type: scope.Project.String(),
},
},
errCode: codes.OK,
},
{
name: "Create a valid Org with type specified",
scopeId: scope.Global.String(),
req: &pbs.CreateScopeRequest{
Item: &pb.Scope{
ScopeId: scope.Global.String(),
Description: &wrapperspb.StringValue{Value: "desc"},
Type: scope.Org.String(),
},
},
res: &pbs.CreateScopeResponse{
Uri: "scopes/o_",
Item: &pb.Scope{
ScopeId: scope.Global.String(),
Scope: &pb.ScopeInfo{Id: scope.Global.String(), Type: scope.Global.String()},
Description: &wrapperspb.StringValue{Value: "desc"},
Version: 1,
Type: scope.Org.String(),
},
},
errCode: codes.OK,
},
{
name: "Project with bad type specified",
scopeId: defaultOrg.GetPublicId(),
req: &pbs.CreateScopeRequest{
Item: &pb.Scope{
ScopeId: defaultOrg.GetPublicId(),
Description: &wrapperspb.StringValue{Value: "desc"},
Type: scope.Org.String(),
},
},
errCode: codes.InvalidArgument,
},
{
name: "Org with bad type specified",
scopeId: scope.Global.String(),
req: &pbs.CreateScopeRequest{
Item: &pb.Scope{
ScopeId: scope.Global.String(),
Description: &wrapperspb.StringValue{Value: "desc"},
Type: scope.Project.String(),
},
},
errCode: codes.InvalidArgument,
},
{
name: "Can't specify Id",
scopeId: defaultOrg.GetPublicId(),
@ -492,6 +565,7 @@ func TestCreate(t *testing.T) {
for _, tc := range cases {
for _, withUserId := range []bool{false, true} {
t.Run(fmt.Sprintf("%s-userid-%t", tc.name, withUserId), func(t *testing.T) {
assert, require := assert.New(t), require.New(t)
var name string
if tc.req != nil && tc.req.GetItem() != nil && tc.req.GetItem().GetName() != nil {
name = tc.req.GetItem().GetName().GetValue()
@ -500,7 +574,6 @@ func TestCreate(t *testing.T) {
tc.res.GetItem().GetName().Value = localName
}()
}
assert := assert.New(t)
req := proto.Clone(toMerge).(*pbs.CreateScopeRequest)
proto.Merge(req, tc.req)
@ -563,10 +636,9 @@ func TestCreate(t *testing.T) {
}
func TestUpdate(t *testing.T) {
require := require.New(t)
org, proj, repoFn := createDefaultScopesAndRepo(t)
tested, err := scopes.NewService(repoFn)
require.NoError(err, "Error when getting new project service.")
require.NoError(t, err, "Error when getting new project service.")
var orgVersion uint32 = 2
var projVersion uint32 = 2
@ -574,23 +646,23 @@ func TestUpdate(t *testing.T) {
resetOrg := func() {
orgVersion++
repo, err := repoFn()
require.NoError(err, "Couldn't get a new repo")
require.NoError(t, err, "Couldn't get a new repo")
org, _, err = repo.UpdateScope(context.Background(), org, orgVersion, []string{"Name", "Description"})
require.NoError(err, "Failed to reset the org")
require.NoError(t, err, "Failed to reset the org")
orgVersion++
}
resetProject := func() {
projVersion++
repo, err := repoFn()
require.NoError(err, "Couldn't get a new repo")
require.NoError(t, err, "Couldn't get a new repo")
proj, _, err = repo.UpdateScope(context.Background(), proj, projVersion, []string{"Name", "Description"})
require.NoError(err, "Failed to reset the project")
require.NoError(t, err, "Failed to reset the project")
projVersion++
}
projCreated, err := ptypes.Timestamp(proj.GetCreateTime().GetTimestamp())
require.NoError(err, "Error converting proto to timestamp")
require.NoError(t, err, "Error converting proto to timestamp")
projToMerge := &pbs.UpdateScopeRequest{
Id: proj.GetPublicId(),
}
@ -616,6 +688,7 @@ func TestUpdate(t *testing.T) {
Item: &pb.Scope{
Name: &wrapperspb.StringValue{Value: "new"},
Description: &wrapperspb.StringValue{Value: "desc"},
Type: scope.Project.String(),
},
},
res: &pbs.UpdateScopeResponse{
@ -626,6 +699,7 @@ func TestUpdate(t *testing.T) {
Name: &wrapperspb.StringValue{Value: "new"},
Description: &wrapperspb.StringValue{Value: "desc"},
CreatedTime: proj.GetCreateTime().GetTimestamp(),
Type: scope.Project.String(),
},
},
errCode: codes.OK,
@ -640,6 +714,7 @@ func TestUpdate(t *testing.T) {
Item: &pb.Scope{
Name: &wrapperspb.StringValue{Value: "new"},
Description: &wrapperspb.StringValue{Value: "desc"},
Type: scope.Org.String(),
},
},
res: &pbs.UpdateScopeResponse{
@ -650,6 +725,7 @@ func TestUpdate(t *testing.T) {
Name: &wrapperspb.StringValue{Value: "new"},
Description: &wrapperspb.StringValue{Value: "desc"},
CreatedTime: org.GetCreateTime().GetTimestamp(),
Type: scope.Org.String(),
},
},
errCode: codes.OK,
@ -674,6 +750,7 @@ func TestUpdate(t *testing.T) {
Name: &wrapperspb.StringValue{Value: "new"},
Description: &wrapperspb.StringValue{Value: "desc"},
CreatedTime: proj.GetCreateTime().GetTimestamp(),
Type: scope.Project.String(),
},
},
errCode: codes.OK,
@ -689,6 +766,20 @@ func TestUpdate(t *testing.T) {
},
errCode: codes.InvalidArgument,
},
{
name: "Cant modify type",
scopeId: org.GetPublicId(),
req: &pbs.UpdateScopeRequest{
UpdateMask: &field_mask.FieldMask{
Paths: []string{"name", "type"},
},
Item: &pb.Scope{
Name: &wrapperspb.StringValue{Value: "updated name"},
Type: scope.Org.String(),
},
},
errCode: codes.InvalidArgument,
},
{
name: "No Paths in Mask",
scopeId: org.GetPublicId(),
@ -731,6 +822,7 @@ func TestUpdate(t *testing.T) {
Scope: &pb.ScopeInfo{Id: org.GetPublicId(), Type: scope.Org.String()},
Description: &wrapperspb.StringValue{Value: "defaultProj"},
CreatedTime: proj.GetCreateTime().GetTimestamp(),
Type: scope.Project.String(),
},
},
errCode: codes.OK,
@ -753,6 +845,7 @@ func TestUpdate(t *testing.T) {
Scope: &pb.ScopeInfo{Id: org.GetPublicId(), Type: scope.Org.String()},
Name: &wrappers.StringValue{Value: "defaultProj"},
CreatedTime: proj.GetCreateTime().GetTimestamp(),
Type: scope.Project.String(),
},
},
errCode: codes.OK,
@ -777,6 +870,7 @@ func TestUpdate(t *testing.T) {
Name: &wrapperspb.StringValue{Value: "updated"},
Description: &wrapperspb.StringValue{Value: "defaultProj"},
CreatedTime: proj.GetCreateTime().GetTimestamp(),
Type: scope.Project.String(),
},
},
errCode: codes.OK,
@ -801,6 +895,7 @@ func TestUpdate(t *testing.T) {
Name: &wrapperspb.StringValue{Value: "defaultProj"},
Description: &wrapperspb.StringValue{Value: "notignored"},
CreatedTime: proj.GetCreateTime().GetTimestamp(),
Type: scope.Project.String(),
},
},
errCode: codes.OK,
@ -874,7 +969,7 @@ func TestUpdate(t *testing.T) {
}
tc.req.Item.Version = ver
assert := assert.New(t)
assert, require := assert.New(t), require.New(t)
var req *pbs.UpdateScopeRequest
switch tc.scopeId {
case scope.Global.String():

Loading…
Cancel
Save