diff --git a/cmd/cc-backend/main.go b/cmd/cc-backend/main.go index e0c18ef..96d7c8d 100644 --- a/cmd/cc-backend/main.go +++ b/cmd/cc-backend/main.go @@ -347,7 +347,7 @@ func main() { info := map[string]interface{}{} info["hasOpenIDConnect"] = false - if config.Keys.OpenIDProvider != "" { + if config.Keys.OpenIDConfig != nil { openIDConnect := auth.NewOIDC(authentication) openIDConnect.RegisterEndpoints(r) info["hasOpenIDConnect"] = true @@ -569,8 +569,8 @@ func main() { } var cfg struct { - Compression int `json:"compression"` Retention schema.Retention `json:"retention"` + Compression int `json:"compression"` } cfg.Retention.IncludeDB = true diff --git a/internal/auth/auth.go b/internal/auth/auth.go index 9bca62e..16e816d 100644 --- a/internal/auth/auth.go +++ b/internal/auth/auth.go @@ -129,6 +129,19 @@ func Init() (*Authentication, error) { return auth, nil } +func persistUser(user *schema.User) { + r := repository.GetUserRepository() + _, err := r.GetUser(user.Username) + + if err != nil && err != sql.ErrNoRows { + log.Errorf("Error while loading user '%s': %v", user.Username, err) + } else if err == sql.ErrNoRows { + if err := r.AddUser(user); err != nil { + log.Errorf("Error while adding user '%s' to DB: %v", user.Username, err) + } + } +} + func (auth *Authentication) SaveSession(rw http.ResponseWriter, r *http.Request, user *schema.User) error { session, err := auth.sessionStore.New(r, "session") if err != nil { diff --git a/internal/auth/jwtCookieSession.go b/internal/auth/jwtCookieSession.go index 01f5746..3cf02d9 100644 --- a/internal/auth/jwtCookieSession.go +++ b/internal/auth/jwtCookieSession.go @@ -199,9 +199,7 @@ func (ja *JWTCookieSessionAuthenticator) Login( } if jc.SyncUserOnLogin { - if err := repository.GetUserRepository().AddUser(user); err != nil { - log.Errorf("Error while adding user '%s' to DB", user.Username) - } + persistUser(user) } } diff --git a/internal/auth/jwtSession.go b/internal/auth/jwtSession.go index 541e31e..ca2daf5 100644 --- a/internal/auth/jwtSession.go +++ b/internal/auth/jwtSession.go @@ -139,9 +139,7 @@ func (ja *JWTSessionAuthenticator) Login( } if config.Keys.JwtConfig.SyncUserOnLogin { - if err := repository.GetUserRepository().AddUser(user); err != nil { - log.Errorf("Error while adding user '%s' to DB", user.Username) - } + persistUser(user) } } diff --git a/internal/auth/oidc.go b/internal/auth/oidc.go index 04dcaf3..abfed16 100644 --- a/internal/auth/oidc.go +++ b/internal/auth/oidc.go @@ -49,7 +49,7 @@ func setCallbackCookie(w http.ResponseWriter, r *http.Request, name, value strin } func NewOIDC(a *Authentication) *OIDC { - provider, err := oidc.NewProvider(context.Background(), config.Keys.OpenIDProvider) + provider, err := oidc.NewProvider(context.Background(), config.Keys.OpenIDConfig.Provider) if err != nil { log.Fatal(err) } @@ -89,6 +89,10 @@ func (oa *OIDC) OAuth2Callback(rw http.ResponseWriter, r *http.Request) { state := c.Value c, err = r.Cookie("verifier") + if err != nil { + http.Error(rw, "verifier cookie not found", http.StatusBadRequest) + return + } codeVerifier := c.Value _ = r.ParseForm() @@ -152,7 +156,7 @@ func (oa *OIDC) OAuth2Callback(rw http.ResponseWriter, r *http.Request) { } } - if len(claims.Profile.Client.Roles) == 0 { + if len(roles) == 0 { roles = append(roles, schema.GetRoleString(schema.RoleUser)) } @@ -163,6 +167,11 @@ func (oa *OIDC) OAuth2Callback(rw http.ResponseWriter, r *http.Request) { Projects: projects, AuthSource: schema.AuthViaOIDC, } + + if config.Keys.OpenIDConfig.SyncUserOnLogin { + persistUser(user) + } + oa.authentication.SaveSession(rw, r, user) log.Infof("login successfull: user: %#v (roles: %v, projects: %v)", user.Username, user.Roles, user.Projects) ctx := context.WithValue(r.Context(), repository.ContextUserKey, user) diff --git a/pkg/schema/config.go b/pkg/schema/config.go index b3b6afb..adc47dd 100644 --- a/pkg/schema/config.go +++ b/pkg/schema/config.go @@ -23,6 +23,11 @@ type LdapConfig struct { SyncUserOnLogin bool `json:"syncUserOnLogin"` } +type OpenIDConfig struct { + Provider string `json:"provider"` + SyncUserOnLogin bool `json:"syncUserOnLogin"` +} + type JWTAuthConfig struct { // Specifies for how long a JWT token shall be valid // as a string parsable by time.ParseDuration(). @@ -109,11 +114,9 @@ type ProgramConfig struct { Validate bool `json:"validate"` // For LDAP Authentication and user synchronisation. - LdapConfig *LdapConfig `json:"ldap"` - JwtConfig *JWTAuthConfig `json:"jwts"` - - // Enable OpenID connect Authentication - OpenIDProvider string `json:"openIDProvider"` + LdapConfig *LdapConfig `json:"ldap"` + JwtConfig *JWTAuthConfig `json:"jwts"` + OpenIDConfig *OpenIDConfig `json:"oidc"` // If 0 or empty, the session does not expire! SessionMaxAge string `json:"session-max-age"`