feat(handlers): CRUDL support for static Username-Password-Domain credentials

pull/6010/head
Andrew Gaffney 1 year ago committed by irenarindos
parent e4dfa76c8e
commit f265ec4e5b

@ -143,6 +143,18 @@ func DefaultDescription() Option {
}
}
func WithUsernamePasswordDomainCredentialDomain(inDomain string) Option {
return func(o *options) {
raw, ok := o.postMap["attributes"]
if !ok {
raw = any(map[string]any{})
}
val := raw.(map[string]any)
val["domain"] = inDomain
o.postMap["attributes"] = val
}
}
func WithName(inName string) Option {
return func(o *options) {
o.postMap["name"] = inName
@ -179,6 +191,18 @@ func WithUsernamePasswordCredentialPassword(inPassword string) Option {
}
}
func WithUsernamePasswordDomainCredentialPassword(inPassword string) Option {
return func(o *options) {
raw, ok := o.postMap["attributes"]
if !ok {
raw = any(map[string]any{})
}
val := raw.(map[string]any)
val["password"] = inPassword
o.postMap["attributes"] = val
}
}
func WithSshPrivateKeyCredentialPrivateKey(inPrivateKey string) Option {
return func(o *options) {
raw, ok := o.postMap["attributes"]
@ -238,3 +262,15 @@ func WithUsernamePasswordCredentialUsername(inUsername string) Option {
o.postMap["attributes"] = val
}
}
func WithUsernamePasswordDomainCredentialUsername(inUsername string) Option {
return func(o *options) {
raw, ok := o.postMap["attributes"]
if !ok {
raw = any(map[string]any{})
}
val := raw.(map[string]any)
val["username"] = inUsername
o.postMap["attributes"] = val
}
}

@ -0,0 +1,43 @@
// Code generated by "make api"; DO NOT EDIT.
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: MPL-2.0
package credentials
import (
"fmt"
"github.com/mitchellh/mapstructure"
)
type UsernamePasswordDomainAttributes struct {
Username string `json:"username,omitempty"`
Password string `json:"password,omitempty"`
PasswordHmac string `json:"password_hmac,omitempty"`
Domain string `json:"domain,omitempty"`
}
func AttributesMapToUsernamePasswordDomainAttributes(in map[string]any) (*UsernamePasswordDomainAttributes, error) {
if in == nil {
return nil, fmt.Errorf("nil input map")
}
var out UsernamePasswordDomainAttributes
dec, err := mapstructure.NewDecoder(&mapstructure.DecoderConfig{
Result: &out,
TagName: "json",
})
if err != nil {
return nil, fmt.Errorf("error creating mapstructure decoder: %w", err)
}
if err := dec.Decode(in); err != nil {
return nil, fmt.Errorf("error decoding: %w", err)
}
return &out, nil
}
func (pt *Credential) GetUsernamePasswordDomainAttributes() (*UsernamePasswordDomainAttributes, error) {
if pt.Type != "username_password_domain" {
return nil, fmt.Errorf("asked to fetch %s-type attributes but credential is of type %s", "username_password_domain", pt.Type)
}
return AttributesMapToUsernamePasswordDomainAttributes(pt.Attributes)
}

@ -696,6 +696,30 @@ var inputStructs = []*structInfo{
mapstructureConversionTemplate,
},
},
{
inProto: &credentials.UsernamePasswordDomainAttributes{},
outFile: "credentials/username_password_domain_attributes.gen.go",
subtypeName: "UsernamePasswordDomainCredential",
subtype: "username_password_domain",
fieldOverrides: []fieldInfo{
{
Name: "Username",
SkipDefault: true,
},
{
Name: "Password",
SkipDefault: true,
},
{
Name: "Domain",
SkipDefault: true,
},
},
parentTypeName: "Credential",
templates: []*template.Template{
mapstructureConversionTemplate,
},
},
{
inProto: &credentials.SshPrivateKeyAttributes{},
outFile: "credentials/ssh_private_key_attributes.gen.go",

@ -37,6 +37,7 @@ import (
const (
usernameField = "attributes.username"
passwordField = "attributes.password"
domainField = "attributes.domain"
privateKeyField = "attributes.private_key"
privateKeyPassphraseField = "attributes.private_key_passphrase"
objectField = "attributes.object"
@ -44,6 +45,7 @@ const (
)
var (
updMaskManager handlers.MaskManager
upMaskManager handlers.MaskManager
spkMaskManager handlers.MaskManager
jsonMaskManager handlers.MaskManager
@ -88,6 +90,13 @@ func init() {
); err != nil {
panic(err)
}
if updMaskManager, err = handlers.NewMaskManager(
context.Background(),
handlers.MaskDestination{&store.UsernamePasswordDomainCredential{}},
handlers.MaskSource{&pb.Credential{}, &pb.UsernamePasswordDomainAttributes{}},
); err != nil {
panic(err)
}
// TODO: refactor to remove IdActionsMap and CollectionActions package variables
action.RegisterResource(resource.Credential, IdActions, CollectionActions)
@ -428,6 +437,23 @@ func (s Service) createInRepo(ctx context.Context, scopeId string, item *pb.Cred
return nil, handlers.ApiErrorWithCodeAndMessage(codes.Internal, "Unable to create credential but no error returned from repository.")
}
return out, nil
case credential.UsernamePasswordDomainSubtype.String():
cred, err := toUsernamePasswordDomainStorageCredential(ctx, item.GetCredentialStoreId(), item)
if err != nil {
return nil, errors.Wrap(ctx, err, op)
}
repo, err := s.repoFn()
if err != nil {
return nil, errors.Wrap(ctx, err, op)
}
out, err := repo.CreateUsernamePasswordDomainCredential(ctx, scopeId, cred)
if err != nil {
return nil, errors.Wrap(ctx, err, op, errors.WithMsg("unable to create credential"))
}
if out == nil {
return nil, handlers.ApiErrorWithCodeAndMessage(codes.Internal, "Unable to create credential but no error returned from repository.")
}
return out, nil
case credential.SshPrivateKeySubtype.String():
cred, err := toSshPrivateKeyStorageCredential(ctx, item.GetCredentialStoreId(), item)
if err != nil {
@ -502,6 +528,29 @@ func (s Service) updateInRepo(
return nil, handlers.NotFoundErrorf("Credential %q doesn't exist or incorrect version provided.", id)
}
return out, nil
case credential.UsernamePasswordDomainSubtype:
dbMasks = append(dbMasks, updMaskManager.Translate(masks)...)
if len(dbMasks) == 0 {
return nil, handlers.InvalidArgumentErrorf("No valid fields included in the update mask.", map[string]string{"update_mask": "No valid fields provided in the update mask."})
}
cred, err := toUsernamePasswordDomainStorageCredential(ctx, storeId, in)
if err != nil {
return nil, errors.Wrap(ctx, err, op, errors.WithMsg("unable to convert to username/password/domain storage credential"))
}
cred.PublicId = id
repo, err := s.repoFn()
if err != nil {
return nil, errors.Wrap(ctx, err, op)
}
out, rowsUpdated, err := repo.UpdateUsernamePasswordDomainCredential(ctx, scopeId, cred, item.GetVersion(), dbMasks)
if err != nil {
return nil, errors.Wrap(ctx, err, op, errors.WithMsg("unable to update credential"))
}
if rowsUpdated == 0 {
return nil, handlers.NotFoundErrorf("Credential %q doesn't exist or incorrect version provided.", id)
}
return out, nil
case credential.SshPrivateKeySubtype:
dbMasks = append(dbMasks, spkMaskManager.Translate(masks)...)
@ -680,6 +729,8 @@ func toProto(in credential.Static, opt ...handlers.Option) (*pb.Credential, erro
switch in.(type) {
case *static.UsernamePasswordCredential:
out.Type = credential.UsernamePasswordSubtype.String()
case *static.UsernamePasswordDomainCredential:
out.Type = credential.UsernamePasswordDomainSubtype.String()
case *static.SshPrivateKeyCredential:
out.Type = credential.SshPrivateKeySubtype.String()
case *static.JsonCredential:
@ -718,6 +769,16 @@ func toProto(in credential.Static, opt ...handlers.Option) (*pb.Credential, erro
},
}
}
case *static.UsernamePasswordDomainCredential:
if outputFields.Has(globals.AttributesField) {
out.Attrs = &pb.Credential_UsernamePasswordDomainAttributes{
UsernamePasswordDomainAttributes: &pb.UsernamePasswordDomainAttributes{
Username: wrapperspb.String(cred.GetUsername()),
PasswordHmac: base64.RawURLEncoding.EncodeToString(cred.GetPasswordHmac()),
Domain: wrapperspb.String(cred.GetDomain()),
},
}
}
case *static.SshPrivateKeyCredential:
if outputFields.Has(globals.AttributesField) {
out.Attrs = &pb.Credential_SshPrivateKeyAttributes{
@ -763,6 +824,30 @@ func toUsernamePasswordStorageCredential(ctx context.Context, storeId string, in
return cs, err
}
func toUsernamePasswordDomainStorageCredential(ctx context.Context, storeId string, in *pb.Credential) (out *static.UsernamePasswordDomainCredential, err error) {
const op = "credentials.toUsernamePasswordDomainStorageCredential"
var opts []static.Option
if in.GetName() != nil {
opts = append(opts, static.WithName(in.GetName().GetValue()))
}
if in.GetDescription() != nil {
opts = append(opts, static.WithDescription(in.GetDescription().GetValue()))
}
attrs := in.GetUsernamePasswordDomainAttributes()
cs, err := static.NewUsernamePasswordDomainCredential(
storeId,
attrs.GetUsername().GetValue(),
credential.Password(attrs.GetPassword().GetValue()),
attrs.GetDomain().GetValue(),
opts...)
if err != nil {
return nil, errors.Wrap(ctx, err, op, errors.WithMsg("unable to build credential"))
}
return cs, err
}
func toSshPrivateKeyStorageCredential(ctx context.Context, storeId string, in *pb.Credential) (out *static.SshPrivateKeyCredential, err error) {
const op = "credentials.toSshPrivateKeyStorageCredential"
var opts []static.Option
@ -833,6 +918,7 @@ func validateGetRequest(req *pbs.GetCredentialRequest) error {
req,
globals.UsernamePasswordCredentialPrefix,
globals.UsernamePasswordCredentialPreviousPrefix,
globals.UsernamePasswordDomainCredentialPrefix,
globals.SshPrivateKeyCredentialPrefix,
globals.JsonCredentialPrefix,
)
@ -853,7 +939,16 @@ func validateCreateRequest(req *pbs.CreateCredentialRequest) error {
if req.Item.GetUsernamePasswordAttributes().GetPassword().GetValue() == "" {
badFields[passwordField] = "Field required for creating a username-password credential."
}
case credential.UsernamePasswordDomainSubtype.String():
if req.Item.GetUsernamePasswordDomainAttributes().GetUsername().GetValue() == "" {
badFields[usernameField] = "Field required for creating a username-password-domain credential."
}
if req.Item.GetUsernamePasswordDomainAttributes().GetPassword().GetValue() == "" {
badFields[passwordField] = "Field required for creating a username-password-domain credential."
}
if req.Item.GetUsernamePasswordDomainAttributes().GetDomain().GetValue() == "" {
badFields[domainField] = "Field required for creating a username-password-domain credential."
}
case credential.SshPrivateKeySubtype.String():
if req.Item.GetSshPrivateKeyAttributes().GetUsername().GetValue() == "" {
badFields[usernameField] = "Field required for creating an SSH private key credential."
@ -912,6 +1007,18 @@ func validateUpdateRequest(req *pbs.UpdateCredentialRequest) error {
badFields[passwordField] = "This is a required field and cannot be set to empty."
}
case credential.UsernamePasswordDomainSubtype:
attrs := req.GetItem().GetUsernamePasswordDomainAttributes()
if handlers.MaskContains(req.GetUpdateMask().GetPaths(), usernameField) && attrs.GetUsername().GetValue() == "" {
badFields[usernameField] = "This is a required field and cannot be set to empty."
}
if handlers.MaskContains(req.GetUpdateMask().GetPaths(), passwordField) && attrs.GetPassword().GetValue() == "" {
badFields[passwordField] = "This is a required field and cannot be set to empty."
}
if handlers.MaskContains(req.GetUpdateMask().GetPaths(), domainField) && attrs.GetDomain().GetValue() == "" {
badFields[domainField] = "This is a required field and cannot be set to empty."
}
case credential.SshPrivateKeySubtype:
attrs := req.GetItem().GetSshPrivateKeyAttributes()
if handlers.MaskContains(req.GetUpdateMask().GetPaths(), usernameField) && attrs.GetUsername().GetValue() == "" {
@ -962,6 +1069,7 @@ func validateUpdateRequest(req *pbs.UpdateCredentialRequest) error {
},
globals.UsernamePasswordCredentialPrefix,
globals.UsernamePasswordCredentialPreviousPrefix,
globals.UsernamePasswordDomainCredentialPrefix,
globals.SshPrivateKeyCredentialPrefix,
globals.JsonCredentialPrefix,
)
@ -973,6 +1081,7 @@ func validateDeleteRequest(req *pbs.DeleteCredentialRequest) error {
req,
globals.UsernamePasswordCredentialPrefix,
globals.UsernamePasswordCredentialPreviousPrefix,
globals.UsernamePasswordDomainCredentialPrefix,
globals.SshPrivateKeyCredentialPrefix,
globals.JsonCredentialPrefix,
)

@ -87,6 +87,26 @@ func staticPasswordCredentialToProto(cred *static.UsernamePasswordCredential, pr
}
}
func staticPasswordDomainCredentialToProto(cred *static.UsernamePasswordDomainCredential, prj *iam.Scope, hmac string) *pb.Credential {
return &pb.Credential{
Id: cred.GetPublicId(),
CredentialStoreId: cred.GetStoreId(),
Scope: &scopepb.ScopeInfo{Id: prj.GetPublicId(), Type: scope.Project.String(), ParentScopeId: prj.GetParentId()},
CreatedTime: cred.GetCreateTime().GetTimestamp(),
UpdatedTime: cred.GetUpdateTime().GetTimestamp(),
Version: cred.GetVersion(),
Type: credential.UsernamePasswordDomainSubtype.String(),
AuthorizedActions: testAuthorizedActions,
Attrs: &pb.Credential_UsernamePasswordDomainAttributes{
UsernamePasswordDomainAttributes: &pb.UsernamePasswordDomainAttributes{
Username: wrapperspb.String(cred.GetUsername()),
PasswordHmac: base64.RawURLEncoding.EncodeToString([]byte(hmac)),
Domain: wrapperspb.String(cred.GetDomain()),
},
},
}
}
func staticSshCredentialToProto(cred *static.SshPrivateKeyCredential, prj *iam.Scope, hmac string) *pb.Credential {
return &pb.Credential{
Id: cred.GetPublicId(),
@ -137,6 +157,12 @@ func TestList(t *testing.T) {
require.NoError(t, err)
wantCreds = append(wantCreds, staticPasswordCredentialToProto(c, prj, hm))
domain := fmt.Sprintf("domain-%d", i)
upd := static.TestUsernamePasswordDomainCredential(t, conn, wrapper, user, pass, domain, store.GetPublicId(), prj.GetPublicId())
hm, err = crypto.HmacSha256(ctx, []byte(pass), databaseWrapper, []byte(store.GetPublicId()), nil, crypto.WithEd25519())
require.NoError(t, err)
wantCreds = append(wantCreds, staticPasswordDomainCredentialToProto(upd, prj, hm))
spk := static.TestSshPrivateKeyCredential(t, conn, wrapper, user, static.TestSshPrivateKeyPem, store.GetPublicId(), prj.GetPublicId())
hm, err = crypto.HmacSha256(ctx, []byte(static.TestSshPrivateKeyPem), databaseWrapper, []byte(store.GetPublicId()), nil)
require.NoError(t, err)
@ -167,7 +193,7 @@ func TestList(t *testing.T) {
SortBy: "created_time",
SortDir: "desc",
RemovedIds: nil,
EstItemCount: 30,
EstItemCount: 40,
},
anonRes: &pbs.ListCredentialsResponse{
Items: wantCreds,
@ -221,15 +247,15 @@ func TestList(t *testing.T) {
},
{
name: "Filter on Attribute",
req: &pbs.ListCredentialsRequest{CredentialStoreId: store.GetPublicId(), Filter: fmt.Sprintf(`"/item/attributes/username"==%q`, wantCreds[3].GetUsernamePasswordAttributes().GetUsername().Value)},
req: &pbs.ListCredentialsRequest{CredentialStoreId: store.GetPublicId(), Filter: fmt.Sprintf(`"/item/attributes/username"==%q`, wantCreds[4].GetUsernamePasswordAttributes().GetUsername().Value)},
res: &pbs.ListCredentialsResponse{
Items: wantCreds[3:5],
Items: wantCreds[4:7],
ResponseType: "complete",
ListToken: "",
SortBy: "created_time",
SortDir: "desc",
RemovedIds: nil,
EstItemCount: 2,
EstItemCount: 3,
},
anonRes: &pbs.ListCredentialsResponse{
ResponseType: "complete",
@ -333,6 +359,10 @@ func TestGet(t *testing.T) {
upHm, err := crypto.HmacSha256(context.Background(), []byte("pass"), databaseWrapper, []byte(store.GetPublicId()), nil, crypto.WithEd25519())
require.NoError(t, err)
updCred := static.TestUsernamePasswordDomainCredential(t, conn, wrapper, "user", "pass", "domain", store.GetPublicId(), prj.GetPublicId())
updHm, err := crypto.HmacSha256(context.Background(), []byte("pass"), databaseWrapper, []byte(store.GetPublicId()), nil, crypto.WithEd25519())
require.NoError(t, err)
spkCred := static.TestSshPrivateKeyCredential(t, conn, wrapper, "user", static.TestSshPrivateKeyPem, store.GetPublicId(), prj.GetPublicId())
spkHm, err := crypto.HmacSha256(context.Background(), []byte(static.TestSshPrivateKeyPem), databaseWrapper, []byte(store.GetPublicId()), nil)
require.NoError(t, err)
@ -402,6 +432,30 @@ func TestGet(t *testing.T) {
},
},
},
{
name: "success-upd",
id: updCred.GetPublicId(),
res: &pbs.GetCredentialResponse{
Item: &pb.Credential{
Id: updCred.GetPublicId(),
CredentialStoreId: updCred.GetStoreId(),
Scope: &scopepb.ScopeInfo{Id: store.GetProjectId(), Type: scope.Project.String(), ParentScopeId: prj.GetParentId()},
Type: credential.UsernamePasswordDomainSubtype.String(),
AuthorizedActions: testAuthorizedActions,
CreatedTime: updCred.CreateTime.GetTimestamp(),
UpdatedTime: updCred.UpdateTime.GetTimestamp(),
Version: 1,
Attrs: &pb.Credential_UsernamePasswordDomainAttributes{
UsernamePasswordDomainAttributes: &pb.UsernamePasswordDomainAttributes{
Username: wrapperspb.String("user"),
PasswordHmac: base64.RawURLEncoding.EncodeToString([]byte(updHm)),
Domain: wrapperspb.String("domain"),
},
},
},
},
},
{
name: "success-spk",
id: spkCred.GetPublicId(),
@ -534,6 +588,7 @@ func TestDelete(t *testing.T) {
require.NoError(t, err)
upCred := static.TestUsernamePasswordCredential(t, conn, wrapper, "user", "pass", store.GetPublicId(), prj.GetPublicId())
updCred := static.TestUsernamePasswordDomainCredential(t, conn, wrapper, "user", "pass", "domain", store.GetPublicId(), prj.GetPublicId())
spkCred := static.TestSshPrivateKeyCredential(t, conn, wrapper, "user", static.TestSshPrivateKeyPem, store.GetPublicId(), prj.GetPublicId())
obj, _ := static.TestJsonObject(t)
@ -550,6 +605,10 @@ func TestDelete(t *testing.T) {
name: "success-up",
id: upCred.GetPublicId(),
},
{
name: "success-upd",
id: updCred.GetPublicId(),
},
{
name: "success-spk",
id: spkCred.GetPublicId(),
@ -654,6 +713,7 @@ func TestCreate(t *testing.T) {
Attrs: &pb.Credential_UsernamePasswordAttributes{
UsernamePasswordAttributes: &pb.UsernamePasswordAttributes{
Username: wrapperspb.String("username"),
Password: wrapperspb.String("password"),
},
},
}},
@ -718,6 +778,134 @@ func TestCreate(t *testing.T) {
res: nil,
err: handlers.ApiErrorWithCode(codes.InvalidArgument),
},
{
name: "Can't specify Id UPD",
req: &pbs.CreateCredentialRequest{Item: &pb.Credential{
CredentialStoreId: store.GetPublicId(),
Id: globals.UsernamePasswordDomainCredentialPrefix + "_notallowed",
Type: credential.UsernamePasswordDomainSubtype.String(),
Attrs: &pb.Credential_UsernamePasswordDomainAttributes{
UsernamePasswordDomainAttributes: &pb.UsernamePasswordDomainAttributes{
Username: wrapperspb.String("username"),
Password: wrapperspb.String("password"),
Domain: wrapperspb.String("domain"),
},
},
}},
res: nil,
err: handlers.ApiErrorWithCode(codes.InvalidArgument),
},
{
name: "Invalid Credential Store Id UPD",
req: &pbs.CreateCredentialRequest{Item: &pb.Credential{
CredentialStoreId: "p_invalidid",
Type: credential.UsernamePasswordDomainSubtype.String(),
Attrs: &pb.Credential_UsernamePasswordDomainAttributes{
UsernamePasswordDomainAttributes: &pb.UsernamePasswordDomainAttributes{
Username: wrapperspb.String("username"),
Password: wrapperspb.String("password"),
Domain: wrapperspb.String("domain"),
},
},
}},
res: nil,
err: handlers.ApiErrorWithCode(codes.InvalidArgument),
},
{
name: "Can't specify Created Time",
req: &pbs.CreateCredentialRequest{Item: &pb.Credential{
CredentialStoreId: store.GetPublicId(),
CreatedTime: timestamppb.Now(),
Type: credential.UsernamePasswordDomainSubtype.String(),
Attrs: &pb.Credential_UsernamePasswordDomainAttributes{
UsernamePasswordDomainAttributes: &pb.UsernamePasswordDomainAttributes{
Username: wrapperspb.String("username"),
Password: wrapperspb.String("password"),
Domain: wrapperspb.String("domain"),
},
},
}},
res: nil,
err: handlers.ApiErrorWithCode(codes.InvalidArgument),
},
{
name: "Can't specify Updated Time",
req: &pbs.CreateCredentialRequest{Item: &pb.Credential{
CredentialStoreId: store.GetPublicId(),
UpdatedTime: timestamppb.Now(),
Type: credential.UsernamePasswordDomainSubtype.String(),
Attrs: &pb.Credential_UsernamePasswordDomainAttributes{
UsernamePasswordDomainAttributes: &pb.UsernamePasswordDomainAttributes{
Username: wrapperspb.String("username"),
Password: wrapperspb.String("password"),
Domain: wrapperspb.String("domain"),
},
},
}},
res: nil,
err: handlers.ApiErrorWithCode(codes.InvalidArgument),
},
{
name: "Must provide type",
req: &pbs.CreateCredentialRequest{Item: &pb.Credential{
CredentialStoreId: store.GetPublicId(),
Attrs: &pb.Credential_UsernamePasswordDomainAttributes{
UsernamePasswordDomainAttributes: &pb.UsernamePasswordDomainAttributes{
Username: wrapperspb.String("username"),
Password: wrapperspb.String("password"),
Domain: wrapperspb.String("domain"),
},
},
}},
res: nil,
err: handlers.ApiErrorWithCode(codes.InvalidArgument),
},
{
name: "Must provide username",
req: &pbs.CreateCredentialRequest{Item: &pb.Credential{
CredentialStoreId: store.GetPublicId(),
Type: credential.UsernamePasswordDomainSubtype.String(),
Attrs: &pb.Credential_UsernamePasswordDomainAttributes{
UsernamePasswordDomainAttributes: &pb.UsernamePasswordDomainAttributes{
Password: wrapperspb.String("password"),
Domain: wrapperspb.String("domain"),
},
},
}},
res: nil,
err: handlers.ApiErrorWithCode(codes.InvalidArgument),
},
{
name: "Must provide password",
req: &pbs.CreateCredentialRequest{Item: &pb.Credential{
CredentialStoreId: store.GetPublicId(),
Type: credential.UsernamePasswordDomainSubtype.String(),
Attrs: &pb.Credential_UsernamePasswordDomainAttributes{
UsernamePasswordDomainAttributes: &pb.UsernamePasswordDomainAttributes{
Username: wrapperspb.String("username"),
Domain: wrapperspb.String("domain"),
},
},
}},
res: nil,
err: handlers.ApiErrorWithCode(codes.InvalidArgument),
},
{
name: "Must provide domain",
req: &pbs.CreateCredentialRequest{Item: &pb.Credential{
CredentialStoreId: store.GetPublicId(),
Type: credential.UsernamePasswordDomainSubtype.String(),
Attrs: &pb.Credential_UsernamePasswordDomainAttributes{
UsernamePasswordDomainAttributes: &pb.UsernamePasswordDomainAttributes{
Username: wrapperspb.String("username"),
Password: wrapperspb.String("password"),
},
},
}},
res: nil,
err: handlers.ApiErrorWithCode(codes.InvalidArgument),
},
{
name: "Must provide private key",
req: &pbs.CreateCredentialRequest{Item: &pb.Credential{
@ -995,6 +1183,16 @@ func TestUpdate(t *testing.T) {
return cred, clean
}
freshCredUpd := func(user, pass, domain string) (*static.UsernamePasswordDomainCredential, func()) {
t.Helper()
cred := static.TestUsernamePasswordDomainCredential(t, conn, wrapper, user, pass, domain, store.GetPublicId(), prj.GetPublicId())
clean := func() {
_, err := s.DeleteCredential(ctx, &pbs.DeleteCredentialRequest{Id: cred.GetPublicId()})
require.NoError(t, err)
}
return cred, clean
}
freshCredSpk := func(user string) (*static.SshPrivateKeyCredential, func()) {
t.Helper()
cred := static.TestSshPrivateKeyCredential(t, conn, wrapper, user, static.TestSshPrivateKeyPem, store.GetPublicId(), prj.GetPublicId())
@ -1113,6 +1311,24 @@ func TestUpdate(t *testing.T) {
return out
},
},
{
name: "update-username-domainupd",
req: &pbs.UpdateCredentialRequest{
UpdateMask: fieldmask("attributes.username"),
Item: &pb.Credential{
Attrs: &pb.Credential_UsernamePasswordDomainAttributes{
UsernamePasswordDomainAttributes: &pb.UsernamePasswordDomainAttributes{
Username: wrapperspb.String("new-user-name"),
},
},
},
},
res: func(in *pb.Credential) *pb.Credential {
out := proto.Clone(in).(*pb.Credential)
out.GetUsernamePasswordDomainAttributes().Username = wrapperspb.String("new-user-name")
return out
},
},
{
name: "update-username-spk",
req: &pbs.UpdateCredentialRequest{
@ -1151,6 +1367,44 @@ func TestUpdate(t *testing.T) {
return out
},
},
{
name: "update-password-domainupd",
req: &pbs.UpdateCredentialRequest{
UpdateMask: fieldmask("attributes.password"),
Item: &pb.Credential{
Attrs: &pb.Credential_UsernamePasswordDomainAttributes{
UsernamePasswordDomainAttributes: &pb.UsernamePasswordDomainAttributes{
Password: wrapperspb.String("new-password"),
},
},
},
},
res: func(in *pb.Credential) *pb.Credential {
out := proto.Clone(in).(*pb.Credential)
hm, err := crypto.HmacSha256(context.Background(), []byte("new-password"), databaseWrapper, []byte(store.GetPublicId()), nil, crypto.WithEd25519())
require.NoError(t, err)
out.GetUsernamePasswordDomainAttributes().PasswordHmac = base64.RawURLEncoding.EncodeToString([]byte(hm))
return out
},
},
{
name: "update-domain-domainupd",
req: &pbs.UpdateCredentialRequest{
UpdateMask: fieldmask("attributes.domain"),
Item: &pb.Credential{
Attrs: &pb.Credential_UsernamePasswordDomainAttributes{
UsernamePasswordDomainAttributes: &pb.UsernamePasswordDomainAttributes{
Domain: wrapperspb.String("new-domain"),
},
},
},
},
res: func(in *pb.Credential) *pb.Credential {
out := proto.Clone(in).(*pb.Credential)
out.GetUsernamePasswordDomainAttributes().Domain = wrapperspb.String("new-domain")
return out
},
},
{
name: "update-spk",
req: &pbs.UpdateCredentialRequest{
@ -1195,6 +1449,56 @@ func TestUpdate(t *testing.T) {
return out
},
},
{
name: "update-username-password-domainupd",
req: &pbs.UpdateCredentialRequest{
UpdateMask: fieldmask("attributes.username", "attributes.password"),
Item: &pb.Credential{
Attrs: &pb.Credential_UsernamePasswordDomainAttributes{
UsernamePasswordDomainAttributes: &pb.UsernamePasswordDomainAttributes{
Username: wrapperspb.String("new-username"),
Password: wrapperspb.String("new-password"),
},
},
},
},
res: func(in *pb.Credential) *pb.Credential {
out := proto.Clone(in).(*pb.Credential)
out.GetUsernamePasswordDomainAttributes().Username = wrapperspb.String("new-username")
hm, err := crypto.HmacSha256(context.Background(), []byte("new-password"), databaseWrapper, []byte(store.GetPublicId()), nil, crypto.WithEd25519())
require.NoError(t, err)
out.GetUsernamePasswordDomainAttributes().PasswordHmac = base64.RawURLEncoding.EncodeToString([]byte(hm))
return out
},
},
{
name: "update-username-password-and-domain-domainupd",
req: &pbs.UpdateCredentialRequest{
UpdateMask: fieldmask("attributes.username", "attributes.password", "attributes.domain"),
Item: &pb.Credential{
Attrs: &pb.Credential_UsernamePasswordDomainAttributes{
UsernamePasswordDomainAttributes: &pb.UsernamePasswordDomainAttributes{
Username: wrapperspb.String("new-username"),
Password: wrapperspb.String("new-password"),
Domain: wrapperspb.String("new-domain"),
},
},
},
},
res: func(in *pb.Credential) *pb.Credential {
out := proto.Clone(in).(*pb.Credential)
out.GetUsernamePasswordDomainAttributes().Username = wrapperspb.String("new-username")
hm, err := crypto.HmacSha256(context.Background(), []byte("new-password"), databaseWrapper, []byte(store.GetPublicId()), nil, crypto.WithEd25519())
require.NoError(t, err)
out.GetUsernamePasswordDomainAttributes().Domain = wrapperspb.String("new-domain")
out.GetUsernamePasswordDomainAttributes().PasswordHmac = base64.RawURLEncoding.EncodeToString([]byte(hm))
return out
},
},
{
name: "update-username-and-spk",
req: &pbs.UpdateCredentialRequest{
@ -1357,6 +1661,8 @@ func TestUpdate(t *testing.T) {
cred, cleanup = freshCredSpk("user")
} else if strings.Contains(tc.name, "json") {
cred, cleanup = freshCredJson()
} else if strings.Contains(tc.name, "domainupd") {
cred, cleanup = freshCredUpd("user", "pass", "domain")
} else {
cred, cleanup = freshCredUp("user", "pass")
}
@ -1532,6 +1838,11 @@ func TestListPagination(t *testing.T) {
require.NoError(err)
allCredentials = append(allCredentials, staticSshCredentialToProto(l, prj, hm))
}
for _, l := range static.TestUsernamePasswordDomainCredentials(t, conn, wrapper, "username", "password", "domain", credStore.GetPublicId(), prj.PublicId, 5) {
hm, err := crypto.HmacSha256(ctx, []byte("password"), databaseWrapper, []byte(credStore.GetPublicId()), nil, crypto.WithEd25519())
require.NoError(err)
allCredentials = append(allCredentials, staticPasswordDomainCredentialToProto(l, prj, hm))
}
for _, l := range static.TestUsernamePasswordCredentials(t, conn, wrapper, "username", "password", credStore.GetPublicId(), prj.PublicId, 5) {
hm, err := crypto.HmacSha256(ctx, []byte("password"), databaseWrapper, []byte(credStore.GetPublicId()), nil, crypto.WithEd25519())
require.NoError(err)
@ -1592,7 +1903,7 @@ func TestListPagination(t *testing.T) {
SortBy: "created_time",
SortDir: "desc",
RemovedIds: nil,
EstItemCount: 15,
EstItemCount: 20,
},
cmpopts.SortSlices(func(a, b string) bool {
return a < b
@ -1618,7 +1929,7 @@ func TestListPagination(t *testing.T) {
SortBy: "created_time",
SortDir: "desc",
RemovedIds: nil,
EstItemCount: 15,
EstItemCount: 20,
},
cmpopts.SortSlices(func(a, b string) bool {
return a < b
@ -1630,10 +1941,10 @@ func TestListPagination(t *testing.T) {
// Request rest of results
req.ListToken = got.ListToken
req.PageSize = 15
req.PageSize = 16
got, err = s.ListCredentials(ctx, req)
require.NoError(err)
require.Len(got.GetItems(), 11)
require.Len(got.GetItems(), 16)
// Compare without comparing the list token
assert.Empty(
cmp.Diff(
@ -1645,7 +1956,7 @@ func TestListPagination(t *testing.T) {
SortBy: "created_time",
SortDir: "desc",
RemovedIds: nil,
EstItemCount: 15,
EstItemCount: 20,
},
cmpopts.SortSlices(func(a, b string) bool {
return a < b
@ -1714,7 +2025,7 @@ func TestListPagination(t *testing.T) {
SortDir: "desc",
// Should contain the deleted credential
RemovedIds: []string{deletedCred.Id},
EstItemCount: 15,
EstItemCount: 20,
},
cmpopts.SortSlices(func(a, b string) bool {
return a < b
@ -1738,7 +2049,7 @@ func TestListPagination(t *testing.T) {
SortBy: "updated_time",
SortDir: "desc",
RemovedIds: nil,
EstItemCount: 15,
EstItemCount: 20,
},
cmpopts.SortSlices(func(a, b string) bool {
return a < b
@ -1767,7 +2078,7 @@ func TestListPagination(t *testing.T) {
SortDir: "desc",
// Should be empty again
RemovedIds: nil,
EstItemCount: 15,
EstItemCount: 20,
},
cmpopts.SortSlices(func(a, b string) bool {
return a < b
@ -1791,7 +2102,7 @@ func TestListPagination(t *testing.T) {
SortBy: "created_time",
SortDir: "desc",
RemovedIds: nil,
EstItemCount: 15,
EstItemCount: 20,
},
cmpopts.SortSlices(func(a, b string) bool {
return a < b

@ -77,6 +77,11 @@ message Credential {
(custom_options.v1.generate_sdk_option) = true,
(custom_options.v1.subtype) = "json"
];
UsernamePasswordDomainAttributes username_password_domain_attributes = 104 [
(google.api.field_visibility).restriction = "INTERNAL",
(custom_options.v1.generate_sdk_option) = true,
(custom_options.v1.subtype) = "username_password_domain"
];
}
// Output only. The available actions on this resource for this user.
@ -114,6 +119,44 @@ message UsernamePasswordAttributes {
]; // @gotags: `class:"public"`
}
message UsernamePasswordDomainAttributes {
// The username associated with the credential.
google.protobuf.StringValue username = 10 [
(custom_options.v1.generate_sdk_option) = true,
(custom_options.v1.mask_mapping) = {
this: "attributes.username"
that: "Username"
}
]; // @gotags: `class:"public"`
// Input only. The password associated with the credential.
google.protobuf.StringValue password = 20 [
json_name = "password",
(custom_options.v1.generate_sdk_option) = true,
(custom_options.v1.mask_mapping) = {
this: "attributes.password"
that: "Password"
}
]; // @gotags: `class:"secret"`
// Output only. The hmac value of the password.
string password_hmac = 30 [
json_name = "password_hmac",
(custom_options.v1.mask_mapping) = {
this: "attributes.password_hmac"
that: "PasswordHmac"
}
]; // @gotags: `class:"public"`
google.protobuf.StringValue domain = 40 [
(custom_options.v1.generate_sdk_option) = true,
(custom_options.v1.mask_mapping) = {
this: "attributes.domain"
that: "Domain"
}
]; // @gotags: `class:"public"`
}
// The attributes of a SshPrivateKey Credential.
message SshPrivateKeyAttributes {
// The username associated with the credential.

@ -58,6 +58,7 @@ type Credential struct {
// *Credential_UsernamePasswordAttributes
// *Credential_SshPrivateKeyAttributes
// *Credential_JsonAttributes
// *Credential_UsernamePasswordDomainAttributes
Attrs isCredential_Attrs `protobuf_oneof:"attrs"`
// Output only. The available actions on this resource for this user.
AuthorizedActions []string `protobuf:"bytes,300,rep,name=authorized_actions,proto3" json:"authorized_actions,omitempty" class:"public"` // @gotags: `class:"public"`
@ -201,6 +202,15 @@ func (x *Credential) GetJsonAttributes() *JsonAttributes {
return nil
}
func (x *Credential) GetUsernamePasswordDomainAttributes() *UsernamePasswordDomainAttributes {
if x != nil {
if x, ok := x.Attrs.(*Credential_UsernamePasswordDomainAttributes); ok {
return x.UsernamePasswordDomainAttributes
}
}
return nil
}
func (x *Credential) GetAuthorizedActions() []string {
if x != nil {
return x.AuthorizedActions
@ -229,6 +239,10 @@ type Credential_JsonAttributes struct {
JsonAttributes *JsonAttributes `protobuf:"bytes,103,opt,name=json_attributes,json=jsonAttributes,proto3,oneof"`
}
type Credential_UsernamePasswordDomainAttributes struct {
UsernamePasswordDomainAttributes *UsernamePasswordDomainAttributes `protobuf:"bytes,104,opt,name=username_password_domain_attributes,json=usernamePasswordDomainAttributes,proto3,oneof"`
}
func (*Credential_Attributes) isCredential_Attrs() {}
func (*Credential_UsernamePasswordAttributes) isCredential_Attrs() {}
@ -237,6 +251,8 @@ func (*Credential_SshPrivateKeyAttributes) isCredential_Attrs() {}
func (*Credential_JsonAttributes) isCredential_Attrs() {}
func (*Credential_UsernamePasswordDomainAttributes) isCredential_Attrs() {}
// The attributes of a UsernamePassword Credential.
type UsernamePasswordAttributes struct {
state protoimpl.MessageState `protogen:"open.v1"`
@ -301,6 +317,77 @@ func (x *UsernamePasswordAttributes) GetPasswordHmac() string {
return ""
}
type UsernamePasswordDomainAttributes struct {
state protoimpl.MessageState `protogen:"open.v1"`
// The username associated with the credential.
Username *wrapperspb.StringValue `protobuf:"bytes,10,opt,name=username,proto3" json:"username,omitempty" class:"public"` // @gotags: `class:"public"`
// Input only. The password associated with the credential.
Password *wrapperspb.StringValue `protobuf:"bytes,20,opt,name=password,proto3" json:"password,omitempty" class:"secret"` // @gotags: `class:"secret"`
// Output only. The hmac value of the password.
PasswordHmac string `protobuf:"bytes,30,opt,name=password_hmac,proto3" json:"password_hmac,omitempty" class:"public"` // @gotags: `class:"public"`
Domain *wrapperspb.StringValue `protobuf:"bytes,40,opt,name=domain,proto3" json:"domain,omitempty" class:"public"` // @gotags: `class:"public"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *UsernamePasswordDomainAttributes) Reset() {
*x = UsernamePasswordDomainAttributes{}
mi := &file_controller_api_resources_credentials_v1_credential_proto_msgTypes[2]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *UsernamePasswordDomainAttributes) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*UsernamePasswordDomainAttributes) ProtoMessage() {}
func (x *UsernamePasswordDomainAttributes) ProtoReflect() protoreflect.Message {
mi := &file_controller_api_resources_credentials_v1_credential_proto_msgTypes[2]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use UsernamePasswordDomainAttributes.ProtoReflect.Descriptor instead.
func (*UsernamePasswordDomainAttributes) Descriptor() ([]byte, []int) {
return file_controller_api_resources_credentials_v1_credential_proto_rawDescGZIP(), []int{2}
}
func (x *UsernamePasswordDomainAttributes) GetUsername() *wrapperspb.StringValue {
if x != nil {
return x.Username
}
return nil
}
func (x *UsernamePasswordDomainAttributes) GetPassword() *wrapperspb.StringValue {
if x != nil {
return x.Password
}
return nil
}
func (x *UsernamePasswordDomainAttributes) GetPasswordHmac() string {
if x != nil {
return x.PasswordHmac
}
return ""
}
func (x *UsernamePasswordDomainAttributes) GetDomain() *wrapperspb.StringValue {
if x != nil {
return x.Domain
}
return nil
}
// The attributes of a SshPrivateKey Credential.
type SshPrivateKeyAttributes struct {
state protoimpl.MessageState `protogen:"open.v1"`
@ -320,7 +407,7 @@ type SshPrivateKeyAttributes struct {
func (x *SshPrivateKeyAttributes) Reset() {
*x = SshPrivateKeyAttributes{}
mi := &file_controller_api_resources_credentials_v1_credential_proto_msgTypes[2]
mi := &file_controller_api_resources_credentials_v1_credential_proto_msgTypes[3]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@ -332,7 +419,7 @@ func (x *SshPrivateKeyAttributes) String() string {
func (*SshPrivateKeyAttributes) ProtoMessage() {}
func (x *SshPrivateKeyAttributes) ProtoReflect() protoreflect.Message {
mi := &file_controller_api_resources_credentials_v1_credential_proto_msgTypes[2]
mi := &file_controller_api_resources_credentials_v1_credential_proto_msgTypes[3]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@ -345,7 +432,7 @@ func (x *SshPrivateKeyAttributes) ProtoReflect() protoreflect.Message {
// Deprecated: Use SshPrivateKeyAttributes.ProtoReflect.Descriptor instead.
func (*SshPrivateKeyAttributes) Descriptor() ([]byte, []int) {
return file_controller_api_resources_credentials_v1_credential_proto_rawDescGZIP(), []int{2}
return file_controller_api_resources_credentials_v1_credential_proto_rawDescGZIP(), []int{3}
}
func (x *SshPrivateKeyAttributes) GetUsername() *wrapperspb.StringValue {
@ -396,7 +483,7 @@ type JsonAttributes struct {
func (x *JsonAttributes) Reset() {
*x = JsonAttributes{}
mi := &file_controller_api_resources_credentials_v1_credential_proto_msgTypes[3]
mi := &file_controller_api_resources_credentials_v1_credential_proto_msgTypes[4]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@ -408,7 +495,7 @@ func (x *JsonAttributes) String() string {
func (*JsonAttributes) ProtoMessage() {}
func (x *JsonAttributes) ProtoReflect() protoreflect.Message {
mi := &file_controller_api_resources_credentials_v1_credential_proto_msgTypes[3]
mi := &file_controller_api_resources_credentials_v1_credential_proto_msgTypes[4]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@ -421,7 +508,7 @@ func (x *JsonAttributes) ProtoReflect() protoreflect.Message {
// Deprecated: Use JsonAttributes.ProtoReflect.Descriptor instead.
func (*JsonAttributes) Descriptor() ([]byte, []int) {
return file_controller_api_resources_credentials_v1_credential_proto_rawDescGZIP(), []int{3}
return file_controller_api_resources_credentials_v1_credential_proto_rawDescGZIP(), []int{4}
}
func (x *JsonAttributes) GetObject() *structpb.Struct {
@ -442,7 +529,8 @@ var File_controller_api_resources_credentials_v1_credential_proto protoreflect.F
const file_controller_api_resources_credentials_v1_credential_proto_rawDesc = "" +
"\n" +
"8controller/api/resources/credentials/v1/credential.proto\x12'controller.api.resources.credentials.v1\x1a.controller/api/resources/scopes/v1/scope.proto\x1a*controller/custom_options/v1/options.proto\x1a\x1bgoogle/api/visibility.proto\x1a\x1cgoogle/protobuf/struct.proto\x1a\x1fgoogle/protobuf/timestamp.proto\x1a\x1egoogle/protobuf/wrappers.proto\"\xd6\b\n" +
"8controller/api/resources/credentials/v1/credential.proto\x12'controller.api.resources.credentials.v1\x1a.controller/api/resources/scopes/v1/scope.proto\x1a*controller/custom_options/v1/options.proto\x1a\x1bgoogle/api/visibility.proto\x1a\x1cgoogle/protobuf/struct.proto\x1a\x1fgoogle/protobuf/timestamp.proto\x1a\x1egoogle/protobuf/wrappers.proto\"\xa5\n" +
"\n" +
"\n" +
"Credential\x12\x0e\n" +
"\x02id\x18\n" +
@ -465,7 +553,9 @@ const file_controller_api_resources_credentials_v1_credential_proto_rawDesc = ""
"\x1assh_private_key_attributes\x18f \x01(\v2@.controller.api.resources.credentials.v1.SshPrivateKeyAttributesB'\xa0\xda)\x01\x9a\xe3)\x0fssh_private_key\xfa\xd2\xe4\x93\x02\n" +
"\x12\bINTERNALH\x00R\x17sshPrivateKeyAttributes\x12\x80\x01\n" +
"\x0fjson_attributes\x18g \x01(\v27.controller.api.resources.credentials.v1.JsonAttributesB\x1c\xa0\xda)\x01\x9a\xe3)\x04json\xfa\xd2\xe4\x93\x02\n" +
"\x12\bINTERNALH\x00R\x0ejsonAttributes\x12/\n" +
"\x12\bINTERNALH\x00R\x0ejsonAttributes\x12\xcc\x01\n" +
"#username_password_domain_attributes\x18h \x01(\v2I.controller.api.resources.credentials.v1.UsernamePasswordDomainAttributesB0\xa0\xda)\x01\x9a\xe3)\x18username_password_domain\xfa\xd2\xe4\x93\x02\n" +
"\x12\bINTERNALH\x00R usernamePasswordDomainAttributes\x12/\n" +
"\x12authorized_actions\x18\xac\x02 \x03(\tR\x12authorized_actionsB\a\n" +
"\x05attrs\"\xb6\x02\n" +
"\x1aUsernamePasswordAttributes\x12a\n" +
@ -475,7 +565,17 @@ const file_controller_api_resources_credentials_v1_credential_proto_rawDesc = ""
"\bpassword\x18\x14 \x01(\v2\x1c.google.protobuf.StringValueB'\xa0\xda)\x01\xc2\xdd)\x1f\n" +
"\x13attributes.password\x12\bPasswordR\bpassword\x12R\n" +
"\rpassword_hmac\x18\x1e \x01(\tB,\xc2\xdd)(\n" +
"\x18attributes.password_hmac\x12\fPasswordHmacR\rpassword_hmac\"\xee\x04\n" +
"\x18attributes.password_hmac\x12\fPasswordHmacR\rpassword_hmac\"\x97\x03\n" +
" UsernamePasswordDomainAttributes\x12a\n" +
"\busername\x18\n" +
" \x01(\v2\x1c.google.protobuf.StringValueB'\xa0\xda)\x01\xc2\xdd)\x1f\n" +
"\x13attributes.username\x12\bUsernameR\busername\x12a\n" +
"\bpassword\x18\x14 \x01(\v2\x1c.google.protobuf.StringValueB'\xa0\xda)\x01\xc2\xdd)\x1f\n" +
"\x13attributes.password\x12\bPasswordR\bpassword\x12R\n" +
"\rpassword_hmac\x18\x1e \x01(\tB,\xc2\xdd)(\n" +
"\x18attributes.password_hmac\x12\fPasswordHmacR\rpassword_hmac\x12Y\n" +
"\x06domain\x18( \x01(\v2\x1c.google.protobuf.StringValueB#\xa0\xda)\x01\xc2\xdd)\x1b\n" +
"\x11attributes.domain\x12\x06DomainR\x06domain\"\xee\x04\n" +
"\x17SshPrivateKeyAttributes\x12a\n" +
"\busername\x18\n" +
" \x01(\v2\x1c.google.protobuf.StringValueB'\xa0\xda)\x01\xc2\xdd)\x1f\n" +
@ -509,38 +609,43 @@ func file_controller_api_resources_credentials_v1_credential_proto_rawDescGZIP()
return file_controller_api_resources_credentials_v1_credential_proto_rawDescData
}
var file_controller_api_resources_credentials_v1_credential_proto_msgTypes = make([]protoimpl.MessageInfo, 4)
var file_controller_api_resources_credentials_v1_credential_proto_msgTypes = make([]protoimpl.MessageInfo, 5)
var file_controller_api_resources_credentials_v1_credential_proto_goTypes = []any{
(*Credential)(nil), // 0: controller.api.resources.credentials.v1.Credential
(*UsernamePasswordAttributes)(nil), // 1: controller.api.resources.credentials.v1.UsernamePasswordAttributes
(*SshPrivateKeyAttributes)(nil), // 2: controller.api.resources.credentials.v1.SshPrivateKeyAttributes
(*JsonAttributes)(nil), // 3: controller.api.resources.credentials.v1.JsonAttributes
(*scopes.ScopeInfo)(nil), // 4: controller.api.resources.scopes.v1.ScopeInfo
(*wrapperspb.StringValue)(nil), // 5: google.protobuf.StringValue
(*timestamppb.Timestamp)(nil), // 6: google.protobuf.Timestamp
(*structpb.Struct)(nil), // 7: google.protobuf.Struct
(*Credential)(nil), // 0: controller.api.resources.credentials.v1.Credential
(*UsernamePasswordAttributes)(nil), // 1: controller.api.resources.credentials.v1.UsernamePasswordAttributes
(*UsernamePasswordDomainAttributes)(nil), // 2: controller.api.resources.credentials.v1.UsernamePasswordDomainAttributes
(*SshPrivateKeyAttributes)(nil), // 3: controller.api.resources.credentials.v1.SshPrivateKeyAttributes
(*JsonAttributes)(nil), // 4: controller.api.resources.credentials.v1.JsonAttributes
(*scopes.ScopeInfo)(nil), // 5: controller.api.resources.scopes.v1.ScopeInfo
(*wrapperspb.StringValue)(nil), // 6: google.protobuf.StringValue
(*timestamppb.Timestamp)(nil), // 7: google.protobuf.Timestamp
(*structpb.Struct)(nil), // 8: google.protobuf.Struct
}
var file_controller_api_resources_credentials_v1_credential_proto_depIdxs = []int32{
4, // 0: controller.api.resources.credentials.v1.Credential.scope:type_name -> controller.api.resources.scopes.v1.ScopeInfo
5, // 1: controller.api.resources.credentials.v1.Credential.name:type_name -> google.protobuf.StringValue
5, // 2: controller.api.resources.credentials.v1.Credential.description:type_name -> google.protobuf.StringValue
6, // 3: controller.api.resources.credentials.v1.Credential.created_time:type_name -> google.protobuf.Timestamp
6, // 4: controller.api.resources.credentials.v1.Credential.updated_time:type_name -> google.protobuf.Timestamp
7, // 5: controller.api.resources.credentials.v1.Credential.attributes:type_name -> google.protobuf.Struct
5, // 0: controller.api.resources.credentials.v1.Credential.scope:type_name -> controller.api.resources.scopes.v1.ScopeInfo
6, // 1: controller.api.resources.credentials.v1.Credential.name:type_name -> google.protobuf.StringValue
6, // 2: controller.api.resources.credentials.v1.Credential.description:type_name -> google.protobuf.StringValue
7, // 3: controller.api.resources.credentials.v1.Credential.created_time:type_name -> google.protobuf.Timestamp
7, // 4: controller.api.resources.credentials.v1.Credential.updated_time:type_name -> google.protobuf.Timestamp
8, // 5: controller.api.resources.credentials.v1.Credential.attributes:type_name -> google.protobuf.Struct
1, // 6: controller.api.resources.credentials.v1.Credential.username_password_attributes:type_name -> controller.api.resources.credentials.v1.UsernamePasswordAttributes
2, // 7: controller.api.resources.credentials.v1.Credential.ssh_private_key_attributes:type_name -> controller.api.resources.credentials.v1.SshPrivateKeyAttributes
3, // 8: controller.api.resources.credentials.v1.Credential.json_attributes:type_name -> controller.api.resources.credentials.v1.JsonAttributes
5, // 9: controller.api.resources.credentials.v1.UsernamePasswordAttributes.username:type_name -> google.protobuf.StringValue
5, // 10: controller.api.resources.credentials.v1.UsernamePasswordAttributes.password:type_name -> google.protobuf.StringValue
5, // 11: controller.api.resources.credentials.v1.SshPrivateKeyAttributes.username:type_name -> google.protobuf.StringValue
5, // 12: controller.api.resources.credentials.v1.SshPrivateKeyAttributes.private_key:type_name -> google.protobuf.StringValue
5, // 13: controller.api.resources.credentials.v1.SshPrivateKeyAttributes.private_key_passphrase:type_name -> google.protobuf.StringValue
7, // 14: controller.api.resources.credentials.v1.JsonAttributes.object:type_name -> google.protobuf.Struct
15, // [15:15] is the sub-list for method output_type
15, // [15:15] is the sub-list for method input_type
15, // [15:15] is the sub-list for extension type_name
15, // [15:15] is the sub-list for extension extendee
0, // [0:15] is the sub-list for field type_name
3, // 7: controller.api.resources.credentials.v1.Credential.ssh_private_key_attributes:type_name -> controller.api.resources.credentials.v1.SshPrivateKeyAttributes
4, // 8: controller.api.resources.credentials.v1.Credential.json_attributes:type_name -> controller.api.resources.credentials.v1.JsonAttributes
2, // 9: controller.api.resources.credentials.v1.Credential.username_password_domain_attributes:type_name -> controller.api.resources.credentials.v1.UsernamePasswordDomainAttributes
6, // 10: controller.api.resources.credentials.v1.UsernamePasswordAttributes.username:type_name -> google.protobuf.StringValue
6, // 11: controller.api.resources.credentials.v1.UsernamePasswordAttributes.password:type_name -> google.protobuf.StringValue
6, // 12: controller.api.resources.credentials.v1.UsernamePasswordDomainAttributes.username:type_name -> google.protobuf.StringValue
6, // 13: controller.api.resources.credentials.v1.UsernamePasswordDomainAttributes.password:type_name -> google.protobuf.StringValue
6, // 14: controller.api.resources.credentials.v1.UsernamePasswordDomainAttributes.domain:type_name -> google.protobuf.StringValue
6, // 15: controller.api.resources.credentials.v1.SshPrivateKeyAttributes.username:type_name -> google.protobuf.StringValue
6, // 16: controller.api.resources.credentials.v1.SshPrivateKeyAttributes.private_key:type_name -> google.protobuf.StringValue
6, // 17: controller.api.resources.credentials.v1.SshPrivateKeyAttributes.private_key_passphrase:type_name -> google.protobuf.StringValue
8, // 18: controller.api.resources.credentials.v1.JsonAttributes.object:type_name -> google.protobuf.Struct
19, // [19:19] is the sub-list for method output_type
19, // [19:19] is the sub-list for method input_type
19, // [19:19] is the sub-list for extension type_name
19, // [19:19] is the sub-list for extension extendee
0, // [0:19] is the sub-list for field type_name
}
func init() { file_controller_api_resources_credentials_v1_credential_proto_init() }
@ -553,6 +658,7 @@ func file_controller_api_resources_credentials_v1_credential_proto_init() {
(*Credential_UsernamePasswordAttributes)(nil),
(*Credential_SshPrivateKeyAttributes)(nil),
(*Credential_JsonAttributes)(nil),
(*Credential_UsernamePasswordDomainAttributes)(nil),
}
type x struct{}
out := protoimpl.TypeBuilder{
@ -560,7 +666,7 @@ func file_controller_api_resources_credentials_v1_credential_proto_init() {
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: unsafe.Slice(unsafe.StringData(file_controller_api_resources_credentials_v1_credential_proto_rawDesc), len(file_controller_api_resources_credentials_v1_credential_proto_rawDesc)),
NumEnums: 0,
NumMessages: 4,
NumMessages: 5,
NumExtensions: 0,
NumServices: 0,
},

Loading…
Cancel
Save