From a301c94d22a8b64691ae63b010b51fedaf24578a Mon Sep 17 00:00:00 2001
From: Hugo <hnouts@grandlyon.com>
Date: Wed, 23 Sep 2020 10:24:32 +0200
Subject: [PATCH] set up proxy to work with grdf state parameter

---
 main.go | 112 +++++++++++++++++++++++++++++++++++++++++++++++++++-----
 1 file changed, 102 insertions(+), 10 deletions(-)

diff --git a/main.go b/main.go
index 273d53d..d53f8d3 100644
--- a/main.go
+++ b/main.go
@@ -20,6 +20,7 @@ var (
 	logLevel    		= flag.String("loglevel", LookupEnvOrString("LOGLEVEL", "debug"), "log level (debug, info, warning, error) (defaults to debug)")
 	cozyDomain 			= flag.String("cozy_domain", LookupEnvOrString("COZY_DOMAIN", "cozy.wf.alpha.grandlyon.com"), "Cozy domain (defaults to cozy.wf.alpha.grandlyon.com)")
 	cozyRedirectURI 	= flag.String("cozy_redirect_uri", LookupEnvOrString("COZY_REDIRECT_URI", "/accounts/enedisgrandlyon/redirect"), "Cozy redirect URI (defaults to /accounts/enedisgrandlyon/redirect)")
+	cozyGrdfRedirectURI 	= flag.String("cozy_redirect_uri", LookupEnvOrString("COZY_REDIRECT_URI", "/accounts/grdfgrandlyon/redirect"), "Cozy redirect URI (defaults to /accounts/grdfgrandlyon/redirect)")
 )
 
 type TokenResponse struct {
@@ -136,17 +137,14 @@ func main() {
 		http.Redirect(w, r, redirectUrl, 302)
 	})
 
-	// GRDF ADICT ACCESS_TOKEN ENDPOINT
-	mux.HandleFunc("/grdfAccess", func(w http.ResponseWriter, r *http.Request) {
+	// GRDF ADICT AUTHORIZE ENDPOINT
+	mux.HandleFunc("/grdf_authorize", func(w http.ResponseWriter, r *http.Request) {
 		log.Debug("New grdf auth request")
 		query := r.URL.Query()
 		log.Debug("Query received - ", query)
 
 		clientId := query.Get("client_id")
 		state := query.Get("state")
-		scope := "/adict/v1"
-		// here we use the redirect_uri param to transmit our stack url
-		// We keep only the instance name to not reach the 100 max char of redirectUrl
 		cozyOrigin := query.Get("redirect_uri")
 		splitIndexStart := strings.Index(cozyOrigin, ":")
 		if splitIndexStart == -1 {
@@ -160,13 +158,12 @@ func main() {
 		}
 		instanceName := cozyOrigin[splitIndexStart+3:splitIndexEnd]
 
-		// DEV API
-		// authURL := "https://gw.hml.api.enedis.fr/dataconnect/v1/oauth2/authorize"
-		// PROD API
-		authURL := "https://mon-compte-particulier.enedis.fr/dataconnect/v1/oauth2/authorize"
+		redirectProxy := "https://oauth-proxy.wf.alpha.grandlyon.com"
+		authURL := "https://sofit-sso-oidc.grdf.fr/openam/oauth2/realms/externeGrdf/authorize"
 
-		redirectUrl := authURL + "?client_id=" + clientId + "&duration=P6M&response_type=" + responseType + "&state=" + state + "-" + instanceName
+		redirectUrl := authURL + "?client_id=" + clientId + "&scope=openid&response_type=code&redirect_uri="+ redirectProxy + "&state=" + state + "-" + instanceName
 
+		// TODO Add Login Hint in request
 		log.Debug("Redirect to - ", redirectUrl)
 		http.Redirect(w, r, redirectUrl, 302)
 	})
@@ -206,6 +203,29 @@ func main() {
 		}
 	})
 
+	//GRDF REDIRECT ENDPOINT
+	mux.HandleFunc("/redirect-grdf", func(w http.ResponseWriter, r *http.Request) {
+		log.Debug("New redirection on grdf-redirect")
+		query := r.URL.Query()
+		log.Debug(query)
+
+		code := query.Get("code")
+		req_state := query.Get("state")
+		//TODO Get pce_id
+		splitIndex := strings.Index(req_state, "-")
+		if splitIndex == -1 {
+			log.Warning("No host found")
+		}
+		state := req_state[0:splitIndex]
+		host := req_state[splitIndex+1:]
+
+		cozyURL := "https://" + host + "." + *cozyDomain + *cozyGrdfRedirectURI
+
+		redir := cozyURL + "?code=" + code + "&state=" + state + "&usage_point_id=" + usagePointId
+		log.Debug("Redirect to -", redir)
+		http.Redirect(w, r, redir, 302)
+	})
+
 	//ENEDIS TOKEN ENDPOINT
 	mux.HandleFunc("/token", func(w http.ResponseWriter, r *http.Request) {
 		log.Debug("New token request")
@@ -335,5 +355,77 @@ func main() {
 		}
 	})
 
+	//GRDF TOKEN ENDPOINT
+	mux.HandleFunc("/grdf_token", func(w http.ResponseWriter, r *http.Request) {
+		log.Debug("New GRDF token request")
+		query := r.URL.Query()
+		log.Debug(query)
+
+		clientId := ""
+		clientSecret := ""
+		code := ""
+		grantType := ""
+		scope := ""
+
+	// For request token params are into query parameters
+		// Retrieve params from query
+		clientId = query.Get("client_id")
+		clientSecret = query.Get("client_secret")
+		code = query.Get("code")
+		grantType = query.Get("grant_type")
+		scope = query.Get("scope")
+	// Print out the result
+	log.WithFields(log.Fields{
+		"client_id":     clientId,
+		"client_secret": clientSecret,
+		"code":          code,
+		"grant_type":    grantType,
+		"scope": scope,
+	}).Debug("result")
+
+		tokenUrl := "https://sofit-sso-oidc.grdf.fr/openam/oauth2/realms/externeGrdf/access_token"
+
+		data := url.Values{}
+		data.Set("client_id", clientId)
+		data.Set("client_secret", clientSecret)
+		data.Set("grant_type", grantType)
+		if code != "" {
+			data.Set("code", code)
+		}
+		if scope != "" {
+			data.Set("scope", scope)
+		}
+
+		log.Debug("Send request to token endpoint: ", tokenUrl)
+		response, err := http.PostForm(tokenUrl, data)
+		if err != nil {
+			log.Error(err)
+		} else {
+			log.Debug("Endpoint response with status", response.Status)
+			defer response.Body.Close()
+			if response.StatusCode >= 200 && response.StatusCode <= 299 {
+				// Set Content-Type in response header
+				w.Header().Add("Content-Type", "application/json")
+
+				// Decode response Body using the defined type "TokenResponse"
+				data := TokenResponse{}
+				decodeError := json.NewDecoder(response.Body).Decode(&data)
+				if decodeError != nil {
+					http.Error(w, decodeError.Error(), 500)
+					return
+				}
+
+				// Response with json data
+				jsonError := json.NewEncoder(w).Encode(data)
+				if jsonError != nil {
+					http.Error(w, jsonError.Error(), 500)
+					return
+				}
+			} else {
+				http.Error(w, http.StatusText(response.StatusCode), response.StatusCode)
+			}
+		}
+	})
+
 	log.Fatal(http.ListenAndServe(":"+strconv.Itoa(*httpPort), mux))
 }
-- 
GitLab