Add LDAPSyncOnLogin option

Cleanup
Extend docs
Remove obsolete Expiration attribute
This commit is contained in:
2023-08-14 12:40:21 +02:00
parent 9e3ba41746
commit 4a2afc7a5a
8 changed files with 84 additions and 56 deletions

View File

@@ -43,7 +43,6 @@ type User struct {
AuthSource AuthSource `json:"authSource"`
Email string `json:"email"`
Projects []string `json:"projects"`
Expiration time.Time
}
func (u *User) HasProject(project string) bool {
@@ -66,7 +65,7 @@ func GetUser(ctx context.Context) *User {
type Authenticator interface {
Init(auth *Authentication, config interface{}) error
CanLogin(user *User, rw http.ResponseWriter, r *http.Request) bool
CanLogin(user *User, username string, rw http.ResponseWriter, r *http.Request) bool
Login(user *User, rw http.ResponseWriter, r *http.Request) (*User, error)
}
@@ -208,7 +207,7 @@ func (auth *Authentication) Login(
}
for _, authenticator := range auth.authenticators {
if !authenticator.CanLogin(dbUser, rw, r) {
if !authenticator.CanLogin(dbUser, username, rw, r) {
continue
}

View File

@@ -86,11 +86,6 @@ func (ja *JWTAuthenticator) AuthViaJWT(
// Token is valid, extract payload
claims := token.Claims.(jwt.MapClaims)
sub, _ := claims["sub"].(string)
exp, _ := claims["exp"].(float64)
if exp < float64(time.Now().Unix()) {
return nil, errors.New("token is expired")
}
var roles []string

View File

@@ -10,7 +10,6 @@ import (
"errors"
"net/http"
"os"
"time"
"github.com/ClusterCockpit/cc-backend/pkg/log"
"github.com/ClusterCockpit/cc-backend/pkg/schema"
@@ -91,6 +90,7 @@ func (ja *JWTCookieSessionAuthenticator) Init(auth *Authentication, conf interfa
func (ja *JWTCookieSessionAuthenticator) CanLogin(
user *User,
username string,
rw http.ResponseWriter,
r *http.Request) bool {
@@ -140,7 +140,7 @@ func (ja *JWTCookieSessionAuthenticator) Login(
return ja.publicKey, nil
})
if err != nil {
log.Warn("Error while parsing token")
log.Warn("error while parsing token")
return nil, err
}
@@ -152,7 +152,6 @@ func (ja *JWTCookieSessionAuthenticator) Login(
claims := token.Claims.(jwt.MapClaims)
sub, _ := claims["sub"].(string)
exp, _ := claims["exp"].(float64)
var name string
if val, ok := claims["name"]; ok {
@@ -201,6 +200,5 @@ func (ja *JWTCookieSessionAuthenticator) Login(
}
}
user.Expiration = time.Unix(int64(exp), 0)
return user, nil
}

View File

@@ -10,7 +10,6 @@ import (
"net/http"
"os"
"strings"
"time"
"github.com/ClusterCockpit/cc-backend/pkg/log"
"github.com/golang-jwt/jwt/v4"
@@ -42,6 +41,7 @@ func (ja *JWTSessionAuthenticator) Init(auth *Authentication, conf interface{})
func (ja *JWTSessionAuthenticator) CanLogin(
user *User,
username string,
rw http.ResponseWriter,
r *http.Request) bool {
@@ -76,7 +76,6 @@ func (ja *JWTSessionAuthenticator) Login(
claims := token.Claims.(jwt.MapClaims)
sub, _ := claims["sub"].(string)
exp, _ := claims["exp"].(float64)
var name string
if val, ok := claims["name"]; ok {
@@ -102,6 +101,5 @@ func (ja *JWTSessionAuthenticator) Login(
}
}
user.Expiration = time.Unix(int64(exp), 0)
return user, nil
}

View File

@@ -66,10 +66,51 @@ func (la *LdapAuthenticator) Init(
func (la *LdapAuthenticator) CanLogin(
user *User,
username string,
rw http.ResponseWriter,
r *http.Request) bool {
return user != nil && user.AuthSource == AuthViaLDAP
if user != nil && user.AuthSource == AuthViaLDAP {
return true
} else {
if la.config.SyncUserOnLogin {
l, err := la.getLdapConnection(true)
if err != nil {
log.Error("LDAP connection error")
}
// Search for the given username
searchRequest := ldap.NewSearchRequest(
la.config.UserBase,
ldap.ScopeWholeSubtree, ldap.NeverDerefAliases, 0, 0, false,
fmt.Sprintf("(%s(uid=%s))", la.config.UserFilter, username),
[]string{"dn", "uid", "gecos"}, nil)
sr, err := l.Search(searchRequest)
if err != nil {
log.Warn(err)
return false
}
if len(sr.Entries) != 1 {
log.Warn("User does not exist or too many entries returned")
return false
}
entry := sr.Entries[0]
name := entry.GetAttributeValue("gecos")
if _, err := la.auth.db.Exec(`INSERT INTO user (username, ldap, name, roles) VALUES (?, ?, ?, ?)`,
username, 1, name, "[\""+GetRoleString(RoleUser)+"\"]"); err != nil {
log.Errorf("User '%s' new in LDAP: Insert into DB failed", username)
return false
}
return true
}
}
return false
}
func (la *LdapAuthenticator) Login(
@@ -124,8 +165,10 @@ func (la *LdapAuthenticator) Sync() error {
defer l.Close()
ldapResults, err := l.Search(ldap.NewSearchRequest(
la.config.UserBase, ldap.ScopeWholeSubtree, ldap.NeverDerefAliases, 0, 0, false,
la.config.UserFilter, []string{"dn", "uid", "gecos"}, nil))
la.config.UserBase,
ldap.ScopeWholeSubtree, ldap.NeverDerefAliases, 0, 0, false,
fmt.Sprintf("(%s(uid=%s))", la.config.UserFilter, "*"),
[]string{"dn", "uid", "gecos"}, nil))
if err != nil {
log.Warn("LDAP search error")
return err

View File

@@ -28,6 +28,7 @@ func (la *LocalAuthenticator) Init(
func (la *LocalAuthenticator) CanLogin(
user *User,
username string,
rw http.ResponseWriter,
r *http.Request) bool {