From eb43941771722ea34f2712c4d4677fb3c947b1b4 Mon Sep 17 00:00:00 2001 From: irenarindos Date: Mon, 28 Mar 2022 11:12:02 -0400 Subject: [PATCH] refact(account): Use OneOf for Account attributes --- internal/gen/controller.swagger.json | 54 +++ .../api/resources/accounts/v1/account.proto | 8 +- .../handlers/accounts/account_service.go | 67 +-- .../handlers/accounts/account_service_test.go | 418 +++++++++++------- .../handlers/accounts/validate_test.go | 85 +--- .../api/resources/accounts/account.pb.go | 193 +++++--- 6 files changed, 476 insertions(+), 349 deletions(-) diff --git a/internal/gen/controller.swagger.json b/internal/gen/controller.swagger.json index 54c1efe60..a3b218709 100644 --- a/internal/gen/controller.swagger.json +++ b/internal/gen/controller.swagger.json @@ -3702,6 +3702,12 @@ "type": "object", "description": "The attributes that are applicable for the specific Account type." }, + "password_account_attributes": { + "$ref": "#/definitions/controller.api.resources.accounts.v1.PasswordAccountAttributes" + }, + "oidc_account_attributes": { + "$ref": "#/definitions/controller.api.resources.accounts.v1.OidcAccountAttributes" + }, "managed_group_ids": { "type": "array", "items": { @@ -3721,6 +3727,54 @@ }, "title": "Account contains all fields related to an Account resource" }, + "controller.api.resources.accounts.v1.OidcAccountAttributes": { + "type": "object", + "properties": { + "issuer": { + "type": "string", + "description": "issuer is a case sensitive URL that maps to the OIDC iss claim.\nThis value is immutable after creation time." + }, + "subject": { + "type": "string", + "description": "subject is a case sensitive string that maps to the OIDC sub claim.\nThis value is immutable after creation time." + }, + "full_name": { + "type": "string", + "description": "Output only. full_name is a string that maps to the OIDC name claim.", + "readOnly": true + }, + "email": { + "type": "string", + "description": "Output only. email is a string that maps to the OIDC email claim.", + "readOnly": true + }, + "token_claims": { + "type": "object", + "description": "Output only. token_claims are the marshaled claims from the token.", + "readOnly": true + }, + "userinfo_claims": { + "type": "object", + "description": "Output only. userinfo_claims are the marshaled claims from userinfo.", + "readOnly": true + } + }, + "description": "Attributes associated only with Accounts with type \"oidc\"." + }, + "controller.api.resources.accounts.v1.PasswordAccountAttributes": { + "type": "object", + "properties": { + "login_name": { + "type": "string", + "description": "The login name of this Account. This is unique per Auth Method." + }, + "password": { + "type": "string", + "description": "The password for this Account." + } + }, + "description": "Attributes associated only with Accounts with type \"password\"." + }, "controller.api.resources.authmethods.v1.AuthMethod": { "type": "object", "properties": { diff --git a/internal/proto/controller/api/resources/accounts/v1/account.proto b/internal/proto/controller/api/resources/accounts/v1/account.proto index 77b70708d..12a74f7a0 100644 --- a/internal/proto/controller/api/resources/accounts/v1/account.proto +++ b/internal/proto/controller/api/resources/accounts/v1/account.proto @@ -40,8 +40,12 @@ message Account { // The ID of the Auth Method that is associated with this Account. string auth_method_id = 90 [json_name="auth_method_id"]; - // The attributes that are applicable for the specific Account type. - google.protobuf.Struct attributes = 100 [(custom_options.v1.generate_sdk_option) = true]; + oneof attrs { + // The attributes that are applicable for the specific Account type. + google.protobuf.Struct attributes = 100 [(custom_options.v1.generate_sdk_option) = true, (custom_options.v1.subtype) = "default"]; + PasswordAccountAttributes password_account_attributes = 101 [(custom_options.v1.generate_sdk_option) = true, (custom_options.v1.subtype) = "password"]; + OidcAccountAttributes oidc_account_attributes = 102 [(custom_options.v1.generate_sdk_option) = true, (custom_options.v1.subtype) = "oidc"]; + } // Output only. managed_group_ids indicates IDs of the managed groups that currently contain this account repeated string managed_group_ids = 110 [json_name="managed_group_ids"]; diff --git a/internal/servers/controller/handlers/accounts/account_service.go b/internal/servers/controller/handlers/accounts/account_service.go index fc3a3e984..8fc0510d2 100644 --- a/internal/servers/controller/handlers/accounts/account_service.go +++ b/internal/servers/controller/handlers/accounts/account_service.go @@ -437,11 +437,7 @@ func (s Service) createPwInRepo(ctx context.Context, am auth.AuthMethod, item *p if item == nil { return nil, errors.New(ctx, errors.InvalidParameter, op, "missing item") } - pwAttrs := &pb.PasswordAccountAttributes{} - if err := handlers.StructToProto(item.GetAttributes(), pwAttrs); err != nil { - return nil, handlers.InvalidArgumentErrorf("Error in provided request.", - map[string]string{"attributes": "Attribute fields do not match the expected format."}) - } + pwAttrs := item.GetPasswordAccountAttributes() opts := []password.Option{password.WithLoginName(pwAttrs.GetLoginName())} if item.GetName() != nil { opts = append(opts, password.WithName(item.GetName().GetValue())) @@ -484,11 +480,7 @@ func (s Service) createOidcInRepo(ctx context.Context, am auth.AuthMethod, item if item.GetDescription() != nil { opts = append(opts, oidc.WithDescription(item.GetDescription().GetValue())) } - attrs := &pb.OidcAccountAttributes{} - if err := handlers.StructToProto(item.GetAttributes(), attrs); err != nil { - return nil, handlers.InvalidArgumentErrorf("Error in provided request.", - map[string]string{"attributes": "Attribute fields do not match the expected format."}) - } + attrs := item.GetOidcAccountAttributes() if attrs.GetIssuer() != "" { u, err := url.Parse(attrs.GetIssuer()) if err != nil { @@ -867,11 +859,11 @@ func toProto(ctx context.Context, in auth.Account, opt ...handlers.Option) (*pb. if !outputFields.Has(globals.AttributesField) { break } - st, err := handlers.ProtoToStruct(&pb.PasswordAccountAttributes{LoginName: i.GetLoginName()}) - if err != nil { - return nil, handlers.ApiErrorWithCodeAndMessage(codes.Internal, "failed building password attribute struct: %v", err) + out.Attrs = &pb.Account_PasswordAccountAttributes{ + PasswordAccountAttributes: &pb.PasswordAccountAttributes{ + LoginName: i.GetLoginName(), + }, } - out.Attributes = st case *oidc.Account: if outputFields.Has(globals.TypeField) { out.Type = oidc.Subtype.String() @@ -879,11 +871,13 @@ func toProto(ctx context.Context, in auth.Account, opt ...handlers.Option) (*pb. if !outputFields.Has(globals.AttributesField) { break } - attrs := &pb.OidcAccountAttributes{ - Issuer: i.GetIssuer(), - Subject: i.GetSubject(), - FullName: i.GetFullName(), - Email: i.GetEmail(), + attrs := &pb.Account_OidcAccountAttributes{ + OidcAccountAttributes: &pb.OidcAccountAttributes{ + Issuer: i.GetIssuer(), + Subject: i.GetSubject(), + FullName: i.GetFullName(), + Email: i.GetEmail(), + }, } if s := i.GetTokenClaims(); s != "" { m := make(map[string]interface{}) @@ -891,7 +885,7 @@ func toProto(ctx context.Context, in auth.Account, opt ...handlers.Option) (*pb. if err = json.Unmarshal([]byte(s), &m); err != nil { return nil, errors.Wrap(ctx, err, op, errors.WithMsg("error unmarshaling stored token claims")) } - if attrs.TokenClaims, err = structpb.NewStruct(m); err != nil { + if attrs.OidcAccountAttributes.TokenClaims, err = structpb.NewStruct(m); err != nil { return nil, errors.Wrap(ctx, err, op, errors.WithMsg("error converting stored token claims to protobuf struct")) } } @@ -901,15 +895,11 @@ func toProto(ctx context.Context, in auth.Account, opt ...handlers.Option) (*pb. if err = json.Unmarshal([]byte(s), &m); err != nil { return nil, errors.Wrap(ctx, err, op, errors.WithMsg("error unmarshaling stored userinfo claims")) } - if attrs.UserinfoClaims, err = structpb.NewStruct(m); err != nil { + if attrs.OidcAccountAttributes.UserinfoClaims, err = structpb.NewStruct(m); err != nil { return nil, errors.Wrap(ctx, err, op, errors.WithMsg("error converting stored userinfo claims to protobuf struct")) } } - st, err := handlers.ProtoToStruct(attrs) - if err != nil { - return nil, handlers.ApiErrorWithCodeAndMessage(codes.Internal, "failed building oidc attribute struct: %v", err) - } - out.Attributes = st + out.Attrs = attrs } return &out, nil } @@ -931,12 +921,7 @@ func toStoragePwAccount(amId string, item *pb.Account) (*password.Account, error return nil, handlers.ApiErrorWithCodeAndMessage(codes.Internal, "Unable to build account for creation: %v.", err) } - attrs := &pb.PasswordAccountAttributes{} - if err := handlers.StructToProto(item.GetAttributes(), attrs); err != nil { - return nil, handlers.InvalidArgumentErrorf("Error in provided request.", - map[string]string{attributesField: "Attribute fields do not match the expected format."}) - } - + attrs := item.GetPasswordAccountAttributes() if attrs.GetLoginName() != "" { u.LoginName = attrs.GetLoginName() } @@ -971,10 +956,7 @@ func validateCreateRequest(req *pbs.CreateAccountRequest) error { if req.GetItem().GetType() != "" && req.GetItem().GetType() != password.Subtype.String() { badFields[typeField] = "Doesn't match the parent resource's type." } - attrs := &pb.PasswordAccountAttributes{} - if err := handlers.StructToProto(req.GetItem().GetAttributes(), attrs); err != nil { - badFields[attributesField] = "Attribute fields do not match the expected format." - } + attrs := req.GetItem().GetPasswordAccountAttributes() if attrs.GetLoginName() == "" { badFields[loginNameKey] = "This is a required field for this type." } @@ -982,10 +964,7 @@ func validateCreateRequest(req *pbs.CreateAccountRequest) error { if req.GetItem().GetType() != "" && req.GetItem().GetType() != oidc.Subtype.String() { badFields[typeField] = "Doesn't match the parent resource's type." } - attrs := &pb.OidcAccountAttributes{} - if err := handlers.StructToProto(req.GetItem().GetAttributes(), attrs); err != nil { - badFields[attributesField] = "Attribute fields do not match the expected format." - } + attrs := req.GetItem().GetOidcAccountAttributes() if attrs.GetSubject() == "" { badFields[subjectField] = "This is a required field for this type." } @@ -1023,18 +1002,10 @@ func validateUpdateRequest(req *pbs.UpdateAccountRequest) error { if req.GetItem().GetType() != "" && req.GetItem().GetType() != password.Subtype.String() { badFields[typeField] = "Cannot modify the resource type." } - attrs := &pb.PasswordAccountAttributes{} - if err := handlers.StructToProto(req.GetItem().GetAttributes(), attrs); err != nil { - badFields[attributesField] = "Attribute fields do not match the expected format." - } case oidc.Subtype: if req.GetItem().GetType() != "" && req.GetItem().GetType() != oidc.Subtype.String() { badFields[typeField] = "Cannot modify the resource type." } - attrs := &pb.OidcAccountAttributes{} - if err := handlers.StructToProto(req.GetItem().GetAttributes(), attrs); err != nil { - badFields[attributesField] = "Attribute fields do not match the expected format." - } if handlers.MaskContains(req.GetUpdateMask().GetPaths(), subjectField) { badFields[subjectField] = "Field cannot be updated." } diff --git a/internal/servers/controller/handlers/accounts/account_service_test.go b/internal/servers/controller/handlers/accounts/account_service_test.go index 056983ae3..7a3e04105 100644 --- a/internal/servers/controller/handlers/accounts/account_service_test.go +++ b/internal/servers/controller/handlers/accounts/account_service_test.go @@ -32,7 +32,6 @@ import ( "google.golang.org/genproto/protobuf/field_mask" "google.golang.org/grpc/codes" "google.golang.org/protobuf/testing/protocmp" - "google.golang.org/protobuf/types/known/structpb" "google.golang.org/protobuf/types/known/timestamppb" "google.golang.org/protobuf/types/known/wrapperspb" ) @@ -130,14 +129,16 @@ func TestGet(t *testing.T) { pwA := password.TestAccount(t, conn, am.GetPublicId(), "name1") pwWireAccount := pb.Account{ - Id: pwA.GetPublicId(), - AuthMethodId: pwA.GetAuthMethodId(), - CreatedTime: pwA.GetCreateTime().GetTimestamp(), - UpdatedTime: pwA.GetUpdateTime().GetTimestamp(), - Scope: &scopepb.ScopeInfo{Id: org.GetPublicId(), Type: scope.Org.String(), ParentScopeId: scope.Global.String()}, - Version: 1, - Type: password.Subtype.String(), - Attributes: &structpb.Struct{Fields: map[string]*structpb.Value{"login_name": structpb.NewStringValue(pwA.GetLoginName())}}, + Id: pwA.GetPublicId(), + AuthMethodId: pwA.GetAuthMethodId(), + CreatedTime: pwA.GetCreateTime().GetTimestamp(), + UpdatedTime: pwA.GetUpdateTime().GetTimestamp(), + Scope: &scopepb.ScopeInfo{Id: org.GetPublicId(), Type: scope.Org.String(), ParentScopeId: scope.Global.String()}, + Version: 1, + Type: password.Subtype.String(), + Attrs: &pb.Account_PasswordAccountAttributes{ + &pb.PasswordAccountAttributes{LoginName: pwA.GetLoginName()}, + }, AuthorizedActions: pwAuthorizedActions, } @@ -162,10 +163,12 @@ func TestGet(t *testing.T) { Scope: &scopepb.ScopeInfo{Id: org.GetPublicId(), Type: scope.Org.String(), ParentScopeId: scope.Global.String()}, Version: 1, Type: oidc.Subtype.String(), - Attributes: &structpb.Struct{Fields: map[string]*structpb.Value{ - "issuer": structpb.NewStringValue(oidcAm.GetIssuer()), - "subject": structpb.NewStringValue("test-subject"), - }}, + Attrs: &pb.Account_OidcAccountAttributes{ + &pb.OidcAccountAttributes{ + Issuer: oidcAm.GetIssuer(), + Subject: "test-subject", + }, + }, AuthorizedActions: oidcAuthorizedActions, ManagedGroupIds: []string{mg.GetPublicId()}, } @@ -267,14 +270,16 @@ func TestListPassword(t *testing.T) { var wantSomeAccounts []*pb.Account for _, aa := range password.TestMultipleAccounts(t, conn, amSomeAccounts.GetPublicId(), 3) { wantSomeAccounts = append(wantSomeAccounts, &pb.Account{ - Id: aa.GetPublicId(), - AuthMethodId: aa.GetAuthMethodId(), - CreatedTime: aa.GetCreateTime().GetTimestamp(), - UpdatedTime: aa.GetUpdateTime().GetTimestamp(), - Scope: &scopepb.ScopeInfo{Id: o.GetPublicId(), Type: scope.Org.String(), ParentScopeId: scope.Global.String()}, - Version: 1, - Type: "password", - Attributes: &structpb.Struct{Fields: map[string]*structpb.Value{"login_name": structpb.NewStringValue(aa.GetLoginName())}}, + Id: aa.GetPublicId(), + AuthMethodId: aa.GetAuthMethodId(), + CreatedTime: aa.GetCreateTime().GetTimestamp(), + UpdatedTime: aa.GetUpdateTime().GetTimestamp(), + Scope: &scopepb.ScopeInfo{Id: o.GetPublicId(), Type: scope.Org.String(), ParentScopeId: scope.Global.String()}, + Version: 1, + Type: "password", + Attrs: &pb.Account_PasswordAccountAttributes{ + PasswordAccountAttributes: &pb.PasswordAccountAttributes{LoginName: aa.GetLoginName()}, + }, AuthorizedActions: pwAuthorizedActions, }) } @@ -282,14 +287,16 @@ func TestListPassword(t *testing.T) { var wantOtherAccounts []*pb.Account for _, aa := range password.TestMultipleAccounts(t, conn, amOtherAccounts.GetPublicId(), 3) { wantOtherAccounts = append(wantOtherAccounts, &pb.Account{ - Id: aa.GetPublicId(), - AuthMethodId: aa.GetAuthMethodId(), - CreatedTime: aa.GetCreateTime().GetTimestamp(), - UpdatedTime: aa.GetUpdateTime().GetTimestamp(), - Scope: &scopepb.ScopeInfo{Id: o.GetPublicId(), Type: scope.Org.String(), ParentScopeId: scope.Global.String()}, - Version: 1, - Type: "password", - Attributes: &structpb.Struct{Fields: map[string]*structpb.Value{"login_name": structpb.NewStringValue(aa.GetLoginName())}}, + Id: aa.GetPublicId(), + AuthMethodId: aa.GetAuthMethodId(), + CreatedTime: aa.GetCreateTime().GetTimestamp(), + UpdatedTime: aa.GetUpdateTime().GetTimestamp(), + Scope: &scopepb.ScopeInfo{Id: o.GetPublicId(), Type: scope.Org.String(), ParentScopeId: scope.Global.String()}, + Version: 1, + Type: "password", + Attrs: &pb.Account_PasswordAccountAttributes{ + &pb.PasswordAccountAttributes{LoginName: aa.GetLoginName()}, + }, AuthorizedActions: pwAuthorizedActions, }) } @@ -325,7 +332,7 @@ func TestListPassword(t *testing.T) { name: "Filter Some Accounts", req: &pbs.ListAccountsRequest{ AuthMethodId: amSomeAccounts.GetPublicId(), - Filter: fmt.Sprintf(`"/item/attributes/login_name"==%q`, wantSomeAccounts[1].Attributes.AsMap()["login_name"]), + Filter: fmt.Sprintf(`"/item/attributes/login_name"==%q`, wantSomeAccounts[1].GetPasswordAccountAttributes().LoginName), }, res: &pbs.ListAccountsResponse{Items: wantSomeAccounts[1:2]}, skipAnon: true, @@ -369,7 +376,7 @@ func TestListPassword(t *testing.T) { require.NoError(gErr) assert.Len(got.Items, len(tc.res.Items)) for _, g := range got.GetItems() { - assert.Nil(g.Attributes) + assert.Nil(g.Attrs) assert.Nil(g.CreatedTime) assert.Nil(g.UpdatedTime) assert.Empty(g.Version) @@ -416,10 +423,12 @@ func TestListOidc(t *testing.T) { Scope: &scopepb.ScopeInfo{Id: o.GetPublicId(), Type: scope.Org.String(), ParentScopeId: scope.Global.String()}, Version: 1, Type: oidc.Subtype.String(), - Attributes: &structpb.Struct{Fields: map[string]*structpb.Value{ - "issuer": structpb.NewStringValue(amSomeAccounts.GetIssuer()), - "subject": structpb.NewStringValue(subId), - }}, + Attrs: &pb.Account_OidcAccountAttributes{ + &pb.OidcAccountAttributes{ + Issuer: amSomeAccounts.GetIssuer(), + Subject: subId, + }, + }, AuthorizedActions: oidcAuthorizedActions, }) } @@ -436,10 +445,12 @@ func TestListOidc(t *testing.T) { Scope: &scopepb.ScopeInfo{Id: o.GetPublicId(), Type: scope.Org.String(), ParentScopeId: scope.Global.String()}, Version: 1, Type: oidc.Subtype.String(), - Attributes: &structpb.Struct{Fields: map[string]*structpb.Value{ - "issuer": structpb.NewStringValue(amOtherAccounts.GetIssuer()), - "subject": structpb.NewStringValue(subId), - }}, + Attrs: &pb.Account_OidcAccountAttributes{ + &pb.OidcAccountAttributes{ + Issuer: amOtherAccounts.GetIssuer(), + Subject: subId, + }, + }, AuthorizedActions: oidcAuthorizedActions, }) } @@ -475,7 +486,7 @@ func TestListOidc(t *testing.T) { name: "Filter Some Accounts", req: &pbs.ListAccountsRequest{ AuthMethodId: amSomeAccounts.GetPublicId(), - Filter: fmt.Sprintf(`"/item/attributes/subject"==%q`, wantSomeAccounts[1].Attributes.AsMap()["subject"]), + Filter: fmt.Sprintf(`"/item/attributes/subject"==%q`, wantSomeAccounts[1].GetOidcAccountAttributes().Subject), }, res: &pbs.ListAccountsResponse{Items: wantSomeAccounts[1:2]}, skipAnon: true, @@ -509,8 +520,8 @@ func TestListOidc(t *testing.T) { require.NoError(gErr) } sort.Slice(got.Items, func(i, j int) bool { - return strings.Compare(got.Items[i].GetAttributes().GetFields()["subject"].GetStringValue(), - got.Items[j].GetAttributes().GetFields()["subject"].GetStringValue()) < 0 + return strings.Compare(got.Items[i].GetOidcAccountAttributes().Subject, + got.Items[j].GetOidcAccountAttributes().Subject) < 0 }) assert.Empty(cmp.Diff(got, tc.res, protocmp.Transform()), "ListAccounts() with scope %q got response %q, wanted %q", tc.req, got, tc.res) @@ -522,7 +533,7 @@ func TestListOidc(t *testing.T) { require.NoError(gErr) assert.Len(got.Items, len(tc.res.Items)) for _, g := range got.GetItems() { - assert.Nil(g.Attributes) + assert.Nil(g.Attrs) assert.Nil(g.CreatedTime) assert.Nil(g.UpdatedTime) assert.Empty(g.Version) @@ -684,16 +695,6 @@ func TestCreatePassword(t *testing.T) { defaultCreated := defaultAccount.GetCreateTime().GetTimestamp() require.NoError(t, err, "Error converting proto to timestamp.") - createAttr := func(un, pw string) *structpb.Struct { - attr := &pb.PasswordAccountAttributes{LoginName: un} - if pw != "" { - attr.Password = wrapperspb.String(pw) - } - ret, err := handlers.ProtoToStruct(attr) - require.NoError(t, err, "Error converting proto to struct.") - return ret - } - cases := []struct { name string req *pbs.CreateAccountRequest @@ -708,19 +709,29 @@ func TestCreatePassword(t *testing.T) { Name: &wrapperspb.StringValue{Value: "name"}, Description: &wrapperspb.StringValue{Value: "desc"}, Type: "password", - Attributes: createAttr("validaccount", ""), + Attrs: &pb.Account_PasswordAccountAttributes{ + &pb.PasswordAccountAttributes{ + LoginName: "validaccount", + Password: nil, + }, + }, }, }, res: &pbs.CreateAccountResponse{ Uri: fmt.Sprintf("accounts/%s_", intglobals.NewPasswordAccountPrefix), Item: &pb.Account{ - AuthMethodId: defaultAccount.GetAuthMethodId(), - Name: &wrapperspb.StringValue{Value: "name"}, - Description: &wrapperspb.StringValue{Value: "desc"}, - Scope: &scopepb.ScopeInfo{Id: o.GetPublicId(), Type: scope.Org.String(), ParentScopeId: scope.Global.String()}, - Version: 1, - Type: "password", - Attributes: createAttr("validaccount", ""), + AuthMethodId: defaultAccount.GetAuthMethodId(), + Name: &wrapperspb.StringValue{Value: "name"}, + Description: &wrapperspb.StringValue{Value: "desc"}, + Scope: &scopepb.ScopeInfo{Id: o.GetPublicId(), Type: scope.Org.String(), ParentScopeId: scope.Global.String()}, + Version: 1, + Type: "password", + Attrs: &pb.Account_PasswordAccountAttributes{ + &pb.PasswordAccountAttributes{ + LoginName: "validaccount", + Password: nil, + }, + }, AuthorizedActions: pwAuthorizedActions, }, }, @@ -730,17 +741,27 @@ func TestCreatePassword(t *testing.T) { req: &pbs.CreateAccountRequest{ Item: &pb.Account{ AuthMethodId: defaultAccount.GetAuthMethodId(), - Attributes: createAttr("notypedefined", ""), + Attrs: &pb.Account_PasswordAccountAttributes{ + &pb.PasswordAccountAttributes{ + LoginName: "notypedefined", + Password: nil, + }, + }, }, }, res: &pbs.CreateAccountResponse{ Uri: fmt.Sprintf("accounts/%s_", intglobals.NewPasswordAccountPrefix), Item: &pb.Account{ - AuthMethodId: defaultAccount.GetAuthMethodId(), - Scope: &scopepb.ScopeInfo{Id: o.GetPublicId(), Type: scope.Org.String(), ParentScopeId: scope.Global.String()}, - Version: 1, - Type: "password", - Attributes: createAttr("notypedefined", ""), + AuthMethodId: defaultAccount.GetAuthMethodId(), + Scope: &scopepb.ScopeInfo{Id: o.GetPublicId(), Type: scope.Org.String(), ParentScopeId: scope.Global.String()}, + Version: 1, + Type: "password", + Attrs: &pb.Account_PasswordAccountAttributes{ + &pb.PasswordAccountAttributes{ + LoginName: "notypedefined", + Password: nil, + }, + }, AuthorizedActions: pwAuthorizedActions, }, }, @@ -752,19 +773,29 @@ func TestCreatePassword(t *testing.T) { AuthMethodId: defaultAccount.GetAuthMethodId(), Name: &wrapperspb.StringValue{Value: "name_with_password"}, Description: &wrapperspb.StringValue{Value: "desc"}, - Attributes: createAttr("haspassword", "somepassword"), + Attrs: &pb.Account_PasswordAccountAttributes{ + &pb.PasswordAccountAttributes{ + LoginName: "haspassword", + Password: &wrapperspb.StringValue{Value: "somepassword"}, + }, + }, }, }, res: &pbs.CreateAccountResponse{ Uri: fmt.Sprintf("accounts/%s_", intglobals.NewPasswordAccountPrefix), Item: &pb.Account{ - AuthMethodId: defaultAccount.GetAuthMethodId(), - Name: &wrapperspb.StringValue{Value: "name_with_password"}, - Description: &wrapperspb.StringValue{Value: "desc"}, - Scope: &scopepb.ScopeInfo{Id: o.GetPublicId(), Type: scope.Org.String(), ParentScopeId: scope.Global.String()}, - Version: 1, - Type: "password", - Attributes: createAttr("haspassword", ""), + AuthMethodId: defaultAccount.GetAuthMethodId(), + Name: &wrapperspb.StringValue{Value: "name_with_password"}, + Description: &wrapperspb.StringValue{Value: "desc"}, + Scope: &scopepb.ScopeInfo{Id: o.GetPublicId(), Type: scope.Org.String(), ParentScopeId: scope.Global.String()}, + Version: 1, + Type: "password", + Attrs: &pb.Account_PasswordAccountAttributes{ + &pb.PasswordAccountAttributes{ + LoginName: "haspassword", + Password: nil, + }, + }, AuthorizedActions: pwAuthorizedActions, }, }, @@ -775,7 +806,12 @@ func TestCreatePassword(t *testing.T) { Item: &pb.Account{ AuthMethodId: defaultAccount.GetAuthMethodId(), Type: "wrong", - Attributes: createAttr("nopwprovided", ""), + Attrs: &pb.Account_PasswordAccountAttributes{ + &pb.PasswordAccountAttributes{ + LoginName: "nopwprovided", + Password: nil, + }, + }, }, }, res: nil, @@ -788,7 +824,12 @@ func TestCreatePassword(t *testing.T) { AuthMethodId: defaultAccount.GetAuthMethodId(), Id: intglobals.NewPasswordAccountPrefix + "_notallowed", Type: "password", - Attributes: createAttr("cantprovideid", ""), + Attrs: &pb.Account_PasswordAccountAttributes{ + &pb.PasswordAccountAttributes{ + LoginName: "cantprovideid", + Password: nil, + }, + }, }, }, res: nil, @@ -801,7 +842,12 @@ func TestCreatePassword(t *testing.T) { AuthMethodId: defaultAccount.GetAuthMethodId(), CreatedTime: timestamppb.Now(), Type: "password", - Attributes: createAttr("nocreatedtime", ""), + Attrs: &pb.Account_PasswordAccountAttributes{ + &pb.PasswordAccountAttributes{ + LoginName: "nocreatedtime", + Password: nil, + }, + }, }, }, res: nil, @@ -814,7 +860,12 @@ func TestCreatePassword(t *testing.T) { AuthMethodId: defaultAccount.GetAuthMethodId(), UpdatedTime: timestamppb.Now(), Type: "password", - Attributes: createAttr("noupdatetime", ""), + Attrs: &pb.Account_PasswordAccountAttributes{ + &pb.PasswordAccountAttributes{ + LoginName: "noupdatetime", + Password: nil, + }, + }, }, }, res: nil, @@ -839,6 +890,8 @@ func TestCreatePassword(t *testing.T) { if tc.err != nil { require.Error(gErr) assert.True(errors.Is(gErr, tc.err), "CreateAccount(%+v) got error %v, wanted %v", tc.req, gErr, tc.err) + } else { + require.NoError(gErr) } if got != nil { assert.Contains(got.GetUri(), tc.res.Uri) @@ -891,13 +944,6 @@ func TestCreateOidc(t *testing.T) { oidc.WithApiUrl(oidc.TestConvertToUrls(t, "https://www.alice.com/callback")[0]), ) - createAttr := func(sid string) *structpb.Struct { - attr := &pb.OidcAccountAttributes{Subject: sid} - ret, err := handlers.ProtoToStruct(attr) - require.NoError(t, err, "Error converting proto to struct.") - return ret - } - cases := []struct { name string req *pbs.CreateAccountRequest @@ -912,7 +958,11 @@ func TestCreateOidc(t *testing.T) { Name: &wrapperspb.StringValue{Value: "name"}, Description: &wrapperspb.StringValue{Value: "desc"}, Type: oidc.Subtype.String(), - Attributes: createAttr("valid-account"), + Attrs: &pb.Account_OidcAccountAttributes{ + &pb.OidcAccountAttributes{ + Subject: "valid-account", + }, + }, }, }, res: &pbs.CreateAccountResponse{ @@ -924,11 +974,12 @@ func TestCreateOidc(t *testing.T) { Scope: &scopepb.ScopeInfo{Id: o.GetPublicId(), Type: scope.Org.String(), ParentScopeId: scope.Global.String()}, Version: 1, Type: oidc.Subtype.String(), - Attributes: func() *structpb.Struct { - a := createAttr("valid-account") - a.Fields["issuer"] = structpb.NewStringValue(am.GetIssuer()) - return a - }(), + Attrs: &pb.Account_OidcAccountAttributes{ + &pb.OidcAccountAttributes{ + Subject: "valid-account", + Issuer: am.GetIssuer(), + }, + }, AuthorizedActions: oidcAuthorizedActions, }, }, @@ -938,7 +989,11 @@ func TestCreateOidc(t *testing.T) { req: &pbs.CreateAccountRequest{ Item: &pb.Account{ AuthMethodId: am.GetPublicId(), - Attributes: createAttr("no type defined"), + Attrs: &pb.Account_OidcAccountAttributes{ + &pb.OidcAccountAttributes{ + Subject: "no type defined", + }, + }, }, }, res: &pbs.CreateAccountResponse{ @@ -948,11 +1003,12 @@ func TestCreateOidc(t *testing.T) { Scope: &scopepb.ScopeInfo{Id: o.GetPublicId(), Type: scope.Org.String(), ParentScopeId: scope.Global.String()}, Version: 1, Type: oidc.Subtype.String(), - Attributes: func() *structpb.Struct { - a := createAttr("no type defined") - a.Fields["issuer"] = structpb.NewStringValue(am.GetIssuer()) - return a - }(), + Attrs: &pb.Account_OidcAccountAttributes{ + &pb.OidcAccountAttributes{ + Subject: "no type defined", + Issuer: am.GetIssuer(), + }, + }, AuthorizedActions: oidcAuthorizedActions, }, }, @@ -964,11 +1020,12 @@ func TestCreateOidc(t *testing.T) { AuthMethodId: am.GetPublicId(), Name: &wrapperspb.StringValue{Value: "overwritten issuer"}, Type: oidc.Subtype.String(), - Attributes: func() *structpb.Struct { - a := createAttr("overwritten-issuer") - a.Fields["issuer"] = structpb.NewStringValue("https://overwrite.com") - return a - }(), + Attrs: &pb.Account_OidcAccountAttributes{ + &pb.OidcAccountAttributes{ + Subject: "overwritten-issuer", + Issuer: "https://overwrite.com", + }, + }, }, }, res: &pbs.CreateAccountResponse{ @@ -979,11 +1036,12 @@ func TestCreateOidc(t *testing.T) { Scope: &scopepb.ScopeInfo{Id: o.GetPublicId(), Type: scope.Org.String(), ParentScopeId: scope.Global.String()}, Version: 1, Type: oidc.Subtype.String(), - Attributes: func() *structpb.Struct { - a := createAttr("overwritten-issuer") - a.Fields["issuer"] = structpb.NewStringValue("https://overwrite.com") - return a - }(), + Attrs: &pb.Account_OidcAccountAttributes{ + &pb.OidcAccountAttributes{ + Subject: "overwritten-issuer", + Issuer: "https://overwrite.com", + }, + }, AuthorizedActions: oidcAuthorizedActions, }, }, @@ -994,7 +1052,11 @@ func TestCreateOidc(t *testing.T) { Item: &pb.Account{ AuthMethodId: am.GetPublicId(), Type: password.Subtype.String(), - Attributes: createAttr("cant-specify-mismatching-type"), + Attrs: &pb.Account_OidcAccountAttributes{ + &pb.OidcAccountAttributes{ + Subject: "cant-specify-mismatching-type", + }, + }, }, }, res: nil, @@ -1007,7 +1069,11 @@ func TestCreateOidc(t *testing.T) { AuthMethodId: am.GetPublicId(), Id: oidc.AccountPrefix + "_notallowed", Type: oidc.Subtype.String(), - Attributes: createAttr("cant-specify-id"), + Attrs: &pb.Account_OidcAccountAttributes{ + &pb.OidcAccountAttributes{ + Subject: "cant-specify-id", + }, + }, }, }, res: nil, @@ -1020,7 +1086,11 @@ func TestCreateOidc(t *testing.T) { AuthMethodId: am.GetPublicId(), CreatedTime: timestamppb.Now(), Type: oidc.Subtype.String(), - Attributes: createAttr("cant-specify-created-time"), + Attrs: &pb.Account_OidcAccountAttributes{ + &pb.OidcAccountAttributes{ + Subject: "cant-specify-created-time", + }, + }, }, }, res: nil, @@ -1033,7 +1103,11 @@ func TestCreateOidc(t *testing.T) { AuthMethodId: am.GetPublicId(), UpdatedTime: timestamppb.Now(), Type: oidc.Subtype.String(), - Attributes: createAttr("cant-specify-update-time"), + Attrs: &pb.Account_OidcAccountAttributes{ + &pb.OidcAccountAttributes{ + Subject: "cant-specify-update-time", + }, + }, }, }, res: nil, @@ -1096,12 +1170,16 @@ func TestUpdatePassword(t *testing.T) { require.NoError(t, err, "Error when getting new accounts service.") defaultScopeInfo := &scopepb.ScopeInfo{Id: o.GetPublicId(), Type: o.GetType(), ParentScopeId: scope.Global.String()} - defaultAttributes := &structpb.Struct{Fields: map[string]*structpb.Value{ - "login_name": structpb.NewStringValue("default"), - }} - modifiedAttributes := &structpb.Struct{Fields: map[string]*structpb.Value{ - "login_name": structpb.NewStringValue("modified"), - }} + defaultAttributes := &pb.Account_PasswordAccountAttributes{ + &pb.PasswordAccountAttributes{ + LoginName: "default", + }, + } + modifiedAttributes := &pb.Account_PasswordAccountAttributes{ + &pb.PasswordAccountAttributes{ + LoginName: "modified", + }, + } freshAccount := func(t *testing.T) (*pb.Account, func()) { t.Helper() @@ -1112,7 +1190,7 @@ func TestUpdatePassword(t *testing.T) { Name: wrapperspb.String("default"), Description: wrapperspb.String("default"), Type: "password", - Attributes: defaultAttributes, + Attrs: defaultAttributes, }, }, ) @@ -1151,7 +1229,7 @@ func TestUpdatePassword(t *testing.T) { Name: &wrapperspb.StringValue{Value: "new"}, Description: &wrapperspb.StringValue{Value: "desc"}, Type: "password", - Attributes: defaultAttributes, + Attrs: defaultAttributes, Scope: defaultScopeInfo, AuthorizedActions: pwAuthorizedActions, }, @@ -1175,7 +1253,7 @@ func TestUpdatePassword(t *testing.T) { Name: &wrapperspb.StringValue{Value: "new"}, Description: &wrapperspb.StringValue{Value: "desc"}, Type: "password", - Attributes: defaultAttributes, + Attrs: defaultAttributes, Scope: defaultScopeInfo, AuthorizedActions: pwAuthorizedActions, }, @@ -1187,7 +1265,7 @@ func TestUpdatePassword(t *testing.T) { Item: &pb.Account{ Name: &wrapperspb.StringValue{Value: "updated name"}, Description: &wrapperspb.StringValue{Value: "updated desc"}, - Attributes: modifiedAttributes, + Attrs: modifiedAttributes, }, }, err: handlers.ApiErrorWithCode(codes.InvalidArgument), @@ -1212,7 +1290,7 @@ func TestUpdatePassword(t *testing.T) { Item: &pb.Account{ Name: &wrapperspb.StringValue{Value: "updated name"}, Description: &wrapperspb.StringValue{Value: "updated desc"}, - Attributes: modifiedAttributes, + Attrs: modifiedAttributes, }, }, err: handlers.ApiErrorWithCode(codes.InvalidArgument), @@ -1224,7 +1302,7 @@ func TestUpdatePassword(t *testing.T) { Item: &pb.Account{ Name: &wrapperspb.StringValue{Value: "updated name"}, Description: &wrapperspb.StringValue{Value: "updated desc"}, - Attributes: modifiedAttributes, + Attrs: modifiedAttributes, }, }, err: handlers.ApiErrorWithCode(codes.InvalidArgument), @@ -1237,7 +1315,7 @@ func TestUpdatePassword(t *testing.T) { }, Item: &pb.Account{ Description: &wrapperspb.StringValue{Value: "ignored"}, - Attributes: modifiedAttributes, + Attrs: modifiedAttributes, }, }, res: &pbs.UpdateAccountResponse{ @@ -1245,7 +1323,7 @@ func TestUpdatePassword(t *testing.T) { AuthMethodId: am.GetPublicId(), Description: &wrapperspb.StringValue{Value: "default"}, Type: "password", - Attributes: defaultAttributes, + Attrs: defaultAttributes, Scope: defaultScopeInfo, AuthorizedActions: pwAuthorizedActions, }, @@ -1260,7 +1338,7 @@ func TestUpdatePassword(t *testing.T) { Item: &pb.Account{ Name: &wrapperspb.StringValue{Value: "updated"}, Description: &wrapperspb.StringValue{Value: "ignored"}, - Attributes: modifiedAttributes, + Attrs: modifiedAttributes, }, }, res: &pbs.UpdateAccountResponse{ @@ -1269,7 +1347,7 @@ func TestUpdatePassword(t *testing.T) { Name: &wrapperspb.StringValue{Value: "updated"}, Description: &wrapperspb.StringValue{Value: "default"}, Type: "password", - Attributes: defaultAttributes, + Attrs: defaultAttributes, Scope: defaultScopeInfo, AuthorizedActions: pwAuthorizedActions, }, @@ -1284,7 +1362,7 @@ func TestUpdatePassword(t *testing.T) { Item: &pb.Account{ Name: &wrapperspb.StringValue{Value: "ignored"}, Description: &wrapperspb.StringValue{Value: "notignored"}, - Attributes: modifiedAttributes, + Attrs: modifiedAttributes, }, }, res: &pbs.UpdateAccountResponse{ @@ -1293,7 +1371,7 @@ func TestUpdatePassword(t *testing.T) { Name: &wrapperspb.StringValue{Value: "default"}, Description: &wrapperspb.StringValue{Value: "notignored"}, Type: "password", - Attributes: defaultAttributes, + Attrs: defaultAttributes, Scope: defaultScopeInfo, AuthorizedActions: pwAuthorizedActions, }, @@ -1308,7 +1386,7 @@ func TestUpdatePassword(t *testing.T) { Item: &pb.Account{ Name: &wrapperspb.StringValue{Value: "ignored"}, Description: &wrapperspb.StringValue{Value: "ignored"}, - Attributes: modifiedAttributes, + Attrs: modifiedAttributes, }, }, res: &pbs.UpdateAccountResponse{ @@ -1317,7 +1395,7 @@ func TestUpdatePassword(t *testing.T) { Name: &wrapperspb.StringValue{Value: "default"}, Description: &wrapperspb.StringValue{Value: "default"}, Type: "password", - Attributes: modifiedAttributes, + Attrs: modifiedAttributes, Scope: defaultScopeInfo, AuthorizedActions: pwAuthorizedActions, }, @@ -1427,6 +1505,8 @@ func TestUpdatePassword(t *testing.T) { if tc.err != nil { require.Error(gErr) assert.True(errors.Is(gErr, tc.err), "UpdateAccount(%+v) got error %v, wanted %v", tc.req, gErr, tc.err) + } else { + require.NoError(gErr) } if tc.res == nil { @@ -1486,14 +1566,18 @@ func TestUpdateOidc(t *testing.T) { require.NoError(t, err, "Error when getting new auth_method service.") defaultScopeInfo := &scopepb.ScopeInfo{Id: o.GetPublicId(), Type: o.GetType(), ParentScopeId: scope.Global.String()} - defaultAttributes := &structpb.Struct{Fields: map[string]*structpb.Value{ - "issuer": structpb.NewStringValue("https://www.alice.com"), - "subject": structpb.NewStringValue("test-subject"), - }} - modifiedAttributes := &structpb.Struct{Fields: map[string]*structpb.Value{ - "issuer": structpb.NewStringValue("https://www.changed.com"), - "subject": structpb.NewStringValue("changed"), - }} + defaultAttributes := &pb.Account_OidcAccountAttributes{ + &pb.OidcAccountAttributes{ + Issuer: "https://www.alice.com", + Subject: "test-subject", + }, + } + modifiedAttributes := &pb.Account_OidcAccountAttributes{ + &pb.OidcAccountAttributes{ + Issuer: "https://www.changed.com", + Subject: "changed", + }, + } freshAccount := func(t *testing.T) (*oidc.Account, func()) { t.Helper() @@ -1532,7 +1616,7 @@ func TestUpdateOidc(t *testing.T) { Name: &wrapperspb.StringValue{Value: "new"}, Description: &wrapperspb.StringValue{Value: "desc"}, Type: oidc.Subtype.String(), - Attributes: defaultAttributes, + Attrs: defaultAttributes, Scope: defaultScopeInfo, AuthorizedActions: oidcAuthorizedActions, }, @@ -1556,7 +1640,7 @@ func TestUpdateOidc(t *testing.T) { Name: &wrapperspb.StringValue{Value: "new"}, Description: &wrapperspb.StringValue{Value: "desc"}, Type: oidc.Subtype.String(), - Attributes: defaultAttributes, + Attrs: defaultAttributes, Scope: defaultScopeInfo, AuthorizedActions: oidcAuthorizedActions, }, @@ -1568,7 +1652,7 @@ func TestUpdateOidc(t *testing.T) { Item: &pb.Account{ Name: &wrapperspb.StringValue{Value: "updated name"}, Description: &wrapperspb.StringValue{Value: "updated desc"}, - Attributes: modifiedAttributes, + Attrs: modifiedAttributes, }, }, err: handlers.ApiErrorWithCode(codes.InvalidArgument), @@ -1593,7 +1677,7 @@ func TestUpdateOidc(t *testing.T) { Item: &pb.Account{ Name: &wrapperspb.StringValue{Value: "updated name"}, Description: &wrapperspb.StringValue{Value: "updated desc"}, - Attributes: modifiedAttributes, + Attrs: modifiedAttributes, }, }, err: handlers.ApiErrorWithCode(codes.InvalidArgument), @@ -1605,7 +1689,7 @@ func TestUpdateOidc(t *testing.T) { Item: &pb.Account{ Name: &wrapperspb.StringValue{Value: "updated name"}, Description: &wrapperspb.StringValue{Value: "updated desc"}, - Attributes: modifiedAttributes, + Attrs: modifiedAttributes, }, }, err: handlers.ApiErrorWithCode(codes.InvalidArgument), @@ -1618,7 +1702,7 @@ func TestUpdateOidc(t *testing.T) { }, Item: &pb.Account{ Description: &wrapperspb.StringValue{Value: "ignored"}, - Attributes: modifiedAttributes, + Attrs: modifiedAttributes, }, }, res: &pbs.UpdateAccountResponse{ @@ -1626,7 +1710,7 @@ func TestUpdateOidc(t *testing.T) { AuthMethodId: am.GetPublicId(), Description: &wrapperspb.StringValue{Value: "default"}, Type: oidc.Subtype.String(), - Attributes: defaultAttributes, + Attrs: defaultAttributes, Scope: defaultScopeInfo, AuthorizedActions: oidcAuthorizedActions, }, @@ -1641,7 +1725,7 @@ func TestUpdateOidc(t *testing.T) { Item: &pb.Account{ Name: &wrapperspb.StringValue{Value: "updated"}, Description: &wrapperspb.StringValue{Value: "ignored"}, - Attributes: modifiedAttributes, + Attrs: modifiedAttributes, }, }, res: &pbs.UpdateAccountResponse{ @@ -1650,7 +1734,7 @@ func TestUpdateOidc(t *testing.T) { Name: &wrapperspb.StringValue{Value: "updated"}, Description: &wrapperspb.StringValue{Value: "default"}, Type: oidc.Subtype.String(), - Attributes: defaultAttributes, + Attrs: defaultAttributes, Scope: defaultScopeInfo, AuthorizedActions: oidcAuthorizedActions, }, @@ -1665,7 +1749,7 @@ func TestUpdateOidc(t *testing.T) { Item: &pb.Account{ Name: &wrapperspb.StringValue{Value: "ignored"}, Description: &wrapperspb.StringValue{Value: "notignored"}, - Attributes: modifiedAttributes, + Attrs: modifiedAttributes, }, }, res: &pbs.UpdateAccountResponse{ @@ -1674,7 +1758,7 @@ func TestUpdateOidc(t *testing.T) { Name: &wrapperspb.StringValue{Value: "default"}, Description: &wrapperspb.StringValue{Value: "notignored"}, Type: oidc.Subtype.String(), - Attributes: defaultAttributes, + Attrs: defaultAttributes, Scope: defaultScopeInfo, AuthorizedActions: oidcAuthorizedActions, }, @@ -1689,7 +1773,7 @@ func TestUpdateOidc(t *testing.T) { Item: &pb.Account{ Name: &wrapperspb.StringValue{Value: "ignored"}, Description: &wrapperspb.StringValue{Value: "ignored"}, - Attributes: modifiedAttributes, + Attrs: modifiedAttributes, }, }, err: handlers.ApiErrorWithCode(codes.InvalidArgument), @@ -1769,8 +1853,8 @@ func TestUpdateOidc(t *testing.T) { Paths: []string{"attributes.issuer"}, }, Item: &pb.Account{ - Name: &wrapperspb.StringValue{Value: "ignored"}, - Attributes: modifiedAttributes, + Name: &wrapperspb.StringValue{Value: "ignored"}, + Attrs: modifiedAttributes, }, }, err: handlers.ApiErrorWithCode(codes.InvalidArgument), @@ -1782,8 +1866,8 @@ func TestUpdateOidc(t *testing.T) { Paths: []string{"attributes.subject"}, }, Item: &pb.Account{ - Name: &wrapperspb.StringValue{Value: "ignored"}, - Attributes: modifiedAttributes, + Name: &wrapperspb.StringValue{Value: "ignored"}, + Attrs: modifiedAttributes, }, }, err: handlers.ApiErrorWithCode(codes.InvalidArgument), @@ -1860,19 +1944,19 @@ func TestSetPassword(t *testing.T) { createAccount := func(t *testing.T, pw string) *pb.Account { am := password.TestAuthMethods(t, conn, o.GetPublicId(), 1)[0] - pwAttrs := &pb.PasswordAccountAttributes{ - LoginName: "testusername", + pwAttrs := &pb.Account_PasswordAccountAttributes{ + &pb.PasswordAccountAttributes{ + LoginName: "testusername", + }, } if pw != "" { - pwAttrs.Password = wrapperspb.String(pw) + pwAttrs.PasswordAccountAttributes.Password = wrapperspb.String(pw) } - attrs, err := handlers.ProtoToStruct(pwAttrs) - require.NoError(t, err) createResp, err := tested.CreateAccount(requestauth.DisabledAuthTestContext(iamRepoFn, o.GetPublicId()), &pbs.CreateAccountRequest{ Item: &pb.Account{ AuthMethodId: am.GetPublicId(), Type: "password", - Attributes: attrs, + Attrs: pwAttrs, }, }) require.NoError(t, err) @@ -1999,19 +2083,17 @@ func TestChangePassword(t *testing.T) { createAccount := func(t *testing.T, pw string) *pb.Account { am := password.TestAuthMethods(t, conn, o.GetPublicId(), 1)[0] - pwAttrs := &pb.PasswordAccountAttributes{ + pwAttrs := &pb.Account_PasswordAccountAttributes{&pb.PasswordAccountAttributes{ LoginName: "testusername", - } + }} if pw != "" { - pwAttrs.Password = wrapperspb.String(pw) + pwAttrs.PasswordAccountAttributes.Password = wrapperspb.String(pw) } - attrs, err := handlers.ProtoToStruct(pwAttrs) - require.NoError(t, err) createResp, err := tested.CreateAccount(requestauth.DisabledAuthTestContext(iamRepoFn, o.GetPublicId()), &pbs.CreateAccountRequest{ Item: &pb.Account{ AuthMethodId: am.GetPublicId(), Type: "password", - Attributes: attrs, + Attrs: pwAttrs, }, }) require.NoError(t, err) diff --git a/internal/servers/controller/handlers/accounts/validate_test.go b/internal/servers/controller/handlers/accounts/validate_test.go index aefcdfec7..cca7a580a 100644 --- a/internal/servers/controller/handlers/accounts/validate_test.go +++ b/internal/servers/controller/handlers/accounts/validate_test.go @@ -13,7 +13,6 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "google.golang.org/protobuf/types/known/fieldmaskpb" - "google.golang.org/protobuf/types/known/structpb" ) func fieldError(field, details string) string { @@ -63,9 +62,9 @@ func TestValidateCreateRequest(t *testing.T) { item: &pb.Account{ Type: oidc.Subtype.String(), AuthMethodId: oidc.AuthMethodPrefix + "_1234567890", - Attributes: &structpb.Struct{Fields: map[string]*structpb.Value{ - "full_name": structpb.NewStringValue("something"), - }}, + Attrs: &pb.Account_OidcAccountAttributes{ + OidcAccountAttributes: &pb.OidcAccountAttributes{FullName: "something"}, + }, }, errContains: fieldError(nameClaimField, "This is a read only field."), }, @@ -74,9 +73,9 @@ func TestValidateCreateRequest(t *testing.T) { item: &pb.Account{ Type: oidc.Subtype.String(), AuthMethodId: oidc.AuthMethodPrefix + "_1234567890", - Attributes: &structpb.Struct{Fields: map[string]*structpb.Value{ - "email": structpb.NewStringValue("something"), - }}, + Attrs: &pb.Account_OidcAccountAttributes{ + OidcAccountAttributes: &pb.OidcAccountAttributes{Email: "something"}, + }, }, errContains: fieldError(emailClaimField, "This is a read only field."), }, @@ -88,36 +87,16 @@ func TestValidateCreateRequest(t *testing.T) { }, errContains: fieldError(loginNameKey, "This is a required field for this type."), }, - { - name: "bad pw attributes", - item: &pb.Account{ - Type: password.Subtype.String(), - AuthMethodId: password.AuthMethodPrefix + "_1234567890", - Attributes: &structpb.Struct{Fields: map[string]*structpb.Value{ - "test": structpb.NewStringValue("something"), - }}, - }, - errContains: fieldError(attributesField, "Attribute fields do not match the expected format."), - }, - { - name: "bad oidc attributes", - item: &pb.Account{ - Type: oidc.Subtype.String(), - AuthMethodId: oidc.AuthMethodPrefix + "_1234567890", - Attributes: &structpb.Struct{Fields: map[string]*structpb.Value{ - "test": structpb.NewStringValue("something"), - }}, - }, - errContains: fieldError(attributesField, "Attribute fields do not match the expected format."), - }, { name: "no error", item: &pb.Account{ Type: password.Subtype.String(), AuthMethodId: password.AuthMethodPrefix + "_1234567890", - Attributes: &structpb.Struct{Fields: map[string]*structpb.Value{ - loginNameKey: structpb.NewStringValue("something"), - }}, + Attrs: &pb.Account_PasswordAccountAttributes{ + PasswordAccountAttributes: &pb.PasswordAccountAttributes{ + LoginName: "something", + }, + }, }, }, { @@ -125,9 +104,9 @@ func TestValidateCreateRequest(t *testing.T) { item: &pb.Account{ Type: oidc.Subtype.String(), AuthMethodId: oidc.AuthMethodPrefix + "_1234567890", - Attributes: &structpb.Struct{Fields: map[string]*structpb.Value{ - "subject": structpb.NewStringValue("no oidc errors"), - }}, + Attrs: &pb.Account_OidcAccountAttributes{ + OidcAccountAttributes: &pb.OidcAccountAttributes{Subject: "no oidc errors"}, + }, }, }, } @@ -183,42 +162,6 @@ func TestValidateUpdateRequest(t *testing.T) { }, errContains: fieldError(typeField, "Cannot modify the resource type."), }, - { - name: "password bad attributes old prefix", - req: &pbs.UpdateAccountRequest{ - Id: intglobals.OldPasswordAccountPrefix + "_1234567890", - Item: &pb.Account{ - Attributes: &structpb.Struct{Fields: map[string]*structpb.Value{ - "test": structpb.NewStringValue("something"), - }}, - }, - }, - errContains: fieldError(attributesField, "Attribute fields do not match the expected format."), - }, - { - name: "password bad attributes new prefix", - req: &pbs.UpdateAccountRequest{ - Id: intglobals.NewPasswordAccountPrefix + "_1234567890", - Item: &pb.Account{ - Attributes: &structpb.Struct{Fields: map[string]*structpb.Value{ - "test": structpb.NewStringValue("something"), - }}, - }, - }, - errContains: fieldError(attributesField, "Attribute fields do not match the expected format."), - }, - { - name: "oidc bad attributes", - req: &pbs.UpdateAccountRequest{ - Id: oidc.AccountPrefix + "_1234567890", - Item: &pb.Account{ - Attributes: &structpb.Struct{Fields: map[string]*structpb.Value{ - "test": structpb.NewStringValue("something"), - }}, - }, - }, - errContains: fieldError(attributesField, "Attribute fields do not match the expected format."), - }, { name: "no error", req: &pbs.UpdateAccountRequest{ diff --git a/sdk/pbs/controller/api/resources/accounts/account.pb.go b/sdk/pbs/controller/api/resources/accounts/account.pb.go index 9313f43d0..436302a91 100644 --- a/sdk/pbs/controller/api/resources/accounts/account.pb.go +++ b/sdk/pbs/controller/api/resources/accounts/account.pb.go @@ -50,8 +50,11 @@ type Account struct { Type string `protobuf:"bytes,80,opt,name=type,proto3" json:"type,omitempty"` // The ID of the Auth Method that is associated with this Account. AuthMethodId string `protobuf:"bytes,90,opt,name=auth_method_id,proto3" json:"auth_method_id,omitempty"` - // The attributes that are applicable for the specific Account type. - Attributes *structpb.Struct `protobuf:"bytes,100,opt,name=attributes,proto3" json:"attributes,omitempty"` + // Types that are assignable to Attrs: + // *Account_Attributes + // *Account_PasswordAccountAttributes + // *Account_OidcAccountAttributes + Attrs isAccount_Attrs `protobuf_oneof:"attrs"` // Output only. managed_group_ids indicates IDs of the managed groups that currently contain this account ManagedGroupIds []string `protobuf:"bytes,110,rep,name=managed_group_ids,proto3" json:"managed_group_ids,omitempty"` // Output only. The available actions on this resource for this user. @@ -153,13 +156,34 @@ func (x *Account) GetAuthMethodId() string { return "" } +func (m *Account) GetAttrs() isAccount_Attrs { + if m != nil { + return m.Attrs + } + return nil +} + func (x *Account) GetAttributes() *structpb.Struct { - if x != nil { + if x, ok := x.GetAttrs().(*Account_Attributes); ok { return x.Attributes } return nil } +func (x *Account) GetPasswordAccountAttributes() *PasswordAccountAttributes { + if x, ok := x.GetAttrs().(*Account_PasswordAccountAttributes); ok { + return x.PasswordAccountAttributes + } + return nil +} + +func (x *Account) GetOidcAccountAttributes() *OidcAccountAttributes { + if x, ok := x.GetAttrs().(*Account_OidcAccountAttributes); ok { + return x.OidcAccountAttributes + } + return nil +} + func (x *Account) GetManagedGroupIds() []string { if x != nil { return x.ManagedGroupIds @@ -174,6 +198,29 @@ func (x *Account) GetAuthorizedActions() []string { return nil } +type isAccount_Attrs interface { + isAccount_Attrs() +} + +type Account_Attributes struct { + // The attributes that are applicable for the specific Account type. + Attributes *structpb.Struct `protobuf:"bytes,100,opt,name=attributes,proto3,oneof"` +} + +type Account_PasswordAccountAttributes struct { + PasswordAccountAttributes *PasswordAccountAttributes `protobuf:"bytes,101,opt,name=password_account_attributes,json=passwordAccountAttributes,proto3,oneof"` +} + +type Account_OidcAccountAttributes struct { + OidcAccountAttributes *OidcAccountAttributes `protobuf:"bytes,102,opt,name=oidc_account_attributes,json=oidcAccountAttributes,proto3,oneof"` +} + +func (*Account_Attributes) isAccount_Attrs() {} + +func (*Account_PasswordAccountAttributes) isAccount_Attrs() {} + +func (*Account_OidcAccountAttributes) isAccount_Attrs() {} + // Attributes associated only with Accounts with type "password". type PasswordAccountAttributes struct { state protoimpl.MessageState @@ -348,7 +395,7 @@ var file_controller_api_resources_accounts_v1_account_proto_rawDesc = []byte{ 0x6f, 0x70, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x2a, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2f, 0x63, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x5f, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x76, 0x31, 0x2f, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xfe, 0x04, 0x0a, 0x07, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xb0, 0x07, 0x0a, 0x07, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x43, 0x0a, 0x05, 0x73, 0x63, 0x6f, 0x70, 0x65, 0x18, 0x14, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2d, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2e, 0x61, 0x70, @@ -378,50 +425,69 @@ var file_controller_api_resources_accounts_v1_account_proto_rawDesc = []byte{ 0x74, 0x79, 0x70, 0x65, 0x18, 0x50, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x26, 0x0a, 0x0e, 0x61, 0x75, 0x74, 0x68, 0x5f, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x5f, 0x69, 0x64, 0x18, 0x5a, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x61, 0x75, 0x74, 0x68, 0x5f, 0x6d, - 0x65, 0x74, 0x68, 0x6f, 0x64, 0x5f, 0x69, 0x64, 0x12, 0x3d, 0x0a, 0x0a, 0x61, 0x74, 0x74, 0x72, + 0x65, 0x74, 0x68, 0x6f, 0x64, 0x5f, 0x69, 0x64, 0x12, 0x4a, 0x0a, 0x0a, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x18, 0x64, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, - 0x74, 0x72, 0x75, 0x63, 0x74, 0x42, 0x04, 0xa0, 0xda, 0x29, 0x01, 0x52, 0x0a, 0x61, 0x74, 0x74, - 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x12, 0x2c, 0x0a, 0x11, 0x6d, 0x61, 0x6e, 0x61, 0x67, - 0x65, 0x64, 0x5f, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x5f, 0x69, 0x64, 0x73, 0x18, 0x6e, 0x20, 0x03, - 0x28, 0x09, 0x52, 0x11, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x64, 0x5f, 0x67, 0x72, 0x6f, 0x75, - 0x70, 0x5f, 0x69, 0x64, 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, 0x22, 0xa7, 0x01, 0x0a, 0x19, 0x50, 0x61, 0x73, 0x73, 0x77, - 0x6f, 0x72, 0x64, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, - 0x75, 0x74, 0x65, 0x73, 0x12, 0x4a, 0x0a, 0x0a, 0x6c, 0x6f, 0x67, 0x69, 0x6e, 0x5f, 0x6e, 0x61, - 0x6d, 0x65, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, 0x42, 0x2a, 0xa0, 0xda, 0x29, 0x01, 0xc2, 0xdd, - 0x29, 0x22, 0x0a, 0x15, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2e, 0x6c, - 0x6f, 0x67, 0x69, 0x6e, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x09, 0x4c, 0x6f, 0x67, 0x69, 0x6e, - 0x4e, 0x61, 0x6d, 0x65, 0x52, 0x0a, 0x6c, 0x6f, 0x67, 0x69, 0x6e, 0x5f, 0x6e, 0x61, 0x6d, 0x65, - 0x12, 0x3e, 0x0a, 0x08, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x18, 0x14, 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, 0x04, 0xa0, 0xda, 0x29, 0x01, 0x52, 0x08, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, - 0x22, 0x88, 0x02, 0x0a, 0x15, 0x4f, 0x69, 0x64, 0x63, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, - 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x12, 0x1c, 0x0a, 0x06, 0x69, 0x73, - 0x73, 0x75, 0x65, 0x72, 0x18, 0x50, 0x20, 0x01, 0x28, 0x09, 0x42, 0x04, 0xa0, 0xda, 0x29, 0x01, - 0x52, 0x06, 0x69, 0x73, 0x73, 0x75, 0x65, 0x72, 0x12, 0x1e, 0x0a, 0x07, 0x73, 0x75, 0x62, 0x6a, - 0x65, 0x63, 0x74, 0x18, 0x5a, 0x20, 0x01, 0x28, 0x09, 0x42, 0x04, 0xa0, 0xda, 0x29, 0x01, 0x52, - 0x07, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x12, 0x1c, 0x0a, 0x09, 0x66, 0x75, 0x6c, 0x6c, - 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x64, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x66, 0x75, 0x6c, - 0x6c, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x18, - 0x6e, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x12, 0x3a, 0x0a, 0x0c, - 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x5f, 0x63, 0x6c, 0x61, 0x69, 0x6d, 0x73, 0x18, 0x78, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, 0x52, 0x0b, 0x74, 0x6f, 0x6b, - 0x65, 0x6e, 0x43, 0x6c, 0x61, 0x69, 0x6d, 0x73, 0x12, 0x41, 0x0a, 0x0f, 0x75, 0x73, 0x65, 0x72, - 0x69, 0x6e, 0x66, 0x6f, 0x5f, 0x63, 0x6c, 0x61, 0x69, 0x6d, 0x73, 0x18, 0x82, 0x01, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, 0x52, 0x0e, 0x75, 0x73, 0x65, - 0x72, 0x69, 0x6e, 0x66, 0x6f, 0x43, 0x6c, 0x61, 0x69, 0x6d, 0x73, 0x42, 0x52, 0x5a, 0x50, 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, 0x61, 0x63, - 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x3b, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x62, - 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x74, 0x72, 0x75, 0x63, 0x74, 0x42, 0x0f, 0xa0, 0xda, 0x29, 0x01, 0x9a, 0xe3, 0x29, 0x07, 0x64, + 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x48, 0x00, 0x52, 0x0a, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, + 0x75, 0x74, 0x65, 0x73, 0x12, 0x93, 0x01, 0x0a, 0x1b, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, + 0x64, 0x5f, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x5f, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, + 0x75, 0x74, 0x65, 0x73, 0x18, 0x65, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x3f, 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, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x2e, 0x76, + 0x31, 0x2e, 0x50, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, + 0x74, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x42, 0x10, 0xa0, 0xda, 0x29, + 0x01, 0x9a, 0xe3, 0x29, 0x08, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x48, 0x00, 0x52, + 0x19, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, + 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x12, 0x83, 0x01, 0x0a, 0x17, 0x6f, + 0x69, 0x64, 0x63, 0x5f, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x5f, 0x61, 0x74, 0x74, 0x72, + 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x18, 0x66, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x3b, 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, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x73, + 0x2e, 0x76, 0x31, 0x2e, 0x4f, 0x69, 0x64, 0x63, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x41, + 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x42, 0x0c, 0xa0, 0xda, 0x29, 0x01, 0x9a, + 0xe3, 0x29, 0x04, 0x6f, 0x69, 0x64, 0x63, 0x48, 0x00, 0x52, 0x15, 0x6f, 0x69, 0x64, 0x63, 0x41, + 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, + 0x12, 0x2c, 0x0a, 0x11, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x64, 0x5f, 0x67, 0x72, 0x6f, 0x75, + 0x70, 0x5f, 0x69, 0x64, 0x73, 0x18, 0x6e, 0x20, 0x03, 0x28, 0x09, 0x52, 0x11, 0x6d, 0x61, 0x6e, + 0x61, 0x67, 0x65, 0x64, 0x5f, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x5f, 0x69, 0x64, 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, + 0x07, 0x0a, 0x05, 0x61, 0x74, 0x74, 0x72, 0x73, 0x22, 0xa7, 0x01, 0x0a, 0x19, 0x50, 0x61, 0x73, + 0x73, 0x77, 0x6f, 0x72, 0x64, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x41, 0x74, 0x74, 0x72, + 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x12, 0x4a, 0x0a, 0x0a, 0x6c, 0x6f, 0x67, 0x69, 0x6e, 0x5f, + 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, 0x42, 0x2a, 0xa0, 0xda, 0x29, 0x01, + 0xc2, 0xdd, 0x29, 0x22, 0x0a, 0x15, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, + 0x2e, 0x6c, 0x6f, 0x67, 0x69, 0x6e, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x09, 0x4c, 0x6f, 0x67, + 0x69, 0x6e, 0x4e, 0x61, 0x6d, 0x65, 0x52, 0x0a, 0x6c, 0x6f, 0x67, 0x69, 0x6e, 0x5f, 0x6e, 0x61, + 0x6d, 0x65, 0x12, 0x3e, 0x0a, 0x08, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x18, 0x14, + 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, 0x04, 0xa0, 0xda, 0x29, 0x01, 0x52, 0x08, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, + 0x72, 0x64, 0x22, 0x88, 0x02, 0x0a, 0x15, 0x4f, 0x69, 0x64, 0x63, 0x41, 0x63, 0x63, 0x6f, 0x75, + 0x6e, 0x74, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x12, 0x1c, 0x0a, 0x06, + 0x69, 0x73, 0x73, 0x75, 0x65, 0x72, 0x18, 0x50, 0x20, 0x01, 0x28, 0x09, 0x42, 0x04, 0xa0, 0xda, + 0x29, 0x01, 0x52, 0x06, 0x69, 0x73, 0x73, 0x75, 0x65, 0x72, 0x12, 0x1e, 0x0a, 0x07, 0x73, 0x75, + 0x62, 0x6a, 0x65, 0x63, 0x74, 0x18, 0x5a, 0x20, 0x01, 0x28, 0x09, 0x42, 0x04, 0xa0, 0xda, 0x29, + 0x01, 0x52, 0x07, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x12, 0x1c, 0x0a, 0x09, 0x66, 0x75, + 0x6c, 0x6c, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x64, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x66, + 0x75, 0x6c, 0x6c, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x6d, 0x61, 0x69, + 0x6c, 0x18, 0x6e, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x12, 0x3a, + 0x0a, 0x0c, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x5f, 0x63, 0x6c, 0x61, 0x69, 0x6d, 0x73, 0x18, 0x78, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, 0x52, 0x0b, 0x74, + 0x6f, 0x6b, 0x65, 0x6e, 0x43, 0x6c, 0x61, 0x69, 0x6d, 0x73, 0x12, 0x41, 0x0a, 0x0f, 0x75, 0x73, + 0x65, 0x72, 0x69, 0x6e, 0x66, 0x6f, 0x5f, 0x63, 0x6c, 0x61, 0x69, 0x6d, 0x73, 0x18, 0x82, 0x01, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, 0x52, 0x0e, 0x75, + 0x73, 0x65, 0x72, 0x69, 0x6e, 0x66, 0x6f, 0x43, 0x6c, 0x61, 0x69, 0x6d, 0x73, 0x42, 0x52, 0x5a, + 0x50, 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, + 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x3b, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, + 0x73, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -447,20 +513,22 @@ var file_controller_api_resources_accounts_v1_account_proto_goTypes = []interfac (*structpb.Struct)(nil), // 6: google.protobuf.Struct } var file_controller_api_resources_accounts_v1_account_proto_depIdxs = []int32{ - 3, // 0: controller.api.resources.accounts.v1.Account.scope:type_name -> controller.api.resources.scopes.v1.ScopeInfo - 4, // 1: controller.api.resources.accounts.v1.Account.name:type_name -> google.protobuf.StringValue - 4, // 2: controller.api.resources.accounts.v1.Account.description:type_name -> google.protobuf.StringValue - 5, // 3: controller.api.resources.accounts.v1.Account.created_time:type_name -> google.protobuf.Timestamp - 5, // 4: controller.api.resources.accounts.v1.Account.updated_time:type_name -> google.protobuf.Timestamp - 6, // 5: controller.api.resources.accounts.v1.Account.attributes:type_name -> google.protobuf.Struct - 4, // 6: controller.api.resources.accounts.v1.PasswordAccountAttributes.password:type_name -> google.protobuf.StringValue - 6, // 7: controller.api.resources.accounts.v1.OidcAccountAttributes.token_claims:type_name -> google.protobuf.Struct - 6, // 8: controller.api.resources.accounts.v1.OidcAccountAttributes.userinfo_claims:type_name -> google.protobuf.Struct - 9, // [9:9] is the sub-list for method output_type - 9, // [9:9] is the sub-list for method input_type - 9, // [9:9] is the sub-list for extension type_name - 9, // [9:9] is the sub-list for extension extendee - 0, // [0:9] is the sub-list for field type_name + 3, // 0: controller.api.resources.accounts.v1.Account.scope:type_name -> controller.api.resources.scopes.v1.ScopeInfo + 4, // 1: controller.api.resources.accounts.v1.Account.name:type_name -> google.protobuf.StringValue + 4, // 2: controller.api.resources.accounts.v1.Account.description:type_name -> google.protobuf.StringValue + 5, // 3: controller.api.resources.accounts.v1.Account.created_time:type_name -> google.protobuf.Timestamp + 5, // 4: controller.api.resources.accounts.v1.Account.updated_time:type_name -> google.protobuf.Timestamp + 6, // 5: controller.api.resources.accounts.v1.Account.attributes:type_name -> google.protobuf.Struct + 1, // 6: controller.api.resources.accounts.v1.Account.password_account_attributes:type_name -> controller.api.resources.accounts.v1.PasswordAccountAttributes + 2, // 7: controller.api.resources.accounts.v1.Account.oidc_account_attributes:type_name -> controller.api.resources.accounts.v1.OidcAccountAttributes + 4, // 8: controller.api.resources.accounts.v1.PasswordAccountAttributes.password:type_name -> google.protobuf.StringValue + 6, // 9: controller.api.resources.accounts.v1.OidcAccountAttributes.token_claims:type_name -> google.protobuf.Struct + 6, // 10: controller.api.resources.accounts.v1.OidcAccountAttributes.userinfo_claims:type_name -> google.protobuf.Struct + 11, // [11:11] is the sub-list for method output_type + 11, // [11:11] is the sub-list for method input_type + 11, // [11:11] is the sub-list for extension type_name + 11, // [11:11] is the sub-list for extension extendee + 0, // [0:11] is the sub-list for field type_name } func init() { file_controller_api_resources_accounts_v1_account_proto_init() } @@ -506,6 +574,11 @@ func file_controller_api_resources_accounts_v1_account_proto_init() { } } } + file_controller_api_resources_accounts_v1_account_proto_msgTypes[0].OneofWrappers = []interface{}{ + (*Account_Attributes)(nil), + (*Account_PasswordAccountAttributes)(nil), + (*Account_OidcAccountAttributes)(nil), + } type x struct{} out := protoimpl.TypeBuilder{ File: protoimpl.DescBuilder{