package pgconn
import (
)
type authMethod uint8
const (
authMethodPassword authMethod = iota
authMethodMD5
authMethodGSS
authMethodSSPI
authMethodSCRAMSHA256
authMethodOAuth
authMethodNone
authMethodCount
)
var authMethodNames = [authMethodCount]string{
authMethodPassword: "password",
authMethodMD5: "md5",
authMethodGSS: "gss",
authMethodSSPI: "sspi",
authMethodSCRAMSHA256: "scram-sha-256",
authMethodOAuth: "oauth",
authMethodNone: "none",
}
type requireAuth struct {
raw string
authRequired bool
allowed uint8
}
func ( requireAuth) ( authMethod) bool {
return .allowed&(1<<) != 0
}
func ( requireAuth) ( authMethod) error {
if .allows() {
return nil
}
var string
if == authMethodNone {
= "server did not complete authentication"
} else {
= fmt.Sprintf("server requested %s authentication", authMethodNames[])
}
return fmt.Errorf("authentication method requirement %q failed: %s", .raw, )
}
func ( string) (requireAuth, error) {
:= requireAuth{raw: }
if == "" {
.allowed = 1<<authMethodCount - 1
return , nil
}
:= true
:= false
for := range strings.SplitSeq(, ",") {
:= strings.TrimSpace()
:= strings.HasPrefix(, "!")
if {
= [1:]
}
if {
=
if {
.allowed = 1<<authMethodCount - 1
} else {
.authRequired = true
}
= false
} else if != {
if {
return requireAuth{}, fmt.Errorf("negative require_auth method %q cannot be mixed with non-negative methods", )
}
return requireAuth{}, fmt.Errorf("require_auth method %q cannot be mixed with negative methods", )
}
var authMethod
switch {
case "password":
= authMethodPassword
case "md5":
= authMethodMD5
case "gss":
= authMethodGSS
case "sspi":
= authMethodSSPI
case "scram-sha-256":
= authMethodSCRAMSHA256
case "oauth":
= authMethodOAuth
case "none":
= authMethodNone
default:
return requireAuth{}, fmt.Errorf("invalid require_auth method: %q", )
}
:= uint8(1) <<
if {
if .allowed& == 0 {
return requireAuth{}, fmt.Errorf("require_auth method %q is specified more than once", )
}
.allowed &^=
if == authMethodNone {
.authRequired = true
}
} else {
if .allowed& != 0 {
return requireAuth{}, fmt.Errorf("require_auth method %q is specified more than once", )
}
.allowed |=
if == authMethodNone {
.authRequired = false
}
}
}
return , nil
}