2020-08-06 12:50:20 -07:00
package authmethods
import (
"context"
2020-11-05 16:54:03 -05:00
stderrors "errors"
2020-08-06 12:50:20 -07:00
"fmt"
2020-10-12 18:03:15 -04:00
"strings"
2020-08-06 12:50:20 -07:00
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/auth/password/store"
2020-10-12 18:03:15 -04:00
"github.com/hashicorp/boundary/internal/authtoken"
2020-11-05 16:54:03 -05: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-10-12 18:03:15 -04:00
pba "github.com/hashicorp/boundary/internal/gen/controller/api/resources/authtokens"
"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"
2020-10-12 18:03:15 -04:00
"github.com/hashicorp/boundary/internal/iam"
"github.com/hashicorp/boundary/internal/kms"
2020-09-04 14:48:11 -07:00
"github.com/hashicorp/boundary/internal/servers/controller/common"
2020-08-10 17:15:02 -04:00
"github.com/hashicorp/boundary/internal/servers/controller/handlers"
2020-09-04 14:48:11 -07:00
"github.com/hashicorp/boundary/internal/types/action"
"github.com/hashicorp/boundary/internal/types/resource"
2020-09-03 08:02:30 -07: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/types/known/wrapperspb"
)
2020-10-12 18:03:15 -04:00
const (
loginNameKey = "login_name"
pwKey = "password"
)
2020-08-06 12:50:20 -07:00
var (
maskManager handlers . MaskManager
)
func init () {
var err error
2020-08-14 14:08:12 -07:00
if maskManager , err = handlers . NewMaskManager ( & store . AuthMethod {}, & pb . AuthMethod {}, & pb . PasswordAuthMethodAttributes {}); err != nil {
2020-08-06 12:50:20 -07:00
panic ( err )
}
}
// Service handles request as described by the pbs.AuthMethodServiceServer interface.
type Service struct {
2020-11-11 14:41:05 -05:00
pbs . UnimplementedAuthMethodServiceServer
2020-10-12 18:03:15 -04:00
kms * kms . Kms
pwRepoFn common . PasswordAuthRepoFactory
2020-09-04 14:48:11 -07:00
iamRepoFn common . IamRepoFactory
2020-10-12 18:03:15 -04:00
atRepoFn common . AuthTokenRepoFactory
2020-08-06 12:50:20 -07:00
}
2020-08-10 17:15:02 -04:00
// NewService returns a auth method service which handles auth method related requests to boundary.
2020-10-12 18:03:15 -04:00
func NewService ( kms * kms . Kms , pwRepoFn common . PasswordAuthRepoFactory , iamRepoFn common . IamRepoFactory , atRepoFn common . AuthTokenRepoFactory ) ( Service , error ) {
if kms == nil {
2020-11-05 16:54:03 -05:00
return Service {}, stderrors . New ( "nil kms provided" )
2020-10-12 18:03:15 -04:00
}
if pwRepoFn == nil {
2020-09-04 14:48:11 -07:00
return Service {}, fmt . Errorf ( "nil password repository provided" )
}
if iamRepoFn == nil {
2020-08-06 12:50:20 -07:00
return Service {}, fmt . Errorf ( "nil iam repository provided" )
}
2020-10-12 18:03:15 -04:00
return Service { kms : kms , pwRepoFn : pwRepoFn , iamRepoFn : iamRepoFn , atRepoFn : atRepoFn }, nil
2020-08-06 12:50:20 -07:00
}
var _ pbs . AuthMethodServiceServer = Service {}
// ListAuthMethods implements the interface pbs.AuthMethodServiceServer.
func ( s Service ) ListAuthMethods ( ctx context . Context , req * pbs . ListAuthMethodsRequest ) ( * pbs . ListAuthMethodsResponse , error ) {
if err := validateListRequest ( req ); err != nil {
return nil , err
}
2020-09-04 14:48:11 -07:00
authResults := s . authResult ( ctx , req . GetScopeId (), action . List )
if authResults . Error != nil {
return nil , authResults . Error
}
2020-08-06 12:50:20 -07:00
ul , err := s . listFromRepo ( ctx , authResults . Scope . GetId ())
if err != nil {
return nil , err
}
for _ , item := range ul {
item . Scope = authResults . Scope
}
return & pbs . ListAuthMethodsResponse { Items : ul }, nil
}
2020-08-21 08:15:32 -07:00
// GetAuthMethod implements the interface pbs.AuthMethodServiceServer.
2020-08-06 12:50:20 -07:00
func ( s Service ) GetAuthMethod ( ctx context . Context , req * pbs . GetAuthMethodRequest ) ( * pbs . GetAuthMethodResponse , error ) {
if err := validateGetRequest ( req ); err != nil {
return nil , err
}
2020-09-04 14:48:11 -07:00
authResults := s . authResult ( ctx , req . GetId (), action . Read )
if authResults . Error != nil {
return nil , authResults . Error
}
2020-08-06 12:50:20 -07:00
u , err := s . getFromRepo ( ctx , req . GetId ())
if err != nil {
return nil , err
}
u . Scope = authResults . Scope
return & pbs . GetAuthMethodResponse { Item : u }, nil
}
// CreateAuthMethod implements the interface pbs.AuthMethodServiceServer.
func ( s Service ) CreateAuthMethod ( ctx context . Context , req * pbs . CreateAuthMethodRequest ) ( * pbs . CreateAuthMethodResponse , error ) {
if err := validateCreateRequest ( req ); err != nil {
return nil , err
}
2020-09-04 14:48:11 -07:00
authResults := s . authResult ( ctx , req . GetItem (). GetScopeId (), action . Create )
if authResults . Error != nil {
return nil , authResults . Error
}
u , err := s . createInRepo ( ctx , authResults . Scope . GetId (), req . GetItem ())
2020-08-06 12:50:20 -07:00
if err != nil {
return nil , err
}
u . Scope = authResults . Scope
2020-09-02 19:43:41 -07:00
return & pbs . CreateAuthMethodResponse { Item : u , Uri : fmt . Sprintf ( "auth-methods/%s" , u . GetId ())}, nil
2020-08-06 12:50:20 -07:00
}
// UpdateAuthMethod implements the interface pbs.AuthMethodServiceServer.
func ( s Service ) UpdateAuthMethod ( ctx context . Context , req * pbs . UpdateAuthMethodRequest ) ( * pbs . UpdateAuthMethodResponse , error ) {
if err := validateUpdateRequest ( req ); err != nil {
return nil , err
}
2020-09-04 14:48:11 -07:00
authResults := s . authResult ( ctx , req . GetId (), action . Update )
if authResults . Error != nil {
return nil , authResults . Error
}
2020-08-18 17:38:38 -07:00
u , err := s . updateInRepo ( ctx , authResults . Scope . GetId (), req . GetId (), req . GetUpdateMask (). GetPaths (), req . GetItem ())
2020-08-06 12:50:20 -07:00
if err != nil {
return nil , err
}
2020-08-12 08:20:35 -07:00
u . Scope = authResults . Scope
2020-08-06 12:50:20 -07:00
return & pbs . UpdateAuthMethodResponse { Item : u }, nil
}
// DeleteAuthMethod implements the interface pbs.AuthMethodServiceServer.
func ( s Service ) DeleteAuthMethod ( ctx context . Context , req * pbs . DeleteAuthMethodRequest ) ( * pbs . DeleteAuthMethodResponse , error ) {
if err := validateDeleteRequest ( req ); err != nil {
return nil , err
}
2020-09-04 14:48:11 -07:00
authResults := s . authResult ( ctx , req . GetId (), action . Delete )
if authResults . Error != nil {
return nil , authResults . Error
}
2020-09-08 23:57:26 -04:00
_ , err := s . deleteFromRepo ( ctx , authResults . Scope . GetId (), req . GetId ())
2020-08-06 12:50:20 -07:00
if err != nil {
return nil , err
}
2020-09-21 12:09:30 -07:00
return & pbs . DeleteAuthMethodResponse {}, nil
2020-08-06 12:50:20 -07:00
}
2020-10-12 18:03:15 -04:00
// Authenticate implements the interface pbs.AuthenticationServiceServer.
func ( s Service ) Authenticate ( ctx context . Context , req * pbs . AuthenticateRequest ) ( * pbs . AuthenticateResponse , error ) {
if err := validateAuthenticateRequest ( req ); err != nil {
return nil , err
}
authResults := s . authResult ( ctx , req . GetAuthMethodId (), action . Authenticate )
if authResults . Error != nil {
return nil , authResults . Error
}
creds := req . GetCredentials (). GetFields ()
tok , err := s . authenticateWithRepo ( ctx , authResults . Scope . GetId (), req . GetAuthMethodId (), creds [ loginNameKey ]. GetStringValue (), creds [ pwKey ]. GetStringValue ())
if err != nil {
return nil , err
}
return & pbs . AuthenticateResponse { Item : tok , TokenType : req . GetTokenType ()}, nil
}
2020-08-06 12:50:20 -07:00
func ( s Service ) getFromRepo ( ctx context . Context , id string ) ( * pb . AuthMethod , error ) {
2020-10-12 18:03:15 -04:00
repo , err := s . pwRepoFn ()
2020-08-06 12:50:20 -07:00
if err != nil {
return nil , err
}
u , err := repo . LookupAuthMethod ( ctx , id )
if err != nil {
2020-11-05 16:54:03 -05:00
if errors . Is ( err , errors . ErrRecordNotFound ) {
2020-08-06 12:50:20 -07:00
return nil , handlers . NotFoundErrorf ( "AuthMethod %q doesn't exist." , id )
}
return nil , err
}
if u == nil {
return nil , handlers . NotFoundErrorf ( "AuthMethod %q doesn't exist." , id )
}
2020-10-12 18:03:15 -04:00
return toAuthMethodProto ( u )
2020-08-06 12:50:20 -07:00
}
func ( s Service ) listFromRepo ( ctx context . Context , scopeId string ) ([] * pb . AuthMethod , error ) {
2020-10-12 18:03:15 -04:00
repo , err := s . pwRepoFn ()
2020-08-06 12:50:20 -07:00
if err != nil {
return nil , err
}
ul , err := repo . ListAuthMethods ( ctx , scopeId )
if err != nil {
return nil , err
}
var outUl [] * pb . AuthMethod
for _ , u := range ul {
2020-10-12 18:03:15 -04:00
ou , err := toAuthMethodProto ( u )
2020-08-06 12:50:20 -07:00
if err != nil {
return nil , err
}
outUl = append ( outUl , ou )
}
return outUl , nil
}
func ( s Service ) createInRepo ( ctx context . Context , scopeId string , item * pb . AuthMethod ) ( * pb . AuthMethod , error ) {
var opts [] password . Option
if item . GetName () != nil {
opts = append ( opts , password . WithName ( item . GetName (). GetValue ()))
}
if item . GetDescription () != nil {
opts = append ( opts , password . WithDescription ( item . GetDescription (). GetValue ()))
}
u , err := password . NewAuthMethod ( scopeId , opts ... )
if err != nil {
2020-09-25 13:41:20 -07:00
return nil , handlers . ApiErrorWithCodeAndMessage ( codes . Internal , "Unable to build auth method for creation: %v." , err )
2020-08-06 12:50:20 -07:00
}
2020-10-12 18:03:15 -04:00
repo , err := s . pwRepoFn ()
2020-08-06 12:50:20 -07:00
if err != nil {
return nil , err
}
out , err := repo . CreateAuthMethod ( ctx , u )
if err != nil {
2020-10-06 13:17:28 -04:00
return nil , fmt . Errorf ( "unable to create auth method: %w" , err )
2020-08-06 12:50:20 -07:00
}
if out == nil {
2020-09-25 13:41:20 -07:00
return nil , handlers . ApiErrorWithCodeAndMessage ( codes . Internal , "Unable to create auth method but no error returned from repository." )
2020-08-06 12:50:20 -07:00
}
2020-10-12 18:03:15 -04:00
return toAuthMethodProto ( out )
2020-08-06 12:50:20 -07:00
}
2020-08-18 17:38:38 -07:00
func ( s Service ) updateInRepo ( ctx context . Context , scopeId , id string , mask [] string , item * pb . AuthMethod ) ( * pb . AuthMethod , error ) {
2020-08-06 12:50:20 -07:00
var opts [] password . Option
if desc := item . GetDescription (); desc != nil {
opts = append ( opts , password . WithDescription ( desc . GetValue ()))
}
if name := item . GetName (); name != nil {
opts = append ( opts , password . WithName ( name . GetValue ()))
}
u , err := password . NewAuthMethod ( scopeId , opts ... )
if err != nil {
2020-09-25 13:41:20 -07:00
return nil , handlers . ApiErrorWithCodeAndMessage ( codes . Internal , "Unable to build auth method for update: %v." , err )
2020-08-06 12:50:20 -07:00
}
2020-08-14 14:08:12 -07:00
pwAttrs := & pb . PasswordAuthMethodAttributes {}
if err := handlers . StructToProto ( item . GetAttributes (), pwAttrs ); err != nil {
2020-09-25 13:41:20 -07:00
return nil , handlers . InvalidArgumentErrorf ( "Error in provided request." ,
map [ string ] string { "attributes" : "Attribute fields do not match the expected format." })
2020-08-14 14:08:12 -07:00
}
if pwAttrs . GetMinLoginNameLength () != 0 {
u . MinLoginNameLength = pwAttrs . GetMinLoginNameLength ()
}
if pwAttrs . GetMinPasswordLength () != 0 {
u . MinPasswordLength = pwAttrs . GetMinPasswordLength ()
}
2020-08-18 17:38:38 -07:00
version := item . GetVersion ()
2020-08-14 14:08:12 -07:00
2020-08-06 12:50:20 -07:00
u . PublicId = id
dbMask := maskManager . Translate ( mask )
if len ( dbMask ) == 0 {
2020-08-28 00:17:09 -04:00
return nil , handlers . InvalidArgumentErrorf ( "No valid fields included in the update mask." , map [ string ] string { "update_mask" : "No valid fields provided in the update mask." })
2020-08-06 12:50:20 -07:00
}
2020-10-12 18:03:15 -04:00
repo , err := s . pwRepoFn ()
2020-08-06 12:50:20 -07:00
if err != nil {
return nil , err
}
2020-08-11 11:19:29 -04:00
out , rowsUpdated , err := repo . UpdateAuthMethod ( ctx , u , version , dbMask )
2020-08-06 12:50:20 -07:00
if err != nil {
2020-09-25 13:41:20 -07:00
return nil , fmt . Errorf ( "unable to update auth method: %w" , err )
2020-08-06 12:50:20 -07:00
}
if rowsUpdated == 0 {
2020-09-25 13:41:20 -07:00
return nil , handlers . NotFoundErrorf ( "AuthMethod %q doesn't exist or incorrect version provided." , id )
2020-08-06 12:50:20 -07:00
}
2020-10-12 18:03:15 -04:00
return toAuthMethodProto ( out )
2020-08-06 12:50:20 -07:00
}
2020-08-19 16:47:18 -04:00
func ( s Service ) deleteFromRepo ( ctx context . Context , scopeId , id string ) ( bool , error ) {
2020-10-12 18:03:15 -04:00
repo , err := s . pwRepoFn ()
2020-08-06 12:50:20 -07:00
if err != nil {
return false , err
}
2020-08-19 16:47:18 -04:00
rows , err := repo . DeleteAuthMethod ( ctx , scopeId , id )
2020-08-06 12:50:20 -07:00
if err != nil {
2020-11-05 16:54:03 -05:00
if errors . Is ( err , errors . ErrRecordNotFound ) {
2020-08-06 12:50:20 -07:00
return false , nil
}
2020-09-25 13:41:20 -07:00
return false , fmt . Errorf ( "unable to delete auth method: %w" , err )
2020-08-06 12:50:20 -07:00
}
return rows > 0 , nil
}
2020-10-12 18:03:15 -04:00
func ( s Service ) authenticateWithRepo ( ctx context . Context , scopeId , authMethodId , loginName , pw string ) ( * pba . AuthToken , error ) {
iamRepo , err := s . iamRepoFn ()
if err != nil {
return nil , err
}
atRepo , err := s . atRepoFn ()
if err != nil {
return nil , err
}
pwRepo , err := s . pwRepoFn ()
if err != nil {
return nil , err
}
acct , err := pwRepo . Authenticate ( ctx , scopeId , authMethodId , loginName , pw )
if err != nil {
return nil , err
}
if acct == nil {
return nil , handlers . ApiErrorWithCodeAndMessage ( codes . Unauthenticated , "Unable to authenticate." )
}
u , err := iamRepo . LookupUserWithLogin ( ctx , acct . GetPublicId (), iam . WithAutoVivify ( true ))
if err != nil {
return nil , err
}
tok , err := atRepo . CreateAuthToken ( ctx , u , acct . GetPublicId ())
if err != nil {
return nil , err
}
token , err := authtoken . EncryptToken ( ctx , s . kms , scopeId , tok . GetPublicId (), tok . GetToken ())
if err != nil {
return nil , err
}
tok . Token = tok . GetPublicId () + "_" + token
prot := toAuthTokenProto ( tok )
scp , err := iamRepo . LookupScope ( ctx , u . GetScopeId ())
if err != nil {
return nil , err
}
if scp == nil {
return nil , err
}
prot . Scope = & scopes . ScopeInfo {
Id : scp . GetPublicId (),
Type : scp . GetType (),
ParentScopeId : scp . GetParentId (),
}
return prot , nil
}
2020-09-04 14:48:11 -07:00
func ( s Service ) authResult ( ctx context . Context , id string , a action . Type ) auth . VerifyResults {
res := auth . VerifyResults {}
var parentId string
opts := [] auth . Option { auth . WithType ( resource . AuthMethod ), auth . WithAction ( a )}
switch a {
case action . List , action . Create :
parentId = id
iamRepo , err := s . iamRepoFn ()
if err != nil {
res . Error = err
return res
}
scp , err := iamRepo . LookupScope ( ctx , parentId )
if err != nil {
res . Error = err
return res
}
if scp == nil {
2020-09-08 23:57:26 -04:00
res . Error = handlers . NotFoundError ()
2020-09-04 14:48:11 -07:00
return res
}
default :
2020-10-12 18:03:15 -04:00
repo , err := s . pwRepoFn ()
2020-09-04 14:48:11 -07:00
if err != nil {
res . Error = err
return res
}
authMeth , err := repo . LookupAuthMethod ( ctx , id )
if err != nil {
res . Error = err
return res
}
if authMeth == nil {
2020-09-08 23:57:26 -04:00
res . Error = handlers . NotFoundError ()
2020-09-04 14:48:11 -07:00
return res
}
parentId = authMeth . GetScopeId ()
opts = append ( opts , auth . WithId ( id ))
}
opts = append ( opts , auth . WithScopeId ( parentId ))
return auth . Verify ( ctx , opts ... )
}
2020-10-12 18:03:15 -04:00
func toAuthMethodProto ( in * password . AuthMethod ) ( * pb . AuthMethod , error ) {
2020-08-06 12:50:20 -07:00
out := pb . AuthMethod {
Id : in . GetPublicId (),
2020-09-02 19:43:41 -07:00
ScopeId : in . GetScopeId (),
2020-08-06 12:50:20 -07:00
CreatedTime : in . GetCreateTime (). GetTimestamp (),
UpdatedTime : in . GetUpdateTime (). GetTimestamp (),
2020-08-11 11:19:29 -04:00
Version : in . GetVersion (),
2020-08-19 10:51:15 -07:00
Type : auth . PasswordSubtype . String (),
2020-08-06 12:50:20 -07:00
}
if in . GetDescription () != "" {
2020-08-14 14:08:12 -07:00
out . Description = wrapperspb . String ( in . GetDescription ())
2020-08-06 12:50:20 -07:00
}
if in . GetName () != "" {
2020-08-14 14:08:12 -07:00
out . Name = wrapperspb . String ( in . GetName ())
2020-08-06 12:50:20 -07:00
}
st , err := handlers . ProtoToStruct ( & pb . PasswordAuthMethodAttributes {
2020-08-11 17:25:00 -04:00
MinLoginNameLength : in . GetMinLoginNameLength (),
MinPasswordLength : in . GetMinPasswordLength (),
2020-08-06 12:50:20 -07:00
})
if err != nil {
2020-09-25 13:41:20 -07:00
return nil , handlers . ApiErrorWithCodeAndMessage ( codes . Internal , "failed building password attribute struct: %v" , err )
2020-08-06 12:50:20 -07:00
}
out . Attributes = st
return & out , nil
}
2020-10-12 18:03:15 -04:00
func toAuthTokenProto ( t * authtoken . AuthToken ) * pba . AuthToken {
return & pba . AuthToken {
Id : t . GetPublicId (),
Token : t . GetToken (),
UserId : t . GetIamUserId (),
AuthMethodId : t . GetAuthMethodId (),
AccountId : t . GetAuthAccountId (),
CreatedTime : t . GetCreateTime (). GetTimestamp (),
UpdatedTime : t . GetUpdateTime (). GetTimestamp (),
ApproximateLastUsedTime : t . GetApproximateLastAccessTime (). GetTimestamp (),
ExpirationTime : t . GetExpirationTime (). GetTimestamp (),
}
}
2020-08-06 12:50:20 -07:00
// A validateX method should exist for each method above. These methods do not make calls to any backing service but enforce
// requirements on the structure of the request. They verify that:
// * The path passed in is correctly formatted
// * All required parameters are set
// * There are no conflicting parameters provided
func validateGetRequest ( req * pbs . GetAuthMethodRequest ) error {
2020-08-21 08:15:32 -07:00
return handlers . ValidateGetRequest ( password . AuthMethodPrefix , req , handlers . NoopValidatorFn )
2020-08-06 12:50:20 -07:00
}
func validateCreateRequest ( req * pbs . CreateAuthMethodRequest ) error {
2020-08-21 08:15:32 -07:00
return handlers . ValidateCreateRequest ( req . GetItem (), func () map [ string ] string {
badFields := map [ string ] string {}
2020-09-03 08:02:30 -07:00
if ! handlers . ValidId ( scope . Org . Prefix (), req . GetItem (). GetScopeId ()) &&
scope . Global . String () != req . GetItem (). GetScopeId () {
2020-10-02 16:45:32 -07:00
badFields [ "scope_id" ] = "This field must be 'global' or a valid org scope id."
2020-09-03 08:02:30 -07:00
}
2020-08-21 08:15:32 -07:00
switch auth . SubtypeFromType ( req . GetItem (). GetType ()) {
case auth . PasswordSubtype :
pwAttrs := & pb . PasswordAuthMethodAttributes {}
if err := handlers . StructToProto ( req . GetItem (). GetAttributes (), pwAttrs ); err != nil {
badFields [ "attributes" ] = "Attribute fields do not match the expected format."
}
default :
badFields [ "type" ] = fmt . Sprintf ( "This is a required field and must be %q." , auth . PasswordSubtype . String ())
2020-08-06 12:50:20 -07:00
}
2020-08-21 08:15:32 -07:00
return badFields
})
2020-08-06 12:50:20 -07:00
}
func validateUpdateRequest ( req * pbs . UpdateAuthMethodRequest ) error {
2020-08-21 08:15:32 -07:00
return handlers . ValidateUpdateRequest ( password . AuthMethodPrefix , req , req . GetItem (), func () map [ string ] string {
badFields := map [ string ] string {}
2020-09-08 16:04:19 -07:00
switch auth . SubtypeFromId ( req . GetId ()) {
case auth . PasswordSubtype :
if req . GetItem (). GetType () != "" && auth . SubtypeFromType ( req . GetItem (). GetType ()) != auth . PasswordSubtype {
2020-09-23 08:30:25 -07:00
badFields [ "type" ] = "Cannot modify the resource type."
2020-09-08 16:04:19 -07:00
}
pwAttrs := & pb . PasswordAuthMethodAttributes {}
if err := handlers . StructToProto ( req . GetItem (). GetAttributes (), pwAttrs ); err != nil {
badFields [ "attributes" ] = "Attribute fields do not match the expected format."
}
default :
badFields [ "id" ] = "Incorrectly formatted identifier."
2020-08-21 08:15:32 -07:00
}
return badFields
})
2020-08-06 12:50:20 -07:00
}
func validateDeleteRequest ( req * pbs . DeleteAuthMethodRequest ) error {
2020-08-21 08:15:32 -07:00
return handlers . ValidateDeleteRequest ( password . AuthMethodPrefix , req , handlers . NoopValidatorFn )
}
2020-09-08 23:57:26 -04:00
func validateListRequest ( req * pbs . ListAuthMethodsRequest ) error {
2020-08-06 12:50:20 -07:00
badFields := map [ string ] string {}
2020-09-08 23:57:26 -04:00
if ! handlers . ValidId ( scope . Org . Prefix (), req . GetScopeId ()) &&
req . GetScopeId () != scope . Global . String () {
2020-10-02 16:45:32 -07:00
badFields [ "scope_id" ] = "This field must be 'global' or a valid org scope id."
2020-09-08 23:57:26 -04:00
}
2020-08-06 12:50:20 -07:00
if len ( badFields ) > 0 {
2020-08-21 08:15:32 -07:00
return handlers . InvalidArgumentErrorf ( "Improperly formatted identifier." , badFields )
2020-08-06 12:50:20 -07:00
}
return nil
}
2020-10-12 18:03:15 -04:00
func validateAuthenticateRequest ( req * pbs . AuthenticateRequest ) error {
badFields := make ( map [ string ] string )
if strings . TrimSpace ( req . GetAuthMethodId ()) == "" {
badFields [ "auth_method_id" ] = "This is a required field."
} else if ! handlers . ValidId ( password . AuthMethodPrefix , req . GetAuthMethodId ()) {
badFields [ "auth_method_id" ] = "Invalid formatted identifier."
}
// TODO: Update this when we enable different auth method types.
if req . GetCredentials () == nil {
badFields [ "credentials" ] = "This is a required field."
}
creds := req . GetCredentials (). GetFields ()
if _ , ok := creds [ loginNameKey ]; ! ok {
badFields [ "credentials.login_name" ] = "This is a required field."
}
if _ , ok := creds [ pwKey ]; ! ok {
badFields [ "credentials.password" ] = "This is a required field."
}
tType := strings . ToLower ( strings . TrimSpace ( req . GetTokenType ()))
if tType != "" && tType != "token" && tType != "cookie" {
badFields [ "token_type" ] = `The only accepted types are "token" and "cookie".`
}
if len ( badFields ) > 0 {
return handlers . InvalidArgumentErrorf ( "Invalid fields provided in request." , badFields )
}
return nil
}