mirror of
https://github.com/nais/wonderwall.git
synced 2026-05-07 17:06:57 +00:00
134 lines
3.6 KiB
Go
134 lines
3.6 KiB
Go
package handler
|
|
|
|
import (
|
|
"fmt"
|
|
"net/http"
|
|
urllib "net/url"
|
|
|
|
log "github.com/sirupsen/logrus"
|
|
|
|
"github.com/nais/wonderwall/pkg/config"
|
|
"github.com/nais/wonderwall/pkg/handler/url"
|
|
"github.com/nais/wonderwall/pkg/ingress"
|
|
mw "github.com/nais/wonderwall/pkg/middleware"
|
|
openidclient "github.com/nais/wonderwall/pkg/openid/client"
|
|
"github.com/nais/wonderwall/pkg/router"
|
|
"github.com/nais/wonderwall/pkg/router/paths"
|
|
)
|
|
|
|
var _ router.Source = &SSOProxyHandler{}
|
|
|
|
type SSOProxyHandler struct {
|
|
Config *config.Config
|
|
Ingresses *ingress.Ingresses
|
|
SSOServerURL *urllib.URL
|
|
}
|
|
|
|
func NewSSOProxyHandler(cfg *config.Config) (*SSOProxyHandler, error) {
|
|
ingresses, err := ingress.ParseIngresses(cfg)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
u, err := urllib.ParseRequestURI(cfg.SSO.ServerURL)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("parsing sso server url: %w", err)
|
|
}
|
|
|
|
query := u.Query()
|
|
|
|
if len(cfg.OpenID.ACRValues) > 0 {
|
|
query.Set(openidclient.SecurityLevelURLParameter, cfg.OpenID.ACRValues)
|
|
}
|
|
|
|
if len(cfg.OpenID.UILocales) > 0 {
|
|
query.Set(openidclient.LocaleURLParameter, cfg.OpenID.UILocales)
|
|
}
|
|
|
|
u.RawQuery = query.Encode()
|
|
|
|
return &SSOProxyHandler{
|
|
Config: cfg,
|
|
Ingresses: ingresses,
|
|
SSOServerURL: u,
|
|
}, nil
|
|
}
|
|
|
|
func (s *SSOProxyHandler) Login(w http.ResponseWriter, r *http.Request) {
|
|
target := *s.SSOServerURL
|
|
targetQuery := target.Query()
|
|
|
|
reqQuery := r.URL.Query()
|
|
|
|
if reqQuery.Has(openidclient.SecurityLevelURLParameter) {
|
|
targetQuery.Set(openidclient.SecurityLevelURLParameter, reqQuery.Get(openidclient.SecurityLevelURLParameter))
|
|
}
|
|
|
|
if reqQuery.Has(openidclient.LocaleURLParameter) {
|
|
targetQuery.Set(openidclient.LocaleURLParameter, reqQuery.Get(openidclient.LocaleURLParameter))
|
|
}
|
|
|
|
target.RawQuery = reqQuery.Encode()
|
|
|
|
redirect, err := url.Ingress(r)
|
|
if err != nil {
|
|
redirect = s.Ingresses.Single().NewURL()
|
|
}
|
|
parsedRedirect, err := urllib.ParseRequestURI(reqQuery.Get(url.RedirectURLParameter))
|
|
if err == nil {
|
|
redirect = redirect.JoinPath(parsedRedirect.Path)
|
|
}
|
|
|
|
ssoServerLoginURL := url.Login(&target, redirect.String())
|
|
|
|
mw.LogEntryFrom(r).
|
|
WithFields(log.Fields{
|
|
"redirect_to": ssoServerLoginURL,
|
|
"redirect_after_login": redirect.String(),
|
|
}).
|
|
Info("login: redirecting to sso server")
|
|
|
|
http.Redirect(w, r, ssoServerLoginURL, http.StatusTemporaryRedirect)
|
|
}
|
|
|
|
func (s *SSOProxyHandler) LoginCallback(w http.ResponseWriter, r *http.Request) {
|
|
http.NotFound(w, r)
|
|
}
|
|
|
|
func (s *SSOProxyHandler) Logout(w http.ResponseWriter, r *http.Request) {
|
|
target := s.SSOServerURL.JoinPath(paths.OAuth2, paths.Logout)
|
|
http.Redirect(w, r, target.String(), http.StatusTemporaryRedirect)
|
|
}
|
|
|
|
func (s *SSOProxyHandler) LogoutCallback(w http.ResponseWriter, r *http.Request) {
|
|
http.NotFound(w, r)
|
|
}
|
|
|
|
func (s *SSOProxyHandler) LogoutFrontChannel(w http.ResponseWriter, r *http.Request) {
|
|
http.NotFound(w, r)
|
|
}
|
|
|
|
func (s *SSOProxyHandler) LogoutLocal(w http.ResponseWriter, r *http.Request) {
|
|
target := s.SSOServerURL.JoinPath(paths.OAuth2, paths.LogoutLocal)
|
|
http.Redirect(w, r, target.String(), http.StatusTemporaryRedirect)
|
|
}
|
|
|
|
func (s *SSOProxyHandler) Session(w http.ResponseWriter, r *http.Request) {
|
|
// TODO proxy to sso-server or use session handler that fetches directly from session store)
|
|
panic("implement me")
|
|
}
|
|
|
|
func (s *SSOProxyHandler) SessionRefresh(w http.ResponseWriter, r *http.Request) {
|
|
// TODO proxy to sso-server
|
|
panic("implement me")
|
|
}
|
|
|
|
func (s *SSOProxyHandler) ReverseProxy(w http.ResponseWriter, r *http.Request) {
|
|
// TODO implement me
|
|
panic("implement me")
|
|
}
|
|
|
|
func (s *SSOProxyHandler) GetIngresses() *ingress.Ingresses {
|
|
return s.Ingresses
|
|
}
|