mirror of
https://github.com/ClusterCockpit/cc-backend
synced 2024-12-24 12:29:05 +01:00
Refactor and cleanup Auth configuration
This commit is contained in:
parent
14c487c9e4
commit
32b0c8bdd7
@ -211,10 +211,7 @@ func main() {
|
|||||||
var authentication *auth.Authentication
|
var authentication *auth.Authentication
|
||||||
if !config.Keys.DisableAuthentication {
|
if !config.Keys.DisableAuthentication {
|
||||||
var err error
|
var err error
|
||||||
if authentication, err = auth.Init(map[string]interface{}{
|
if authentication, err = auth.Init(); err != nil {
|
||||||
"ldap": config.Keys.LdapConfig,
|
|
||||||
"jwt": config.Keys.JwtConfig,
|
|
||||||
}); err != nil {
|
|
||||||
log.Fatalf("auth initialization failed: %v", err)
|
log.Fatalf("auth initialization failed: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -14,6 +14,7 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/ClusterCockpit/cc-backend/internal/config"
|
||||||
"github.com/ClusterCockpit/cc-backend/internal/repository"
|
"github.com/ClusterCockpit/cc-backend/internal/repository"
|
||||||
"github.com/ClusterCockpit/cc-backend/pkg/log"
|
"github.com/ClusterCockpit/cc-backend/pkg/log"
|
||||||
"github.com/ClusterCockpit/cc-backend/pkg/schema"
|
"github.com/ClusterCockpit/cc-backend/pkg/schema"
|
||||||
@ -21,7 +22,6 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type Authenticator interface {
|
type Authenticator interface {
|
||||||
Init(config interface{}) error
|
|
||||||
CanLogin(user *schema.User, username string, rw http.ResponseWriter, r *http.Request) (*schema.User, bool)
|
CanLogin(user *schema.User, username string, rw http.ResponseWriter, r *http.Request) (*schema.User, bool)
|
||||||
Login(user *schema.User, rw http.ResponseWriter, r *http.Request) (*schema.User, error)
|
Login(user *schema.User, rw http.ResponseWriter, r *http.Request) (*schema.User, error)
|
||||||
}
|
}
|
||||||
@ -80,7 +80,7 @@ func (auth *Authentication) AuthViaSession(
|
|||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func Init(configs map[string]interface{}) (*Authentication, error) {
|
func Init() (*Authentication, error) {
|
||||||
auth := &Authentication{}
|
auth := &Authentication{}
|
||||||
|
|
||||||
sessKey := os.Getenv("SESSION_KEY")
|
sessKey := os.Getenv("SESSION_KEY")
|
||||||
@ -101,9 +101,9 @@ func Init(configs map[string]interface{}) (*Authentication, error) {
|
|||||||
auth.sessionStore = sessions.NewCookieStore(bytes)
|
auth.sessionStore = sessions.NewCookieStore(bytes)
|
||||||
}
|
}
|
||||||
|
|
||||||
if config, ok := configs["ldap"]; ok {
|
if config.Keys.LdapConfig != nil {
|
||||||
ldapAuth := &LdapAuthenticator{}
|
ldapAuth := &LdapAuthenticator{}
|
||||||
if err := ldapAuth.Init(config); err != nil {
|
if err := ldapAuth.Init(); err != nil {
|
||||||
log.Warn("Error while initializing authentication -> ldapAuth init failed")
|
log.Warn("Error while initializing authentication -> ldapAuth init failed")
|
||||||
} else {
|
} else {
|
||||||
auth.LdapAuth = ldapAuth
|
auth.LdapAuth = ldapAuth
|
||||||
@ -113,32 +113,32 @@ func Init(configs map[string]interface{}) (*Authentication, error) {
|
|||||||
log.Info("Missing LDAP configuration: No LDAP support!")
|
log.Info("Missing LDAP configuration: No LDAP support!")
|
||||||
}
|
}
|
||||||
|
|
||||||
if config, ok := configs["jwt"]; ok {
|
if config.Keys.JwtConfig != nil {
|
||||||
auth.JwtAuth = &JWTAuthenticator{}
|
auth.JwtAuth = &JWTAuthenticator{}
|
||||||
if err := auth.JwtAuth.Init(config); err != nil {
|
if err := auth.JwtAuth.Init(); err != nil {
|
||||||
log.Error("Error while initializing authentication -> jwtAuth init failed")
|
log.Error("Error while initializing authentication -> jwtAuth init failed")
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
jwtSessionAuth := &JWTSessionAuthenticator{}
|
jwtSessionAuth := &JWTSessionAuthenticator{}
|
||||||
if err := jwtSessionAuth.Init(config); err != nil {
|
if err := jwtSessionAuth.Init(); err != nil {
|
||||||
log.Warn("Error while initializing authentication -> jwtSessionAuth init failed")
|
log.Info("jwtSessionAuth init failed: No JWT login support!")
|
||||||
} else {
|
} else {
|
||||||
auth.authenticators = append(auth.authenticators, jwtSessionAuth)
|
auth.authenticators = append(auth.authenticators, jwtSessionAuth)
|
||||||
}
|
}
|
||||||
|
|
||||||
jwtCookieSessionAuth := &JWTCookieSessionAuthenticator{}
|
jwtCookieSessionAuth := &JWTCookieSessionAuthenticator{}
|
||||||
if err := jwtCookieSessionAuth.Init(configs["jwt"]); err != nil {
|
if err := jwtCookieSessionAuth.Init(); err != nil {
|
||||||
log.Warn("Error while initializing authentication -> jwtCookieSessionAuth init failed")
|
log.Info("jwtCookieSessionAuth init failed: No JWT cookie login support!")
|
||||||
} else {
|
} else {
|
||||||
auth.authenticators = append(auth.authenticators, jwtCookieSessionAuth)
|
auth.authenticators = append(auth.authenticators, jwtCookieSessionAuth)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
log.Info("Missing JWT configuration: No JWT token login support!")
|
log.Info("Missing JWT configuration: No JWT token support!")
|
||||||
}
|
}
|
||||||
|
|
||||||
auth.LocalAuth = &LocalAuthenticator{}
|
auth.LocalAuth = &LocalAuthenticator{}
|
||||||
if err := auth.LocalAuth.Init(nil); err != nil {
|
if err := auth.LocalAuth.Init(); err != nil {
|
||||||
log.Error("Error while initializing authentication -> localAuth init failed")
|
log.Error("Error while initializing authentication -> localAuth init failed")
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -13,6 +13,7 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/ClusterCockpit/cc-backend/internal/config"
|
||||||
"github.com/ClusterCockpit/cc-backend/internal/repository"
|
"github.com/ClusterCockpit/cc-backend/internal/repository"
|
||||||
"github.com/ClusterCockpit/cc-backend/pkg/log"
|
"github.com/ClusterCockpit/cc-backend/pkg/log"
|
||||||
"github.com/ClusterCockpit/cc-backend/pkg/schema"
|
"github.com/ClusterCockpit/cc-backend/pkg/schema"
|
||||||
@ -22,12 +23,9 @@ import (
|
|||||||
type JWTAuthenticator struct {
|
type JWTAuthenticator struct {
|
||||||
publicKey ed25519.PublicKey
|
publicKey ed25519.PublicKey
|
||||||
privateKey ed25519.PrivateKey
|
privateKey ed25519.PrivateKey
|
||||||
config *schema.JWTAuthConfig
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ja *JWTAuthenticator) Init(conf interface{}) error {
|
func (ja *JWTAuthenticator) Init() error {
|
||||||
ja.config = conf.(*schema.JWTAuthConfig)
|
|
||||||
|
|
||||||
pubKey, privKey := os.Getenv("JWT_PUBLIC_KEY"), os.Getenv("JWT_PRIVATE_KEY")
|
pubKey, privKey := os.Getenv("JWT_PUBLIC_KEY"), os.Getenv("JWT_PRIVATE_KEY")
|
||||||
if pubKey == "" || privKey == "" {
|
if pubKey == "" || privKey == "" {
|
||||||
log.Warn("environment variables 'JWT_PUBLIC_KEY' or 'JWT_PRIVATE_KEY' not set (token based authentication will not work)")
|
log.Warn("environment variables 'JWT_PUBLIC_KEY' or 'JWT_PRIVATE_KEY' not set (token based authentication will not work)")
|
||||||
@ -87,7 +85,7 @@ func (ja *JWTAuthenticator) AuthViaJWT(
|
|||||||
var roles []string
|
var roles []string
|
||||||
|
|
||||||
// Validate user + roles from JWT against database?
|
// Validate user + roles from JWT against database?
|
||||||
if ja.config != nil && ja.config.ValidateUser {
|
if config.Keys.JwtConfig.ValidateUser {
|
||||||
ur := repository.GetUserRepository()
|
ur := repository.GetUserRepository()
|
||||||
user, err := ur.GetUser(sub)
|
user, err := ur.GetUser(sub)
|
||||||
|
|
||||||
@ -130,8 +128,8 @@ func (ja *JWTAuthenticator) ProvideJWT(user *schema.User) (string, error) {
|
|||||||
"roles": user.Roles,
|
"roles": user.Roles,
|
||||||
"iat": now.Unix(),
|
"iat": now.Unix(),
|
||||||
}
|
}
|
||||||
if ja.config != nil && ja.config.MaxAge != "" {
|
if config.Keys.JwtConfig.MaxAge != "" {
|
||||||
d, err := time.ParseDuration(ja.config.MaxAge)
|
d, err := time.ParseDuration(config.Keys.JwtConfig.MaxAge)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", errors.New("cannot parse max-age config key")
|
return "", errors.New("cannot parse max-age config key")
|
||||||
}
|
}
|
||||||
|
@ -12,6 +12,7 @@ import (
|
|||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
|
"github.com/ClusterCockpit/cc-backend/internal/config"
|
||||||
"github.com/ClusterCockpit/cc-backend/internal/repository"
|
"github.com/ClusterCockpit/cc-backend/internal/repository"
|
||||||
"github.com/ClusterCockpit/cc-backend/pkg/log"
|
"github.com/ClusterCockpit/cc-backend/pkg/log"
|
||||||
"github.com/ClusterCockpit/cc-backend/pkg/schema"
|
"github.com/ClusterCockpit/cc-backend/pkg/schema"
|
||||||
@ -22,15 +23,11 @@ type JWTCookieSessionAuthenticator struct {
|
|||||||
publicKey ed25519.PublicKey
|
publicKey ed25519.PublicKey
|
||||||
privateKey ed25519.PrivateKey
|
privateKey ed25519.PrivateKey
|
||||||
publicKeyCrossLogin ed25519.PublicKey // For accepting externally generated JWTs
|
publicKeyCrossLogin ed25519.PublicKey // For accepting externally generated JWTs
|
||||||
|
|
||||||
config *schema.JWTAuthConfig
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var _ Authenticator = (*JWTCookieSessionAuthenticator)(nil)
|
var _ Authenticator = (*JWTCookieSessionAuthenticator)(nil)
|
||||||
|
|
||||||
func (ja *JWTCookieSessionAuthenticator) Init(conf interface{}) error {
|
func (ja *JWTCookieSessionAuthenticator) Init() error {
|
||||||
ja.config = conf.(*schema.JWTAuthConfig)
|
|
||||||
|
|
||||||
pubKey, privKey := os.Getenv("JWT_PUBLIC_KEY"), os.Getenv("JWT_PRIVATE_KEY")
|
pubKey, privKey := os.Getenv("JWT_PUBLIC_KEY"), os.Getenv("JWT_PRIVATE_KEY")
|
||||||
if pubKey == "" || privKey == "" {
|
if pubKey == "" || privKey == "" {
|
||||||
log.Warn("environment variables 'JWT_PUBLIC_KEY' or 'JWT_PRIVATE_KEY' not set (token based authentication will not work)")
|
log.Warn("environment variables 'JWT_PUBLIC_KEY' or 'JWT_PRIVATE_KEY' not set (token based authentication will not work)")
|
||||||
@ -65,17 +62,18 @@ func (ja *JWTCookieSessionAuthenticator) Init(conf interface{}) error {
|
|||||||
return errors.New("environment variable 'CROSS_LOGIN_JWT_PUBLIC_KEY' not set (cross login token based authentication will not work)")
|
return errors.New("environment variable 'CROSS_LOGIN_JWT_PUBLIC_KEY' not set (cross login token based authentication will not work)")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
jc := config.Keys.JwtConfig
|
||||||
// Warn if other necessary settings are not configured
|
// Warn if other necessary settings are not configured
|
||||||
if ja.config != nil {
|
if jc != nil {
|
||||||
if ja.config.CookieName == "" {
|
if jc.CookieName == "" {
|
||||||
log.Warn("cookieName for JWTs not configured (cross login via JWT cookie will fail)")
|
log.Info("cookieName for JWTs not configured (cross login via JWT cookie will fail)")
|
||||||
return errors.New("cookieName for JWTs not configured (cross login via JWT cookie will fail)")
|
return errors.New("cookieName for JWTs not configured (cross login via JWT cookie will fail)")
|
||||||
}
|
}
|
||||||
if !ja.config.ValidateUser {
|
if !jc.ValidateUser {
|
||||||
log.Warn("forceJWTValidationViaDatabase not set to true: CC will accept users and roles defined in JWTs regardless of its own database!")
|
log.Info("forceJWTValidationViaDatabase not set to true: CC will accept users and roles defined in JWTs regardless of its own database!")
|
||||||
}
|
}
|
||||||
if ja.config.TrustedIssuer == "" {
|
if jc.TrustedIssuer == "" {
|
||||||
log.Warn("trustedExternalIssuer for JWTs not configured (cross login via JWT cookie will fail)")
|
log.Info("trustedExternalIssuer for JWTs not configured (cross login via JWT cookie will fail)")
|
||||||
return errors.New("trustedExternalIssuer for JWTs not configured (cross login via JWT cookie will fail)")
|
return errors.New("trustedExternalIssuer for JWTs not configured (cross login via JWT cookie will fail)")
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -93,9 +91,10 @@ func (ja *JWTCookieSessionAuthenticator) CanLogin(
|
|||||||
rw http.ResponseWriter,
|
rw http.ResponseWriter,
|
||||||
r *http.Request) (*schema.User, bool) {
|
r *http.Request) (*schema.User, bool) {
|
||||||
|
|
||||||
|
jc := config.Keys.JwtConfig
|
||||||
cookieName := ""
|
cookieName := ""
|
||||||
if ja.config != nil && ja.config.CookieName != "" {
|
if jc.CookieName != "" {
|
||||||
cookieName = ja.config.CookieName
|
cookieName = jc.CookieName
|
||||||
}
|
}
|
||||||
|
|
||||||
// Try to read the JWT cookie
|
// Try to read the JWT cookie
|
||||||
@ -115,7 +114,8 @@ func (ja *JWTCookieSessionAuthenticator) Login(
|
|||||||
rw http.ResponseWriter,
|
rw http.ResponseWriter,
|
||||||
r *http.Request) (*schema.User, error) {
|
r *http.Request) (*schema.User, error) {
|
||||||
|
|
||||||
jwtCookie, err := r.Cookie(ja.config.CookieName)
|
jc := config.Keys.JwtConfig
|
||||||
|
jwtCookie, err := r.Cookie(jc.CookieName)
|
||||||
var rawtoken string
|
var rawtoken string
|
||||||
|
|
||||||
if err == nil && jwtCookie.Value != "" {
|
if err == nil && jwtCookie.Value != "" {
|
||||||
@ -128,7 +128,7 @@ func (ja *JWTCookieSessionAuthenticator) Login(
|
|||||||
}
|
}
|
||||||
|
|
||||||
unvalidatedIssuer, success := t.Claims.(jwt.MapClaims)["iss"].(string)
|
unvalidatedIssuer, success := t.Claims.(jwt.MapClaims)["iss"].(string)
|
||||||
if success && unvalidatedIssuer == ja.config.TrustedIssuer {
|
if success && unvalidatedIssuer == jc.TrustedIssuer {
|
||||||
// The (unvalidated) issuer seems to be the expected one,
|
// The (unvalidated) issuer seems to be the expected one,
|
||||||
// use public cross login key from config
|
// use public cross login key from config
|
||||||
return ja.publicKeyCrossLogin, nil
|
return ja.publicKeyCrossLogin, nil
|
||||||
@ -167,7 +167,7 @@ func (ja *JWTCookieSessionAuthenticator) Login(
|
|||||||
|
|
||||||
var roles []string
|
var roles []string
|
||||||
|
|
||||||
if ja.config.ValidateUser {
|
if jc.ValidateUser {
|
||||||
// Deny any logins for unknown usernames
|
// Deny any logins for unknown usernames
|
||||||
if user == nil {
|
if user == nil {
|
||||||
log.Warn("Could not find user from JWT in internal database.")
|
log.Warn("Could not find user from JWT in internal database.")
|
||||||
@ -189,7 +189,7 @@ func (ja *JWTCookieSessionAuthenticator) Login(
|
|||||||
|
|
||||||
// (Ask browser to) Delete JWT cookie
|
// (Ask browser to) Delete JWT cookie
|
||||||
deletedCookie := &http.Cookie{
|
deletedCookie := &http.Cookie{
|
||||||
Name: ja.config.CookieName,
|
Name: jc.CookieName,
|
||||||
Value: "",
|
Value: "",
|
||||||
Path: "/",
|
Path: "/",
|
||||||
MaxAge: -1,
|
MaxAge: -1,
|
||||||
@ -208,7 +208,7 @@ func (ja *JWTCookieSessionAuthenticator) Login(
|
|||||||
AuthSource: schema.AuthViaToken,
|
AuthSource: schema.AuthViaToken,
|
||||||
}
|
}
|
||||||
|
|
||||||
if ja.config.SyncUserOnLogin {
|
if jc.SyncUserOnLogin {
|
||||||
if err := repository.GetUserRepository().AddUser(user); err != nil {
|
if err := repository.GetUserRepository().AddUser(user); err != nil {
|
||||||
log.Errorf("Error while adding user '%s' to DB", user.Username)
|
log.Errorf("Error while adding user '%s' to DB", user.Username)
|
||||||
}
|
}
|
||||||
|
@ -12,6 +12,7 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"github.com/ClusterCockpit/cc-backend/internal/config"
|
||||||
"github.com/ClusterCockpit/cc-backend/internal/repository"
|
"github.com/ClusterCockpit/cc-backend/internal/repository"
|
||||||
"github.com/ClusterCockpit/cc-backend/pkg/log"
|
"github.com/ClusterCockpit/cc-backend/pkg/log"
|
||||||
"github.com/ClusterCockpit/cc-backend/pkg/schema"
|
"github.com/ClusterCockpit/cc-backend/pkg/schema"
|
||||||
@ -20,15 +21,11 @@ import (
|
|||||||
|
|
||||||
type JWTSessionAuthenticator struct {
|
type JWTSessionAuthenticator struct {
|
||||||
loginTokenKey []byte // HS256 key
|
loginTokenKey []byte // HS256 key
|
||||||
|
|
||||||
config *schema.JWTAuthConfig
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var _ Authenticator = (*JWTSessionAuthenticator)(nil)
|
var _ Authenticator = (*JWTSessionAuthenticator)(nil)
|
||||||
|
|
||||||
func (ja *JWTSessionAuthenticator) Init(conf interface{}) error {
|
func (ja *JWTSessionAuthenticator) Init() error {
|
||||||
ja.config = conf.(*schema.JWTAuthConfig)
|
|
||||||
|
|
||||||
if pubKey := os.Getenv("CROSS_LOGIN_JWT_HS512_KEY"); pubKey != "" {
|
if pubKey := os.Getenv("CROSS_LOGIN_JWT_HS512_KEY"); pubKey != "" {
|
||||||
bytes, err := base64.StdEncoding.DecodeString(pubKey)
|
bytes, err := base64.StdEncoding.DecodeString(pubKey)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -96,7 +93,7 @@ func (ja *JWTSessionAuthenticator) Login(
|
|||||||
|
|
||||||
var roles []string
|
var roles []string
|
||||||
|
|
||||||
if ja.config.ValidateUser {
|
if config.Keys.JwtConfig.ValidateUser {
|
||||||
// Deny any logins for unknown usernames
|
// Deny any logins for unknown usernames
|
||||||
if user == nil {
|
if user == nil {
|
||||||
log.Warn("Could not find user from JWT in internal database.")
|
log.Warn("Could not find user from JWT in internal database.")
|
||||||
@ -142,7 +139,7 @@ func (ja *JWTSessionAuthenticator) Login(
|
|||||||
AuthSource: schema.AuthViaToken,
|
AuthSource: schema.AuthViaToken,
|
||||||
}
|
}
|
||||||
|
|
||||||
if ja.config.SyncUserOnLogin {
|
if config.Keys.JwtConfig.SyncUserOnLogin {
|
||||||
if err := repository.GetUserRepository().AddUser(user); err != nil {
|
if err := repository.GetUserRepository().AddUser(user); err != nil {
|
||||||
log.Errorf("Error while adding user '%s' to DB", user.Username)
|
log.Errorf("Error while adding user '%s' to DB", user.Username)
|
||||||
}
|
}
|
||||||
|
@ -12,6 +12,7 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/ClusterCockpit/cc-backend/internal/config"
|
||||||
"github.com/ClusterCockpit/cc-backend/internal/repository"
|
"github.com/ClusterCockpit/cc-backend/internal/repository"
|
||||||
"github.com/ClusterCockpit/cc-backend/pkg/log"
|
"github.com/ClusterCockpit/cc-backend/pkg/log"
|
||||||
"github.com/ClusterCockpit/cc-backend/pkg/schema"
|
"github.com/ClusterCockpit/cc-backend/pkg/schema"
|
||||||
@ -19,25 +20,22 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type LdapAuthenticator struct {
|
type LdapAuthenticator struct {
|
||||||
config *schema.LdapConfig
|
|
||||||
syncPassword string
|
syncPassword string
|
||||||
}
|
}
|
||||||
|
|
||||||
var _ Authenticator = (*LdapAuthenticator)(nil)
|
var _ Authenticator = (*LdapAuthenticator)(nil)
|
||||||
|
|
||||||
func (la *LdapAuthenticator) Init(conf interface{}) error {
|
func (la *LdapAuthenticator) Init() error {
|
||||||
|
|
||||||
la.config = conf.(*schema.LdapConfig)
|
|
||||||
|
|
||||||
la.syncPassword = os.Getenv("LDAP_ADMIN_PASSWORD")
|
la.syncPassword = os.Getenv("LDAP_ADMIN_PASSWORD")
|
||||||
if la.syncPassword == "" {
|
if la.syncPassword == "" {
|
||||||
log.Warn("environment variable 'LDAP_ADMIN_PASSWORD' not set (ldap sync will not work)")
|
log.Warn("environment variable 'LDAP_ADMIN_PASSWORD' not set (ldap sync will not work)")
|
||||||
}
|
}
|
||||||
|
|
||||||
if la.config != nil && la.config.SyncInterval != "" {
|
if config.Keys.LdapConfig.SyncInterval != "" {
|
||||||
interval, err := time.ParseDuration(la.config.SyncInterval)
|
interval, err := time.ParseDuration(config.Keys.LdapConfig.SyncInterval)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Warnf("Could not parse duration for sync interval: %v", la.config.SyncInterval)
|
log.Warnf("Could not parse duration for sync interval: %v",
|
||||||
|
config.Keys.LdapConfig.SyncInterval)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -57,7 +55,7 @@ func (la *LdapAuthenticator) Init(conf interface{}) error {
|
|||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
} else {
|
} else {
|
||||||
log.Info("Missing LDAP configuration key sync_interval")
|
log.Info("LDAP configuration key sync_interval invalid")
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
@ -69,12 +67,14 @@ func (la *LdapAuthenticator) CanLogin(
|
|||||||
rw http.ResponseWriter,
|
rw http.ResponseWriter,
|
||||||
r *http.Request) (*schema.User, bool) {
|
r *http.Request) (*schema.User, bool) {
|
||||||
|
|
||||||
|
lc := config.Keys.LdapConfig
|
||||||
|
|
||||||
if user != nil {
|
if user != nil {
|
||||||
if user.AuthSource == schema.AuthViaLDAP {
|
if user.AuthSource == schema.AuthViaLDAP {
|
||||||
return user, true
|
return user, true
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if la.config.SyncUserOnLogin {
|
if lc.SyncUserOnLogin {
|
||||||
l, err := la.getLdapConnection(true)
|
l, err := la.getLdapConnection(true)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("LDAP connection error")
|
log.Error("LDAP connection error")
|
||||||
@ -83,9 +83,9 @@ func (la *LdapAuthenticator) CanLogin(
|
|||||||
|
|
||||||
// Search for the given username
|
// Search for the given username
|
||||||
searchRequest := ldap.NewSearchRequest(
|
searchRequest := ldap.NewSearchRequest(
|
||||||
la.config.UserBase,
|
lc.UserBase,
|
||||||
ldap.ScopeWholeSubtree, ldap.NeverDerefAliases, 0, 0, false,
|
ldap.ScopeWholeSubtree, ldap.NeverDerefAliases, 0, 0, false,
|
||||||
fmt.Sprintf("(&%s(uid=%s))", la.config.UserFilter, username),
|
fmt.Sprintf("(&%s(uid=%s))", lc.UserFilter, username),
|
||||||
[]string{"dn", "uid", "gecos"}, nil)
|
[]string{"dn", "uid", "gecos"}, nil)
|
||||||
|
|
||||||
sr, err := l.Search(searchRequest)
|
sr, err := l.Search(searchRequest)
|
||||||
@ -138,7 +138,7 @@ func (la *LdapAuthenticator) Login(
|
|||||||
}
|
}
|
||||||
defer l.Close()
|
defer l.Close()
|
||||||
|
|
||||||
userDn := strings.Replace(la.config.UserBind, "{username}", user.Username, -1)
|
userDn := strings.Replace(config.Keys.LdapConfig.UserBind, "{username}", user.Username, -1)
|
||||||
if err := l.Bind(userDn, r.FormValue("password")); err != nil {
|
if err := l.Bind(userDn, r.FormValue("password")); err != nil {
|
||||||
log.Errorf("AUTH/LOCAL > Authentication for user %s failed: %v",
|
log.Errorf("AUTH/LOCAL > Authentication for user %s failed: %v",
|
||||||
user.Username, err)
|
user.Username, err)
|
||||||
@ -153,6 +153,7 @@ func (la *LdapAuthenticator) Sync() error {
|
|||||||
const IN_LDAP int = 2
|
const IN_LDAP int = 2
|
||||||
const IN_BOTH int = 3
|
const IN_BOTH int = 3
|
||||||
ur := repository.GetUserRepository()
|
ur := repository.GetUserRepository()
|
||||||
|
lc := config.Keys.LdapConfig
|
||||||
|
|
||||||
users := map[string]int{}
|
users := map[string]int{}
|
||||||
usernames, err := ur.GetLdapUsernames()
|
usernames, err := ur.GetLdapUsernames()
|
||||||
@ -172,9 +173,9 @@ func (la *LdapAuthenticator) Sync() error {
|
|||||||
defer l.Close()
|
defer l.Close()
|
||||||
|
|
||||||
ldapResults, err := l.Search(ldap.NewSearchRequest(
|
ldapResults, err := l.Search(ldap.NewSearchRequest(
|
||||||
la.config.UserBase,
|
lc.UserBase,
|
||||||
ldap.ScopeWholeSubtree, ldap.NeverDerefAliases, 0, 0, false,
|
ldap.ScopeWholeSubtree, ldap.NeverDerefAliases, 0, 0, false,
|
||||||
la.config.UserFilter,
|
lc.UserFilter,
|
||||||
[]string{"dn", "uid", "gecos"}, nil))
|
[]string{"dn", "uid", "gecos"}, nil))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Warn("LDAP search error")
|
log.Warn("LDAP search error")
|
||||||
@ -198,7 +199,7 @@ func (la *LdapAuthenticator) Sync() error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for username, where := range users {
|
for username, where := range users {
|
||||||
if where == IN_DB && la.config.SyncDelOldUsers {
|
if where == IN_DB && lc.SyncDelOldUsers {
|
||||||
ur.DelUser(username)
|
ur.DelUser(username)
|
||||||
log.Debugf("sync: remove %v (does not show up in LDAP anymore)", username)
|
log.Debugf("sync: remove %v (does not show up in LDAP anymore)", username)
|
||||||
} else if where == IN_LDAP {
|
} else if where == IN_LDAP {
|
||||||
@ -231,14 +232,15 @@ func (la *LdapAuthenticator) Sync() error {
|
|||||||
// that so that connections can be reused/cached.
|
// that so that connections can be reused/cached.
|
||||||
func (la *LdapAuthenticator) getLdapConnection(admin bool) (*ldap.Conn, error) {
|
func (la *LdapAuthenticator) getLdapConnection(admin bool) (*ldap.Conn, error) {
|
||||||
|
|
||||||
conn, err := ldap.DialURL(la.config.Url)
|
lc := config.Keys.LdapConfig
|
||||||
|
conn, err := ldap.DialURL(lc.Url)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Warn("LDAP URL dial failed")
|
log.Warn("LDAP URL dial failed")
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if admin {
|
if admin {
|
||||||
if err := conn.Bind(la.config.SearchDN, la.syncPassword); err != nil {
|
if err := conn.Bind(lc.SearchDN, la.syncPassword); err != nil {
|
||||||
conn.Close()
|
conn.Close()
|
||||||
log.Warn("LDAP connection bind failed")
|
log.Warn("LDAP connection bind failed")
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -19,9 +19,7 @@ type LocalAuthenticator struct {
|
|||||||
|
|
||||||
var _ Authenticator = (*LocalAuthenticator)(nil)
|
var _ Authenticator = (*LocalAuthenticator)(nil)
|
||||||
|
|
||||||
func (la *LocalAuthenticator) Init(
|
func (la *LocalAuthenticator) Init() error {
|
||||||
_ interface{}) error {
|
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -22,7 +22,6 @@ var Keys schema.ProgramConfig = schema.ProgramConfig{
|
|||||||
Archive: json.RawMessage(`{\"kind\":\"file\",\"path\":\"./var/job-archive\"}`),
|
Archive: json.RawMessage(`{\"kind\":\"file\",\"path\":\"./var/job-archive\"}`),
|
||||||
DisableArchive: false,
|
DisableArchive: false,
|
||||||
Validate: false,
|
Validate: false,
|
||||||
LdapConfig: nil,
|
|
||||||
SessionMaxAge: "168h",
|
SessionMaxAge: "168h",
|
||||||
StopJobsExceedingWalltime: 0,
|
StopJobsExceedingWalltime: 0,
|
||||||
ShortRunningJobsDuration: 5 * 60,
|
ShortRunningJobsDuration: 5 * 60,
|
||||||
|
Loading…
Reference in New Issue
Block a user