From c2f2910a838e8a359bba6c2f3c872b2f884db697 Mon Sep 17 00:00:00 2001 From: Pierre-Olivier Mercier Date: Wed, 14 Sep 2022 00:19:43 +0200 Subject: [PATCH] Fetch PGP keys from GitLab CRI as fallback --- gitlab.go | 82 ++++++++++++++++++++++++++++++++++++++++++++++++++++--- keys.go | 15 ++++++++-- 2 files changed, 90 insertions(+), 7 deletions(-) diff --git a/gitlab.go b/gitlab.go index 54f3db6..9afeec5 100644 --- a/gitlab.go +++ b/gitlab.go @@ -1,13 +1,16 @@ package main import ( + "bytes" "context" "encoding/hex" "encoding/json" "flag" "fmt" + "io/ioutil" "log" "net/http" + "net/url" "os" "time" @@ -157,13 +160,18 @@ type GitLabRepositoryNamespace struct { Kind string } -type GitLabRepositoryUser struct { +type GitLabUser struct { ID int Username string Name string State string } +type GitLabUserKey struct { + ID int + Key string +} + type GitLabRepository struct { ID int Description string @@ -177,9 +185,9 @@ type GitLabRepository struct { AvatarURL string `json:"avatar_url"` LastActivityAt time.Time `json:"last_activity_at,omitempty"` Namespace GitLabRepositoryNamespace - Visibility string `json:"visibility,omitempty"` - Owner *GitLabRepositoryUser `json:"owner,omitempty"` - ForkedFromProject *GitLabRepository `json:"forked_from_project,omitempty"` + Visibility string `json:"visibility,omitempty"` + Owner *GitLabUser `json:"owner,omitempty"` + ForkedFromProject *GitLabRepository `json:"forked_from_project,omitempty"` } func GitLab_GetMyRepositories(c *gin.Context) { @@ -251,3 +259,69 @@ func GitLab_getUsersRepositories(c context.Context, u *User) ([]*GitLabRepositor return repositories, err } + +func GitLab_getUserId(c context.Context, u *User) (int, error) { + client := gitlaboauth2Config.Client(c, gitlabToken()) + + val := url.Values{} + val.Set("username", u.Login) + + req, err := http.NewRequest("GET", gitlabBaseURL+fmt.Sprintf("/api/v4/users?%s", val.Encode()), nil) + if err != nil { + return 0, err + } + + resp, err := client.Do(req) + if err != nil { + return 0, err + } + + if resp.StatusCode != http.StatusOK { + return 0, fmt.Errorf("Bad status code from the API") + } + + var users []*GitLabUser + err = json.NewDecoder(resp.Body).Decode(&users) + + if len(users) == 0 { + return 0, fmt.Errorf("Login not found in GitLab") + } + + return users[0].ID, nil +} + +func GitLab_getUserPGPKeys(c context.Context, u *User) ([]byte, error) { + userid, err := GitLab_getUserId(c, u) + if err != nil { + return nil, err + } + + client := gitlaboauth2Config.Client(c, gitlabToken()) + + req, err := http.NewRequest("GET", gitlabBaseURL+fmt.Sprintf("/api/v4/users/%d/gpg_keys", userid), nil) + if err != nil { + return nil, err + } + + resp, err := client.Do(req) + if err != nil { + return nil, err + } + + if resp.StatusCode != http.StatusOK { + rep, _ := ioutil.ReadAll(resp.Body) + log.Printf("%d %s", resp.StatusCode, rep) + return nil, fmt.Errorf("Bad status code from the API") + } + + var keys []*GitLabUserKey + err = json.NewDecoder(resp.Body).Decode(&keys) + + var b bytes.Buffer + for _, k := range keys { + b.Write([]byte(k.Key)) + b.Write([]byte{'\n'}) + } + + return b.Bytes(), nil +} diff --git a/keys.go b/keys.go index 77f9321..e0cf925 100644 --- a/keys.go +++ b/keys.go @@ -33,9 +33,18 @@ func declareAPIKeysRoutes(router *gin.RouterGroup) { } var ret []byte - for _, key := range keys { - if key.Type == "pgp" { - ret = append(ret, []byte(key.Content)...) + if len(keys) == 0 { + ret, err = GitLab_getUserPGPKeys(c.Request.Context(), u) + if err != nil { + log.Println("Unable to GitLab_getUserPGPKeys:", err) + c.AbortWithStatusJSON(http.StatusInternalServerError, gin.H{"errmsg": "Unable to retrieve your keys from GitLab. Please try again in a few moment or add them directly on /keys page on this website."}) + return + } + } else { + for _, key := range keys { + if key.Type == "pgp" { + ret = append(ret, []byte(key.Content)...) + } } }