2020-08-06 12:50:20 -07:00
package authmethods_test
import (
2020-10-12 18:03:15 -04:00
"context"
2020-08-06 12:50:20 -07:00
"fmt"
2021-04-08 20:54:32 -04:00
"regexp"
2021-06-11 11:43:36 -07:00
"sort"
2020-08-06 12:50:20 -07:00
"strings"
"testing"
"github.com/google/go-cmp/cmp"
2021-04-08 20:54:32 -04:00
"github.com/hashicorp/boundary/internal/auth/oidc"
2020-08-10 17:15:02 -04:00
"github.com/hashicorp/boundary/internal/auth/password"
2020-10-12 18:03:15 -04:00
"github.com/hashicorp/boundary/internal/authtoken"
2020-08-10 17:15:02 -04:00
"github.com/hashicorp/boundary/internal/db"
2021-04-08 20:54:32 -04:00
"github.com/hashicorp/boundary/internal/errors"
2020-08-10 17:15:02 -04:00
pb "github.com/hashicorp/boundary/internal/gen/controller/api/resources/authmethods"
2020-08-12 08:20:35 -07:00
scopepb "github.com/hashicorp/boundary/internal/gen/controller/api/resources/scopes"
2020-08-10 17:15:02 -04:00
pbs "github.com/hashicorp/boundary/internal/gen/controller/api/services"
"github.com/hashicorp/boundary/internal/iam"
2020-08-19 16:47:18 -04:00
"github.com/hashicorp/boundary/internal/kms"
2021-07-27 09:59:52 -07:00
requestauth "github.com/hashicorp/boundary/internal/servers/controller/auth"
2020-09-23 08:10:27 -07:00
"github.com/hashicorp/boundary/internal/servers/controller/handlers"
2020-08-10 17:15:02 -04:00
"github.com/hashicorp/boundary/internal/servers/controller/handlers/authmethods"
2021-04-08 20:54:32 -04:00
"github.com/hashicorp/boundary/internal/types/action"
2020-08-10 17:15:02 -04:00
"github.com/hashicorp/boundary/internal/types/scope"
2020-08-06 12:50:20 -07:00
"google.golang.org/grpc/codes"
"google.golang.org/protobuf/testing/protocmp"
"google.golang.org/protobuf/types/known/structpb"
2021-03-24 16:07:43 -04:00
"google.golang.org/protobuf/types/known/timestamppb"
2020-08-06 12:50:20 -07:00
"google.golang.org/protobuf/types/known/wrapperspb"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
2020-10-12 18:03:15 -04:00
const (
testPassword = "thetestpassword"
testLoginName = "default"
)
2021-04-08 20:54:32 -04:00
var (
pwAuthorizedActions = [] string {
2021-04-23 09:13:37 -05:00
action . NoOp . String (),
2021-04-08 20:54:32 -04:00
action . Read . String (),
action . Update . String (),
action . Delete . String (),
action . Authenticate . String (),
}
oidcAuthorizedActions = [] string {
2021-04-23 09:13:37 -05:00
action . NoOp . String (),
2021-04-08 20:54:32 -04:00
action . Read . String (),
action . Update . String (),
action . Delete . String (),
action . ChangeState . String (),
action . Authenticate . String (),
}
)
2021-01-20 10:53:01 -05:00
var authorizedCollectionActions = map [ string ] * structpb . ListValue {
"accounts" : {
Values : [] * structpb . Value {
structpb . NewStringValue ( "create" ),
structpb . NewStringValue ( "list" ),
},
},
}
2020-08-06 12:50:20 -07:00
func TestGet ( t * testing . T ) {
conn , _ := db . TestSetup ( t , "postgres" )
rw := db . New ( conn )
2020-08-19 16:47:18 -04:00
wrapper := db . TestWrapper ( t )
2021-04-08 20:54:32 -04:00
kmsCache := kms . TestKms ( t , conn , wrapper )
2020-09-04 14:48:11 -07:00
iamRepoFn := func () ( * iam . Repository , error ) {
return iam . TestRepo ( t , conn , wrapper ), nil
}
2021-04-08 20:54:32 -04:00
oidcRepoFn := func () ( * oidc . Repository , error ) {
return oidc . NewRepository ( rw , rw , kmsCache )
}
2020-10-12 18:03:15 -04:00
pwRepoFn := func () ( * password . Repository , error ) {
2021-04-08 20:54:32 -04:00
return password . NewRepository ( rw , rw , kmsCache )
2020-08-06 12:50:20 -07:00
}
2020-10-12 18:03:15 -04:00
atRepoFn := func () ( * authtoken . Repository , error ) {
2021-04-08 20:54:32 -04:00
return authtoken . NewRepository ( rw , rw , kmsCache )
2020-10-12 18:03:15 -04:00
}
2020-08-19 16:47:18 -04:00
iamRepo := iam . TestRepo ( t , conn , wrapper )
2020-08-06 12:50:20 -07:00
2020-08-19 16:47:18 -04:00
o , _ := iam . TestScopes ( t , iamRepo )
2020-08-06 12:50:20 -07:00
am := password . TestAuthMethods ( t , conn , o . GetPublicId (), 1 )[ 0 ]
2021-04-08 20:54:32 -04:00
iam . TestSetPrimaryAuthMethod ( t , iamRepo , o , am . GetPublicId ())
2020-08-06 12:50:20 -07:00
2021-04-08 20:54:32 -04:00
wantPw := & pb . AuthMethod {
2020-08-06 12:50:20 -07:00
Id : am . GetPublicId (),
2020-09-02 19:43:41 -07:00
ScopeId : am . GetScopeId (),
2020-08-06 12:50:20 -07:00
CreatedTime : am . CreateTime . GetTimestamp (),
UpdatedTime : am . UpdateTime . GetTimestamp (),
Type : "password" ,
Attributes : & structpb . Struct { Fields : map [ string ] * structpb . Value {
2020-08-11 17:25:00 -04:00
"min_password_length" : structpb . NewNumberValue ( 8 ),
"min_login_name_length" : structpb . NewNumberValue ( 3 ),
2020-08-06 12:50:20 -07:00
}},
2020-08-11 11:19:29 -04:00
Version : 1 ,
2020-08-12 08:20:35 -07:00
Scope : & scopepb . ScopeInfo {
2021-03-25 03:15:43 -04:00
Id : o . GetPublicId (),
Type : o . GetType (),
ParentScopeId : scope . Global . String (),
2020-08-06 12:50:20 -07:00
},
2021-04-08 20:54:32 -04:00
IsPrimary : true ,
AuthorizedActions : pwAuthorizedActions ,
AuthorizedCollectionActions : authorizedCollectionActions ,
}
databaseWrapper , err := kmsCache . GetWrapper ( context . Background (), o . GetPublicId (), kms . KeyPurposeDatabase )
require . NoError ( t , err )
oidcam := oidc . TestAuthMethod ( t , conn , databaseWrapper , o . GetPublicId (), oidc . InactiveState , "alice_rp" , "secret" ,
oidc . WithIssuer ( oidc . TestConvertToUrls ( t , "https://alice.com" )[ 0 ]), oidc . WithApiUrl ( oidc . TestConvertToUrls ( t , "https://api.com" )[ 0 ]))
wantOidc := & pb . AuthMethod {
Id : oidcam . GetPublicId (),
ScopeId : oidcam . GetScopeId (),
CreatedTime : oidcam . CreateTime . GetTimestamp (),
UpdatedTime : oidcam . UpdateTime . GetTimestamp (),
2021-07-27 09:59:52 -07:00
Type : oidc . Subtype . String (),
2021-04-08 20:54:32 -04:00
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 )),
"api_url_prefix" : structpb . NewStringValue ( "https://api.com" ),
2021-05-02 15:25:29 -04:00
"callback_url" : structpb . NewStringValue ( fmt . Sprintf ( oidc . CallbackEndpoint , "https://api.com" )),
2021-04-08 20:54:32 -04:00
}},
Version : 1 ,
Scope : & scopepb . ScopeInfo {
Id : o . GetPublicId (),
Type : o . GetType (),
ParentScopeId : scope . Global . String (),
},
AuthorizedActions : oidcAuthorizedActions ,
2021-01-20 10:53:01 -05:00
AuthorizedCollectionActions : authorizedCollectionActions ,
2020-08-06 12:50:20 -07:00
}
cases := [] struct {
name string
scopeId string
req * pbs . GetAuthMethodRequest
res * pbs . GetAuthMethodResponse
2020-09-23 08:10:27 -07:00
err error
2020-08-06 12:50:20 -07:00
}{
{
2021-04-08 20:54:32 -04:00
name : "Get an Existing PW AuthMethod" ,
2020-08-06 12:50:20 -07:00
scopeId : o . GetPublicId (),
req : & pbs . GetAuthMethodRequest { Id : am . GetPublicId ()},
2021-04-08 20:54:32 -04:00
res : & pbs . GetAuthMethodResponse { Item : wantPw },
},
{
name : "Get an Existing OIDC AuthMethod" ,
scopeId : o . GetPublicId (),
req : & pbs . GetAuthMethodRequest { Id : oidcam . GetPublicId ()},
res : & pbs . GetAuthMethodResponse { Item : wantOidc },
2020-08-06 12:50:20 -07:00
},
{
name : "Get a non existant AuthMethod" ,
scopeId : o . GetPublicId (),
req : & pbs . GetAuthMethodRequest { Id : password . AuthMethodPrefix + "_DoesntExis" },
res : nil ,
2020-09-23 08:10:27 -07:00
err : handlers . ApiErrorWithCode ( codes . NotFound ),
2020-08-06 12:50:20 -07:00
},
{
name : "Wrong id prefix" ,
scopeId : o . GetPublicId (),
req : & pbs . GetAuthMethodRequest { Id : "j_1234567890" },
res : nil ,
2020-09-23 08:10:27 -07:00
err : handlers . ApiErrorWithCode ( codes . InvalidArgument ),
2020-08-06 12:50:20 -07:00
},
{
name : "space in id" ,
scopeId : o . GetPublicId (),
req : & pbs . GetAuthMethodRequest { Id : password . AuthMethodPrefix + "_1 23456789" },
res : nil ,
2020-09-23 08:10:27 -07:00
err : handlers . ApiErrorWithCode ( codes . InvalidArgument ),
2020-08-06 12:50:20 -07:00
},
}
for _ , tc := range cases {
t . Run ( tc . name , func ( t * testing . T ) {
assert , require := assert . New ( t ), require . New ( t )
2021-04-08 20:54:32 -04:00
s , err := authmethods . NewService ( kmsCache , pwRepoFn , oidcRepoFn , iamRepoFn , atRepoFn )
2020-08-06 12:50:20 -07:00
require . NoError ( err , "Couldn't create new auth_method service." )
2021-07-27 09:59:52 -07:00
got , gErr := s . GetAuthMethod ( requestauth . DisabledAuthTestContext ( iamRepoFn , tc . scopeId ), tc . req )
2020-09-23 08:10:27 -07:00
if tc . err != nil {
require . Error ( gErr )
assert . True ( errors . Is ( gErr , tc . err ), "GetAuthMethod(%+v) got error %v, wanted %v" , tc . req , gErr , tc . err )
2021-04-08 20:54:32 -04:00
return
}
require . NoError ( gErr )
if _ , ok := got . Item . Attributes . Fields [ "client_secret_hmac" ]; ok {
assert . NotEqual ( "secret" , got . Item . Attributes . Fields [ "client_secret_hmac" ])
got . Item . Attributes . Fields [ "client_secret_hmac" ] = structpb . NewStringValue ( "<hmac>" )
2020-09-23 08:10:27 -07:00
}
2020-08-06 12:50:20 -07:00
assert . Empty ( cmp . Diff ( got , tc . res , protocmp . Transform ()), "GetAuthMethod(%q) got response %q, wanted %q" , tc . req , got , tc . res )
})
}
}
func TestList ( t * testing . T ) {
conn , _ := db . TestSetup ( t , "postgres" )
rw := db . New ( conn )
2020-08-19 16:47:18 -04:00
wrapper := db . TestWrapper ( t )
2021-04-08 20:54:32 -04:00
kmsCache := kms . TestKms ( t , conn , wrapper )
2020-09-04 14:48:11 -07:00
iamRepoFn := func () ( * iam . Repository , error ) {
return iam . TestRepo ( t , conn , wrapper ), nil
}
2021-04-08 20:54:32 -04:00
oidcRepoFn := func () ( * oidc . Repository , error ) {
return oidc . NewRepository ( rw , rw , kmsCache )
}
2020-10-12 18:03:15 -04:00
pwRepoFn := func () ( * password . Repository , error ) {
2021-04-08 20:54:32 -04:00
return password . NewRepository ( rw , rw , kmsCache )
2020-08-06 12:50:20 -07:00
}
2020-10-12 18:03:15 -04:00
atRepoFn := func () ( * authtoken . Repository , error ) {
2021-04-08 20:54:32 -04:00
return authtoken . NewRepository ( rw , rw , kmsCache )
2020-10-12 18:03:15 -04:00
}
2020-08-19 16:47:18 -04:00
iamRepo := iam . TestRepo ( t , conn , wrapper )
2020-08-06 12:50:20 -07:00
2020-08-19 16:47:18 -04:00
oNoAuthMethods , _ := iam . TestScopes ( t , iamRepo )
oWithAuthMethods , _ := iam . TestScopes ( t , iamRepo )
oWithOtherAuthMethods , _ := iam . TestScopes ( t , iamRepo )
2020-08-06 12:50:20 -07:00
var wantSomeAuthMethods [] * pb . AuthMethod
2021-04-08 20:54:32 -04:00
databaseWrapper , err := kmsCache . GetWrapper ( context . Background (), oWithAuthMethods . GetPublicId (), kms . KeyPurposeDatabase )
require . NoError ( t , err )
2021-04-13 16:42:25 -07:00
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 ))
2021-04-08 20:54:32 -04:00
iam . TestSetPrimaryAuthMethod ( t , iamRepo , oWithAuthMethods , oidcam . GetPublicId ())
wantSomeAuthMethods = append ( wantSomeAuthMethods , & pb . AuthMethod {
Id : oidcam . GetPublicId (),
ScopeId : oWithAuthMethods . GetPublicId (),
CreatedTime : oidcam . GetCreateTime (). GetTimestamp (),
UpdatedTime : oidcam . GetUpdateTime (). GetTimestamp (),
Scope : & scopepb . ScopeInfo { Id : oWithAuthMethods . GetPublicId (), Type : scope . Org . String (), ParentScopeId : scope . Global . String ()},
2021-04-13 16:42:25 -07:00
Version : 2 ,
2021-07-27 09:59:52 -07:00
Type : oidc . Subtype . String (),
2021-04-08 20:54:32 -04:00
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>" ),
2021-04-13 16:42:25 -07:00
"state" : structpb . NewStringValue ( string ( oidc . ActivePublicState )),
2021-04-08 20:54:32 -04:00
"api_url_prefix" : structpb . NewStringValue ( "https://api.com" ),
2021-05-02 15:25:29 -04:00
"callback_url" : structpb . NewStringValue ( fmt . Sprintf ( oidc . CallbackEndpoint , "https://api.com" )),
2021-04-13 16:42:25 -07:00
"signing_algorithms" : func () * structpb . Value {
lv , _ := structpb . NewList ([] interface {}{ string ( oidc . EdDSA )})
return structpb . NewListValue ( lv )
}(),
2021-04-08 20:54:32 -04:00
}},
IsPrimary : true ,
AuthorizedActions : oidcAuthorizedActions ,
AuthorizedCollectionActions : authorizedCollectionActions ,
})
2020-08-06 12:50:20 -07:00
for _ , am := range password . TestAuthMethods ( t , conn , oWithAuthMethods . GetPublicId (), 3 ) {
wantSomeAuthMethods = append ( wantSomeAuthMethods , & pb . AuthMethod {
Id : am . GetPublicId (),
2020-09-02 19:43:41 -07:00
ScopeId : oWithAuthMethods . GetPublicId (),
2020-08-06 12:50:20 -07:00
CreatedTime : am . GetCreateTime (). GetTimestamp (),
UpdatedTime : am . GetUpdateTime (). GetTimestamp (),
2021-03-25 03:15:43 -04:00
Scope : & scopepb . ScopeInfo { Id : oWithAuthMethods . GetPublicId (), Type : scope . Org . String (), ParentScopeId : scope . Global . String ()},
2020-08-11 11:19:29 -04:00
Version : 1 ,
2020-08-06 12:50:20 -07:00
Type : "password" ,
Attributes : & structpb . Struct { Fields : map [ string ] * structpb . Value {
2020-08-11 17:25:00 -04:00
"min_password_length" : structpb . NewNumberValue ( 8 ),
"min_login_name_length" : structpb . NewNumberValue ( 3 ),
2020-08-06 12:50:20 -07:00
}},
2021-04-08 20:54:32 -04:00
AuthorizedActions : pwAuthorizedActions ,
2021-01-20 10:53:01 -05:00
AuthorizedCollectionActions : authorizedCollectionActions ,
2020-08-06 12:50:20 -07:00
})
}
var wantOtherAuthMethods [] * pb . AuthMethod
for _ , aa := range password . TestAuthMethods ( t , conn , oWithOtherAuthMethods . GetPublicId (), 3 ) {
wantOtherAuthMethods = append ( wantOtherAuthMethods , & pb . AuthMethod {
Id : aa . GetPublicId (),
2020-09-02 19:43:41 -07:00
ScopeId : oWithOtherAuthMethods . GetPublicId (),
2020-08-06 12:50:20 -07:00
CreatedTime : aa . GetCreateTime (). GetTimestamp (),
UpdatedTime : aa . GetUpdateTime (). GetTimestamp (),
2021-03-25 03:15:43 -04:00
Scope : & scopepb . ScopeInfo { Id : oWithOtherAuthMethods . GetPublicId (), Type : scope . Org . String (), ParentScopeId : scope . Global . String ()},
2020-08-11 11:19:29 -04:00
Version : 1 ,
2020-08-06 12:50:20 -07:00
Type : "password" ,
Attributes : & structpb . Struct { Fields : map [ string ] * structpb . Value {
2020-08-11 17:25:00 -04:00
"min_password_length" : structpb . NewNumberValue ( 8 ),
"min_login_name_length" : structpb . NewNumberValue ( 3 ),
2020-08-06 12:50:20 -07:00
}},
2021-04-08 20:54:32 -04:00
AuthorizedActions : pwAuthorizedActions ,
2021-01-20 10:53:01 -05:00
AuthorizedCollectionActions : authorizedCollectionActions ,
2020-08-06 12:50:20 -07:00
})
}
cases := [] struct {
2021-01-25 19:37:40 -05:00
name string
req * pbs . ListAuthMethodsRequest
res * pbs . ListAuthMethodsResponse
err error
2020-08-06 12:50:20 -07:00
}{
{
2021-01-25 19:37:40 -05:00
name : "List Some Auth Methods" ,
req : & pbs . ListAuthMethodsRequest { ScopeId : oWithAuthMethods . GetPublicId ()},
res : & pbs . ListAuthMethodsResponse { Items : wantSomeAuthMethods },
2020-08-06 12:50:20 -07:00
},
{
2021-01-25 19:37:40 -05:00
name : "List Other Auth Methods" ,
req : & pbs . ListAuthMethodsRequest { ScopeId : oWithOtherAuthMethods . GetPublicId ()},
res : & pbs . ListAuthMethodsResponse { Items : wantOtherAuthMethods },
2020-08-06 12:50:20 -07:00
},
{
2021-01-25 19:37:40 -05:00
name : "List No Auth Methods" ,
req : & pbs . ListAuthMethodsRequest { ScopeId : oNoAuthMethods . GetPublicId ()},
res : & pbs . ListAuthMethodsResponse {},
2020-08-06 12:50:20 -07:00
},
{
2021-01-25 19:37:40 -05:00
name : "Unfound Auth Method" ,
req : & pbs . ListAuthMethodsRequest { ScopeId : "o_DoesntExis" },
err : handlers . ApiErrorWithCode ( codes . NotFound ),
},
{
name : "List All Auth Methods Recursively" ,
req : & pbs . ListAuthMethodsRequest { ScopeId : "global" , Recursive : true },
res : & pbs . ListAuthMethodsResponse {
Items : append ( wantSomeAuthMethods , wantOtherAuthMethods ... ),
},
2020-08-06 12:50:20 -07:00
},
2021-02-22 10:09:25 -07:00
{
name : "Filter To Some Auth Methods" ,
req : & pbs . ListAuthMethodsRequest {
ScopeId : "global" , Recursive : true ,
Filter : fmt . Sprintf ( `"/item/scope/id"==%q` , oWithAuthMethods . GetPublicId ()),
},
res : & pbs . ListAuthMethodsResponse { Items : wantSomeAuthMethods },
},
{
name : "Filter All Auth Methods" ,
req : & pbs . ListAuthMethodsRequest { ScopeId : oWithAuthMethods . GetPublicId (), Filter : `"/item/id"=="nothingmatchesthis"` },
res : & pbs . ListAuthMethodsResponse {},
},
{
name : "Filter Bad Format" ,
req : & pbs . ListAuthMethodsRequest { ScopeId : oWithAuthMethods . GetPublicId (), Filter : `"//id/"=="bad"` },
err : handlers . InvalidArgumentErrorf ( "bad format" , nil ),
},
2020-08-06 12:50:20 -07:00
}
for _ , tc := range cases {
t . Run ( tc . name , func ( t * testing . T ) {
assert , require := assert . New ( t ), require . New ( t )
2021-04-08 20:54:32 -04:00
s , err := authmethods . NewService ( kmsCache , pwRepoFn , oidcRepoFn , iamRepoFn , atRepoFn )
2020-08-06 12:50:20 -07:00
require . NoError ( err , "Couldn't create new auth_method service." )
2021-04-14 15:49:08 -05:00
// First check with non-anonymous user
2021-07-27 09:59:52 -07:00
got , gErr := s . ListAuthMethods ( requestauth . DisabledAuthTestContext ( iamRepoFn , tc . req . GetScopeId ()), tc . req )
2020-09-23 08:10:27 -07:00
if tc . err != nil {
require . Error ( gErr )
2021-01-25 19:37:40 -05:00
assert . True ( errors . Is ( gErr , tc . err ), "ListAuthMethods() for scope %q got error %v, wanted %v" , tc . req . GetScopeId (), gErr , tc . err )
2021-04-08 20:54:32 -04:00
return
}
require . NoError ( gErr )
for i , g := range got . Items {
if _ , ok := g . Attributes . Fields [ "client_secret_hmac" ]; ok {
assert . NotEqual ( "secret" , g . Attributes . Fields [ "client_secret_hmac" ])
delete ( g . Attributes . Fields , "client_secret_hmac" )
delete ( tc . res . Items [ i ]. Attributes . Fields , "client_secret_hmac" )
}
2020-09-23 08:10:27 -07:00
}
2021-01-25 19:37:40 -05:00
assert . Empty ( cmp . Diff ( got , tc . res , protocmp . Transform ()), "ListAuthMethods() for scope %q got response %q, wanted %q" , tc . req . GetScopeId (), got , tc . res )
2021-04-14 15:49:08 -05:00
// Now check with anonymous user
2021-07-27 09:59:52 -07:00
got , gErr = s . ListAuthMethods ( requestauth . DisabledAuthTestContext ( iamRepoFn , tc . req . GetScopeId (), requestauth . WithUserId ( requestauth . AnonymousUserId )), tc . req )
2021-04-14 15:49:08 -05:00
require . NoError ( gErr )
2021-05-04 19:57:35 -05:00
assert . Len ( got . Items , len ( tc . res . Items ))
2021-04-14 16:19:02 -05:00
for _ , g := range got . GetItems () {
2021-04-14 15:49:08 -05:00
assert . Nil ( g . Attributes )
assert . Nil ( g . CreatedTime )
assert . Nil ( g . UpdatedTime )
assert . Empty ( g . Version )
}
2020-08-06 12:50:20 -07:00
})
}
}
func TestDelete ( t * testing . T ) {
conn , _ := db . TestSetup ( t , "postgres" )
rw := db . New ( conn )
2020-08-19 16:47:18 -04:00
wrapper := db . TestWrapper ( t )
2021-04-08 20:54:32 -04:00
kmsCache := kms . TestKms ( t , conn , wrapper )
2020-09-04 14:48:11 -07:00
iamRepoFn := func () ( * iam . Repository , error ) {
return iam . TestRepo ( t , conn , wrapper ), nil
}
2021-04-08 20:54:32 -04:00
oidcRepoFn := func () ( * oidc . Repository , error ) {
return oidc . NewRepository ( rw , rw , kmsCache )
}
2020-10-12 18:03:15 -04:00
pwRepoFn := func () ( * password . Repository , error ) {
2021-04-08 20:54:32 -04:00
return password . NewRepository ( rw , rw , kmsCache )
2020-08-06 12:50:20 -07:00
}
2020-10-12 18:03:15 -04:00
atRepoFn := func () ( * authtoken . Repository , error ) {
2021-04-08 20:54:32 -04:00
return authtoken . NewRepository ( rw , rw , kmsCache )
2020-10-12 18:03:15 -04:00
}
2020-08-19 16:47:18 -04:00
iamRepo := iam . TestRepo ( t , conn , wrapper )
2020-08-06 12:50:20 -07:00
2020-08-19 16:47:18 -04:00
o , _ := iam . TestScopes ( t , iamRepo )
2021-04-08 20:54:32 -04:00
pwam := password . TestAuthMethods ( t , conn , o . GetPublicId (), 1 )[ 0 ]
2020-08-06 12:50:20 -07:00
2021-04-08 20:54:32 -04:00
databaseWrapper , err := kmsCache . GetWrapper ( context . Background (), o . GetPublicId (), kms . KeyPurposeDatabase )
require . NoError ( t , err )
oidcam := oidc . TestAuthMethod ( t , conn , databaseWrapper , o . GetPublicId (), oidc . InactiveState , "alice_rp" , "my-dogs-name" ,
oidc . WithIssuer ( oidc . TestConvertToUrls ( t , "https://alice.com" )[ 0 ]), oidc . WithApiUrl ( oidc . TestConvertToUrls ( t , "https://api.com" )[ 0 ]))
s , err := authmethods . NewService ( kmsCache , pwRepoFn , oidcRepoFn , iamRepoFn , atRepoFn )
2020-08-06 12:50:20 -07:00
require . NoError ( t , err , "Error when getting new auth_method service." )
cases := [] struct {
2020-09-23 08:10:27 -07:00
name string
req * pbs . DeleteAuthMethodRequest
res * pbs . DeleteAuthMethodResponse
err error
2020-08-06 12:50:20 -07:00
}{
{
2021-04-08 20:54:32 -04:00
name : "Delete an Existing PW AuthMethod" ,
req : & pbs . DeleteAuthMethodRequest {
Id : pwam . GetPublicId (),
},
},
{
name : "Delete an Existing OIDC AuthMethod" ,
2020-08-06 12:50:20 -07:00
req : & pbs . DeleteAuthMethodRequest {
2021-04-08 20:54:32 -04:00
Id : oidcam . GetPublicId (),
2020-08-06 12:50:20 -07:00
},
},
{
name : "Delete bad auth_method id" ,
req : & pbs . DeleteAuthMethodRequest {
Id : password . AuthMethodPrefix + "_doesntexis" ,
},
2020-09-23 08:10:27 -07:00
err : handlers . ApiErrorWithCode ( codes . NotFound ),
2020-08-06 12:50:20 -07:00
},
{
name : "Bad AuthMethod Id formatting" ,
req : & pbs . DeleteAuthMethodRequest {
Id : "bad_format" ,
},
2020-09-23 08:10:27 -07:00
err : handlers . ApiErrorWithCode ( codes . InvalidArgument ),
2020-08-06 12:50:20 -07:00
},
}
for _ , tc := range cases {
t . Run ( tc . name , func ( t * testing . T ) {
2020-09-23 08:10:27 -07:00
assert , require := assert . New ( t ), require . New ( t )
2021-07-27 09:59:52 -07:00
got , gErr := s . DeleteAuthMethod ( requestauth . DisabledAuthTestContext ( iamRepoFn , o . GetPublicId ()), tc . req )
2020-09-23 08:10:27 -07:00
if tc . err != nil {
require . Error ( gErr )
assert . True ( errors . Is ( gErr , tc . err ), "DeleteAuthMethod(%+v) got error %v, wanted %v" , tc . req , gErr , tc . err )
}
2020-08-06 12:50:20 -07:00
assert . EqualValuesf ( tc . res , got , "DeleteAuthMethod(%q) got response %q, wanted %q" , tc . req , got , tc . res )
})
}
}
func TestDelete_twice ( t * testing . T ) {
assert , require := assert . New ( t ), require . New ( t )
conn , _ := db . TestSetup ( t , "postgres" )
rw := db . New ( conn )
2020-08-19 16:47:18 -04:00
wrapper := db . TestWrapper ( t )
kms := kms . TestKms ( t , conn , wrapper )
2020-09-04 14:48:11 -07:00
iamRepoFn := func () ( * iam . Repository , error ) {
return iam . TestRepo ( t , conn , wrapper ), nil
}
2021-04-08 20:54:32 -04:00
oidcRepoFn := func () ( * oidc . Repository , error ) {
return oidc . NewRepository ( rw , rw , kms )
}
2020-10-12 18:03:15 -04:00
pwRepoFn := func () ( * password . Repository , error ) {
2020-08-19 16:47:18 -04:00
return password . NewRepository ( rw , rw , kms )
2020-08-06 12:50:20 -07:00
}
2020-10-12 18:03:15 -04:00
atRepoFn := func () ( * authtoken . Repository , error ) {
return authtoken . NewRepository ( rw , rw , kms )
}
2020-08-19 16:47:18 -04:00
iamRepo := iam . TestRepo ( t , conn , wrapper )
2020-08-06 12:50:20 -07:00
2020-08-19 16:47:18 -04:00
o , _ := iam . TestScopes ( t , iamRepo )
2020-08-06 12:50:20 -07:00
am := password . TestAuthMethods ( t , conn , o . GetPublicId (), 1 )[ 0 ]
2021-04-08 20:54:32 -04:00
s , err := authmethods . NewService ( kms , pwRepoFn , oidcRepoFn , iamRepoFn , atRepoFn )
2020-08-06 12:50:20 -07:00
require . NoError ( err , "Error when getting new auth_method service." )
req := & pbs . DeleteAuthMethodRequest {
Id : am . GetPublicId (),
}
2021-07-27 09:59:52 -07:00
_ , gErr := s . DeleteAuthMethod ( requestauth . DisabledAuthTestContext ( iamRepoFn , o . GetPublicId ()), req )
2020-08-06 12:50:20 -07:00
assert . NoError ( gErr , "First attempt" )
2021-07-27 09:59:52 -07:00
_ , gErr = s . DeleteAuthMethod ( requestauth . DisabledAuthTestContext ( iamRepoFn , o . GetPublicId ()), req )
2020-09-04 14:48:11 -07:00
assert . Error ( gErr , "Second attempt" )
2020-09-23 08:10:27 -07:00
assert . True ( errors . Is ( gErr , handlers . ApiErrorWithCode ( codes . NotFound )), "Expected permission denied for the second delete." )
2020-08-06 12:50:20 -07:00
}
func TestCreate ( t * testing . T ) {
conn , _ := db . TestSetup ( t , "postgres" )
rw := db . New ( conn )
2020-08-19 16:47:18 -04:00
wrapper := db . TestWrapper ( t )
kms := kms . TestKms ( t , conn , wrapper )
2020-09-04 14:48:11 -07:00
iamRepoFn := func () ( * iam . Repository , error ) {
return iam . TestRepo ( t , conn , wrapper ), nil
}
2020-10-12 18:03:15 -04:00
pwRepoFn := func () ( * password . Repository , error ) {
2020-08-19 16:47:18 -04:00
return password . NewRepository ( rw , rw , kms )
2020-08-06 12:50:20 -07:00
}
2021-04-08 20:54:32 -04:00
oidcRepoFn := func () ( * oidc . Repository , error ) {
return oidc . NewRepository ( rw , rw , kms )
}
2020-10-12 18:03:15 -04:00
atRepoFn := func () ( * authtoken . Repository , error ) {
return authtoken . NewRepository ( rw , rw , kms )
}
2020-08-19 16:47:18 -04:00
iamRepo := iam . TestRepo ( t , conn , wrapper )
2020-08-06 12:50:20 -07:00
2020-08-19 16:47:18 -04:00
o , _ := iam . TestScopes ( t , iamRepo )
2020-08-06 12:50:20 -07:00
defaultAm := password . TestAuthMethods ( t , conn , o . GetPublicId (), 1 )[ 0 ]
2021-03-24 16:07:43 -04:00
defaultCreated := defaultAm . GetCreateTime (). GetTimestamp ()
2020-08-06 12:50:20 -07:00
cases := [] struct {
2021-04-08 20:54:32 -04:00
name string
req * pbs . CreateAuthMethodRequest
res * pbs . CreateAuthMethodResponse
idPrefix string
err error
2020-08-06 12:50:20 -07:00
}{
{
2021-04-08 20:54:32 -04:00
name : "Create a valid Password AuthMethod" ,
2020-08-06 12:50:20 -07:00
req : & pbs . CreateAuthMethodRequest { Item : & pb . AuthMethod {
2020-09-02 19:43:41 -07:00
ScopeId : o . GetPublicId (),
2020-08-06 12:50:20 -07:00
Name : & wrapperspb . StringValue { Value : "name" },
Description : & wrapperspb . StringValue { Value : "desc" },
Type : "password" ,
}},
2021-04-08 20:54:32 -04:00
idPrefix : password . AuthMethodPrefix + "_" ,
2020-08-06 12:50:20 -07:00
res : & pbs . CreateAuthMethodResponse {
2020-09-02 19:43:41 -07:00
Uri : fmt . Sprintf ( "auth-methods/%s_" , password . AuthMethodPrefix ),
2020-08-06 12:50:20 -07:00
Item : & pb . AuthMethod {
Id : defaultAm . GetPublicId (),
2020-09-02 19:43:41 -07:00
ScopeId : o . GetPublicId (),
2020-08-06 12:50:20 -07:00
CreatedTime : defaultAm . GetCreateTime (). GetTimestamp (),
UpdatedTime : defaultAm . GetUpdateTime (). GetTimestamp (),
Name : & wrapperspb . StringValue { Value : "name" },
Description : & wrapperspb . StringValue { Value : "desc" },
2021-03-25 03:15:43 -04:00
Scope : & scopepb . ScopeInfo { Id : o . GetPublicId (), Type : o . GetType (), ParentScopeId : scope . Global . String ()},
2020-08-11 11:19:29 -04:00
Version : 1 ,
2020-08-06 12:50:20 -07:00
Type : "password" ,
Attributes : & structpb . Struct { Fields : map [ string ] * structpb . Value {
2020-08-11 17:25:00 -04:00
"min_password_length" : structpb . NewNumberValue ( 8 ),
"min_login_name_length" : structpb . NewNumberValue ( 3 ),
2020-08-06 12:50:20 -07:00
}},
2021-04-08 20:54:32 -04:00
AuthorizedActions : pwAuthorizedActions ,
2021-01-20 10:53:01 -05:00
AuthorizedCollectionActions : authorizedCollectionActions ,
2020-08-06 12:50:20 -07:00
},
},
},
2020-09-03 08:02:30 -07:00
{
2021-04-08 20:54:32 -04:00
name : "Create a valid OIDC AuthMethod" ,
req : & pbs . CreateAuthMethodRequest { Item : & pb . AuthMethod {
ScopeId : o . GetPublicId (),
2021-07-27 09:59:52 -07:00
Type : oidc . Subtype . String (),
2021-04-08 20:54:32 -04:00
Attributes : & structpb . Struct { Fields : map [ string ] * structpb . Value {
"issuer" : structpb . NewStringValue ( "https://example.discovery.url:4821/.well-known/openid-configuration/" ),
"client_id" : structpb . NewStringValue ( "someclientid" ),
"client_secret" : structpb . NewStringValue ( "secret" ),
"api_url_prefix" : structpb . NewStringValue ( "https://callback.prefix:9281/path" ),
"allowed_audiences" : func () * structpb . Value {
lv , _ := structpb . NewList ([] interface {}{ "foo" , "bar" })
return structpb . NewListValue ( lv )
}(),
2021-04-28 06:53:13 -04:00
"claims_scopes" : func () * structpb . Value {
lv , _ := structpb . NewList ([] interface {}{ "email" , "profile" })
return structpb . NewListValue ( lv )
}(),
2021-05-04 08:41:04 -04:00
"account_claim_maps" : func () * structpb . Value {
lv , _ := structpb . NewList ([] interface {}{ "display_name=name" , "oid=sub" })
return structpb . NewListValue ( lv )
}(),
2021-04-08 20:54:32 -04:00
}},
}},
idPrefix : oidc . AuthMethodPrefix + "_" ,
res : & pbs . CreateAuthMethodResponse {
Uri : fmt . Sprintf ( "auth-methods/%s_" , oidc . AuthMethodPrefix ),
Item : & pb . AuthMethod {
Id : defaultAm . GetPublicId (),
ScopeId : o . GetPublicId (),
CreatedTime : defaultAm . GetCreateTime (). GetTimestamp (),
UpdatedTime : defaultAm . GetUpdateTime (). GetTimestamp (),
Scope : & scopepb . ScopeInfo { Id : o . GetPublicId (), Type : o . GetType (), ParentScopeId : scope . Global . String ()},
Version : 1 ,
2021-07-27 09:59:52 -07:00
Type : oidc . Subtype . String (),
2021-04-08 20:54:32 -04:00
Attributes : & structpb . Struct { Fields : map [ string ] * structpb . Value {
"issuer" : structpb . NewStringValue ( "https://example.discovery.url:4821/" ),
"client_id" : structpb . NewStringValue ( "someclientid" ),
"client_secret_hmac" : structpb . NewStringValue ( "<hmac>" ),
"state" : structpb . NewStringValue ( string ( oidc . InactiveState )),
"api_url_prefix" : structpb . NewStringValue ( "https://callback.prefix:9281/path" ),
2021-05-02 15:25:29 -04:00
"callback_url" : structpb . NewStringValue ( "https://callback.prefix:9281/path/v1/auth-methods/oidc:authenticate:callback" ),
2021-04-08 20:54:32 -04:00
"allowed_audiences" : func () * structpb . Value {
lv , _ := structpb . NewList ([] interface {}{ "foo" , "bar" })
return structpb . NewListValue ( lv )
}(),
2021-04-28 06:53:13 -04:00
"claims_scopes" : func () * structpb . Value {
lv , _ := structpb . NewList ([] interface {}{ "email" , "profile" })
return structpb . NewListValue ( lv )
}(),
2021-05-04 08:41:04 -04:00
"account_claim_maps" : func () * structpb . Value {
lv , _ := structpb . NewList ([] interface {}{ "display_name=name" , "oid=sub" })
return structpb . NewListValue ( lv )
}(),
2021-04-08 20:54:32 -04:00
}},
AuthorizedActions : oidcAuthorizedActions ,
AuthorizedCollectionActions : authorizedCollectionActions ,
},
},
},
{
name : "Create a global Password AuthMethod" ,
2020-09-03 08:02:30 -07:00
req : & pbs . CreateAuthMethodRequest { Item : & pb . AuthMethod {
ScopeId : scope . Global . String (),
Name : & wrapperspb . StringValue { Value : "name" },
Description : & wrapperspb . StringValue { Value : "desc" },
Type : "password" ,
}},
2021-04-08 20:54:32 -04:00
idPrefix : password . AuthMethodPrefix + "_" ,
2020-09-03 08:02:30 -07:00
res : & pbs . CreateAuthMethodResponse {
Uri : fmt . Sprintf ( "auth-methods/%s_" , password . AuthMethodPrefix ),
Item : & pb . AuthMethod {
Id : defaultAm . GetPublicId (),
ScopeId : scope . Global . String (),
CreatedTime : defaultAm . GetCreateTime (). GetTimestamp (),
UpdatedTime : defaultAm . GetUpdateTime (). GetTimestamp (),
Name : & wrapperspb . StringValue { Value : "name" },
Description : & wrapperspb . StringValue { Value : "desc" },
2021-03-25 03:15:43 -04:00
Scope : & scopepb . ScopeInfo { Id : scope . Global . String (), Type : scope . Global . String (), Name : scope . Global . String (), Description : "Global Scope" },
2020-09-03 08:02:30 -07:00
Version : 1 ,
Type : "password" ,
Attributes : & structpb . Struct { Fields : map [ string ] * structpb . Value {
"min_password_length" : structpb . NewNumberValue ( 8 ),
"min_login_name_length" : structpb . NewNumberValue ( 3 ),
}},
2021-04-08 20:54:32 -04:00
AuthorizedActions : pwAuthorizedActions ,
AuthorizedCollectionActions : authorizedCollectionActions ,
},
},
},
{
name : "Create a global OIDC AuthMethod" ,
req : & pbs . CreateAuthMethodRequest { Item : & pb . AuthMethod {
ScopeId : scope . Global . String (),
2021-07-27 09:59:52 -07:00
Type : oidc . Subtype . String (),
2021-04-08 20:54:32 -04:00
Attributes : & structpb . Struct { Fields : map [ string ] * structpb . Value {
"issuer" : structpb . NewStringValue ( "https://example.discovery.url" ),
"api_url_prefix" : structpb . NewStringValue ( "https://api.com" ),
"client_id" : structpb . NewStringValue ( "someclientid" ),
"client_secret" : structpb . NewStringValue ( "secret" ),
}},
}},
idPrefix : oidc . AuthMethodPrefix + "_" ,
res : & pbs . CreateAuthMethodResponse {
Uri : fmt . Sprintf ( "auth-methods/%s_" , oidc . AuthMethodPrefix ),
Item : & pb . AuthMethod {
Id : defaultAm . GetPublicId (),
ScopeId : scope . Global . String (),
CreatedTime : defaultAm . GetCreateTime (). GetTimestamp (),
UpdatedTime : defaultAm . GetUpdateTime (). GetTimestamp (),
Scope : & scopepb . ScopeInfo { Id : scope . Global . String (), Type : scope . Global . String (), Name : scope . Global . String (), Description : "Global Scope" },
Version : 1 ,
2021-07-27 09:59:52 -07:00
Type : oidc . Subtype . String (),
2021-04-08 20:54:32 -04:00
Attributes : & structpb . Struct { Fields : map [ string ] * structpb . Value {
"api_url_prefix" : structpb . NewStringValue ( "https://api.com" ),
"issuer" : structpb . NewStringValue ( "https://example.discovery.url" ),
"client_id" : structpb . NewStringValue ( "someclientid" ),
"client_secret_hmac" : structpb . NewStringValue ( "<hmac>" ),
"state" : structpb . NewStringValue ( string ( oidc . InactiveState )),
}},
AuthorizedActions : oidcAuthorizedActions ,
2021-01-20 10:53:01 -05:00
AuthorizedCollectionActions : authorizedCollectionActions ,
2020-09-03 08:02:30 -07:00
},
},
},
2020-08-06 12:50:20 -07:00
{
name : "Can't specify Id" ,
req : & pbs . CreateAuthMethodRequest { Item : & pb . AuthMethod {
2020-09-02 19:43:41 -07:00
ScopeId : o . GetPublicId (),
Id : password . AuthMethodPrefix + "_notallowed" ,
Type : "password" ,
2020-08-06 12:50:20 -07:00
}},
2020-09-23 08:10:27 -07:00
res : nil ,
err : handlers . ApiErrorWithCode ( codes . InvalidArgument ),
2020-08-06 12:50:20 -07:00
},
{
name : "Can't specify Created Time" ,
req : & pbs . CreateAuthMethodRequest { Item : & pb . AuthMethod {
2020-09-02 19:43:41 -07:00
ScopeId : o . GetPublicId (),
2021-03-24 16:07:43 -04:00
CreatedTime : timestamppb . Now (),
2021-07-27 09:59:52 -07:00
Type : password . Subtype . String (),
2020-08-06 12:50:20 -07:00
}},
2020-09-23 08:10:27 -07:00
res : nil ,
err : handlers . ApiErrorWithCode ( codes . InvalidArgument ),
2020-08-06 12:50:20 -07:00
},
{
name : "Can't specify Update Time" ,
req : & pbs . CreateAuthMethodRequest { Item : & pb . AuthMethod {
2020-09-02 19:43:41 -07:00
ScopeId : o . GetPublicId (),
2021-03-24 16:07:43 -04:00
UpdatedTime : timestamppb . Now (),
2021-07-27 09:59:52 -07:00
Type : password . Subtype . String (),
2021-04-08 20:54:32 -04:00
}},
res : nil ,
err : handlers . ApiErrorWithCode ( codes . InvalidArgument ),
},
{
name : "Can't specify IsPrimary" ,
req : & pbs . CreateAuthMethodRequest { Item : & pb . AuthMethod {
ScopeId : o . GetPublicId (),
2021-07-27 09:59:52 -07:00
Type : password . Subtype . String (),
2021-04-08 20:54:32 -04:00
IsPrimary : true ,
2020-08-06 12:50:20 -07:00
}},
2020-09-23 08:10:27 -07:00
res : nil ,
err : handlers . ApiErrorWithCode ( codes . InvalidArgument ),
2020-08-06 12:50:20 -07:00
},
{
name : "Can't specify Update Time" ,
req : & pbs . CreateAuthMethodRequest { Item : & pb . AuthMethod {
2020-09-02 19:43:41 -07:00
ScopeId : o . GetPublicId (),
2021-03-24 16:07:43 -04:00
UpdatedTime : timestamppb . Now (),
2021-07-27 09:59:52 -07:00
Type : password . Subtype . String (),
2020-08-06 12:50:20 -07:00
}},
2020-09-23 08:10:27 -07:00
res : nil ,
err : handlers . ApiErrorWithCode ( codes . InvalidArgument ),
2020-08-06 12:50:20 -07:00
},
{
name : "Must specify type" ,
req : & pbs . CreateAuthMethodRequest { Item : & pb . AuthMethod {
2020-09-02 19:43:41 -07:00
ScopeId : o . GetPublicId (),
2020-08-06 12:50:20 -07:00
Name : & wrapperspb . StringValue { Value : "must specify type" },
Description : & wrapperspb . StringValue { Value : "must specify type" },
}},
2020-09-23 08:10:27 -07:00
res : nil ,
err : handlers . ApiErrorWithCode ( codes . InvalidArgument ),
2020-08-06 12:50:20 -07:00
},
{
2021-04-08 20:54:32 -04:00
name : "Attributes must be valid for password type" ,
2020-08-06 12:50:20 -07:00
req : & pbs . CreateAuthMethodRequest { Item : & pb . AuthMethod {
2020-09-02 19:43:41 -07:00
ScopeId : o . GetPublicId (),
2020-08-06 12:50:20 -07:00
Name : & wrapperspb . StringValue { Value : "Attributes must be valid for type" },
Description : & wrapperspb . StringValue { Value : "Attributes must be valid for type" },
2021-07-27 09:59:52 -07:00
Type : password . Subtype . String (),
2020-08-06 12:50:20 -07:00
Attributes : & structpb . Struct { Fields : map [ string ] * structpb . Value {
2020-08-11 17:25:00 -04:00
"invalid_field" : structpb . NewStringValue ( "invalid_value" ),
"min_login_name_length" : structpb . NewNumberValue ( 3 ),
2020-08-06 12:50:20 -07:00
}},
}},
2020-09-23 08:10:27 -07:00
res : nil ,
err : handlers . ApiErrorWithCode ( codes . InvalidArgument ),
2020-08-06 12:50:20 -07:00
},
{
2021-04-08 20:54:32 -04:00
name : "Attributes must be valid for oidc type" ,
req : & pbs . CreateAuthMethodRequest { Item : & pb . AuthMethod {
ScopeId : o . GetPublicId (),
Name : & wrapperspb . StringValue { Value : "Attributes must be valid for type" },
Description : & wrapperspb . StringValue { Value : "Attributes must be valid for type" },
2021-07-27 09:59:52 -07:00
Type : oidc . Subtype . String (),
2021-04-08 20:54:32 -04:00
Attributes : & structpb . Struct { Fields : map [ string ] * structpb . Value {
"login-name" : structpb . NewStringValue ( "invalid_value" ),
"password" : structpb . NewNumberValue ( 3 ),
}},
}},
res : nil ,
err : handlers . ApiErrorWithCode ( codes . InvalidArgument ),
2020-08-06 12:50:20 -07:00
},
{
2021-04-08 20:54:32 -04:00
name : "OIDC AuthMethod Doesn't Require Issuer" ,
req : & pbs . CreateAuthMethodRequest { Item : & pb . AuthMethod {
ScopeId : o . GetPublicId (),
2021-07-27 09:59:52 -07:00
Type : oidc . Subtype . String (),
2021-04-08 20:54:32 -04:00
Attributes : & structpb . Struct { Fields : map [ string ] * structpb . Value {
"api_url_prefix" : structpb . NewStringValue ( "https://api.com" ),
"client_id" : structpb . NewStringValue ( "someclientid" ),
"client_secret" : structpb . NewStringValue ( "secret" ),
}},
}},
res : & pbs . CreateAuthMethodResponse {
Uri : fmt . Sprintf ( "auth-methods/%s_" , oidc . AuthMethodPrefix ),
2020-08-06 12:50:20 -07:00
Item : & pb . AuthMethod {
2021-04-08 20:54:32 -04:00
Id : defaultAm . GetPublicId (),
2020-09-02 19:43:41 -07:00
ScopeId : o . GetPublicId (),
2021-04-08 20:54:32 -04:00
CreatedTime : defaultAm . GetCreateTime (). GetTimestamp (),
UpdatedTime : defaultAm . GetUpdateTime (). GetTimestamp (),
Scope : & scopepb . ScopeInfo { Id : o . GetPublicId (), Type : o . GetType (), ParentScopeId : scope . Global . String ()},
Version : 1 ,
2021-07-27 09:59:52 -07:00
Type : oidc . Subtype . String (),
2020-08-06 12:50:20 -07:00
Attributes : & structpb . Struct { Fields : map [ string ] * structpb . Value {
2021-04-08 20:54:32 -04:00
"api_url_prefix" : structpb . NewStringValue ( "https://api.com" ),
"client_id" : structpb . NewStringValue ( "someclientid" ),
"client_secret_hmac" : structpb . NewStringValue ( "<hmac>" ),
"state" : structpb . NewStringValue ( string ( oidc . InactiveState )),
2020-08-06 12:50:20 -07:00
}},
2021-04-08 20:54:32 -04:00
AuthorizedActions : oidcAuthorizedActions ,
2021-01-20 10:53:01 -05:00
AuthorizedCollectionActions : authorizedCollectionActions ,
2020-08-06 12:50:20 -07:00
},
},
},
{
2021-04-08 20:54:32 -04:00
name : "OIDC AuthMethod Requires ApiUrl" ,
req : & pbs . CreateAuthMethodRequest { Item : & pb . AuthMethod {
ScopeId : o . GetPublicId (),
2021-07-27 09:59:52 -07:00
Type : oidc . Subtype . String (),
2021-04-08 20:54:32 -04:00
Attributes : & structpb . Struct { Fields : map [ string ] * structpb . Value {
"client_id" : structpb . NewStringValue ( "someclientid" ),
"client_secret" : structpb . NewStringValue ( "secret" ),
}},
}},
2020-09-23 08:10:27 -07:00
err : handlers . ApiErrorWithCode ( codes . InvalidArgument ),
2020-08-06 12:50:20 -07:00
},
{
2021-04-08 20:54:32 -04:00
name : "OIDC AuthMethod Requires Client Id" ,
req : & pbs . CreateAuthMethodRequest { Item : & pb . AuthMethod {
ScopeId : o . GetPublicId (),
2021-07-27 09:59:52 -07:00
Type : oidc . Subtype . String (),
2021-04-08 20:54:32 -04:00
Attributes : & structpb . Struct { Fields : map [ string ] * structpb . Value {
"api_url_prefix" : structpb . NewStringValue ( "https://api.com" ),
"issuer" : structpb . NewStringValue ( "https://example.discovery.url:4821/.well-known/openid-configuration/" ),
"client_secret" : structpb . NewStringValue ( "secret" ),
}},
}},
2020-09-23 08:10:27 -07:00
err : handlers . ApiErrorWithCode ( codes . InvalidArgument ),
2020-08-06 12:50:20 -07:00
},
{
2021-04-08 20:54:32 -04:00
name : "OIDC AuthMethod Requires Client Secret" ,
req : & pbs . CreateAuthMethodRequest { Item : & pb . AuthMethod {
ScopeId : o . GetPublicId (),
2021-07-27 09:59:52 -07:00
Type : oidc . Subtype . String (),
2021-04-08 20:54:32 -04:00
Attributes : & structpb . Struct { Fields : map [ string ] * structpb . Value {
"api_url_prefix" : structpb . NewStringValue ( "https://api.com" ),
"issuer" : structpb . NewStringValue ( "https://example.discovery.url:4821/.well-known/openid-configuration/" ),
"client_id" : structpb . NewStringValue ( "someclientid" ),
}},
}},
2020-09-23 08:10:27 -07:00
err : handlers . ApiErrorWithCode ( codes . InvalidArgument ),
2020-08-06 12:50:20 -07:00
},
2020-09-08 16:04:19 -07:00
{
2021-04-08 20:54:32 -04:00
name : "OIDC AuthMethod cant specify client secret hmac" ,
req : & pbs . CreateAuthMethodRequest { Item : & pb . AuthMethod {
ScopeId : o . GetPublicId (),
2021-07-27 09:59:52 -07:00
Type : oidc . Subtype . String (),
2021-04-08 20:54:32 -04:00
Attributes : & structpb . Struct { Fields : map [ string ] * structpb . Value {
"api_url_prefix" : structpb . NewStringValue ( "https://api.com" ),
"issuer" : structpb . NewStringValue ( "https://example.discovery.url:4821/.well-known/openid-configuration/" ),
"client_id" : structpb . NewStringValue ( "someclientid" ),
"client_secret" : structpb . NewStringValue ( "secret" ),
"client_secret_hmac" : structpb . NewStringValue ( "hmac" ),
}},
}},
2020-09-23 08:10:27 -07:00
err : handlers . ApiErrorWithCode ( codes . InvalidArgument ),
2020-09-08 16:04:19 -07:00
},
2020-08-06 12:50:20 -07:00
{
2021-04-08 20:54:32 -04:00
name : "OIDC AuthMethod cant specify state" ,
req : & pbs . CreateAuthMethodRequest { Item : & pb . AuthMethod {
ScopeId : o . GetPublicId (),
2021-07-27 09:59:52 -07:00
Type : oidc . Subtype . String (),
2021-04-08 20:54:32 -04:00
Attributes : & structpb . Struct { Fields : map [ string ] * structpb . Value {
"api_url_prefix" : structpb . NewStringValue ( "https://api.com" ),
"issuer" : structpb . NewStringValue ( "https://example.discovery.url:4821/.well-known/openid-configuration/" ),
"client_id" : structpb . NewStringValue ( "someclientid" ),
"client_secret" : structpb . NewStringValue ( "secret" ),
"state" : structpb . NewStringValue ( string ( oidc . InactiveState )),
}},
}},
2020-09-23 08:10:27 -07:00
err : handlers . ApiErrorWithCode ( codes . InvalidArgument ),
2020-08-06 12:50:20 -07:00
},
{
2021-04-08 20:54:32 -04:00
name : "OIDC AuthMethod Must Match Standard Alg Names" ,
req : & pbs . CreateAuthMethodRequest { Item : & pb . AuthMethod {
ScopeId : o . GetPublicId (),
2021-07-27 09:59:52 -07:00
Type : oidc . Subtype . String (),
2021-04-08 20:54:32 -04:00
Attributes : & structpb . Struct { Fields : map [ string ] * structpb . Value {
"api_url_prefix" : structpb . NewStringValue ( "https://api.com" ),
"issuer" : structpb . NewStringValue ( "https://example2.discovery.url:4821" ),
"client_id" : structpb . NewStringValue ( "someclientid" ),
"client_secret" : structpb . NewStringValue ( "secret" ),
"signing_algorithms" : func () * structpb . Value {
lv , _ := structpb . NewList ([] interface {}{ string ( oidc . ES256 ), strings . ToLower ( string ( oidc . EdDSA ))})
return structpb . NewListValue ( lv )
}(),
}},
}},
2020-09-23 08:10:27 -07:00
err : handlers . ApiErrorWithCode ( codes . InvalidArgument ),
2020-08-06 12:50:20 -07:00
},
{
2021-04-08 20:54:32 -04:00
name : "OIDC AuthMethod API Urls Prefix Format" ,
req : & pbs . CreateAuthMethodRequest { Item : & pb . AuthMethod {
ScopeId : o . GetPublicId (),
2021-07-27 09:59:52 -07:00
Type : oidc . Subtype . String (),
2021-04-08 20:54:32 -04:00
Attributes : & structpb . Struct { Fields : map [ string ] * structpb . Value {
"issuer" : structpb . NewStringValue ( "https://example2.discovery.url:4821" ),
"client_id" : structpb . NewStringValue ( "someclientid" ),
"client_secret" : structpb . NewStringValue ( "secret" ),
"api_url_prefix" : structpb . NewStringValue ( "invalid path" ),
}},
}},
2020-09-23 08:10:27 -07:00
err : handlers . ApiErrorWithCode ( codes . InvalidArgument ),
2020-08-06 12:50:20 -07:00
},
{
2021-04-08 20:54:32 -04:00
name : "OIDC AuthMethod Callback Url Read Only" ,
req : & pbs . CreateAuthMethodRequest { Item : & pb . AuthMethod {
ScopeId : o . GetPublicId (),
2021-07-27 09:59:52 -07:00
Type : oidc . Subtype . String (),
2021-04-08 20:54:32 -04:00
Attributes : & structpb . Struct { Fields : map [ string ] * structpb . Value {
"issuer" : structpb . NewStringValue ( "https://example2.discovery.url:4821" ),
"client_id" : structpb . NewStringValue ( "someclientid" ),
"client_secret" : structpb . NewStringValue ( "secret" ),
"callback_url" : structpb . NewStringValue ( "http://another.url.com:82471" ),
}},
}},
2020-09-23 08:10:27 -07:00
err : handlers . ApiErrorWithCode ( codes . InvalidArgument ),
2020-08-06 12:50:20 -07:00
},
2020-08-14 14:08:12 -07:00
{
2021-04-08 20:54:32 -04:00
name : "OIDC AuthMethod unparseable certificates" ,
req : & pbs . CreateAuthMethodRequest { Item : & pb . AuthMethod {
ScopeId : o . GetPublicId (),
2021-07-27 09:59:52 -07:00
Type : oidc . Subtype . String (),
2021-04-08 20:54:32 -04:00
Attributes : & structpb . Struct { Fields : map [ string ] * structpb . Value {
"api_url_prefix" : structpb . NewStringValue ( "https://api.com" ),
"issuer" : structpb . NewStringValue ( "https://example2.discovery.url:4821" ),
"client_id" : structpb . NewStringValue ( "someclientid" ),
"client_secret" : structpb . NewStringValue ( "secret" ),
"idp_ca_certs" : func () * structpb . Value {
lv , _ := structpb . NewList ([] interface {}{ "unparseable" })
return structpb . NewListValue ( lv )
}(),
}},
}},
err : handlers . ApiErrorWithCode ( codes . InvalidArgument ),
2020-08-14 14:08:12 -07:00
},
2021-04-28 06:53:13 -04:00
{
name : "OIDC AuthMethod cant specify default claims scopes of openid" ,
req : & pbs . CreateAuthMethodRequest { Item : & pb . AuthMethod {
ScopeId : o . GetPublicId (),
2021-07-27 09:59:52 -07:00
Type : oidc . Subtype . String (),
2021-04-28 06:53:13 -04:00
Attributes : & structpb . Struct { Fields : map [ string ] * structpb . Value {
"api_url_prefix" : structpb . NewStringValue ( "https://api.com" ),
"issuer" : structpb . NewStringValue ( "https://example.discovery.url:4821/.well-known/openid-configuration/" ),
"client_id" : structpb . NewStringValue ( "someclientid" ),
"client_secret" : structpb . NewStringValue ( "secret" ),
"claims_scopes" : func () * structpb . Value {
lv , _ := structpb . NewList ([] interface {}{ "openid" })
return structpb . NewListValue ( lv )
}(),
}},
}},
err : handlers . ApiErrorWithCode ( codes . InvalidArgument ),
},
2020-08-06 12:50:20 -07:00
}
for _ , tc := range cases {
t . Run ( tc . name , func ( t * testing . T ) {
assert , require := assert . New ( t ), require . New ( t )
2021-04-08 20:54:32 -04:00
s , err := authmethods . NewService ( kms , pwRepoFn , oidcRepoFn , iamRepoFn , atRepoFn )
require . NoError ( err , "Error when getting new auth_method service." )
2020-08-06 12:50:20 -07:00
2021-07-27 09:59:52 -07:00
got , gErr := s . CreateAuthMethod ( requestauth . DisabledAuthTestContext ( iamRepoFn , tc . req . GetItem (). GetScopeId ()), tc . req )
2020-09-23 08:10:27 -07:00
if tc . err != nil {
require . Error ( gErr )
2021-04-08 20:54:32 -04:00
assert . True ( errors . Is ( gErr , tc . err ), "CreateAuthMethod(%+v) got error %v, wanted %v" , tc . req , gErr , tc . err )
return
2020-09-23 08:10:27 -07:00
}
2021-04-08 20:54:32 -04:00
require . NoError ( gErr )
2020-08-06 12:50:20 -07:00
if tc . res == nil {
require . Nil ( got )
}
if got != nil {
2021-04-08 20:54:32 -04:00
assert . Contains ( got . GetUri (), tc . res . Uri )
assert . True ( strings . HasPrefix ( got . GetItem (). GetId (), tc . idPrefix ))
gotCreateTime := got . GetItem (). GetCreatedTime ()
gotUpdateTime := got . GetItem (). GetUpdatedTime ()
2020-08-06 12:50:20 -07:00
2021-04-08 20:54:32 -04:00
// Verify it is a auth_method created after the test setup's default auth_method
assert . True ( gotCreateTime . AsTime (). After ( defaultCreated . AsTime ()), "New auth_method should have been created after default auth_method. Was created %v, which is after %v" , gotCreateTime , defaultCreated )
assert . True ( gotUpdateTime . AsTime (). After ( defaultCreated . AsTime ()), "New auth_method should have been updated after default auth_method. Was updated %v, which is after %v" , gotUpdateTime , defaultCreated )
2020-08-06 12:50:20 -07:00
// Clear all values which are hard to compare against.
2021-04-08 20:54:32 -04:00
got . Uri , tc . res . Uri = "" , ""
got . Item . Id , tc . res . Item . Id = "" , ""
got . Item . CreatedTime , got . Item . UpdatedTime , tc . res . Item . CreatedTime , tc . res . Item . UpdatedTime = nil , nil , nil , nil
if _ , ok := got . Item . Attributes . Fields [ "client_secret_hmac" ]; ok {
assert . NotEqual ( tc . req . Item . Attributes . Fields [ "client_secret" ], got . Item . Attributes . Fields [ "client_secret_hmac" ])
got . Item . Attributes . Fields [ "client_secret_hmac" ] = structpb . NewStringValue ( "<hmac>" )
}
if _ , ok := got . Item . Attributes . Fields [ "callback_url" ]; ok {
exp := tc . res . Item . Attributes . Fields [ "callback_url" ]. GetStringValue ()
gVal := got . Item . Attributes . Fields [ "callback_url" ]. GetStringValue ()
matches , err := regexp . MatchString ( exp , gVal )
require . NoError ( err )
assert . True ( matches , "%q doesn't match %q" , gVal , exp )
delete ( got . Item . Attributes . Fields , "callback_url" )
delete ( tc . res . Item . Attributes . Fields , "callback_url" )
}
2021-06-11 11:43:36 -07:00
if v , ok := got . Item . Attributes . Fields [ "account_claim_maps" ]; ok {
lv := v . GetListValue (). GetValues ()
sort . Slice ( lv , func ( i , j int ) bool {
return lv [ i ]. GetStringValue () < lv [ j ]. GetStringValue ()
})
}
if v , ok := tc . res . Item . Attributes . Fields [ "account_claim_maps" ]; ok {
lv := v . GetListValue (). GetValues ()
sort . Slice ( lv , func ( i , j int ) bool {
return lv [ i ]. GetStringValue () < lv [ j ]. GetStringValue ()
})
}
2020-10-12 18:03:15 -04:00
}
2021-05-04 08:41:04 -04:00
assert . Empty ( cmp . Diff ( got , tc . res , protocmp . Transform (), protocmp . SortRepeatedFields ( got )), "CreateAuthMethod(%q) got response %q, wanted %q" , tc . req , got , tc . res )
2020-10-12 18:03:15 -04:00
})
}
}