From 0831ea6088ad1116e37acaecb58870f73da0103d Mon Sep 17 00:00:00 2001 From: Pierre-Olivier Mercier Date: Wed, 8 Jun 2022 00:09:49 +0200 Subject: [PATCH] remote-challenge-sync-airbus: WIP --- remote/challenge-sync-airbus/api.go | 64 ++++++++++++++++++++------- remote/challenge-sync-airbus/main.go | 12 +++-- remote/challenge-sync-airbus/treat.go | 13 ++++-- 3 files changed, 66 insertions(+), 23 deletions(-) diff --git a/remote/challenge-sync-airbus/api.go b/remote/challenge-sync-airbus/api.go index d2bdd0cf..dd0dbd2e 100644 --- a/remote/challenge-sync-airbus/api.go +++ b/remote/challenge-sync-airbus/api.go @@ -2,6 +2,7 @@ package main import ( "bytes" + "crypto/tls" "encoding/json" "fmt" "io" @@ -10,17 +11,23 @@ import ( ) type AirbusAPI struct { - BaseURL string - Token string - SessionID int64 + BaseURL string + Token string + SessionID int64 + SessionUUID string } func (a *AirbusAPI) request(method, endpoint string, data []byte, out interface{}) error { - var reader *bytes.Reader + var req *http.Request + var err error + + http.DefaultTransport.(*http.Transport).TLSClientConfig = &tls.Config{InsecureSkipVerify: true} + if data != nil { - reader = bytes.NewReader(data) + req, err = http.NewRequest(method, a.BaseURL+endpoint, bytes.NewReader(data)) + } else { + req, err = http.NewRequest(method, a.BaseURL+endpoint, nil) } - req, err := http.NewRequest(method, a.BaseURL+endpoint, reader) if err != nil { return fmt.Errorf("unable to prepare request to %q: %w", endpoint, err) } @@ -61,12 +68,18 @@ func (aui AirbusUserId) String() string { return strconv.FormatInt(int64(aui), 10) } -type AirbusUser struct { - Id AirbusUserId `json:"id"` - Name string `json:"name"` +type AirbusUserData struct { + Data []AirbusUser `json:"data"` } -func (a *AirbusAPI) GetUsers() (users []AirbusUser, err error) { +type AirbusUser struct { + Id AirbusUserId `json:"id"` + Email string `json:"email"` + Name string `json:"name"` + Nickname string `json:"nickname"` +} + +func (a *AirbusAPI) GetUsers() (users AirbusUserData, err error) { err = a.request("GET", fmt.Sprintf("/sessions/%d/users", a.SessionID), nil, &users) return } @@ -77,7 +90,7 @@ func (a *AirbusAPI) GetUserFromName(name string) (*AirbusUser, error) { return nil, fmt.Errorf("unable to retrieve users list: %w", err) } - for _, u := range users { + for _, u := range users.Data { if u.Name == name { return &u, nil } @@ -86,19 +99,38 @@ func (a *AirbusAPI) GetUserFromName(name string) (*AirbusUser, error) { return nil, fmt.Errorf("unable to find user %q", name) } +func (a *AirbusAPI) GetUserFromEmail(email string) (*AirbusUser, error) { + users, err := a.GetUsers() + if err != nil { + return nil, fmt.Errorf("unable to retrieve users list: %w", err) + } + + for _, u := range users.Data { + if u.Email == email { + return &u, nil + } + } + + return nil, fmt.Errorf("unable to find user with email %q", email) +} + type AirbusChallengeId int64 func (aci AirbusChallengeId) String() string { return strconv.FormatInt(int64(aci), 10) } +type AirbusChallengeData struct { + Data []AirbusChallenge `json:"data"` +} + type AirbusChallenge struct { Id AirbusChallengeId `json:"id"` Name string `json:"name"` } -func (a *AirbusAPI) GetChallenges() (challenges []AirbusChallenge, err error) { - err = a.request("GET", fmt.Sprintf("/sessions/%d/challenges", a.SessionID), nil, &challenges) +func (a *AirbusAPI) GetChallenges() (challenges AirbusChallengeData, err error) { + err = a.request("GET", fmt.Sprintf("/v1/sessions/%d/challenges", a.SessionID), nil, &challenges) return } @@ -108,7 +140,7 @@ func (a *AirbusAPI) GetChallengeFromName(name string) (*AirbusChallenge, error) return nil, fmt.Errorf("unable to retrieve challenges list: %w", err) } - for _, c := range challenges { + for _, c := range challenges.Data { if c.Name == name { return &c, nil } @@ -118,7 +150,7 @@ func (a *AirbusAPI) GetChallengeFromName(name string) (*AirbusChallenge, error) } func (a *AirbusAPI) ValidateChallengeFromUser(userId AirbusUserId, challengeId AirbusChallengeId) (err error) { - err = a.request("GET", fmt.Sprintf("/sessions/%d/%s/%s/validate", a.SessionID, challengeId.String(), userId.String()), nil, nil) + err = a.request("GET", fmt.Sprintf("/v1/sessions/%d/%s/%s/validate", a.SessionID, challengeId.String(), userId.String()), nil, nil) return } @@ -140,7 +172,7 @@ func (a *AirbusAPI) AwardUser(userId AirbusUserId, value int64, message string) return fmt.Errorf("unable to marshall JSON from awards struct: %w", err) } - err = a.request("POST", fmt.Sprintf("/sessions/%d/awards", a.SessionID), j, nil) + err = a.request("POST", fmt.Sprintf("/v1/sessions/%d/awards", a.SessionID), j, nil) return } diff --git a/remote/challenge-sync-airbus/main.go b/remote/challenge-sync-airbus/main.go index f65c4fe8..82948061 100644 --- a/remote/challenge-sync-airbus/main.go +++ b/remote/challenge-sync-airbus/main.go @@ -10,6 +10,7 @@ import ( "path/filepath" "strconv" "syscall" + "time" "gopkg.in/fsnotify.v1" ) @@ -30,7 +31,7 @@ func main() { flag.Parse() api := AirbusAPI{ - BaseURL: "https://portal.european-cybercup.lan/api/v1", + BaseURL: "https://portal.european-cybercup.lan/api", } if v, exists := os.LookupEnv("AIRBUS_BASEURL"); exists { @@ -46,6 +47,9 @@ func main() { log.Fatal("AIRBUS_SESSIONID is invalid: ", err.Error()) } } + if v, exists := os.LookupEnv("AIRBUS_SESSIONUUID"); exists { + api.SessionUUID = v + } log.SetPrefix("[challenge-sync-airbus] ") @@ -79,7 +83,7 @@ func main() { if !skipInitialSync { // Iterate over teams scores - err = filepath.WalkDir(TeamsDir, w.WalkScore) + err = filepath.WalkDir(TeamsDir, w.WalkScoreSync) if err != nil { log.Printf("Something goes wrong during walking") } @@ -112,7 +116,7 @@ func main() { interrupt3 := make(chan os.Signal, 1) signal.Notify(interrupt3, syscall.SIGUSR2) - c := time.NewTicker(5 * time.Second) + ticker := time.NewTicker(5 * time.Second) watchedNotify := fsnotify.Create @@ -136,7 +140,7 @@ func main() { case <-interrupt2: log.Println("SIGUSR1 received, resynching all teams") // Iterate over teams scores - err = filepath.WalkDir(TeamsDir, w.WalkScore) + err = filepath.WalkDir(TeamsDir, w.WalkScoreSync) if err != nil { log.Printf("Something goes wrong during walking") } diff --git a/remote/challenge-sync-airbus/treat.go b/remote/challenge-sync-airbus/treat.go index df01b87e..f248055c 100644 --- a/remote/challenge-sync-airbus/treat.go +++ b/remote/challenge-sync-airbus/treat.go @@ -38,11 +38,11 @@ func (w *Walker) treat(path string) { airbusTeamId := NewAirbusUserId(w.Teams[fmt.Sprintf("%d", teammy.Id)].ExternalId) // Treat score grid - err = w.TreatScoreGrid(path, airbusTeamId) + /*err = w.TreatScoreGrid(path, airbusTeamId) if err != nil { log.Println("Unable to treat score grid:", err) return - } + }*/ // Balance scores err = w.BalanceScore(int64(float64(teammy.Points)*w.Coeff), airbusTeamId) @@ -53,6 +53,13 @@ func (w *Walker) treat(path string) { } } +func (w *Walker) WalkScoreSync(path string, d os.DirEntry, err error) error { + if filepath.Base(path) == "scores.json" { + w.treat(path) + } + return nil +} + func (w *Walker) WalkScore(path string, d os.DirEntry, err error) error { if filepath.Base(path) == "scores.json" { go w.treat(path) @@ -104,7 +111,7 @@ func (w *Walker) BalanceScore(score int64, airbusTeamId AirbusUserId) error { fmt.Errorf("unable to retrieve current stats: %w", err) } - my_session := stats.Data.GetSession(AirbusUUID(w.API.SessionID)) + my_session := stats.Data.GetSession(AirbusUUID(w.API.SessionUUID)) if my_session == nil { return fmt.Errorf("session not found") }