go-dev-zprox-0.01/internal/auth/middleware.go
2025-03-22 08:57:23 +00:00

190 lines
5.4 KiB
Go

package auth
import (
"crypto/rsa"
"net/http"
"net/http/httputil"
"slices"
"github.com/gookit/goutil/dump"
"github.com/zeevdiukman/zprox/internal/config"
"github.com/zeevdiukman/zprox/internal/session"
"golang.org/x/oauth2"
)
func Middleware(routerData *config.Router, routeID string, w http.ResponseWriter, r *http.Request, rp *httputil.ReverseProxy) {
authConfig := config.Data.AuthMap[routerData.Auth.Provider]
// dump.P("routerData.Auth.Provider", routerData.Auth.Provider)
// dump.P("authConfig.OpenID.EndPoints.RedirectURI", authConfig.OpenID.EndPoints.RedirectURI)
// dump.P("config.Data.AuthMap[routerData.Auth.Provider]", config.Data.AuthMap[routerData.Auth.Provider].OpenID.EndPoints.RedirectURI)
if !routerData.IsAuthRouter && !IsLoggedIn(r, authConfig, routerData, routeID) {
RedirectToLogin(authConfig, w, r)
return
}
rp.ServeHTTP(w, r)
}
// func IsLoggedIn(r *http.Request, routerData *config.Router, routeID string) bool {
// if oauth2Token, ok := session.Manager.Get(r.Context(), "oauth2_token").(*oauth2.Token); ok {
// if publicKey, ok := session.Manager.Get(r.Context(), "jwks_public_key").(*rsa.PublicKey); ok {
// if claims, isValid := GetJwtClaims(r, publicKey, oauth2Token); isValid {
// allowLists := routerData.Auth.JWT.AllowLists
// for listName, list := range allowLists {
// if len(list) > 0 {
// if claim, ok := claims[listName]; ok {
// if !slices.Contains(list, claim.(string)) {
// return false
// } else {
// dump.P("Hello " + claims["name"].(string))
// }
// }
// }
// }
// }
// if !oauth2Token.Valid() {
// return false
// }
// }
// dump.P("IsLoggedIn: token is not valid")
// return false
// }
// dump.P("IsLoggedIn: no token")
// return false
// }
func IsLoggedIn(r *http.Request, authConfig *config.Auth, routerData *config.Router, routeID string) bool {
var oauth2Token *oauth2.Token
var publicKey *rsa.PublicKey
var oauth2TokenOK bool
var publicKeyOK bool
if oauth2Token, oauth2TokenOK = session.Manager.Get(r.Context(), "oauth2_token").(*oauth2.Token); !oauth2TokenOK {
// dump.P("no oauth2Token")
return false
}
if publicKey, publicKeyOK = session.Manager.Get(r.Context(), "jwks_public_key").(*rsa.PublicKey); !publicKeyOK {
dump.P("publicKey not valid")
return false
}
if !oauth2Token.Valid() {
dump.P("oauth2Token not valid")
return false
}
claims, err := GetJwtClaims(r, publicKey, oauth2Token)
if err != nil {
dump.P(err.Error())
return false
}
if err := claims.Valid(); err != nil {
dump.P(err.Error())
return false
}
// dump.P(claims)
// conf := &oauth2.Config{
// ClientID: authConfig.OpenID.ClientID,
// ClientSecret: authConfig.OpenID.ClientSecret,
// RedirectURL: authConfig.OpenID.RedirectURI,
// Scopes: []string{"openid", "email", "profile"},
// Endpoint: oauth2.Endpoint{
// AuthURL: authConfig.OpenID.AuthURL,
// TokenURL: authConfig.OpenID.TokenURL,
// },
// }
// u,_ := url.Parse(authConfig.OpenID.UserURL)
// u.
// client := conf.Client(r.Context(),oauth2Token)
// client.PostForm(authConfig.OpenID.UserURL,url.Values{})
// tokenSource := conf.TokenSource(r.Context(), oauth2Token)
// tokenSource.Token()
// if !oauth2Token.Valid() {
// timeNow := time.Now()
// if !oauth2Token.Expiry.Before(timeNow) {
// return false
// }
// openID := config.Data.AuthMap[routerData.Auth.Provider].OpenID
// conf := &oauth2.Config{
// ClientID: openID.ClientID,
// ClientSecret: openID.ClientSecret,
// RedirectURL: openID.RedirectURI,
// Scopes: []string{"openid", "email", "profile"},
// Endpoint: endPoint,
// }
// oauth2Token, err := conf.Exchange(r.Context(), code)
// if err != nil {
// return false
// log.Println(err.Error())
// }
// return false
// }
for listName, list := range routerData.Auth.JWT.AllowLists {
if len(list) > 0 {
if claim, ok := claims[listName]; ok {
if !slices.Contains(list, claim.(string)) {
return false
} else {
dump.P("Hello " + claims["name"].(string))
}
}
}
}
return true
}
// func getAccessToken(refreshToken string) (TokenResponse, error) {
// keycloakURL := os.Getenv("KEYCLOAK_URL")
// realm := os.Getenv("KEYCLOAK_REALM")
// clientID := os.Getenv("KEYCLOAK_CLIENT_ID")
// clientSecret := os.Getenv("KEYCLOAK_CLIENT_SECRET")
// tokenURL := fmt.Sprintf("%s/auth/realms/%s/protocol/openid-connect/token", keycloakURL, realm)
// data := url.Values{}
// data.Set("grant_type", "refresh_token")
// data.Set("client_id", clientID)
// data.Set("client_secret", clientSecret)
// data.Set("refresh_token", refreshToken)
// req, err := http.NewRequest("POST", tokenURL, bytes.NewBufferString(data.Encode()))
// if err != nil {
// return TokenResponse{}, err
// }
// req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
// client := &http.Client{}
// resp, err := client.Do(req)
// if err != nil {
// return TokenResponse{}, err
// }
// defer resp.Body.Close()
// body, err := io.ReadAll(resp.Body)
// if err != nil {
// return TokenResponse{}, err
// }
// if resp.StatusCode != http.StatusOK {
// return TokenResponse{}, fmt.Errorf("Keycloak returned status: %d, body: %s", resp.StatusCode, string(body))
// }
// var tokenResponse TokenResponse
// err = json.Unmarshal(body, &tokenResponse)
// if err != nil {
// return TokenResponse{}, err
// }
// return tokenResponse, nil
// }