Filter inactive and private oidc auth methods from unauthenticated list requests (#1110)

This commit is contained in:
Todd Knight authored and GitHub committed 2021-04-13 16:42:25 -07:00
1 parent ca57e50516
commit 072b950540
8 files changed
+155 -36

No files matched your search

@@ -157,7 +157,7 @@ func (s Service) ListAuthMethods(ctx context.Context, req *pbs.ListAuthMethodsRe
return &pbs.ListAuthMethodsResponse{}, nil
}
ul, err := s.listFromRepo(ctx, scopeIds)
ul, err := s.listFromRepo(ctx, scopeIds, authResults.UserId == auth.AnonymousUserId)
if err != nil {
return nil, err
}
@@ -376,12 +376,12 @@ func (s Service) getFromRepo(ctx context.Context, id string) (*pb.AuthMethod, er
return toAuthMethodProto(am)
}
func (s Service) listFromRepo(ctx context.Context, scopeIds []string) ([]*pb.AuthMethod, error) {
func (s Service) listFromRepo(ctx context.Context, scopeIds []string, unauthn bool) ([]*pb.AuthMethod, error) {
oidcRepo, err := s.oidcRepoFn()
if err != nil {
return nil, err
}
ol, err := oidcRepo.ListAuthMethods(ctx, scopeIds)
ol, err := oidcRepo.ListAuthMethods(ctx, scopeIds, oidc.WithUnauthenticatedUser(unauthn))
if err != nil {
return nil, err
}
@@ -226,8 +226,8 @@ func TestList(t *testing.T) {
var wantSomeAuthMethods []*pb.AuthMethod
databaseWrapper, err := kmsCache.GetWrapper(context.Background(), oWithAuthMethods.GetPublicId(), kms.KeyPurposeDatabase)
require.NoError(t, err)
oidcam := oidc.TestAuthMethod(t, conn, databaseWrapper, oWithAuthMethods.GetPublicId(), oidc.InactiveState, "alice_rp", "secret",
oidc.WithIssuer(oidc.TestConvertToUrls(t, "https://alice.com")[0]), oidc.WithApiUrl(oidc.TestConvertToUrls(t, "https://api.com")[0]))
oidcam := oidc.TestAuthMethod(t, conn, databaseWrapper, oWithAuthMethods.GetPublicId(), oidc.ActivePublicState, "alice_rp", "secret",
oidc.WithIssuer(oidc.TestConvertToUrls(t, "https://alice.com")[0]), oidc.WithApiUrl(oidc.TestConvertToUrls(t, "https://api.com")[0]), oidc.WithSigningAlgs(oidc.EdDSA))
iam.TestSetPrimaryAuthMethod(t, iamRepo, oWithAuthMethods, oidcam.GetPublicId())
wantSomeAuthMethods = append(wantSomeAuthMethods, &pb.AuthMethod{
@@ -236,15 +236,19 @@ func TestList(t *testing.T) {
CreatedTime: oidcam.GetCreateTime().GetTimestamp(),
UpdatedTime: oidcam.GetUpdateTime().GetTimestamp(),
Scope: &scopepb.ScopeInfo{Id: oWithAuthMethods.GetPublicId(), Type: scope.Org.String(), ParentScopeId: scope.Global.String()},
Version: 1,
Version: 2,
Type: auth.OidcSubtype.String(),
Attributes: &structpb.Struct{Fields: map[string]*structpb.Value{
"issuer": structpb.NewStringValue("https://alice.com"),
"client_id": structpb.NewStringValue("alice_rp"),
"client_secret_hmac": structpb.NewStringValue("<hmac>"),
"state": structpb.NewStringValue(string(oidc.InactiveState)),
"state": structpb.NewStringValue(string(oidc.ActivePublicState)),
"api_url_prefix": structpb.NewStringValue("https://api.com"),
"callback_url": structpb.NewStringValue(fmt.Sprintf(oidc.CallbackEndpoint, "https://api.com", oidcam.GetPublicId())),
"signing_algorithms": func() *structpb.Value {
lv, _ := structpb.NewList([]interface{}{string(oidc.EdDSA)})
return structpb.NewListValue(lv)
}(),
}},
IsPrimary: true,
AuthorizedActions: oidcAuthorizedActions,
@@ -7,6 +7,7 @@ import (
"net/http"
"net/http/httptest"
"regexp"
"sort"
"testing"
"time"
@@ -22,6 +23,7 @@ import (
pbs "github.com/hashicorp/boundary/internal/gen/controller/api/services"
"github.com/hashicorp/boundary/internal/iam"
"github.com/hashicorp/boundary/internal/kms"
"github.com/hashicorp/boundary/internal/servers"
"github.com/hashicorp/boundary/internal/servers/controller/common"
"github.com/hashicorp/boundary/internal/servers/controller/handlers"
"github.com/hashicorp/boundary/internal/servers/controller/handlers/authmethods"
@@ -127,6 +129,110 @@ func getSetup(t *testing.T) setup {
return ret
}
func TestList_FilterNonPublic(t *testing.T) {
conn, _ := db.TestSetup(t, "postgres")
rw := db.New(conn)
wrapper := db.TestWrapper(t)
kmsCache := kms.TestKms(t, conn, wrapper)
iamRepoFn := func() (*iam.Repository, error) {
return iam.TestRepo(t, conn, wrapper), nil
}
oidcRepoFn := func() (*oidc.Repository, error) {
return oidc.NewRepository(rw, rw, kmsCache)
}
pwRepoFn := func() (*password.Repository, error) {
return password.NewRepository(rw, rw, kmsCache)
}
atRepoFn := func() (*authtoken.Repository, error) {
return authtoken.NewRepository(rw, rw, kmsCache)
}
authTokenRepoFn := func() (*authtoken.Repository, error) {
return authtoken.NewRepository(rw, rw, kmsCache)
}
serversRepoFn := func() (*servers.Repository, error) {
return servers.NewRepository(rw, rw, kmsCache)
}
iamRepo := iam.TestRepo(t, conn, wrapper)
o, _ := iam.TestScopes(t, iamRepo)
databaseWrapper, err := kmsCache.GetWrapper(context.Background(), o.GetPublicId(), kms.KeyPurposeDatabase)
require.NoError(t, err)
// 1 Public
i := 0
oidcam := oidc.TestAuthMethod(t, conn, databaseWrapper, o.GetPublicId(), oidc.ActivePublicState, "alice_rp", "secret", oidc.WithDescription(fmt.Sprintf("%d", i)),
oidc.WithIssuer(oidc.TestConvertToUrls(t, fmt.Sprintf("https://alice%d.com", i))[0]), oidc.WithApiUrl(oidc.TestConvertToUrls(t, "https://api.com")[0]), oidc.WithSigningAlgs(oidc.EdDSA))
i++
iam.TestSetPrimaryAuthMethod(t, iamRepo, o, oidcam.GetPublicId())
// 4 private
for ; i < 4; i++ {
_ = oidc.TestAuthMethod(t, conn, databaseWrapper, o.GetPublicId(), oidc.ActivePrivateState, "alice_rp", "secret", oidc.WithDescription(fmt.Sprintf("%d", i)),
oidc.WithIssuer(oidc.TestConvertToUrls(t, fmt.Sprintf("https://alice%d.com", i))[0]), oidc.WithApiUrl(oidc.TestConvertToUrls(t, "https://api.com")[0]), oidc.WithSigningAlgs(oidc.EdDSA))
}
// 5 inactive
for ; i < 10; i++ {
_ = oidc.TestAuthMethod(t, conn, databaseWrapper, o.GetPublicId(), oidc.InactiveState, "alice_rp", "secret", oidc.WithDescription(fmt.Sprintf("%d", i)),
oidc.WithIssuer(oidc.TestConvertToUrls(t, fmt.Sprintf("https://alice%d.com", i))[0]), oidc.WithApiUrl(oidc.TestConvertToUrls(t, "https://api.com")[0]))
}
s, err := authmethods.NewService(kmsCache, pwRepoFn, oidcRepoFn, iamRepoFn, atRepoFn)
require.NoError(t, err, "Couldn't create new auth_method service.")
req := &pbs.ListAuthMethodsRequest{
ScopeId: o.GetPublicId(),
Filter: `"/item/type"=="oidc"`, // We are concerned about OIDC auth methods being filtered by authn state
}
cases := []struct {
name string
reqCtx context.Context
respCount int
}{
{
name: "unauthenticated",
reqCtx: auth.DisabledAuthTestContext(iamRepoFn, o.GetPublicId()),
respCount: 1,
},
{
name: "authenticated",
reqCtx: func() context.Context {
at := authtoken.TestAuthToken(t, conn, kmsCache, o.GetPublicId())
return auth.NewVerifierContext(context.Background(),
nil,
iamRepoFn,
authTokenRepoFn,
serversRepoFn,
kmsCache,
auth.RequestInfo{
Token: at.GetToken(),
TokenFormat: auth.AuthTokenTypeBearer,
PublicId: at.GetPublicId(),
})
}(),
respCount: 10,
},
}
for _, tc := range cases {
t.Run(tc.name, func(t *testing.T) {
got, err := s.ListAuthMethods(tc.reqCtx, req)
assert.NoError(t, err)
require.NotNil(t, got)
require.Len(t, got.GetItems(), tc.respCount)
gotSorted := got.GetItems()
sort.Slice(gotSorted, func(i, j int) bool {
return gotSorted[i].GetDescription().GetValue() < gotSorted[j].GetDescription().GetValue()
})
for i := 0; i < tc.respCount; i++ {
assert.Equal(t, fmt.Sprintf("%d", i), gotSorted[i].GetDescription().GetValue(), "Auth method with description '%d' missing", i)
}
})
}
}
func TestUpdate_OIDC(t *testing.T) {
conn, _ := db.TestSetup(t, "postgres")
rw := db.New(conn)