7f3a8b24ff
defined some more constants and places them in models/constannts.go
221 lines
6.9 KiB
Go
221 lines
6.9 KiB
Go
package handlers
|
|
|
|
import "net/http"
|
|
import "strings"
|
|
|
|
import "codit/internal/db"
|
|
import "codit/internal/auth"
|
|
import "codit/config"
|
|
import "codit/internal/models"
|
|
|
|
func (api *API) ListAuthProviders(w http.ResponseWriter, r *http.Request, _ map[string]string) {
|
|
var providers []models.AuthProvider
|
|
var err error
|
|
if !api.requireAdmin(w, r) {
|
|
return
|
|
}
|
|
providers, err = api.store(r).ListAuthProvidersWithGroupMappings()
|
|
if err != nil {
|
|
WriteJSONWithErrorReason(w, r, http.StatusInternalServerError, err.Error())
|
|
return
|
|
}
|
|
WriteJSON(w, http.StatusOK, providers)
|
|
}
|
|
|
|
func (api *API) GetAuthProvider(w http.ResponseWriter, r *http.Request, params map[string]string) {
|
|
var provider models.AuthProvider
|
|
var err error
|
|
if !api.requireAdmin(w, r) {
|
|
return
|
|
}
|
|
provider, err = api.store(r).GetAuthProviderWithGroupMappings(params["id"])
|
|
if err != nil {
|
|
WriteJSONWithErrorReason(w, r, http.StatusNotFound, "auth provider not found")
|
|
return
|
|
}
|
|
WriteJSON(w, http.StatusOK, provider)
|
|
}
|
|
|
|
func (api *API) CreateAuthProvider(w http.ResponseWriter, r *http.Request, _ map[string]string) {
|
|
var req models.AuthProvider
|
|
var created models.AuthProvider
|
|
var err error
|
|
if !api.requireAdmin(w, r) {
|
|
return
|
|
}
|
|
err = DecodeJSON(r, &req)
|
|
if err != nil {
|
|
WriteJSONWithErrorReason(w, r, http.StatusBadRequest, "invalid json")
|
|
return
|
|
}
|
|
if strings.TrimSpace(req.Name) == "" {
|
|
WriteJSONWithErrorReason(w, r, http.StatusBadRequest, "name is required")
|
|
return
|
|
}
|
|
if req.Type != models.AuthProviderTypeLDAP && req.Type != models.AuthProviderTypeOIDC {
|
|
WriteJSONWithErrorReason(w, r, http.StatusBadRequest, "type must be ldap or oidc")
|
|
return
|
|
}
|
|
if req.Type == models.AuthProviderTypeOIDC && strings.TrimSpace(req.OIDCAdmissionExpr) != "" {
|
|
err = oidcCompileAdmissionExpr(strings.TrimSpace(req.OIDCAdmissionExpr))
|
|
if err != nil {
|
|
WriteJSONWithErrorReason(w, r, http.StatusBadRequest, "invalid admission expression: "+err.Error())
|
|
return
|
|
}
|
|
}
|
|
created, err = api.store(r).CreateAuthProvider(r.Context(), req)
|
|
if err != nil {
|
|
WriteJSONWithErrorReason(w, r, http.StatusBadRequest, err.Error())
|
|
return
|
|
}
|
|
WriteJSON(w, http.StatusCreated, created)
|
|
}
|
|
|
|
func (api *API) UpdateAuthProvider(w http.ResponseWriter, r *http.Request, params map[string]string) {
|
|
var req models.AuthProvider
|
|
var updated models.AuthProvider
|
|
var existing models.AuthProvider
|
|
var err error
|
|
if !api.requireAdmin(w, r) {
|
|
return
|
|
}
|
|
existing, err = api.store(r).GetAuthProvider(params["id"])
|
|
if err != nil {
|
|
WriteJSONWithErrorReason(w, r, http.StatusNotFound, "auth provider not found")
|
|
return
|
|
}
|
|
err = DecodeJSON(r, &req)
|
|
if err != nil {
|
|
WriteJSONWithErrorReason(w, r, http.StatusBadRequest, "invalid json")
|
|
return
|
|
}
|
|
req.ID = existing.ID
|
|
req.Type = existing.Type
|
|
if req.Type == models.AuthProviderTypeOIDC && strings.TrimSpace(req.OIDCAdmissionExpr) != "" {
|
|
err = oidcCompileAdmissionExpr(strings.TrimSpace(req.OIDCAdmissionExpr))
|
|
if err != nil {
|
|
WriteJSONWithErrorReason(w, r, http.StatusBadRequest, "invalid admission expression: "+err.Error())
|
|
return
|
|
}
|
|
}
|
|
if existing.ID == db.BuiltinDBProviderPublicID {
|
|
existing.Enabled = req.Enabled
|
|
if strings.TrimSpace(req.Name) != "" {
|
|
existing.Name = strings.TrimSpace(req.Name)
|
|
}
|
|
updated, err = api.store(r).UpdateAuthProvider(r.Context(), existing)
|
|
} else {
|
|
if strings.TrimSpace(req.Name) == "" {
|
|
WriteJSONWithErrorReason(w, r, http.StatusBadRequest, "name is required")
|
|
return
|
|
}
|
|
updated, err = api.store(r).UpdateAuthProvider(r.Context(), req)
|
|
}
|
|
if err != nil {
|
|
WriteJSONWithErrorReason(w, r, http.StatusBadRequest, err.Error())
|
|
return
|
|
}
|
|
WriteJSON(w, http.StatusOK, updated)
|
|
}
|
|
|
|
func (api *API) DeleteAuthProvider(w http.ResponseWriter, r *http.Request, params map[string]string) {
|
|
var err error
|
|
var force bool
|
|
var count int
|
|
if !api.requireAdmin(w, r) {
|
|
return
|
|
}
|
|
if params["id"] == db.BuiltinDBProviderPublicID {
|
|
WriteJSONWithErrorReason(w, r, http.StatusForbidden, "builtin provider cannot be deleted")
|
|
return
|
|
}
|
|
force = strings.EqualFold(r.URL.Query().Get("force"), "true")
|
|
if !force {
|
|
count, err = api.store(r).CountAuthProviderUsers(params["id"])
|
|
if err != nil {
|
|
WriteJSONWithErrorReason(w, r, http.StatusInternalServerError, err.Error())
|
|
return
|
|
}
|
|
if count > 0 {
|
|
WriteJSON(w, http.StatusConflict, map[string]any{
|
|
"error": "provider has associated users",
|
|
"user_count": count,
|
|
})
|
|
return
|
|
}
|
|
}
|
|
err = api.store(r).DeleteAuthProvider(r.Context(), params["id"], force)
|
|
if err != nil {
|
|
WriteJSONWithErrorReason(w, r, http.StatusInternalServerError, err.Error())
|
|
return
|
|
}
|
|
WriteJSON(w, http.StatusOK, map[string]string{"status": "ok"})
|
|
}
|
|
|
|
func (api *API) TestAuthProvider(w http.ResponseWriter, r *http.Request, params map[string]string) {
|
|
var provider models.AuthProvider
|
|
var req testLDAPSettingsRequest
|
|
var cfg config.Config
|
|
var ldapUser auth.LDAPUser
|
|
var err error
|
|
|
|
if !api.requireAdmin(w, r) { return }
|
|
provider, err = api.store(r).GetAuthProvider(params["id"])
|
|
if err != nil {
|
|
WriteJSONWithErrorReason(w, r, http.StatusNotFound, "auth provider not found")
|
|
return
|
|
}
|
|
if provider.Type != models.AuthProviderTypeLDAP {
|
|
WriteJSONWithErrorReason(w, r, http.StatusBadRequest, "test is only supported for ldap providers")
|
|
return
|
|
}
|
|
err = DecodeJSON(r, &req)
|
|
if err != nil {
|
|
WriteJSONWithErrorReason(w, r, http.StatusBadRequest, "invalid json")
|
|
return
|
|
}
|
|
cfg = api.Cfg
|
|
cfg.LDAPURL = provider.LDAPUrl
|
|
cfg.LDAPBindDN = provider.LDAPBindDN
|
|
cfg.LDAPBindPassword = provider.LDAPBindPassword
|
|
cfg.LDAPUserBaseDN = provider.LDAPUserBaseDN
|
|
cfg.LDAPUserFilter = provider.LDAPUserFilter
|
|
if cfg.LDAPUserFilter == "" {
|
|
cfg.LDAPUserFilter = "(uid={username})"
|
|
}
|
|
cfg.LDAPTLSInsecureSkipVerify = provider.LDAPTLSInsecureSkipVerify
|
|
if strings.TrimSpace(req.LDAPURL) != "" {
|
|
cfg.LDAPURL = strings.TrimSpace(req.LDAPURL)
|
|
}
|
|
if strings.TrimSpace(req.LDAPBindDN) != "" {
|
|
cfg.LDAPBindDN = strings.TrimSpace(req.LDAPBindDN)
|
|
}
|
|
if req.LDAPBindPassword != "" {
|
|
cfg.LDAPBindPassword = req.LDAPBindPassword
|
|
}
|
|
if strings.TrimSpace(req.LDAPUserBaseDN) != "" {
|
|
cfg.LDAPUserBaseDN = strings.TrimSpace(req.LDAPUserBaseDN)
|
|
}
|
|
if strings.TrimSpace(req.LDAPUserFilter) != "" {
|
|
cfg.LDAPUserFilter = strings.TrimSpace(req.LDAPUserFilter)
|
|
}
|
|
if req.LDAPTLSInsecureSkipVerify != nil {
|
|
cfg.LDAPTLSInsecureSkipVerify = *req.LDAPTLSInsecureSkipVerify
|
|
}
|
|
err = auth.LDAPTestConnectionContext(r.Context(), cfg)
|
|
if err != nil {
|
|
WriteJSONWithErrorReason(w, r, http.StatusBadRequest, err.Error())
|
|
return
|
|
}
|
|
if strings.TrimSpace(req.Username) != "" && strings.TrimSpace(req.Password) != "" {
|
|
ldapUser, err = auth.LDAPAuthenticateContext(r.Context(), cfg, strings.TrimSpace(req.Username), req.Password)
|
|
if err != nil {
|
|
WriteJSONWithErrorReason(w, r, http.StatusBadRequest, err.Error())
|
|
return
|
|
}
|
|
WriteJSON(w, http.StatusOK, map[string]string{"status": "ok", "user": ldapUser.Username})
|
|
return
|
|
}
|
|
WriteJSON(w, http.StatusOK, map[string]string{"status": "ok"})
|
|
}
|