GoDoxy/internal/net/gphttp/middleware/oidc.go
yusing 7461344004 fix: json store marshaling, api handler
- code clean up
- uncomment and simplify api auth handler
- fix redirect url for frontend
- proper redirect
2025-04-24 04:47:42 +08:00

87 lines
1.7 KiB
Go

package middleware
import (
"errors"
"net/http"
"sync"
"sync/atomic"
"github.com/yusing/go-proxy/internal/auth"
"github.com/yusing/go-proxy/internal/gperr"
)
type oidcMiddleware struct {
AllowedUsers []string `json:"allowed_users"`
AllowedGroups []string `json:"allowed_groups"`
auth *auth.OIDCProvider
isInitialized int32
initMu sync.Mutex
}
var OIDC = NewMiddleware[oidcMiddleware]()
func (amw *oidcMiddleware) finalize() error {
if !auth.IsOIDCEnabled() {
return gperr.New("OIDC not enabled but OIDC middleware is used")
}
return nil
}
func (amw *oidcMiddleware) init() error {
if atomic.LoadInt32(&amw.isInitialized) == 1 {
return nil
}
return amw.initSlow()
}
func (amw *oidcMiddleware) initSlow() error {
amw.initMu.Lock()
if amw.isInitialized == 1 {
amw.initMu.Unlock()
return nil
}
defer func() {
amw.isInitialized = 1
amw.initMu.Unlock()
}()
authProvider, err := auth.NewOIDCProviderFromEnv()
if err != nil {
return err
}
if len(amw.AllowedUsers) > 0 {
authProvider.SetAllowedUsers(amw.AllowedUsers)
}
if len(amw.AllowedGroups) > 0 {
authProvider.SetAllowedGroups(amw.AllowedGroups)
}
amw.auth = authProvider
return nil
}
func (amw *oidcMiddleware) before(w http.ResponseWriter, r *http.Request) (proceed bool) {
if err := amw.init(); err != nil {
// no need to log here, main OIDC should've already failed and logged
http.Error(w, err.Error(), http.StatusInternalServerError)
return false
}
err := amw.auth.CheckToken(r)
if err == nil {
return true
}
switch {
case errors.Is(err, auth.ErrMissingOAuthToken):
amw.auth.HandleAuth(w, r)
default:
auth.WriteBlockPage(w, http.StatusForbidden, err.Error(), auth.OIDCLogoutPath)
}
return false
}