diff --git a/internal/servers/controller/handlers/authmethods/authmethod_service.go b/internal/servers/controller/handlers/authmethods/authmethod_service.go index 9812a6d72b..cf34aaf35d 100644 --- a/internal/servers/controller/handlers/authmethods/authmethod_service.go +++ b/internal/servers/controller/handlers/authmethods/authmethod_service.go @@ -386,18 +386,18 @@ func (s Service) getFromRepo(ctx context.Context, id string) (*pb.AuthMethod, er return toAuthMethodProto(am) } -func (s Service) listFromRepo(ctx context.Context, scopeIds []string, unauthn bool) ([]*pb.AuthMethod, error) { +func (s Service) listFromRepo(ctx context.Context, scopeIds []string, anonUser bool) ([]*pb.AuthMethod, error) { oidcRepo, err := s.oidcRepoFn() if err != nil { return nil, err } - ol, err := oidcRepo.ListAuthMethods(ctx, scopeIds, oidc.WithUnauthenticatedUser(unauthn)) + ol, err := oidcRepo.ListAuthMethods(ctx, scopeIds, oidc.WithUnauthenticatedUser(anonUser)) if err != nil { return nil, err } var outUl []*pb.AuthMethod for _, u := range ol { - ou, err := toAuthMethodProto(u) + ou, err := toAuthMethodProto(u, handlers.WithAnonymousListing(anonUser)) if err != nil { return nil, err } @@ -413,7 +413,7 @@ func (s Service) listFromRepo(ctx context.Context, scopeIds []string, unauthn bo return nil, err } for _, u := range pl { - ou, err := toAuthMethodProto(u) + ou, err := toAuthMethodProto(u, handlers.WithAnonymousListing(anonUser)) if err != nil { return nil, err } @@ -470,7 +470,7 @@ func (s Service) updateInRepo(ctx context.Context, scopeId string, req *pbs.Upda return nil, handlers.ApiErrorWithCodeAndMessage(codes.Internal, "Unable to update auth method but no error returned from repository.") } if dryRun { - storageToWire = func(in auth.AuthMethod) (*pb.AuthMethod, error) { + storageToWire = func(in auth.AuthMethod, opt ...handlers.Option) (*pb.AuthMethod, error) { am, err := toAuthMethodProto(in) if err != nil { return nil, errors.Wrap(err, op) @@ -630,14 +630,12 @@ func (s Service) authResult(ctx context.Context, id string, a action.Type) auth. return auth.Verify(ctx, opts...) } -func toAuthMethodProto(in auth.AuthMethod) (*pb.AuthMethod, error) { +func toAuthMethodProto(in auth.AuthMethod, opt ...handlers.Option) (*pb.AuthMethod, error) { + anonListing := handlers.GetOpts(opt...).WithAnonymousListing out := &pb.AuthMethod{ - Id: in.GetPublicId(), - ScopeId: in.GetScopeId(), - CreatedTime: in.GetCreateTime().GetTimestamp(), - UpdatedTime: in.GetUpdateTime().GetTimestamp(), - Version: in.GetVersion(), - IsPrimary: in.GetIsPrimaryAuthMethod(), + Id: in.GetPublicId(), + ScopeId: in.GetScopeId(), + IsPrimary: in.GetIsPrimaryAuthMethod(), } if in.GetDescription() != "" { out.Description = wrapperspb.String(in.GetDescription()) @@ -645,9 +643,17 @@ func toAuthMethodProto(in auth.AuthMethod) (*pb.AuthMethod, error) { if in.GetName() != "" { out.Name = wrapperspb.String(in.GetName()) } + if !anonListing { + out.CreatedTime = in.GetCreateTime().GetTimestamp() + out.UpdatedTime = in.GetUpdateTime().GetTimestamp() + out.Version = in.GetVersion() + } switch i := in.(type) { case *password.AuthMethod: out.Type = auth.PasswordSubtype.String() + if anonListing { + break + } st, err := handlers.ProtoToStruct(&pb.PasswordAuthMethodAttributes{ MinLoginNameLength: i.GetMinLoginNameLength(), MinPasswordLength: i.GetMinPasswordLength(), @@ -658,6 +664,9 @@ func toAuthMethodProto(in auth.AuthMethod) (*pb.AuthMethod, error) { out.Attributes = st case *oidc.AuthMethod: out.Type = auth.OidcSubtype.String() + if anonListing { + break + } attrs := &pb.OidcAuthMethodAttributes{ ClientId: wrapperspb.String(i.GetClientId()), ClientSecretHmac: i.ClientSecretHmac, diff --git a/internal/servers/controller/handlers/authmethods/authmethod_service_test.go b/internal/servers/controller/handlers/authmethods/authmethod_service_test.go index 0d67b2b41d..3259a2373b 100644 --- a/internal/servers/controller/handlers/authmethods/authmethod_service_test.go +++ b/internal/servers/controller/handlers/authmethods/authmethod_service_test.go @@ -350,7 +350,8 @@ func TestList(t *testing.T) { s, err := authmethods.NewService(kmsCache, pwRepoFn, oidcRepoFn, iamRepoFn, atRepoFn) require.NoError(err, "Couldn't create new auth_method service.") - got, gErr := s.ListAuthMethods(auth.DisabledAuthTestContext(iamRepoFn, tc.req.GetScopeId()), tc.req) + // First check with non-anonymous user + got, gErr := s.ListAuthMethods(auth.DisabledAuthTestContext(iamRepoFn, tc.req.GetScopeId(), auth.WithUserId("u_auth")), tc.req) if tc.err != nil { require.Error(gErr) assert.True(errors.Is(gErr, tc.err), "ListAuthMethods() for scope %q got error %v, wanted %v", tc.req.GetScopeId(), gErr, tc.err) @@ -365,6 +366,21 @@ func TestList(t *testing.T) { } } assert.Empty(cmp.Diff(got, tc.res, protocmp.Transform()), "ListAuthMethods() for scope %q got response %q, wanted %q", tc.req.GetScopeId(), got, tc.res) + + // Now check with anonymous user + got, gErr = s.ListAuthMethods(auth.DisabledAuthTestContext(iamRepoFn, tc.req.GetScopeId()), tc.req) + if tc.err != nil { + require.Error(gErr) + assert.True(errors.Is(gErr, tc.err), "ListAuthMethods() for scope %q got error %v, wanted %v", tc.req.GetScopeId(), gErr, tc.err) + return + } + require.NoError(gErr) + for _, g := range got.Items { + assert.Nil(g.Attributes) + assert.Nil(g.CreatedTime) + assert.Nil(g.UpdatedTime) + assert.Empty(g.Version) + } }) } } diff --git a/internal/servers/controller/handlers/option_test.go b/internal/servers/controller/handlers/option_test.go index 03b35d9cab..ee40e05404 100644 --- a/internal/servers/controller/handlers/option_test.go +++ b/internal/servers/controller/handlers/option_test.go @@ -36,4 +36,14 @@ func Test_GetOpts(t *testing.T) { opts = GetOpts(WithLogger(hclog.New(nil))) assert.NotNil(opts.WithLogger) }) + + t.Run("WithAnonymousListing", func(t *testing.T) { + assert := assert.New(t) + + opts := GetOpts() + assert.False(opts.WithAnonymousListing) + + opts = GetOpts(WithAnonymousListing(true)) + assert.True(opts.WithAnonymousListing) + }) } diff --git a/internal/servers/controller/handlers/options.go b/internal/servers/controller/handlers/options.go index d9fca4cb17..383a4aaff3 100644 --- a/internal/servers/controller/handlers/options.go +++ b/internal/servers/controller/handlers/options.go @@ -20,6 +20,7 @@ type Option func(*options) type options struct { withDiscardUnknownFields bool WithLogger hclog.Logger + WithAnonymousListing bool } func getDefaultOptions() options { @@ -41,3 +42,11 @@ func WithLogger(logger hclog.Logger) Option { o.WithLogger = logger } } + +// WithAnonymousListing provides an option when creating responses to only include those +// desired for listing to anonymous users. +func WithAnonymousListing(anonListing bool) Option { + return func(o *options) { + o.WithAnonymousListing = anonListing + } +}