Skip to content
Snippets Groups Projects
main.go 5.36 KiB
Newer Older
  • Learn to ignore specific revisions
  • Nicolas PERNOUD's avatar
    Nicolas PERNOUD committed
    package main
    
    import (
    	"flag"
    
    Nicolas PERNOUD's avatar
    Nicolas PERNOUD committed
    	"net/http"
    
    	"net/url"
    
    Nicolas PERNOUD's avatar
    Nicolas PERNOUD committed
    	"strconv"
    
    Hugo NOUTS's avatar
    Hugo NOUTS committed
    	"strings"
    
    	"encoding/json"
    
    Nicolas PERNOUD's avatar
    Nicolas PERNOUD committed
    )
    
    var (
    	httpPort = flag.Int("http_port", 80, "HTTP port to serve on (defaults to 80)")
    )
    
    
    type TokenResponse struct {
    
        AccessToken 			string    	`json:"access_token"`
    
    	TokenType 				string      `json:"token_type"`
    
    	ExpiresIn 				int      	`json:"expires_in"`
    
    	RefreshToken 			string      `json:"refresh_token"`
    	Scope 					string      `json:"scope"`
    	RefreshTokenIssuedAt 	string      `json:"refresh_token_issued_at"`
    	IssueAt 				string      `json:"issued_at"`
    
    Yoan VALLET's avatar
    Yoan VALLET committed
    	UsagePointId			string      `json:"usage_points_id"`
    
    Nicolas PERNOUD's avatar
    Nicolas PERNOUD committed
    func main() {
    	// Parse the flags
    	flag.Parse()
    	mux := http.NewServeMux()
    
    Hugo SUBTIL's avatar
    Hugo SUBTIL committed
        fmt.Println("Server started")
    
    	mux.HandleFunc("/auth", func(w http.ResponseWriter, r *http.Request) {
    
    		fmt.Println("*******************")
    
    		fmt.Println(time.Now().Format("2006-01-02 15:04:05"), "- New auth request")
    		query := r.URL.Query()
    		fmt.Println(time.Now().Format("2006-01-02 15:04:05"), "- Query received - ", query)
    
    		clientId := query.Get("client_id")
    		state := query.Get("state")
    
    		cozyOrigin := query.Get("redirect_uri") // here we use the redirect_uri param to transmit our stack url
    
    		redirectUri := "https://oauth-proxy.wf.alpha.grandlyon.com/"
    
    		responseType := "code" 
    
    
    		authReq := "https://gw.hml.api.enedis.fr/dataconnect/v1/oauth2/authorize?client_id="+ clientId +"&duration=P6M&redirect_uri="+ redirectUri +"&response_type="+ responseType +"&state="+ state +"-"+ cozyOrigin
    
    
    		fmt.Println(time.Now().Format("2006-01-02 15:04:05"), "- Send request to auth endpoint", authReq)
    		response, err := http.Get(authReq)
    		fmt.Println(time.Now().Format("2006-01-02 15:04:05"), "- Endpoint response with status", response.Status)
    		if err != nil {
    			fmt.Println(err)
    		} else {
    			defer response.Body.Close()
    			contents, err := ioutil.ReadAll(response.Body)
    			if err != nil {
    				fmt.Println(err)
    			}
    
    
    			// TO BE REMOVE FOR PROD API
    
    			// Get the response body as a string
    			pageContentString := string(contents)
    
    			// Prevent the closure of the opener
    			pageContentString = strings.ReplaceAll(pageContentString, "this.window.opener.location.href = url;", "this.window.location.href = url;")
    
    			// fmt.Println(pageContentString)
    
    			// Convert string to byte for response writting
    			newPageContentByte := []byte(pageContentString)
    
    
    Yoan VALLET's avatar
    Yoan VALLET committed
    			if response.StatusCode >= 200 && response.StatusCode <= 299 {
    
    				w.Write(newPageContentByte)
    
    Yoan VALLET's avatar
    Yoan VALLET committed
    			} else {
    				http.Error(w, http.StatusText(response.StatusCode), response.StatusCode)
    
    	// To be change by "/redirect" once enedis will have change the redirect uri
    	mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
    
    		fmt.Println("*******************")
    
    		fmt.Println(time.Now().Format("2006-01-02 15:04:05"), "- New redirect request")
    		query := r.URL.Query()
    		fmt.Println(query)
    
    		code := query.Get("code")
    
    		req_state := query.Get("state")
    
    
    		splitIndex := strings.Index(req_state, "-")
    		if splitIndex == -1 {
    			fmt.Println("No host found")
    		}
    		state := string([]byte(req_state[0:splitIndex]))
    		host := string([]byte(req_state[splitIndex+1:len(req_state)]))
    
    		usagePointId := query.Get("usage_point_id")
    
    
    		redir := host + "?code=" + code + "&state="+ state +"&usage_point_id=" + usagePointId
    		fmt.Println(time.Now().Format("2006-01-02 15:04:05"), "- Redirect to -", redir)
    
    		http.Redirect(w, r, redir, 302)
    	})
    
    
    	mux.HandleFunc("/token", func(w http.ResponseWriter, r *http.Request) {
    
    		fmt.Println("*******************")
    
            fmt.Println(time.Now().Format("2006-01-02 15:04:05"), "- New token request")
    
    		query := r.URL.Query()
    		fmt.Println(query)
    
    		fmt.Println(r.Body)
    
    
    		clientId := query.Get("client_id")
    		clientSecret := query.Get("client_secret")
    		code := query.Get("code")
    		grantType := query.Get("grant_type")
    
    		refreshToken := query.Get("refresh_token")
    
    
    		tokenUrl := "https://gw.hml.api.enedis.fr/v1/oauth2/token"
    
    		data := url.Values{}
    		data.Set("client_id", clientId)
    		data.Set("client_secret", clientSecret)
    		data.Set("code", code)
    		data.Set("grant_type", grantType)
    
    		if refreshToken != "" {
    			data.Set("refresh_token", refreshToken)
    			data.Set("grant_type", "refresh_token")
    		}
    
    		
    		client := &http.Client{}
    
    		req, _ := http.NewRequest("POST", tokenUrl, strings.NewReader(data.Encode()))
    		req.Header.Add("Content-Type", "application/x-www-form-urlencoded")
    
    		fmt.Println(time.Now().Format("2006-01-02 15:04:05"), "- Send request to token endpoint", tokenUrl)
    
    		response, err := client.Do(req)
    
    		fmt.Println(time.Now().Format("2006-01-02 15:04:05"), "- Endpoint response with status", response.Status)
    
    		if err != nil {
    			fmt.Println(err)
    		} else {
    			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)
    
    Nicolas PERNOUD's avatar
    Nicolas PERNOUD committed
    	http.ListenAndServe(":"+strconv.Itoa(*httpPort), mux)
    }