Skip to content
Snippets Groups Projects
Commit 999780b7 authored by Bastien DUMONT's avatar Bastien DUMONT :angel:
Browse files

feat(grdf): fetch access token every two hours

parent aa9eb32c
No related branches found
No related tags found
2 merge requests!108chore(release): Ecolyo 3.1.0,!104feat(grdf): fetch access token every two hours
......@@ -20,4 +20,8 @@ DATABASE_USER
DATABASE_PASSWORD
DATABASE_NAME
# rename this to backoffice token ?
SGE_API_TOKEN
GRDF_CLIENT_ID
GRDF_CLIENT_SECRET
......@@ -14,7 +14,7 @@ services:
variables:
DOCKER_DRIVER: overlay2
DOCKER_TLS_CERTDIR: ""
DOCKER_TLS_CERTDIR: ''
GIT_STRATEGY: clone
GIT_DEPTH: 0
......@@ -89,10 +89,10 @@ sonarqube:
- dev
image: ${CI_DEPENDENCY_PROXY_DIRECT_GROUP_IMAGE_PREFIX}/sonarsource/sonar-scanner-cli:4
variables:
SONAR_USER_HOME: "${CI_PROJECT_DIR}/.sonar" # Defines the location of the analysis task cache
GIT_DEPTH: "0" # T
SONAR_USER_HOME: '${CI_PROJECT_DIR}/.sonar' # Defines the location of the analysis task cache
GIT_DEPTH: '0' # T
cache:
key: "${CI_JOB_NAME}"
key: '${CI_JOB_NAME}'
paths:
- .sonar/cache
script:
......@@ -114,10 +114,10 @@ sonarqube-mr:
- merge_requests
image: ${CI_DEPENDENCY_PROXY_DIRECT_GROUP_IMAGE_PREFIX}/sonarsource/sonar-scanner-cli:4
variables:
SONAR_USER_HOME: "${CI_PROJECT_DIR}/.sonar" # Defines the location of the analysis task cache
GIT_DEPTH: "0" # T
SONAR_USER_HOME: '${CI_PROJECT_DIR}/.sonar' # Defines the location of the analysis task cache
GIT_DEPTH: '0' # T
cache:
key: "${CI_JOB_NAME}"
key: '${CI_JOB_NAME}'
paths:
- .sonar/cache
script:
......@@ -142,6 +142,8 @@ deploy_rec:
- sed -i "s/{{CLIENT_ID}}/$REC_CLIENT_ID/" ./k8s/secrets/ecolyo-agent-server-config.yml
- sed -i "s/{{CLIENT_SECRET}}/$REC_CLIENT_SECRET/" ./k8s/secrets/ecolyo-agent-server-config.yml
- sed -i "s/{{SGE_API_TOKEN}}/$REC_SGE_API_TOKEN/" ./k8s/secrets/ecolyo-agent-server-config.yml
- sed -i "s/{{GRDF_CLIENT_ID}}/$GRDF_CLIENT_ID/" ./k8s/secrets/ecolyo-agent-server-config.yml
- sed -i "s/{{GRDF_CLIENT_SECRET}}/$GRDF_CLIENT_SECRET/" ./k8s/secrets/ecolyo-agent-server-config.yml
- sed -i "s/{{HOSTNAME}}/ecolyo-agent-rec.apps.grandlyon.com/g" ./k8s/secrets/ecolyo-agent-server-config.yml
- sed -i "s+{{AUTH_URL}}+https://connexion-rec.grandlyon.fr/IdPOAuth2/authorize/oidc-rec-2+" ./k8s/secrets/ecolyo-agent-server-config.yml
- sed -i "s+{{USERINFO_URL}}+https://connexion-rec.grandlyon.fr/IdPOAuth2/userinfo/oidc-rec-2+" ./k8s/secrets/ecolyo-agent-server-config.yml
......@@ -172,6 +174,8 @@ deploy_prod:
- sed -i "s/{{CLIENT_ID}}/$PROD_CLIENT_ID/" ./k8s/secrets/ecolyo-agent-server-config.yml
- sed -i "s/{{CLIENT_SECRET}}/$PROD_CLIENT_SECRET/" ./k8s/secrets/ecolyo-agent-server-config.yml
- sed -i "s/{{SGE_API_TOKEN}}/$PROD_SGE_API_TOKEN/" ./k8s/secrets/ecolyo-agent-server-config.yml
- sed -i "s/{{GRDF_CLIENT_ID}}/$GRDF_CLIENT_ID/" ./k8s/secrets/ecolyo-agent-server-config.yml
- sed -i "s/{{GRDF_CLIENT_SECRET}}/$GRDF_CLIENT_SECRET/" ./k8s/secrets/ecolyo-agent-server-config.yml
- sed -i "s/{{HOSTNAME}}/ecolyo-agent.apps.grandlyon.com/g" ./k8s/secrets/ecolyo-agent-server-config.yml
- sed -i "s+{{AUTH_URL}}+https://connexion.grandlyon.fr/IdPOAuth2/authorize/oidc-2+" ./k8s/secrets/ecolyo-agent-server-config.yml
- sed -i "s+{{USERINFO_URL}}+https://connexion.grandlyon.fr/IdPOAuth2/userinfo/oidc-2+" ./k8s/secrets/ecolyo-agent-server-config.yml
......
......@@ -20,6 +20,7 @@
},
"peacock.color": "#32f0ff",
"cSpell.words": [
"adict",
"admininfo",
"animatorinfo",
"backoffice",
......
package models
import (
"encoding/json"
"fmt"
"io"
"log"
"net/http"
"net/url"
"os"
"strings"
"time"
"forge.grandlyon.com/web-et-numerique/factory/llle_project/backoffice-server/internal/constants"
"gorm.io/gorm"
)
type GrdfAccessToken struct {
AccessToken string `json:"access_token"`
FetchedAt time.Time `json:"fetched_at"`
}
// Fetches GRDF auth API for an access token and save it in DB
func FetchGRDFAuthAPI() {
log.Println("| Calling GRDF auth API")
dh := NewDataHandler()
reqBody := url.Values{
"scope": {"/adict/v2"},
"grant_type": {"client_credentials"},
"client_id": {os.Getenv("GRDF_CLIENT_ID")},
"client_secret": {os.Getenv("GRDF_CLIENT_SECRET")},
}
client := &http.Client{}
req, err := http.NewRequest(http.MethodPost, "https://adict-connexion.grdf.fr/oauth2/aus5y2ta2uEHjCWIR417/v1/token", strings.NewReader(reqBody.Encode()))
if err != nil {
fmt.Println("Error creating request:", err)
return
}
req.Header.Add("Content-Type", "application/x-www-form-urlencoded")
resp, err := client.Do(req)
if err != nil {
fmt.Println("Error sending request:", err)
return
}
defer resp.Body.Close()
body, err := io.ReadAll(resp.Body)
if err != nil {
fmt.Println("Error reading response body:", err)
return
}
var result map[string]interface{}
if err := json.Unmarshal(body, &result); err != nil {
fmt.Println("Error unmarshaling JSON:", err)
return
}
accessToken, ok := result["access_token"].(string)
if !ok {
fmt.Println("Access token not found in response")
return
}
dh.WriteAccessToken(accessToken)
}
// Writes a new access token to the database
func (dh *DataHandler) WriteAccessToken(token string) {
result := dh.sqlClient.Session(&gorm.Session{AllowGlobalUpdate: true}).Model(&GrdfAccessToken{}).Updates(&GrdfAccessToken{
AccessToken: token,
FetchedAt: time.Now(),
})
if result.Error != nil {
log.Println("| Error updating GRDF access token")
log.Println(result.Error)
} else {
log.Println("| New GRDF access token written")
}
}
func (dh *DataHandler) GetGrdfAccessToken(w http.ResponseWriter, r *http.Request) {
var token GrdfAccessToken
err := dh.sqlClient.First(&token).Error
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
return
}
w.Header().Set(constants.ContentType, constants.Json)
json.NewEncoder(w).Encode(token)
log.Printf("| get partnersInfo | %v", r.RemoteAddr)
}
......@@ -50,6 +50,7 @@ func NewDataHandler() *DataHandler {
sqlClient.AutoMigrate(&Price{})
sqlClient.AutoMigrate(&SgeConsent{})
sqlClient.AutoMigrate(&GrdfConsent{})
sqlClient.AutoMigrate(&GrdfAccessToken{})
// Check if partners info already exists
var partnersInfo PartnersInfo
......@@ -78,5 +79,16 @@ func NewDataHandler() *DataHandler {
})
}
// check if access token already exists
var accessToken GrdfAccessToken
err = sqlClient.First(&accessToken).Error
if errors.Is(err, gorm.ErrRecordNotFound) {
// Create default access token
sqlClient.Create(&GrdfAccessToken{
AccessToken: "",
FetchedAt: time.Now(),
})
}
return &DataHandler{sqlClient: sqlClient}
}
......@@ -64,5 +64,4 @@ func (dh *DataHandler) SavePartnersInfo(w http.ResponseWriter, r *http.Request)
w.Header().Set(constants.ContentType, constants.Json)
json.NewEncoder(w).Encode(partnersInfo)
log.Printf("| updated partnersInfo | %v", r.RemoteAddr)
}
......@@ -90,6 +90,7 @@ func CreateRootMux() RootMux {
r.Post("/consent", dh.PostGrdfConsent)
r.Get("/consent/{id}", dh.GetGrdfConsentById)
r.Delete("/consent/{id}", dh.DeleteGrdfConsentById)
r.Get("/access-token", dh.GetGrdfAccessToken)
})
r.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { /** handles Oauth2 redirection */ })
......
......@@ -60,7 +60,7 @@ func newManager(keyfile string, debug bool) manager {
}
}
// Token represents a token containting data
// Token represents a token containing data
type Token struct {
ExpiresAt int64
IssuedAt int64 `json:"iat,omitempty"`
......
......@@ -20,4 +20,6 @@ stringData:
SGE_API_TOKEN: {{SGE_API_TOKEN}}
TOKEN_URL: {{TOKEN_URL}}
USERINFO_URL: {{USERINFO_URL}}
GRDF_CLIENT_ID: {{GRDF_CLIENT_ID}}
GRDF_CLIENT_SECRET: {{GRDF_CLIENT_SECRET}}
type: Opaque
......@@ -4,11 +4,13 @@ import (
"fmt"
"net/http"
"strconv"
"time"
"log"
"forge.grandlyon.com/web-et-numerique/factory/llle_project/backoffice-server/internal/common"
"forge.grandlyon.com/web-et-numerique/factory/llle_project/backoffice-server/internal/mocks"
"forge.grandlyon.com/web-et-numerique/factory/llle_project/backoffice-server/internal/models"
"forge.grandlyon.com/web-et-numerique/factory/llle_project/backoffice-server/internal/rootmux"
"forge.grandlyon.com/web-et-numerique/factory/llle_project/backoffice-server/internal/tokens"
)
......@@ -37,6 +39,24 @@ func main() {
mockOAuth2Port := ":8090"
go http.ListenAndServe(mockOAuth2Port, mocks.CreateMockOAuth2())
fmt.Println("Mock OAuth2 server Listening on: http://localhost" + mockOAuth2Port)
// Call the function immediately when the server starts
models.FetchGRDFAuthAPI()
// then call GRDF auth api every two hours
ticker := time.NewTicker(time.Hour * 2)
quit := make(chan struct{})
go func() {
for {
select {
case <-ticker.C:
models.FetchGRDFAuthAPI()
case <-quit:
ticker.Stop()
return
}
}
}()
}
// Serve locally with https
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment