213 lines
6 KiB
Go
213 lines
6 KiB
Go
// Copyright Earl Warren <contact@earl-warren.org>
|
|
// Copyright Loïc Dachary <loic@dachary.org>
|
|
// SPDX-License-Identifier: MIT
|
|
|
|
package gitlab
|
|
|
|
import (
|
|
"context"
|
|
"encoding/json"
|
|
"fmt"
|
|
"io"
|
|
"net/http"
|
|
|
|
gitlab_options "code.forgejo.org/f3/gof3/v3/forges/gitlab/options"
|
|
"code.forgejo.org/f3/gof3/v3/kind"
|
|
f3_tree "code.forgejo.org/f3/gof3/v3/tree/f3"
|
|
"code.forgejo.org/f3/gof3/v3/tree/generic"
|
|
|
|
"github.com/hashicorp/go-version"
|
|
"gitlab.com/gitlab-org/api/client-go"
|
|
)
|
|
|
|
type treeDriver struct {
|
|
generic.NullTreeDriver
|
|
|
|
user *gitlab.User
|
|
client *gitlab.Client
|
|
options *gitlab_options.Options
|
|
version *version.Version
|
|
}
|
|
|
|
func (o *treeDriver) GetClient() *gitlab.Client {
|
|
return o.client
|
|
}
|
|
|
|
func (o *treeDriver) GetIsAdmin() bool {
|
|
return o.user.IsAdmin
|
|
}
|
|
|
|
func (o *treeDriver) SetIsAdmin() {
|
|
user, _, err := o.client.Users.CurrentUser()
|
|
if err != nil {
|
|
panic(fmt.Errorf("Failed to get information about the user for: %s. Error: %v", o.options.GetURL(), err))
|
|
}
|
|
o.user = user
|
|
o.options.SetUsername(user.Username)
|
|
}
|
|
|
|
var (
|
|
ForgejoVersion700 = version.Must(version.NewVersion("7.0.0")) // 1.22
|
|
ForgejoVersion600 = version.Must(version.NewVersion("6.0.0")) // 1.21
|
|
ForgejoVersion500 = version.Must(version.NewVersion("5.0.0")) // 1.20.1
|
|
ForgejoVersion501 = version.Must(version.NewVersion("5.0.1")) // 1.20.2
|
|
ForgejoVersion502 = version.Must(version.NewVersion("5.0.2")) // 1.20.3
|
|
ForgejoVersion503 = version.Must(version.NewVersion("5.0.3")) // 1.20.4
|
|
ForgejoVersion504 = version.Must(version.NewVersion("5.0.4")) // 1.20.5
|
|
ForgejoVersion4 = version.Must(version.NewVersion("4.0.0")) // 1.19
|
|
|
|
ForgejoVersionNotFound = version.Must(version.NewVersion("1.0.0"))
|
|
)
|
|
|
|
func (o *treeDriver) GetVersion() *version.Version {
|
|
o.SetVersion()
|
|
return o.version
|
|
}
|
|
|
|
func (o *treeDriver) SetVersion() {
|
|
if o.version != nil {
|
|
return
|
|
}
|
|
client := &http.Client{}
|
|
url := fmt.Sprintf("%s/api/forgejo/v1/version", o.options.GetURL())
|
|
req, err := http.NewRequest("GET", url, nil)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
resp, err := client.Do(req)
|
|
if err != nil {
|
|
panic(fmt.Errorf("while getting %s %w", url, err))
|
|
}
|
|
|
|
switch resp.StatusCode {
|
|
case http.StatusNotFound:
|
|
o.version = ForgejoVersionNotFound
|
|
case http.StatusOK:
|
|
v := struct{ Version string }{}
|
|
body, err := io.ReadAll(resp.Body)
|
|
if err != nil {
|
|
panic(fmt.Errorf("reading response body %+v %w", resp, err))
|
|
}
|
|
if err := json.Unmarshal(body, &v); err != nil {
|
|
panic(fmt.Errorf("decoding JSON response from %s %s %w", url, string(body), err))
|
|
}
|
|
o.version = version.Must(version.NewVersion(v.Version))
|
|
default:
|
|
panic(fmt.Errorf("unexpected status code fetching %s %d %v", url, resp.StatusCode, resp))
|
|
}
|
|
}
|
|
|
|
func (o *treeDriver) maybeSudo(uid interface{}) []gitlab.RequestOptionFunc {
|
|
if !o.GetIsAdmin() {
|
|
return []gitlab.RequestOptionFunc{}
|
|
}
|
|
if name, ok := uid.(string); ok && name == o.options.GetUsername() {
|
|
return []gitlab.RequestOptionFunc{}
|
|
}
|
|
return []gitlab.RequestOptionFunc{
|
|
gitlab.WithSudo(uid),
|
|
}
|
|
}
|
|
|
|
func (o *treeDriver) Init() {
|
|
o.NullTreeDriver.Init()
|
|
|
|
var err error
|
|
var client *gitlab.Client
|
|
if o.options.GetToken() != "" {
|
|
o.Debug("Connecting to %s with token", o.options.GetURL())
|
|
client, err = gitlab.NewClient(o.options.GetToken(), gitlab.WithBaseURL(o.options.GetURL()), gitlab.WithHTTPClient(o.options.GetNewMigrationHTTPClient()()))
|
|
} else {
|
|
o.Debug("Connecting to %s as user %s", o.options.GetURL(), o.options.GetUsername())
|
|
client, err = gitlab.NewBasicAuthClient(o.options.GetUsername(), o.options.GetPassword(), gitlab.WithBaseURL(o.options.GetURL()), gitlab.WithHTTPClient(o.options.GetNewMigrationHTTPClient()()))
|
|
}
|
|
if err != nil {
|
|
panic(fmt.Errorf("Failed to create Forgejo client for: %s. Error: %v", o.options.GetURL(), err))
|
|
}
|
|
o.client = client
|
|
|
|
o.SetIsAdmin()
|
|
if o.GetIsAdmin() {
|
|
o.Debug("Connected as admin")
|
|
} else {
|
|
o.Debug("Connected as regular user")
|
|
}
|
|
}
|
|
|
|
func newTreeDriver(tree generic.TreeInterface, anyOptions any) generic.TreeDriverInterface {
|
|
driver := &treeDriver{
|
|
options: anyOptions.(*gitlab_options.Options),
|
|
}
|
|
driver.SetTree(tree)
|
|
driver.Init()
|
|
return driver
|
|
}
|
|
|
|
func (o *treeDriver) Factory(ctx context.Context, k kind.Kind) generic.NodeDriverInterface {
|
|
switch k {
|
|
case f3_tree.KindForge:
|
|
return newForge()
|
|
case f3_tree.KindOrganizations:
|
|
return newOrganizations()
|
|
case f3_tree.KindOrganization:
|
|
return newOrganization()
|
|
case f3_tree.KindUsers:
|
|
return newUsers()
|
|
case f3_tree.KindUser:
|
|
return newUser()
|
|
case f3_tree.KindProjects:
|
|
return newProjects()
|
|
// case f3_tree.KindProject:
|
|
// return newProject()
|
|
// case f3_tree.KindIssues:
|
|
// return newIssues()
|
|
// case f3_tree.KindIssue:
|
|
// return newIssue()
|
|
// case f3_tree.KindComments:
|
|
// return newComments()
|
|
// case f3_tree.KindComment:
|
|
// return newComment()
|
|
// case f3_tree.KindAssets:
|
|
// return newAssets()
|
|
// case f3_tree.KindAsset:
|
|
// return newAsset()
|
|
// case f3_tree.KindLabels:
|
|
// return newLabels()
|
|
// case f3_tree.KindLabel:
|
|
// return newLabel()
|
|
// case f3_tree.KindReactions:
|
|
// return newReactions()
|
|
// case f3_tree.KindReaction:
|
|
// return newReaction()
|
|
// case f3_tree.KindReviews:
|
|
// return newReviews()
|
|
// case f3_tree.KindReview:
|
|
// return newReview()
|
|
// case f3_tree.KindReviewComments:
|
|
// return newReviewComments()
|
|
// case f3_tree.KindReviewComment:
|
|
// return newReviewComment()
|
|
// case f3_tree.KindMilestones:
|
|
// return newMilestones()
|
|
// case f3_tree.KindMilestone:
|
|
// return newMilestone()
|
|
// case f3_tree.KindPullRequests:
|
|
// return newPullRequests()
|
|
// case f3_tree.KindPullRequest:
|
|
// return newPullRequest()
|
|
// case f3_tree.KindReleases:
|
|
// return newReleases()
|
|
// case f3_tree.KindRelease:
|
|
// return newRelease()
|
|
case f3_tree.KindTopics:
|
|
return newTopics()
|
|
// case f3_tree.KindRepositories:
|
|
// return newRepositories()
|
|
// case f3_tree.KindRepository:
|
|
// return newRepository(ctx)
|
|
case kind.KindRoot:
|
|
return newRoot(o.GetTree().(f3_tree.TreeInterface).NewFormat(k))
|
|
default:
|
|
panic(fmt.Errorf("unexpected kind %s", k))
|
|
}
|
|
}
|