2020-08-06 12:50:20 -07:00
package authmethods_test
import (
2020-09-23 08:10:27 -07:00
"errors"
2020-08-06 12:50:20 -07:00
"fmt"
"strings"
"testing"
"github.com/golang/protobuf/ptypes"
"github.com/google/go-cmp/cmp"
2020-08-10 17:15:02 -04:00
"github.com/hashicorp/boundary/internal/auth"
"github.com/hashicorp/boundary/internal/auth/password"
"github.com/hashicorp/boundary/internal/db"
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"
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"
"github.com/hashicorp/boundary/internal/types/scope"
2020-08-06 12:50:20 -07:00
"google.golang.org/genproto/protobuf/field_mask"
"google.golang.org/grpc/codes"
"google.golang.org/protobuf/testing/protocmp"
"google.golang.org/protobuf/types/known/structpb"
"google.golang.org/protobuf/types/known/wrapperspb"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
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 )
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-08-06 12:50:20 -07:00
repoFn := 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-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 ]
wantU := & pb . AuthMethod {
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 {
2020-08-06 12:50:20 -07:00
Id : o . GetPublicId (),
Type : o . GetType (),
},
}
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
}{
{
name : "Get an Existing AuthMethod" ,
scopeId : o . GetPublicId (),
req : & pbs . GetAuthMethodRequest { Id : am . GetPublicId ()},
res : & pbs . GetAuthMethodResponse { Item : wantU },
},
{
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 )
2020-09-04 14:48:11 -07:00
s , err := authmethods . NewService ( repoFn , iamRepoFn )
2020-08-06 12:50:20 -07:00
require . NoError ( err , "Couldn't create new auth_method service." )
got , gErr := s . GetAuthMethod ( auth . DisabledAuthTestContext ( auth . WithScopeId ( 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 )
}
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 )
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-08-06 12:50:20 -07:00
repoFn := 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-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
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 (),
2020-08-12 08:20:35 -07:00
Scope : & scopepb . ScopeInfo { Id : oWithAuthMethods . GetPublicId (), Type : scope . Org . 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
}},
})
}
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 (),
2020-08-12 08:20:35 -07:00
Scope : & scopepb . ScopeInfo { Id : oWithOtherAuthMethods . GetPublicId (), Type : scope . Org . 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
}},
})
}
cases := [] struct {
name string
scopeId string
res * pbs . ListAuthMethodsResponse
2020-09-23 08:10:27 -07:00
err error
2020-08-06 12:50:20 -07:00
}{
{
name : "List Some Auth Methods" ,
scopeId : oWithAuthMethods . GetPublicId (),
res : & pbs . ListAuthMethodsResponse { Items : wantSomeAuthMethods },
},
{
name : "List Other Auth Methods" ,
scopeId : oWithOtherAuthMethods . GetPublicId (),
res : & pbs . ListAuthMethodsResponse { Items : wantOtherAuthMethods },
},
{
name : "List No Auth Methods" ,
scopeId : oNoAuthMethods . GetPublicId (),
res : & pbs . ListAuthMethodsResponse {},
},
{
name : "Unfound Auth Method" ,
2020-09-08 23:57:26 -04:00
scopeId : "o_DoesntExis" ,
2020-09-23 08:10:27 -07:00
err : handlers . ApiErrorWithCode ( codes . NotFound ),
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 )
2020-09-04 14:48:11 -07:00
s , err := authmethods . NewService ( repoFn , iamRepoFn )
2020-08-06 12:50:20 -07:00
require . NoError ( err , "Couldn't create new auth_method service." )
2020-09-04 14:48:11 -07:00
got , gErr := s . ListAuthMethods ( auth . DisabledAuthTestContext ( auth . WithScopeId ( tc . scopeId )), & pbs . ListAuthMethodsRequest { ScopeId : tc . scopeId })
2020-09-23 08:10:27 -07:00
if tc . err != nil {
require . Error ( gErr )
assert . True ( errors . Is ( gErr , tc . err ), "ListAuthMethods() for scope %q got error %v, wanted %v" , tc . scopeId , gErr , tc . err )
}
2020-08-06 12:50:20 -07:00
assert . Empty ( cmp . Diff ( got , tc . res , protocmp . Transform ()), "ListAuthMethods() for scope %q got response %q, wanted %q" , tc . scopeId , got , tc . res )
})
}
}
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 )
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-08-06 12:50:20 -07:00
repoFn := 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-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 ]
2020-09-04 14:48:11 -07:00
s , err := authmethods . NewService ( repoFn , iamRepoFn )
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
}{
{
name : "Delete an Existing AuthMethod" ,
req : & pbs . DeleteAuthMethodRequest {
Id : am . GetPublicId (),
},
2020-09-23 08:10:27 -07:00
res : & pbs . DeleteAuthMethodResponse {},
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 )
2020-08-06 12:50:20 -07:00
got , gErr := s . DeleteAuthMethod ( auth . DisabledAuthTestContext ( auth . WithScopeId ( 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
}
2020-08-06 12:50:20 -07:00
repoFn := 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-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 ]
2020-09-04 14:48:11 -07:00
s , err := authmethods . NewService ( repoFn , iamRepoFn )
2020-08-06 12:50:20 -07:00
require . NoError ( err , "Error when getting new auth_method service." )
req := & pbs . DeleteAuthMethodRequest {
Id : am . GetPublicId (),
}
2020-09-08 23:57:26 -04:00
_ , gErr := s . DeleteAuthMethod ( auth . DisabledAuthTestContext ( auth . WithScopeId ( o . GetPublicId ())), req )
2020-08-06 12:50:20 -07:00
assert . NoError ( gErr , "First attempt" )
2020-09-08 23:57:26 -04:00
_ , gErr = s . DeleteAuthMethod ( auth . DisabledAuthTestContext ( auth . WithScopeId ( 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-08-06 12:50:20 -07:00
repoFn := 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-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 ]
defaultCreated , err := ptypes . Timestamp ( defaultAm . GetCreateTime (). GetTimestamp ())
require . NoError ( t , err , "Error converting proto to timestamp." )
cases := [] struct {
2020-09-23 08:10:27 -07:00
name string
req * pbs . CreateAuthMethodRequest
res * pbs . CreateAuthMethodResponse
err error
2020-08-06 12:50:20 -07:00
}{
{
name : "Create a valid AuthMethod" ,
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" ,
}},
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" },
2020-08-12 08:20:35 -07:00
Scope : & scopepb . ScopeInfo { Id : o . GetPublicId (), Type : o . GetType ()},
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
}},
},
},
},
2020-09-03 08:02:30 -07:00
{
name : "Create a global AuthMethod" ,
req : & pbs . CreateAuthMethodRequest { Item : & pb . AuthMethod {
ScopeId : scope . Global . String (),
Name : & wrapperspb . StringValue { Value : "name" },
Description : & wrapperspb . StringValue { Value : "desc" },
Type : "password" ,
}},
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" },
Scope : & scopepb . ScopeInfo { Id : scope . Global . String (), Type : scope . Global . String ()},
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 ),
}},
},
},
},
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 (),
2020-08-06 12:50:20 -07:00
CreatedTime : ptypes . TimestampNow (),
}},
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 (),
2020-08-06 12:50:20 -07:00
UpdatedTime : ptypes . TimestampNow (),
Type : "password" ,
}},
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 (),
2020-08-06 12:50:20 -07:00
UpdatedTime : ptypes . TimestampNow (),
Type : "password" ,
}},
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
},
{
name : "Attributes must be valid for 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 : "Attributes must be valid for type" },
Description : & wrapperspb . StringValue { Value : "Attributes must be valid for type" },
Type : "password" ,
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
},
}
for _ , tc := range cases {
t . Run ( tc . name , func ( t * testing . T ) {
assert , require := assert . New ( t ), require . New ( t )
2020-09-04 14:48:11 -07:00
s , err := authmethods . NewService ( repoFn , iamRepoFn )
2020-08-06 12:50:20 -07:00
require . NoError ( err , "Error when getting new auth_method service." )
2020-09-03 08:02:30 -07:00
got , gErr := s . CreateAuthMethod ( auth . DisabledAuthTestContext ( auth . WithScopeId ( tc . req . GetItem (). GetScopeId ())), tc . req )
2020-09-23 08:10:27 -07:00
if tc . err != nil {
require . Error ( gErr )
assert . True ( errors . Is ( gErr , tc . err ), "CreateAuthMethod(%+v) got error %v, wanted %v" , tc . req , gErr , tc . err )
}
2020-08-06 12:50:20 -07:00
if tc . res == nil {
require . Nil ( got )
}
if got != nil {
assert . Contains ( got . GetUri (), tc . res . Uri )
assert . True ( strings . HasPrefix ( got . GetItem (). GetId (), password . AuthMethodPrefix + "_" ))
gotCreateTime , err := ptypes . Timestamp ( got . GetItem (). GetCreatedTime ())
require . NoError ( err , "Error converting proto to timestamp." )
gotUpdateTime , err := ptypes . Timestamp ( got . GetItem (). GetUpdatedTime ())
require . NoError ( err , "Error converting proto to timestamp." )
// Verify it is a auth_method created after the test setup's default auth_method
assert . True ( gotCreateTime . After ( defaultCreated ), "New auth_method should have been created after default auth_method. Was created %v, which is after %v" , gotCreateTime , defaultCreated )
assert . True ( gotUpdateTime . After ( defaultCreated ), "New auth_method should have been updated after default auth_method. Was updated %v, which is after %v" , gotUpdateTime , defaultCreated )
// Clear all values which are hard to compare against.
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
}
assert . Empty ( cmp . Diff ( got , tc . res , protocmp . Transform ()), "CreateAuthMethod(%q) got response %q, wanted %q" , tc . req , got , tc . res )
})
}
}
func TestUpdate ( 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-08-06 12:50:20 -07:00
repoFn := 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-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-09-04 14:48:11 -07:00
tested , err := authmethods . NewService ( repoFn , iamRepoFn )
2020-08-06 12:50:20 -07:00
require . NoError ( t , err , "Error when getting new auth_method service." )
2020-08-12 08:20:35 -07:00
defaultScopeInfo := & scopepb . ScopeInfo { Id : o . GetPublicId (), Type : o . GetType ()}
2020-08-06 12:50:20 -07:00
freshAuthMethod := func () ( * pb . AuthMethod , func ()) {
am , err := tested . CreateAuthMethod ( auth . DisabledAuthTestContext ( auth . WithScopeId ( o . GetPublicId ())),
& pbs . CreateAuthMethodRequest { Item : & pb . AuthMethod {
2020-09-03 08:02:30 -07:00
ScopeId : o . GetPublicId (),
2020-08-06 12:50:20 -07:00
Name : wrapperspb . String ( "default" ),
Description : wrapperspb . String ( "default" ),
Type : "password" ,
}})
require . NoError ( t , err )
clean := func () {
_ , err := tested . DeleteAuthMethod ( auth . DisabledAuthTestContext ( auth . WithScopeId ( o . GetPublicId ())),
& pbs . DeleteAuthMethodRequest { Id : am . GetItem (). GetId ()})
require . NoError ( t , err )
}
return am . GetItem (), clean
}
cases := [] struct {
2020-09-23 08:10:27 -07:00
name string
req * pbs . UpdateAuthMethodRequest
res * pbs . UpdateAuthMethodResponse
err error
2020-08-06 12:50:20 -07:00
}{
{
name : "Update an Existing AuthMethod" ,
req : & pbs . UpdateAuthMethodRequest {
UpdateMask : & field_mask . FieldMask {
Paths : [] string { "name" , "description" },
},
Item : & pb . AuthMethod {
Name : & wrapperspb . StringValue { Value : "new" },
Description : & wrapperspb . StringValue { Value : "desc" },
2020-09-08 16:04:19 -07:00
Type : "password" ,
2020-08-06 12:50:20 -07:00
},
},
res : & pbs . UpdateAuthMethodResponse {
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 : "new" },
Description : & wrapperspb . StringValue { Value : "desc" },
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-12 08:20:35 -07:00
Scope : defaultScopeInfo ,
2020-08-06 12:50:20 -07:00
},
},
},
{
name : "Multiple Paths in single string" ,
req : & pbs . UpdateAuthMethodRequest {
UpdateMask : & field_mask . FieldMask {
2020-09-08 16:04:19 -07:00
Paths : [] string { "name,description,type" },
2020-08-06 12:50:20 -07:00
},
Item : & pb . AuthMethod {
Name : & wrapperspb . StringValue { Value : "new" },
Description : & wrapperspb . StringValue { Value : "desc" },
2020-09-08 16:04:19 -07:00
Type : "password" ,
2020-08-06 12:50:20 -07:00
},
},
res : & pbs . UpdateAuthMethodResponse {
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 : "new" },
Description : & wrapperspb . StringValue { Value : "desc" },
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-12 08:20:35 -07:00
Scope : defaultScopeInfo ,
2020-08-06 12:50:20 -07:00
},
},
},
{
name : "No Update Mask" ,
req : & pbs . UpdateAuthMethodRequest {
Item : & pb . AuthMethod {
Name : & wrapperspb . StringValue { Value : "updated name" },
Description : & wrapperspb . StringValue { Value : "updated desc" },
},
},
2020-09-23 08:10:27 -07:00
err : handlers . ApiErrorWithCode ( codes . InvalidArgument ),
2020-08-06 12:50:20 -07:00
},
{
name : "No Paths in Mask" ,
req : & pbs . UpdateAuthMethodRequest {
UpdateMask : & field_mask . FieldMask { Paths : [] string {}},
Item : & pb . AuthMethod {
Name : & wrapperspb . StringValue { Value : "updated name" },
Description : & wrapperspb . StringValue { Value : "updated desc" },
},
},
2020-09-23 08:10:27 -07:00
err : handlers . ApiErrorWithCode ( codes . InvalidArgument ),
2020-08-06 12:50:20 -07:00
},
{
name : "Only non-existant paths in Mask" ,
req : & pbs . UpdateAuthMethodRequest {
UpdateMask : & field_mask . FieldMask { Paths : [] string { "nonexistant_field" }},
Item : & pb . AuthMethod {
Name : & wrapperspb . StringValue { Value : "updated name" },
Description : & wrapperspb . StringValue { Value : "updated desc" },
},
},
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
{
name : "Cant change type" ,
req : & pbs . UpdateAuthMethodRequest {
UpdateMask : & field_mask . FieldMask { Paths : [] string { "name" , "type" }},
Item : & pb . AuthMethod {
Name : & wrapperspb . StringValue { Value : "updated name" },
Type : "oidc" ,
},
},
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
{
name : "Unset Name" ,
req : & pbs . UpdateAuthMethodRequest {
UpdateMask : & field_mask . FieldMask {
Paths : [] string { "name" },
},
Item : & pb . AuthMethod {
Description : & wrapperspb . StringValue { Value : "ignored" },
},
},
res : & pbs . UpdateAuthMethodResponse {
Item : & pb . AuthMethod {
2020-09-02 19:43:41 -07:00
ScopeId : o . GetPublicId (),
2020-08-06 12:50:20 -07:00
Description : & wrapperspb . StringValue { Value : "default" },
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-12 08:20:35 -07:00
Scope : defaultScopeInfo ,
2020-08-06 12:50:20 -07:00
},
},
},
{
name : "Update Only Name" ,
req : & pbs . UpdateAuthMethodRequest {
UpdateMask : & field_mask . FieldMask {
Paths : [] string { "name" },
},
Item : & pb . AuthMethod {
Name : & wrapperspb . StringValue { Value : "updated" },
Description : & wrapperspb . StringValue { Value : "ignored" },
},
},
res : & pbs . UpdateAuthMethodResponse {
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 : "updated" },
Description : & wrapperspb . StringValue { Value : "default" },
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-12 08:20:35 -07:00
Scope : defaultScopeInfo ,
2020-08-06 12:50:20 -07:00
},
},
},
{
name : "Update Only Description" ,
req : & pbs . UpdateAuthMethodRequest {
UpdateMask : & field_mask . FieldMask {
Paths : [] string { "description" },
},
Item : & pb . AuthMethod {
Name : & wrapperspb . StringValue { Value : "ignored" },
Description : & wrapperspb . StringValue { Value : "notignored" },
},
},
res : & pbs . UpdateAuthMethodResponse {
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 : "default" },
Description : & wrapperspb . StringValue { Value : "notignored" },
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-12 08:20:35 -07:00
Scope : defaultScopeInfo ,
2020-08-06 12:50:20 -07:00
},
},
},
{
name : "Update a Non Existing AuthMethod" ,
req : & pbs . UpdateAuthMethodRequest {
Id : password . AuthMethodPrefix + "_DoesntExis" ,
UpdateMask : & field_mask . FieldMask {
Paths : [] string { "description" },
},
Item : & pb . AuthMethod {
Name : & wrapperspb . StringValue { Value : "new" },
Description : & wrapperspb . StringValue { Value : "desc" },
},
},
2020-09-23 08:10:27 -07:00
err : handlers . ApiErrorWithCode ( codes . NotFound ),
2020-08-06 12:50:20 -07:00
},
{
name : "Cant change Id" ,
req : & pbs . UpdateAuthMethodRequest {
UpdateMask : & field_mask . FieldMask {
Paths : [] string { "id" },
},
Item : & pb . AuthMethod {
Id : password . AuthMethodPrefix + "_somethinge" ,
Name : & wrapperspb . StringValue { Value : "new" },
Description : & wrapperspb . StringValue { Value : "new desc" },
}},
2020-09-23 08:10:27 -07:00
res : nil ,
err : handlers . ApiErrorWithCode ( codes . InvalidArgument ),
2020-08-06 12:50:20 -07:00
},
{
name : "Cant specify Created Time" ,
req : & pbs . UpdateAuthMethodRequest {
UpdateMask : & field_mask . FieldMask {
Paths : [] string { "created_time" },
},
Item : & pb . AuthMethod {
CreatedTime : ptypes . TimestampNow (),
},
},
2020-09-23 08:10:27 -07:00
res : nil ,
err : handlers . ApiErrorWithCode ( codes . InvalidArgument ),
2020-08-06 12:50:20 -07:00
},
{
name : "Cant specify Updated Time" ,
req : & pbs . UpdateAuthMethodRequest {
UpdateMask : & field_mask . FieldMask {
Paths : [] string { "updated_time" },
},
Item : & pb . AuthMethod {
UpdatedTime : ptypes . TimestampNow (),
},
},
2020-09-23 08:10:27 -07:00
res : nil ,
err : handlers . ApiErrorWithCode ( codes . InvalidArgument ),
2020-08-06 12:50:20 -07:00
},
{
name : "Cant specify Type" ,
req : & pbs . UpdateAuthMethodRequest {
UpdateMask : & field_mask . FieldMask {
Paths : [] string { "type" },
},
Item : & pb . AuthMethod {
Type : "oidc" ,
},
},
2020-09-23 08:10:27 -07:00
res : nil ,
err : handlers . ApiErrorWithCode ( codes . InvalidArgument ),
2020-08-06 12:50:20 -07:00
},
2020-08-14 14:08:12 -07:00
{
name : "Update login name length" ,
req : & pbs . UpdateAuthMethodRequest {
UpdateMask : & field_mask . FieldMask {
Paths : [] string { "attributes.min_login_name_length" },
},
Item : & pb . AuthMethod {
Name : & wrapperspb . StringValue { Value : "ignored" },
Description : & wrapperspb . StringValue { Value : "ignored" },
Attributes : & structpb . Struct { Fields : map [ string ] * structpb . Value {
"min_login_name_length" : structpb . NewNumberValue ( 42 ),
"min_password_length" : structpb . NewNumberValue ( 55555 ),
}},
},
},
res : & pbs . UpdateAuthMethodResponse {
Item : & pb . AuthMethod {
2020-09-02 19:43:41 -07:00
ScopeId : o . GetPublicId (),
2020-08-14 14:08:12 -07:00
Name : & wrapperspb . StringValue { Value : "default" },
Description : & wrapperspb . StringValue { Value : "default" },
Type : "password" ,
Attributes : & structpb . Struct { Fields : map [ string ] * structpb . Value {
"min_password_length" : structpb . NewNumberValue ( 8 ),
"min_login_name_length" : structpb . NewNumberValue ( 42 ),
}},
Scope : defaultScopeInfo ,
},
},
},
{
name : "Update password length" ,
req : & pbs . UpdateAuthMethodRequest {
UpdateMask : & field_mask . FieldMask {
Paths : [] string { "attributes.min_password_length" },
},
Item : & pb . AuthMethod {
Name : & wrapperspb . StringValue { Value : "ignored" },
Description : & wrapperspb . StringValue { Value : "ignored" },
Attributes : & structpb . Struct { Fields : map [ string ] * structpb . Value {
"min_login_name_length" : structpb . NewNumberValue ( 5555 ),
"min_password_length" : structpb . NewNumberValue ( 42 ),
}},
},
},
res : & pbs . UpdateAuthMethodResponse {
Item : & pb . AuthMethod {
2020-09-02 19:43:41 -07:00
ScopeId : o . GetPublicId (),
2020-08-14 14:08:12 -07:00
Name : & wrapperspb . StringValue { Value : "default" },
Description : & wrapperspb . StringValue { Value : "default" },
Type : "password" ,
Attributes : & structpb . Struct { Fields : map [ string ] * structpb . Value {
"min_password_length" : structpb . NewNumberValue ( 42 ),
"min_login_name_length" : structpb . NewNumberValue ( 3 ),
}},
Scope : defaultScopeInfo ,
},
},
},
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 )
am , cleanup := freshAuthMethod ()
defer cleanup ()
2020-08-18 17:38:38 -07:00
tc . req . Item . Version = 1
2020-08-11 11:19:29 -04:00
2020-08-06 12:50:20 -07:00
if tc . req . GetId () == "" {
tc . req . Id = am . GetId ()
}
if tc . res != nil && tc . res . Item != nil {
tc . res . Item . Id = am . GetId ()
tc . res . Item . CreatedTime = am . GetCreatedTime ()
}
got , gErr := tested . UpdateAuthMethod ( auth . DisabledAuthTestContext ( auth . WithScopeId ( 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 ), "UpdateAuthMethod(%+v) got error %v, wanted %v" , tc . req , gErr , tc . err )
}
2020-08-06 12:50:20 -07:00
if tc . res == nil {
require . Nil ( got )
}
if got != nil {
assert . NotNilf ( tc . res , "Expected UpdateAuthMethod response to be nil, but was %v" , got )
gotUpdateTime , err := ptypes . Timestamp ( got . GetItem (). GetUpdatedTime ())
require . NoError ( err , "Error converting proto to timestamp" )
created , err := ptypes . Timestamp ( am . GetCreatedTime ())
require . NoError ( err , "Error converting proto to timestamp" )
// Verify it is a auth_method updated after it was created
assert . True ( gotUpdateTime . After ( created ), "Updated auth_method should have been updated after it's creation. Was updated %v, which is after %v" , gotUpdateTime , created )
// Clear all values which are hard to compare against.
got . Item . UpdatedTime , tc . res . Item . UpdatedTime = nil , nil
2020-08-11 11:19:29 -04:00
assert . EqualValues ( 2 , got . Item . Version )
tc . res . Item . Version = 2
2020-08-06 12:50:20 -07:00
}
assert . Empty ( cmp . Diff ( got , tc . res , protocmp . Transform ()), "UpdateAuthMethod(%q) got response %q, wanted %q" , tc . req , got , tc . res )
})
}
}