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 // }