From 26b98417ad460bae64dd45fecc9e4f93fc59ebef Mon Sep 17 00:00:00 2001 From: 6543 <6543@obermui.de> Date: Tue, 23 Mar 2021 11:10:32 +0100 Subject: [PATCH] [Vendor] update gitea-sdk v0.14.0 (#15103) (#15107) * upgraded code.gitea.io/sdk/gitea v0.13.2 => v0.14.0 * rm workaround --- go.mod | 2 +- go.sum | 4 +- modules/migrations/gitea_downloader.go | 22 --- vendor/code.gitea.io/sdk/gitea/admin_cron.go | 3 + vendor/code.gitea.io/sdk/gitea/admin_org.go | 3 + vendor/code.gitea.io/sdk/gitea/admin_repo.go | 3 + vendor/code.gitea.io/sdk/gitea/admin_user.go | 42 +++-- vendor/code.gitea.io/sdk/gitea/attachment.go | 15 ++ vendor/code.gitea.io/sdk/gitea/client.go | 168 +++++++++++++----- vendor/code.gitea.io/sdk/gitea/fork.go | 6 + vendor/code.gitea.io/sdk/gitea/git_blob.go | 3 + vendor/code.gitea.io/sdk/gitea/git_hook.go | 12 ++ vendor/code.gitea.io/sdk/gitea/go.mod | 2 +- vendor/code.gitea.io/sdk/gitea/go.sum | 2 + vendor/code.gitea.io/sdk/gitea/helper.go | 20 +++ vendor/code.gitea.io/sdk/gitea/hook.go | 30 ++++ vendor/code.gitea.io/sdk/gitea/issue.go | 59 ++++-- .../code.gitea.io/sdk/gitea/issue_comment.go | 18 ++ vendor/code.gitea.io/sdk/gitea/issue_label.go | 30 ++++ .../sdk/gitea/issue_milestone.go | 24 +++ .../code.gitea.io/sdk/gitea/issue_reaction.go | 12 +- .../sdk/gitea/issue_stopwatch.go | 18 +- .../sdk/gitea/issue_subscription.go | 9 +- .../sdk/gitea/issue_tracked_time.go | 75 ++++---- .../code.gitea.io/sdk/gitea/notifications.go | 14 +- vendor/code.gitea.io/sdk/gitea/org.go | 12 ++ vendor/code.gitea.io/sdk/gitea/org_member.go | 32 +++- vendor/code.gitea.io/sdk/gitea/org_team.go | 21 +++ vendor/code.gitea.io/sdk/gitea/pull.go | 53 ++++++ vendor/code.gitea.io/sdk/gitea/pull_review.go | 123 ++++++++++++- vendor/code.gitea.io/sdk/gitea/release.go | 61 +++++-- vendor/code.gitea.io/sdk/gitea/repo.go | 167 +++++++++++++---- vendor/code.gitea.io/sdk/gitea/repo_branch.go | 15 +- .../sdk/gitea/repo_branch_protection.go | 140 ++++++++------- .../sdk/gitea/repo_collaborator.go | 12 ++ vendor/code.gitea.io/sdk/gitea/repo_commit.go | 22 ++- vendor/code.gitea.io/sdk/gitea/repo_file.go | 63 ++++++- vendor/code.gitea.io/sdk/gitea/repo_key.go | 12 ++ .../code.gitea.io/sdk/gitea/repo_migrate.go | 48 ++--- vendor/code.gitea.io/sdk/gitea/repo_refs.go | 9 + vendor/code.gitea.io/sdk/gitea/repo_stars.go | 96 ++++++++++ vendor/code.gitea.io/sdk/gitea/repo_tag.go | 17 ++ vendor/code.gitea.io/sdk/gitea/repo_topics.go | 14 +- .../code.gitea.io/sdk/gitea/repo_transfer.go | 3 + vendor/code.gitea.io/sdk/gitea/repo_tree.go | 3 + vendor/code.gitea.io/sdk/gitea/repo_watch.go | 24 ++- vendor/code.gitea.io/sdk/gitea/settings.go | 6 +- vendor/code.gitea.io/sdk/gitea/status.go | 28 ++- vendor/code.gitea.io/sdk/gitea/user.go | 3 + vendor/code.gitea.io/sdk/gitea/user_app.go | 22 ++- vendor/code.gitea.io/sdk/gitea/user_follow.go | 20 +++ vendor/code.gitea.io/sdk/gitea/user_gpgkey.go | 3 + vendor/code.gitea.io/sdk/gitea/user_key.go | 3 + vendor/code.gitea.io/sdk/gitea/version.go | 58 +++--- vendor/modules.txt | 2 +- 55 files changed, 1333 insertions(+), 355 deletions(-) create mode 100644 vendor/code.gitea.io/sdk/gitea/helper.go create mode 100644 vendor/code.gitea.io/sdk/gitea/repo_stars.go diff --git a/go.mod b/go.mod index 165c8f693..9b78a412f 100644 --- a/go.mod +++ b/go.mod @@ -5,7 +5,7 @@ go 1.14 require ( cloud.google.com/go v0.78.0 // indirect code.gitea.io/gitea-vet v0.2.1 - code.gitea.io/sdk/gitea v0.13.2 + code.gitea.io/sdk/gitea v0.14.0 gitea.com/go-chi/binding v0.0.0-20210301195521-1fe1c9a555e7 gitea.com/go-chi/cache v0.0.0-20210110083709-82c4c9ce2d5e gitea.com/go-chi/captcha v0.0.0-20210110083842-e7696c336a1e diff --git a/go.sum b/go.sum index 09dc22e8f..2b4d96aec 100644 --- a/go.sum +++ b/go.sum @@ -38,8 +38,8 @@ cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RX cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= code.gitea.io/gitea-vet v0.2.1 h1:b30by7+3SkmiftK0RjuXqFvZg2q4p68uoPGuxhzBN0s= code.gitea.io/gitea-vet v0.2.1/go.mod h1:zcNbT/aJEmivCAhfmkHOlT645KNOf9W2KnkLgFjGGfE= -code.gitea.io/sdk/gitea v0.13.2 h1:wAnT/J7Z62q3fJXbgnecoaOBh8CM1Qq0/DakWxiv4yA= -code.gitea.io/sdk/gitea v0.13.2/go.mod h1:lee2y8LeV3kQb2iK+hHlMqoadL4bp27QOkOV/hawLKg= +code.gitea.io/sdk/gitea v0.14.0 h1:m4J352I3p9+bmJUfS+g0odeQzBY/5OXP91Gv6D4fnJ0= +code.gitea.io/sdk/gitea v0.14.0/go.mod h1:89WiyOX1KEcvjP66sRHdu0RafojGo60bT9UqW17VbWs= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= gitea.com/go-chi/binding v0.0.0-20210301195521-1fe1c9a555e7 h1:xCVJPY823C8RWpgMabTw2kOglDrg0iS3GcQU6wdwHkU= gitea.com/go-chi/binding v0.0.0-20210301195521-1fe1c9a555e7/go.mod h1:AyfTrwtfYN54R/HmVvMYPnSTenH5bVoyh8x6tBluxEA= diff --git a/modules/migrations/gitea_downloader.go b/modules/migrations/gitea_downloader.go index 87ec9c102..40820ae37 100644 --- a/modules/migrations/gitea_downloader.go +++ b/modules/migrations/gitea_downloader.go @@ -525,9 +525,6 @@ func (g *GiteaDownloader) GetPullRequests(page, perPage int) ([]*base.PullReques headRepoName = pr.Head.Repository.Name headCloneURL = pr.Head.Repository.CloneURL } - if err := fixPullHeadSha(g.client, pr); err != nil { - return nil, false, fmt.Errorf("error while resolving head git ref: %s for pull #%d. Error: %v", pr.Head.Ref, pr.Index, err) - } headSHA = pr.Head.Sha headRef = pr.Head.Ref } @@ -679,22 +676,3 @@ func (g *GiteaDownloader) GetReviews(index int64) ([]*base.Review, error) { } return allReviews, nil } - -// fixPullHeadSha is a workaround for https://github.com/go-gitea/gitea/issues/12675 -// When no head sha is available, this is because the branch got deleted in the base repo. -// pr.Head.Ref points in this case not to the head repo branch name, but the base repo ref, -// which stays available to resolve the commit sha. -func fixPullHeadSha(client *gitea_sdk.Client, pr *gitea_sdk.PullRequest) error { - owner := pr.Base.Repository.Owner.UserName - repo := pr.Base.Repository.Name - if pr.Head != nil && pr.Head.Sha == "" { - refs, _, err := client.GetRepoRefs(owner, repo, pr.Head.Ref) - if err != nil { - return err - } else if len(refs) == 0 { - return fmt.Errorf("unable to resolve PR ref '%s'", pr.Head.Ref) - } - pr.Head.Sha = refs[0].Object.SHA - } - return nil -} diff --git a/vendor/code.gitea.io/sdk/gitea/admin_cron.go b/vendor/code.gitea.io/sdk/gitea/admin_cron.go index 99006b696..84316da2b 100644 --- a/vendor/code.gitea.io/sdk/gitea/admin_cron.go +++ b/vendor/code.gitea.io/sdk/gitea/admin_cron.go @@ -39,6 +39,9 @@ func (c *Client) RunCronTasks(task string) (*Response, error) { if err := c.checkServerVersionGreaterThanOrEqual(version1_13_0); err != nil { return nil, err } + if err := escapeValidatePathSegments(&task); err != nil { + return nil, err + } _, resp, err := c.getResponse("POST", fmt.Sprintf("/admin/cron/%s", task), jsonHeader, nil) return resp, err } diff --git a/vendor/code.gitea.io/sdk/gitea/admin_org.go b/vendor/code.gitea.io/sdk/gitea/admin_org.go index e572680fc..26bf81fb4 100644 --- a/vendor/code.gitea.io/sdk/gitea/admin_org.go +++ b/vendor/code.gitea.io/sdk/gitea/admin_org.go @@ -26,6 +26,9 @@ func (c *Client) AdminListOrgs(opt AdminListOrgsOptions) ([]*Organization, *Resp // AdminCreateOrg create an organization func (c *Client) AdminCreateOrg(user string, opt CreateOrgOption) (*Organization, *Response, error) { + if err := escapeValidatePathSegments(&user); err != nil { + return nil, nil, err + } body, err := json.Marshal(&opt) if err != nil { return nil, nil, err diff --git a/vendor/code.gitea.io/sdk/gitea/admin_repo.go b/vendor/code.gitea.io/sdk/gitea/admin_repo.go index cbd978817..8666690cd 100644 --- a/vendor/code.gitea.io/sdk/gitea/admin_repo.go +++ b/vendor/code.gitea.io/sdk/gitea/admin_repo.go @@ -12,6 +12,9 @@ import ( // AdminCreateRepo create a repo func (c *Client) AdminCreateRepo(user string, opt CreateRepoOption) (*Repository, *Response, error) { + if err := escapeValidatePathSegments(&user); err != nil { + return nil, nil, err + } body, err := json.Marshal(&opt) if err != nil { return nil, nil, err diff --git a/vendor/code.gitea.io/sdk/gitea/admin_user.go b/vendor/code.gitea.io/sdk/gitea/admin_user.go index 5f4917896..161dc6058 100644 --- a/vendor/code.gitea.io/sdk/gitea/admin_user.go +++ b/vendor/code.gitea.io/sdk/gitea/admin_user.go @@ -63,25 +63,28 @@ func (c *Client) AdminCreateUser(opt CreateUserOption) (*User, *Response, error) // EditUserOption edit user options type EditUserOption struct { - SourceID int64 `json:"source_id"` - LoginName string `json:"login_name"` - FullName string `json:"full_name"` - Email string `json:"email"` - Password string `json:"password"` - MustChangePassword *bool `json:"must_change_password"` - Website string `json:"website"` - Location string `json:"location"` - Active *bool `json:"active"` - Admin *bool `json:"admin"` - AllowGitHook *bool `json:"allow_git_hook"` - AllowImportLocal *bool `json:"allow_import_local"` - MaxRepoCreation *int `json:"max_repo_creation"` - ProhibitLogin *bool `json:"prohibit_login"` - AllowCreateOrganization *bool `json:"allow_create_organization"` + SourceID int64 `json:"source_id"` + LoginName string `json:"login_name"` + Email *string `json:"email"` + FullName *string `json:"full_name"` + Password string `json:"password"` + MustChangePassword *bool `json:"must_change_password"` + Website *string `json:"website"` + Location *string `json:"location"` + Active *bool `json:"active"` + Admin *bool `json:"admin"` + AllowGitHook *bool `json:"allow_git_hook"` + AllowImportLocal *bool `json:"allow_import_local"` + MaxRepoCreation *int `json:"max_repo_creation"` + ProhibitLogin *bool `json:"prohibit_login"` + AllowCreateOrganization *bool `json:"allow_create_organization"` } // AdminEditUser modify user informations func (c *Client) AdminEditUser(user string, opt EditUserOption) (*Response, error) { + if err := escapeValidatePathSegments(&user); err != nil { + return nil, err + } body, err := json.Marshal(&opt) if err != nil { return nil, err @@ -92,12 +95,18 @@ func (c *Client) AdminEditUser(user string, opt EditUserOption) (*Response, erro // AdminDeleteUser delete one user according name func (c *Client) AdminDeleteUser(user string) (*Response, error) { + if err := escapeValidatePathSegments(&user); err != nil { + return nil, err + } _, resp, err := c.getResponse("DELETE", fmt.Sprintf("/admin/users/%s", user), nil, nil) return resp, err } // AdminCreateUserPublicKey adds a public key for the user func (c *Client) AdminCreateUserPublicKey(user string, opt CreateKeyOption) (*PublicKey, *Response, error) { + if err := escapeValidatePathSegments(&user); err != nil { + return nil, nil, err + } body, err := json.Marshal(&opt) if err != nil { return nil, nil, err @@ -109,6 +118,9 @@ func (c *Client) AdminCreateUserPublicKey(user string, opt CreateKeyOption) (*Pu // AdminDeleteUserPublicKey deletes a user's public key func (c *Client) AdminDeleteUserPublicKey(user string, keyID int) (*Response, error) { + if err := escapeValidatePathSegments(&user); err != nil { + return nil, err + } _, resp, err := c.getResponse("DELETE", fmt.Sprintf("/admin/users/%s/keys/%d", user, keyID), nil, nil) return resp, err } diff --git a/vendor/code.gitea.io/sdk/gitea/attachment.go b/vendor/code.gitea.io/sdk/gitea/attachment.go index 6f67ae3de..24c57baf4 100644 --- a/vendor/code.gitea.io/sdk/gitea/attachment.go +++ b/vendor/code.gitea.io/sdk/gitea/attachment.go @@ -31,6 +31,9 @@ type ListReleaseAttachmentsOptions struct { // ListReleaseAttachments list release's attachments func (c *Client) ListReleaseAttachments(user, repo string, release int64, opt ListReleaseAttachmentsOptions) ([]*Attachment, *Response, error) { + if err := escapeValidatePathSegments(&user, &repo); err != nil { + return nil, nil, err + } opt.setDefaults() attachments := make([]*Attachment, 0, opt.PageSize) resp, err := c.getParsedResponse("GET", @@ -41,6 +44,9 @@ func (c *Client) ListReleaseAttachments(user, repo string, release int64, opt Li // GetReleaseAttachment returns the requested attachment func (c *Client) GetReleaseAttachment(user, repo string, release int64, id int64) (*Attachment, *Response, error) { + if err := escapeValidatePathSegments(&user, &repo); err != nil { + return nil, nil, err + } a := new(Attachment) resp, err := c.getParsedResponse("GET", fmt.Sprintf("/repos/%s/%s/releases/%d/assets/%d", user, repo, release, id), @@ -50,6 +56,9 @@ func (c *Client) GetReleaseAttachment(user, repo string, release int64, id int64 // CreateReleaseAttachment creates an attachment for the given release func (c *Client) CreateReleaseAttachment(user, repo string, release int64, file io.Reader, filename string) (*Attachment, *Response, error) { + if err := escapeValidatePathSegments(&user, &repo); err != nil { + return nil, nil, err + } // Write file to body body := new(bytes.Buffer) writer := multipart.NewWriter(body) @@ -80,6 +89,9 @@ type EditAttachmentOptions struct { // EditReleaseAttachment updates the given attachment with the given options func (c *Client) EditReleaseAttachment(user, repo string, release int64, attachment int64, form EditAttachmentOptions) (*Attachment, *Response, error) { + if err := escapeValidatePathSegments(&user, &repo); err != nil { + return nil, nil, err + } body, err := json.Marshal(&form) if err != nil { return nil, nil, err @@ -91,6 +103,9 @@ func (c *Client) EditReleaseAttachment(user, repo string, release int64, attachm // DeleteReleaseAttachment deletes the given attachment including the uploaded file func (c *Client) DeleteReleaseAttachment(user, repo string, release int64, id int64) (*Response, error) { + if err := escapeValidatePathSegments(&user, &repo); err != nil { + return nil, err + } _, resp, err := c.getResponse("DELETE", fmt.Sprintf("/repos/%s/%s/releases/%d/assets/%d", user, repo, release, id), nil, nil) return resp, err } diff --git a/vendor/code.gitea.io/sdk/gitea/client.go b/vendor/code.gitea.io/sdk/gitea/client.go index e08bc9edd..9f857f85a 100644 --- a/vendor/code.gitea.io/sdk/gitea/client.go +++ b/vendor/code.gitea.io/sdk/gitea/client.go @@ -13,6 +13,7 @@ import ( "io" "io/ioutil" "net/http" + "net/url" "strings" "sync" @@ -23,22 +24,23 @@ var jsonHeader = http.Header{"content-type": []string{"application/json"}} // Version return the library version func Version() string { - return "0.13.0" + return "0.14.0" } -// Client represents a Gitea API client. +// Client represents a thread-safe Gitea API client. type Client struct { - url string - accessToken string - username string - password string - otp string - sudo string - debug bool - client *http.Client - ctx context.Context - serverVersion *version.Version - versionLock sync.RWMutex + url string + accessToken string + username string + password string + otp string + sudo string + debug bool + client *http.Client + ctx context.Context + mutex sync.RWMutex + serverVersion *version.Version + getVersionOnce sync.Once } // Response represents the gitea response @@ -47,6 +49,7 @@ type Response struct { } // NewClient initializes and returns a API client. +// Usage of all gitea.Client methods is concurrency-safe. func NewClient(url string, options ...func(*Client)) (*Client, error) { client := &Client{ url: strings.TrimSuffix(url, "/"), @@ -56,7 +59,7 @@ func NewClient(url string, options ...func(*Client)) (*Client, error) { for _, opt := range options { opt(client) } - if err := client.checkServerVersionGreaterThanOrEqual(version1_10_0); err != nil { + if err := client.checkServerVersionGreaterThanOrEqual(version1_11_0); err != nil { return nil, err } return client, nil @@ -72,14 +75,23 @@ func NewClientWithHTTP(url string, httpClient *http.Client) *Client { // SetHTTPClient is an option for NewClient to set custom http client func SetHTTPClient(httpClient *http.Client) func(client *Client) { return func(client *Client) { - client.client = httpClient + client.SetHTTPClient(httpClient) } } +// SetHTTPClient replaces default http.Client with user given one. +func (c *Client) SetHTTPClient(client *http.Client) { + c.mutex.Lock() + c.client = client + c.mutex.Unlock() +} + // SetToken is an option for NewClient to set token func SetToken(token string) func(client *Client) { return func(client *Client) { + client.mutex.Lock() client.accessToken = token + client.mutex.Unlock() } } @@ -92,7 +104,9 @@ func SetBasicAuth(username, password string) func(client *Client) { // SetBasicAuth sets username and password func (c *Client) SetBasicAuth(username, password string) { + c.mutex.Lock() c.username, c.password = username, password + c.mutex.Unlock() } // SetOTP is an option for NewClient to set OTP for 2FA @@ -104,7 +118,9 @@ func SetOTP(otp string) func(client *Client) { // SetOTP sets OTP for 2FA func (c *Client) SetOTP(otp string) { + c.mutex.Lock() c.otp = otp + c.mutex.Unlock() } // SetContext is an option for NewClient to set context @@ -116,12 +132,9 @@ func SetContext(ctx context.Context) func(client *Client) { // SetContext set context witch is used for http requests func (c *Client) SetContext(ctx context.Context) { + c.mutex.Lock() c.ctx = ctx -} - -// SetHTTPClient replaces default http.Client with user given one. -func (c *Client) SetHTTPClient(client *http.Client) { - c.client = client + c.mutex.Unlock() } // SetSudo is an option for NewClient to set sudo header @@ -133,43 +146,57 @@ func SetSudo(sudo string) func(client *Client) { // SetSudo sets username to impersonate. func (c *Client) SetSudo(sudo string) { + c.mutex.Lock() c.sudo = sudo + c.mutex.Unlock() } // SetDebugMode is an option for NewClient to enable debug mode func SetDebugMode() func(client *Client) { return func(client *Client) { + client.mutex.Lock() client.debug = true + client.mutex.Unlock() } } func (c *Client) getWebResponse(method, path string, body io.Reader) ([]byte, *Response, error) { - if c.debug { + c.mutex.RLock() + debug := c.debug + if debug { fmt.Printf("%s: %s\nBody: %v\n", method, c.url+path, body) } req, err := http.NewRequestWithContext(c.ctx, method, c.url+path, body) + + client := c.client // client ref can change from this point on so safe it + c.mutex.RUnlock() + if err != nil { return nil, nil, err } - resp, err := c.client.Do(req) + + resp, err := client.Do(req) if err != nil { return nil, nil, err } defer resp.Body.Close() data, err := ioutil.ReadAll(resp.Body) - if c.debug { + if debug { fmt.Printf("Response: %v\n\n", resp) } return data, &Response{resp}, nil } func (c *Client) doRequest(method, path string, header http.Header, body io.Reader) (*Response, error) { - if c.debug { + c.mutex.RLock() + debug := c.debug + if debug { fmt.Printf("%s: %s\nHeader: %v\nBody: %s\n", method, c.url+"/api/v1"+path, header, body) } req, err := http.NewRequestWithContext(c.ctx, method, c.url+"/api/v1"+path, body) if err != nil { + c.mutex.RUnlock() return nil, err } if len(c.accessToken) != 0 { @@ -184,51 +211,83 @@ func (c *Client) doRequest(method, path string, header http.Header, body io.Read if len(c.sudo) != 0 { req.Header.Set("Sudo", c.sudo) } + + client := c.client // client ref can change from this point on so safe it + c.mutex.RUnlock() + for k, v := range header { req.Header[k] = v } - resp, err := c.client.Do(req) + resp, err := client.Do(req) if err != nil { return nil, err } - if c.debug { + if debug { fmt.Printf("Response: %v\n\n", resp) } return &Response{resp}, nil } -func (c *Client) getResponse(method, path string, header http.Header, body io.Reader) ([]byte, *Response, error) { - resp, err := c.doRequest(method, path, header, body) - if err != nil { - return nil, nil, err +// Converts a response for a HTTP status code indicating an error condition +// (non-2XX) to a well-known error value and response body. For non-problematic +// (2XX) status codes nil will be returned. Note that on a non-2XX response, the +// response body stream will have been read and, hence, is closed on return. +func statusCodeToErr(resp *Response) (body []byte, err error) { + // no error + if resp.StatusCode/100 == 2 { + return nil, nil } - defer resp.Body.Close() + // + // error: body will be read for details + // + defer resp.Body.Close() data, err := ioutil.ReadAll(resp.Body) if err != nil { - return nil, resp, err + return nil, fmt.Errorf("body read on HTTP error %d: %v", resp.StatusCode, err) } switch resp.StatusCode { case 403: - return data, resp, errors.New("403 Forbidden") + return data, errors.New("403 Forbidden") case 404: - return data, resp, errors.New("404 Not Found") + return data, errors.New("404 Not Found") case 409: - return data, resp, errors.New("409 Conflict") + return data, errors.New("409 Conflict") case 422: - return data, resp, fmt.Errorf("422 Unprocessable Entity: %s", string(data)) + return data, fmt.Errorf("422 Unprocessable Entity: %s", string(data)) } - if resp.StatusCode/100 != 2 { - errMap := make(map[string]interface{}) - if err = json.Unmarshal(data, &errMap); err != nil { - // when the JSON can't be parsed, data was probably empty or a plain string, - // so we try to return a helpful error anyway - return data, resp, fmt.Errorf("Unknown API Error: %d\nRequest: '%s' with '%s' method '%s' header and '%s' body", resp.StatusCode, path, method, header, string(data)) - } - return data, resp, errors.New(errMap["message"].(string)) + path := resp.Request.URL.Path + method := resp.Request.Method + header := resp.Request.Header + errMap := make(map[string]interface{}) + if err = json.Unmarshal(data, &errMap); err != nil { + // when the JSON can't be parsed, data was probably empty or a + // plain string, so we try to return a helpful error anyway + return data, fmt.Errorf("Unknown API Error: %d\nRequest: '%s' with '%s' method '%s' header and '%s' body", resp.StatusCode, path, method, header, string(data)) + } + return data, errors.New(errMap["message"].(string)) +} + +func (c *Client) getResponse(method, path string, header http.Header, body io.Reader) ([]byte, *Response, error) { + resp, err := c.doRequest(method, path, header, body) + if err != nil { + return nil, nil, err + } + defer resp.Body.Close() + + // check for errors + data, err := statusCodeToErr(resp) + if err != nil { + return data, resp, err + } + + // success (2XX), read body + data, err = ioutil.ReadAll(resp.Body) + if err != nil { + return nil, resp, err } return data, resp, nil @@ -251,3 +310,24 @@ func (c *Client) getStatusCode(method, path string, header http.Header, body io. return resp.StatusCode, resp, nil } + +// pathEscapeSegments escapes segments of a path while not escaping forward slash +func pathEscapeSegments(path string) string { + slice := strings.Split(path, "/") + for index := range slice { + slice[index] = url.PathEscape(slice[index]) + } + escapedPath := strings.Join(slice, "/") + return escapedPath +} + +// escapeValidatePathSegments is a help function to validate and encode url path segments +func escapeValidatePathSegments(seg ...*string) error { + for i := range seg { + if seg[i] == nil || len(*seg[i]) == 0 { + return fmt.Errorf("path segment [%d] is empty", i) + } + *seg[i] = url.PathEscape(*seg[i]) + } + return nil +} diff --git a/vendor/code.gitea.io/sdk/gitea/fork.go b/vendor/code.gitea.io/sdk/gitea/fork.go index a5197125d..c8e5323bc 100644 --- a/vendor/code.gitea.io/sdk/gitea/fork.go +++ b/vendor/code.gitea.io/sdk/gitea/fork.go @@ -17,6 +17,9 @@ type ListForksOptions struct { // ListForks list a repository's forks func (c *Client) ListForks(user string, repo string, opt ListForksOptions) ([]*Repository, *Response, error) { + if err := escapeValidatePathSegments(&user, &repo); err != nil { + return nil, nil, err + } opt.setDefaults() forks := make([]*Repository, opt.PageSize) resp, err := c.getParsedResponse("GET", @@ -33,6 +36,9 @@ type CreateForkOption struct { // CreateFork create a fork of a repository func (c *Client) CreateFork(user, repo string, form CreateForkOption) (*Repository, *Response, error) { + if err := escapeValidatePathSegments(&user, &repo); err != nil { + return nil, nil, err + } body, err := json.Marshal(form) if err != nil { return nil, nil, err diff --git a/vendor/code.gitea.io/sdk/gitea/git_blob.go b/vendor/code.gitea.io/sdk/gitea/git_blob.go index 262fd92df..7668672dc 100644 --- a/vendor/code.gitea.io/sdk/gitea/git_blob.go +++ b/vendor/code.gitea.io/sdk/gitea/git_blob.go @@ -19,6 +19,9 @@ type GitBlobResponse struct { // GetBlob get the blob of a repository file func (c *Client) GetBlob(user, repo, sha string) (*GitBlobResponse, *Response, error) { + if err := escapeValidatePathSegments(&user, &repo, &sha); err != nil { + return nil, nil, err + } blob := new(GitBlobResponse) resp, err := c.getParsedResponse("GET", fmt.Sprintf("/repos/%s/%s/git/blobs/%s", user, repo, sha), nil, nil, blob) return blob, resp, err diff --git a/vendor/code.gitea.io/sdk/gitea/git_hook.go b/vendor/code.gitea.io/sdk/gitea/git_hook.go index 520ce538e..d8fbf71bd 100644 --- a/vendor/code.gitea.io/sdk/gitea/git_hook.go +++ b/vendor/code.gitea.io/sdk/gitea/git_hook.go @@ -24,6 +24,9 @@ type ListRepoGitHooksOptions struct { // ListRepoGitHooks list all the Git hooks of one repository func (c *Client) ListRepoGitHooks(user, repo string, opt ListRepoGitHooksOptions) ([]*GitHook, *Response, error) { + if err := escapeValidatePathSegments(&user, &repo); err != nil { + return nil, nil, err + } opt.setDefaults() hooks := make([]*GitHook, 0, opt.PageSize) resp, err := c.getParsedResponse("GET", fmt.Sprintf("/repos/%s/%s/hooks/git?%s", user, repo, opt.getURLQuery().Encode()), nil, nil, &hooks) @@ -32,6 +35,9 @@ func (c *Client) ListRepoGitHooks(user, repo string, opt ListRepoGitHooksOptions // GetRepoGitHook get a Git hook of a repository func (c *Client) GetRepoGitHook(user, repo, id string) (*GitHook, *Response, error) { + if err := escapeValidatePathSegments(&user, &repo, &id); err != nil { + return nil, nil, err + } h := new(GitHook) resp, err := c.getParsedResponse("GET", fmt.Sprintf("/repos/%s/%s/hooks/git/%s", user, repo, id), nil, nil, h) return h, resp, err @@ -44,6 +50,9 @@ type EditGitHookOption struct { // EditRepoGitHook modify one Git hook of a repository func (c *Client) EditRepoGitHook(user, repo, id string, opt EditGitHookOption) (*Response, error) { + if err := escapeValidatePathSegments(&user, &repo, &id); err != nil { + return nil, err + } body, err := json.Marshal(&opt) if err != nil { return nil, err @@ -54,6 +63,9 @@ func (c *Client) EditRepoGitHook(user, repo, id string, opt EditGitHookOption) ( // DeleteRepoGitHook delete one Git hook from a repository func (c *Client) DeleteRepoGitHook(user, repo, id string) (*Response, error) { + if err := escapeValidatePathSegments(&user, &repo, &id); err != nil { + return nil, err + } _, resp, err := c.getResponse("DELETE", fmt.Sprintf("/repos/%s/%s/hooks/git/%s", user, repo, id), nil, nil) return resp, err } diff --git a/vendor/code.gitea.io/sdk/gitea/go.mod b/vendor/code.gitea.io/sdk/gitea/go.mod index fe2a46ae0..ac2a262ab 100644 --- a/vendor/code.gitea.io/sdk/gitea/go.mod +++ b/vendor/code.gitea.io/sdk/gitea/go.mod @@ -1,6 +1,6 @@ module code.gitea.io/sdk/gitea -go 1.12 +go 1.13 require ( github.com/hashicorp/go-version v1.2.1 diff --git a/vendor/code.gitea.io/sdk/gitea/go.sum b/vendor/code.gitea.io/sdk/gitea/go.sum index e210c1c42..82997d0cc 100644 --- a/vendor/code.gitea.io/sdk/gitea/go.sum +++ b/vendor/code.gitea.io/sdk/gitea/go.sum @@ -2,6 +2,8 @@ github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8 github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/hashicorp/go-version v1.2.0 h1:3vNe/fWF5CBgRIguda1meWhsZHy3m8gCJ5wx+dIzX/E= github.com/hashicorp/go-version v1.2.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= +github.com/hashicorp/go-version v1.2.1 h1:zEfKbn2+PDgroKdiOzqiE8rsmLqU2uwi5PB5pBJ3TkI= +github.com/hashicorp/go-version v1.2.1/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= diff --git a/vendor/code.gitea.io/sdk/gitea/helper.go b/vendor/code.gitea.io/sdk/gitea/helper.go new file mode 100644 index 000000000..ff8038b12 --- /dev/null +++ b/vendor/code.gitea.io/sdk/gitea/helper.go @@ -0,0 +1,20 @@ +// Copyright 2020 The Gitea Authors. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file. + +package gitea + +// OptionalBool convert a bool to a bool reference +func OptionalBool(v bool) *bool { + return &v +} + +// OptionalString convert a string to a string reference +func OptionalString(v string) *string { + return &v +} + +// OptionalInt64 convert a int64 to a int64 reference +func OptionalInt64(v int64) *int64 { + return &v +} diff --git a/vendor/code.gitea.io/sdk/gitea/hook.go b/vendor/code.gitea.io/sdk/gitea/hook.go index 3a6be65ef..af4154e2a 100644 --- a/vendor/code.gitea.io/sdk/gitea/hook.go +++ b/vendor/code.gitea.io/sdk/gitea/hook.go @@ -31,6 +31,9 @@ type ListHooksOptions struct { // ListOrgHooks list all the hooks of one organization func (c *Client) ListOrgHooks(org string, opt ListHooksOptions) ([]*Hook, *Response, error) { + if err := escapeValidatePathSegments(&org); err != nil { + return nil, nil, err + } opt.setDefaults() hooks := make([]*Hook, 0, opt.PageSize) resp, err := c.getParsedResponse("GET", fmt.Sprintf("/orgs/%s/hooks?%s", org, opt.getURLQuery().Encode()), nil, nil, &hooks) @@ -39,6 +42,9 @@ func (c *Client) ListOrgHooks(org string, opt ListHooksOptions) ([]*Hook, *Respo // ListRepoHooks list all the hooks of one repository func (c *Client) ListRepoHooks(user, repo string, opt ListHooksOptions) ([]*Hook, *Response, error) { + if err := escapeValidatePathSegments(&user, &repo); err != nil { + return nil, nil, err + } opt.setDefaults() hooks := make([]*Hook, 0, opt.PageSize) resp, err := c.getParsedResponse("GET", fmt.Sprintf("/repos/%s/%s/hooks?%s", user, repo, opt.getURLQuery().Encode()), nil, nil, &hooks) @@ -47,6 +53,9 @@ func (c *Client) ListRepoHooks(user, repo string, opt ListHooksOptions) ([]*Hook // GetOrgHook get a hook of an organization func (c *Client) GetOrgHook(org string, id int64) (*Hook, *Response, error) { + if err := escapeValidatePathSegments(&org); err != nil { + return nil, nil, err + } h := new(Hook) resp, err := c.getParsedResponse("GET", fmt.Sprintf("/orgs/%s/hooks/%d", org, id), nil, nil, h) return h, resp, err @@ -54,6 +63,9 @@ func (c *Client) GetOrgHook(org string, id int64) (*Hook, *Response, error) { // GetRepoHook get a hook of a repository func (c *Client) GetRepoHook(user, repo string, id int64) (*Hook, *Response, error) { + if err := escapeValidatePathSegments(&user, &repo); err != nil { + return nil, nil, err + } h := new(Hook) resp, err := c.getParsedResponse("GET", fmt.Sprintf("/repos/%s/%s/hooks/%d", user, repo, id), nil, nil, h) return h, resp, err @@ -78,6 +90,9 @@ func (opt CreateHookOption) Validate() error { // CreateOrgHook create one hook for an organization, with options func (c *Client) CreateOrgHook(org string, opt CreateHookOption) (*Hook, *Response, error) { + if err := escapeValidatePathSegments(&org); err != nil { + return nil, nil, err + } if err := opt.Validate(); err != nil { return nil, nil, err } @@ -92,6 +107,9 @@ func (c *Client) CreateOrgHook(org string, opt CreateHookOption) (*Hook, *Respon // CreateRepoHook create one hook for a repository, with options func (c *Client) CreateRepoHook(user, repo string, opt CreateHookOption) (*Hook, *Response, error) { + if err := escapeValidatePathSegments(&user, &repo); err != nil { + return nil, nil, err + } body, err := json.Marshal(&opt) if err != nil { return nil, nil, err @@ -111,6 +129,9 @@ type EditHookOption struct { // EditOrgHook modify one hook of an organization, with hook id and options func (c *Client) EditOrgHook(org string, id int64, opt EditHookOption) (*Response, error) { + if err := escapeValidatePathSegments(&org); err != nil { + return nil, err + } body, err := json.Marshal(&opt) if err != nil { return nil, err @@ -121,6 +142,9 @@ func (c *Client) EditOrgHook(org string, id int64, opt EditHookOption) (*Respons // EditRepoHook modify one hook of a repository, with hook id and options func (c *Client) EditRepoHook(user, repo string, id int64, opt EditHookOption) (*Response, error) { + if err := escapeValidatePathSegments(&user, &repo); err != nil { + return nil, err + } body, err := json.Marshal(&opt) if err != nil { return nil, err @@ -131,12 +155,18 @@ func (c *Client) EditRepoHook(user, repo string, id int64, opt EditHookOption) ( // DeleteOrgHook delete one hook from an organization, with hook id func (c *Client) DeleteOrgHook(org string, id int64) (*Response, error) { + if err := escapeValidatePathSegments(&org); err != nil { + return nil, err + } _, resp, err := c.getResponse("DELETE", fmt.Sprintf("/orgs/%s/hooks/%d", org, id), nil, nil) return resp, err } // DeleteRepoHook delete one hook from a repository, with hook id func (c *Client) DeleteRepoHook(user, repo string, id int64) (*Response, error) { + if err := escapeValidatePathSegments(&user, &repo); err != nil { + return nil, err + } _, resp, err := c.getResponse("DELETE", fmt.Sprintf("/repos/%s/%s/hooks/%d", user, repo, id), nil, nil) return resp, err } diff --git a/vendor/code.gitea.io/sdk/gitea/issue.go b/vendor/code.gitea.io/sdk/gitea/issue.go index 7eef44711..688924634 100644 --- a/vendor/code.gitea.io/sdk/gitea/issue.go +++ b/vendor/code.gitea.io/sdk/gitea/issue.go @@ -32,16 +32,20 @@ type RepositoryMeta struct { type Issue struct { ID int64 `json:"id"` URL string `json:"url"` + HTMLURL string `json:"html_url"` Index int64 `json:"number"` Poster *User `json:"user"` OriginalAuthor string `json:"original_author"` OriginalAuthorID int64 `json:"original_author_id"` Title string `json:"title"` Body string `json:"body"` + Ref string `json:"ref"` Labels []*Label `json:"labels"` Milestone *Milestone `json:"milestone"` - Assignee *User `json:"assignee"` - Assignees []*User `json:"assignees"` + // deprecated + // TODO: rm on sdk 0.15.0 + Assignee *User `json:"assignee"` + Assignees []*User `json:"assignees"` // Whether the issue is open or closed State StateType `json:"state"` IsLocked bool `json:"is_locked"` @@ -128,11 +132,17 @@ func (c *Client) ListIssues(opt ListIssueOption) ([]*Issue, *Response, error) { } } } + for i := range issues { + c.issueBackwardsCompatibility(issues[i]) + } return issues, resp, err } // ListRepoIssues returns all issues for a given repository func (c *Client) ListRepoIssues(owner, repo string, opt ListIssueOption) ([]*Issue, *Response, error) { + if err := escapeValidatePathSegments(&owner, &repo); err != nil { + return nil, nil, err + } opt.setDefaults() issues := make([]*Issue, 0, opt.PageSize) @@ -146,16 +156,23 @@ func (c *Client) ListRepoIssues(owner, repo string, opt ListIssueOption) ([]*Iss } } } + for i := range issues { + c.issueBackwardsCompatibility(issues[i]) + } return issues, resp, err } // GetIssue returns a single issue for a given repository func (c *Client) GetIssue(owner, repo string, index int64) (*Issue, *Response, error) { + if err := escapeValidatePathSegments(&owner, &repo); err != nil { + return nil, nil, err + } issue := new(Issue) resp, err := c.getParsedResponse("GET", fmt.Sprintf("/repos/%s/%s/issues/%d", owner, repo, index), nil, nil, issue) if e := c.checkServerVersionGreaterThanOrEqual(version1_12_0); e != nil && issue.Repository != nil { issue.Repository.Owner = strings.Split(issue.Repository.FullName, "/")[0] } + c.issueBackwardsCompatibility(issue) return issue, resp, err } @@ -163,7 +180,9 @@ func (c *Client) GetIssue(owner, repo string, index int64) (*Issue, *Response, e type CreateIssueOption struct { Title string `json:"title"` Body string `json:"body"` - // username of assignee + Ref string `json:"ref"` + // deprecated + // TODO: rm on sdk 0.15.0 Assignee string `json:"assignee"` Assignees []string `json:"assignees"` Deadline *time.Time `json:"due_date"` @@ -184,6 +203,9 @@ func (opt CreateIssueOption) Validate() error { // CreateIssue create a new issue for a given repository func (c *Client) CreateIssue(owner, repo string, opt CreateIssueOption) (*Issue, *Response, error) { + if err := escapeValidatePathSegments(&owner, &repo); err != nil { + return nil, nil, err + } if err := opt.Validate(); err != nil { return nil, nil, err } @@ -194,18 +216,23 @@ func (c *Client) CreateIssue(owner, repo string, opt CreateIssueOption) (*Issue, issue := new(Issue) resp, err := c.getParsedResponse("POST", fmt.Sprintf("/repos/%s/%s/issues", owner, repo), jsonHeader, bytes.NewReader(body), issue) + c.issueBackwardsCompatibility(issue) return issue, resp, err } // EditIssueOption options for editing an issue type EditIssueOption struct { - Title string `json:"title"` - Body *string `json:"body"` - Assignee *string `json:"assignee"` - Assignees []string `json:"assignees"` - Milestone *int64 `json:"milestone"` - State *StateType `json:"state"` - Deadline *time.Time `json:"due_date"` + Title string `json:"title"` + Body *string `json:"body"` + Ref *string `json:"ref"` + // deprecated + // TODO: rm on sdk 0.15.0 + Assignee *string `json:"assignee"` + Assignees []string `json:"assignees"` + Milestone *int64 `json:"milestone"` + State *StateType `json:"state"` + Deadline *time.Time `json:"due_date"` + RemoveDeadline *bool `json:"unset_due_date"` } // Validate the EditIssueOption struct @@ -218,6 +245,9 @@ func (opt EditIssueOption) Validate() error { // EditIssue modify an existing issue for a given repository func (c *Client) EditIssue(owner, repo string, index int64, opt EditIssueOption) (*Issue, *Response, error) { + if err := escapeValidatePathSegments(&owner, &repo); err != nil { + return nil, nil, err + } if err := opt.Validate(); err != nil { return nil, nil, err } @@ -229,5 +259,14 @@ func (c *Client) EditIssue(owner, repo string, index int64, opt EditIssueOption) resp, err := c.getParsedResponse("PATCH", fmt.Sprintf("/repos/%s/%s/issues/%d", owner, repo, index), jsonHeader, bytes.NewReader(body), issue) + c.issueBackwardsCompatibility(issue) return issue, resp, err } + +func (c *Client) issueBackwardsCompatibility(issue *Issue) { + if c.checkServerVersionGreaterThanOrEqual(version1_12_0) != nil { + c.mutex.RLock() + issue.HTMLURL = fmt.Sprintf("%s/%s/issues/%d", c.url, issue.Repository.FullName, issue.Index) + c.mutex.RUnlock() + } +} diff --git a/vendor/code.gitea.io/sdk/gitea/issue_comment.go b/vendor/code.gitea.io/sdk/gitea/issue_comment.go index 4eff850d1..8131a6edc 100644 --- a/vendor/code.gitea.io/sdk/gitea/issue_comment.go +++ b/vendor/code.gitea.io/sdk/gitea/issue_comment.go @@ -47,6 +47,9 @@ func (opt *ListIssueCommentOptions) QueryEncode() string { // ListIssueComments list comments on an issue. func (c *Client) ListIssueComments(owner, repo string, index int64, opt ListIssueCommentOptions) ([]*Comment, *Response, error) { + if err := escapeValidatePathSegments(&owner, &repo); err != nil { + return nil, nil, err + } opt.setDefaults() link, _ := url.Parse(fmt.Sprintf("/repos/%s/%s/issues/%d/comments", owner, repo, index)) link.RawQuery = opt.QueryEncode() @@ -57,6 +60,9 @@ func (c *Client) ListIssueComments(owner, repo string, index int64, opt ListIssu // ListRepoIssueComments list comments for a given repo. func (c *Client) ListRepoIssueComments(owner, repo string, opt ListIssueCommentOptions) ([]*Comment, *Response, error) { + if err := escapeValidatePathSegments(&owner, &repo); err != nil { + return nil, nil, err + } opt.setDefaults() link, _ := url.Parse(fmt.Sprintf("/repos/%s/%s/issues/comments", owner, repo)) link.RawQuery = opt.QueryEncode() @@ -67,6 +73,9 @@ func (c *Client) ListRepoIssueComments(owner, repo string, opt ListIssueCommentO // GetIssueComment get a comment for a given repo by id. func (c *Client) GetIssueComment(owner, repo string, id int64) (*Comment, *Response, error) { + if err := escapeValidatePathSegments(&owner, &repo); err != nil { + return nil, nil, err + } comment := new(Comment) if err := c.checkServerVersionGreaterThanOrEqual(version1_12_0); err != nil { return comment, nil, err @@ -90,6 +99,9 @@ func (opt CreateIssueCommentOption) Validate() error { // CreateIssueComment create comment on an issue. func (c *Client) CreateIssueComment(owner, repo string, index int64, opt CreateIssueCommentOption) (*Comment, *Response, error) { + if err := escapeValidatePathSegments(&owner, &repo); err != nil { + return nil, nil, err + } if err := opt.Validate(); err != nil { return nil, nil, err } @@ -117,6 +129,9 @@ func (opt EditIssueCommentOption) Validate() error { // EditIssueComment edits an issue comment. func (c *Client) EditIssueComment(owner, repo string, commentID int64, opt EditIssueCommentOption) (*Comment, *Response, error) { + if err := escapeValidatePathSegments(&owner, &repo); err != nil { + return nil, nil, err + } if err := opt.Validate(); err != nil { return nil, nil, err } @@ -131,6 +146,9 @@ func (c *Client) EditIssueComment(owner, repo string, commentID int64, opt EditI // DeleteIssueComment deletes an issue comment. func (c *Client) DeleteIssueComment(owner, repo string, commentID int64) (*Response, error) { + if err := escapeValidatePathSegments(&owner, &repo); err != nil { + return nil, err + } _, resp, err := c.getResponse("DELETE", fmt.Sprintf("/repos/%s/%s/issues/comments/%d", owner, repo, commentID), nil, nil) return resp, err } diff --git a/vendor/code.gitea.io/sdk/gitea/issue_label.go b/vendor/code.gitea.io/sdk/gitea/issue_label.go index b664dacd1..f343ee5ef 100644 --- a/vendor/code.gitea.io/sdk/gitea/issue_label.go +++ b/vendor/code.gitea.io/sdk/gitea/issue_label.go @@ -29,6 +29,9 @@ type ListLabelsOptions struct { // ListRepoLabels list labels of one repository func (c *Client) ListRepoLabels(owner, repo string, opt ListLabelsOptions) ([]*Label, *Response, error) { + if err := escapeValidatePathSegments(&owner, &repo); err != nil { + return nil, nil, err + } opt.setDefaults() labels := make([]*Label, 0, opt.PageSize) resp, err := c.getParsedResponse("GET", fmt.Sprintf("/repos/%s/%s/labels?%s", owner, repo, opt.getURLQuery().Encode()), nil, nil, &labels) @@ -37,6 +40,9 @@ func (c *Client) ListRepoLabels(owner, repo string, opt ListLabelsOptions) ([]*L // GetRepoLabel get one label of repository by repo it func (c *Client) GetRepoLabel(owner, repo string, id int64) (*Label, *Response, error) { + if err := escapeValidatePathSegments(&owner, &repo); err != nil { + return nil, nil, err + } label := new(Label) resp, err := c.getParsedResponse("GET", fmt.Sprintf("/repos/%s/%s/labels/%d", owner, repo, id), nil, nil, label) return label, resp, err @@ -67,6 +73,9 @@ func (opt CreateLabelOption) Validate() error { // CreateLabel create one label of repository func (c *Client) CreateLabel(owner, repo string, opt CreateLabelOption) (*Label, *Response, error) { + if err := escapeValidatePathSegments(&owner, &repo); err != nil { + return nil, nil, err + } if err := opt.Validate(); err != nil { return nil, nil, err } @@ -114,6 +123,9 @@ func (opt EditLabelOption) Validate() error { // EditLabel modify one label with options func (c *Client) EditLabel(owner, repo string, id int64, opt EditLabelOption) (*Label, *Response, error) { + if err := escapeValidatePathSegments(&owner, &repo); err != nil { + return nil, nil, err + } if err := opt.Validate(); err != nil { return nil, nil, err } @@ -128,12 +140,18 @@ func (c *Client) EditLabel(owner, repo string, id int64, opt EditLabelOption) (* // DeleteLabel delete one label of repository by id func (c *Client) DeleteLabel(owner, repo string, id int64) (*Response, error) { + if err := escapeValidatePathSegments(&owner, &repo); err != nil { + return nil, err + } _, resp, err := c.getResponse("DELETE", fmt.Sprintf("/repos/%s/%s/labels/%d", owner, repo, id), nil, nil) return resp, err } // GetIssueLabels get labels of one issue via issue id func (c *Client) GetIssueLabels(owner, repo string, index int64, opts ListLabelsOptions) ([]*Label, *Response, error) { + if err := escapeValidatePathSegments(&owner, &repo); err != nil { + return nil, nil, err + } labels := make([]*Label, 0, 5) resp, err := c.getParsedResponse("GET", fmt.Sprintf("/repos/%s/%s/issues/%d/labels?%s", owner, repo, index, opts.getURLQuery().Encode()), nil, nil, &labels) return labels, resp, err @@ -147,6 +165,9 @@ type IssueLabelsOption struct { // AddIssueLabels add one or more labels to one issue func (c *Client) AddIssueLabels(owner, repo string, index int64, opt IssueLabelsOption) ([]*Label, *Response, error) { + if err := escapeValidatePathSegments(&owner, &repo); err != nil { + return nil, nil, err + } body, err := json.Marshal(&opt) if err != nil { return nil, nil, err @@ -158,6 +179,9 @@ func (c *Client) AddIssueLabels(owner, repo string, index int64, opt IssueLabels // ReplaceIssueLabels replace old labels of issue with new labels func (c *Client) ReplaceIssueLabels(owner, repo string, index int64, opt IssueLabelsOption) ([]*Label, *Response, error) { + if err := escapeValidatePathSegments(&owner, &repo); err != nil { + return nil, nil, err + } body, err := json.Marshal(&opt) if err != nil { return nil, nil, err @@ -170,12 +194,18 @@ func (c *Client) ReplaceIssueLabels(owner, repo string, index int64, opt IssueLa // DeleteIssueLabel delete one label of one issue by issue id and label id // TODO: maybe we need delete by label name and issue id func (c *Client) DeleteIssueLabel(owner, repo string, index, label int64) (*Response, error) { + if err := escapeValidatePathSegments(&owner, &repo); err != nil { + return nil, err + } _, resp, err := c.getResponse("DELETE", fmt.Sprintf("/repos/%s/%s/issues/%d/labels/%d", owner, repo, index, label), nil, nil) return resp, err } // ClearIssueLabels delete all the labels of one issue. func (c *Client) ClearIssueLabels(owner, repo string, index int64) (*Response, error) { + if err := escapeValidatePathSegments(&owner, &repo); err != nil { + return nil, err + } _, resp, err := c.getResponse("DELETE", fmt.Sprintf("/repos/%s/%s/issues/%d/labels", owner, repo, index), nil, nil) return resp, err } diff --git a/vendor/code.gitea.io/sdk/gitea/issue_milestone.go b/vendor/code.gitea.io/sdk/gitea/issue_milestone.go index 236c2367b..a865a4583 100644 --- a/vendor/code.gitea.io/sdk/gitea/issue_milestone.go +++ b/vendor/code.gitea.io/sdk/gitea/issue_milestone.go @@ -49,6 +49,9 @@ func (opt *ListMilestoneOption) QueryEncode() string { // ListRepoMilestones list all the milestones of one repository func (c *Client) ListRepoMilestones(owner, repo string, opt ListMilestoneOption) ([]*Milestone, *Response, error) { + if err := escapeValidatePathSegments(&owner, &repo); err != nil { + return nil, nil, err + } opt.setDefaults() milestones := make([]*Milestone, 0, opt.PageSize) @@ -60,6 +63,9 @@ func (c *Client) ListRepoMilestones(owner, repo string, opt ListMilestoneOption) // GetMilestone get one milestone by repo name and milestone id func (c *Client) GetMilestone(owner, repo string, id int64) (*Milestone, *Response, error) { + if err := escapeValidatePathSegments(&owner, &repo); err != nil { + return nil, nil, err + } milestone := new(Milestone) resp, err := c.getParsedResponse("GET", fmt.Sprintf("/repos/%s/%s/milestones/%d", owner, repo, id), nil, nil, milestone) return milestone, resp, err @@ -72,6 +78,9 @@ func (c *Client) GetMilestoneByName(owner, repo string, name string) (*Milestone m, resp, err := c.resolveMilestoneByName(owner, repo, name) return m, resp, err } + if err := escapeValidatePathSegments(&owner, &repo, &name); err != nil { + return nil, nil, err + } milestone := new(Milestone) resp, err := c.getParsedResponse("GET", fmt.Sprintf("/repos/%s/%s/milestones/%s", owner, repo, name), nil, nil, milestone) return milestone, resp, err @@ -95,6 +104,9 @@ func (opt CreateMilestoneOption) Validate() error { // CreateMilestone create one milestone with options func (c *Client) CreateMilestone(owner, repo string, opt CreateMilestoneOption) (*Milestone, *Response, error) { + if err := escapeValidatePathSegments(&owner, &repo); err != nil { + return nil, nil, err + } if err := opt.Validate(); err != nil { return nil, nil, err } @@ -135,6 +147,9 @@ func (opt EditMilestoneOption) Validate() error { // EditMilestone modify milestone with options func (c *Client) EditMilestone(owner, repo string, id int64, opt EditMilestoneOption) (*Milestone, *Response, error) { + if err := escapeValidatePathSegments(&owner, &repo); err != nil { + return nil, nil, err + } if err := opt.Validate(); err != nil { return nil, nil, err } @@ -157,6 +172,9 @@ func (c *Client) EditMilestoneByName(owner, repo string, name string, opt EditMi } return c.EditMilestone(owner, repo, m.ID, opt) } + if err := escapeValidatePathSegments(&owner, &repo, &name); err != nil { + return nil, nil, err + } if err := opt.Validate(); err != nil { return nil, nil, err } @@ -171,6 +189,9 @@ func (c *Client) EditMilestoneByName(owner, repo string, name string, opt EditMi // DeleteMilestone delete one milestone by id func (c *Client) DeleteMilestone(owner, repo string, id int64) (*Response, error) { + if err := escapeValidatePathSegments(&owner, &repo); err != nil { + return nil, err + } _, resp, err := c.getResponse("DELETE", fmt.Sprintf("/repos/%s/%s/milestones/%d", owner, repo, id), nil, nil) return resp, err } @@ -185,6 +206,9 @@ func (c *Client) DeleteMilestoneByName(owner, repo string, name string) (*Respon } return c.DeleteMilestone(owner, repo, m.ID) } + if err := escapeValidatePathSegments(&owner, &repo, &name); err != nil { + return nil, err + } _, resp, err := c.getResponse("DELETE", fmt.Sprintf("/repos/%s/%s/milestones/%s", owner, repo, name), nil, nil) return resp, err } diff --git a/vendor/code.gitea.io/sdk/gitea/issue_reaction.go b/vendor/code.gitea.io/sdk/gitea/issue_reaction.go index 4ec203c59..b45c06664 100644 --- a/vendor/code.gitea.io/sdk/gitea/issue_reaction.go +++ b/vendor/code.gitea.io/sdk/gitea/issue_reaction.go @@ -20,7 +20,7 @@ type Reaction struct { // GetIssueReactions get a list reactions of an issue func (c *Client) GetIssueReactions(owner, repo string, index int64) ([]*Reaction, *Response, error) { - if err := c.checkServerVersionGreaterThanOrEqual(version1_11_0); err != nil { + if err := escapeValidatePathSegments(&owner, &repo); err != nil { return nil, nil, err } reactions := make([]*Reaction, 0, 10) @@ -30,7 +30,7 @@ func (c *Client) GetIssueReactions(owner, repo string, index int64) ([]*Reaction // GetIssueCommentReactions get a list of reactions from a comment of an issue func (c *Client) GetIssueCommentReactions(owner, repo string, commentID int64) ([]*Reaction, *Response, error) { - if err := c.checkServerVersionGreaterThanOrEqual(version1_11_0); err != nil { + if err := escapeValidatePathSegments(&owner, &repo); err != nil { return nil, nil, err } reactions := make([]*Reaction, 0, 10) @@ -45,7 +45,7 @@ type editReactionOption struct { // PostIssueReaction add a reaction to an issue func (c *Client) PostIssueReaction(owner, repo string, index int64, reaction string) (*Reaction, *Response, error) { - if err := c.checkServerVersionGreaterThanOrEqual(version1_11_0); err != nil { + if err := escapeValidatePathSegments(&owner, &repo); err != nil { return nil, nil, err } reactionResponse := new(Reaction) @@ -61,7 +61,7 @@ func (c *Client) PostIssueReaction(owner, repo string, index int64, reaction str // DeleteIssueReaction remove a reaction from an issue func (c *Client) DeleteIssueReaction(owner, repo string, index int64, reaction string) (*Response, error) { - if err := c.checkServerVersionGreaterThanOrEqual(version1_11_0); err != nil { + if err := escapeValidatePathSegments(&owner, &repo); err != nil { return nil, err } body, err := json.Marshal(&editReactionOption{Reaction: reaction}) @@ -74,7 +74,7 @@ func (c *Client) DeleteIssueReaction(owner, repo string, index int64, reaction s // PostIssueCommentReaction add a reaction to a comment of an issue func (c *Client) PostIssueCommentReaction(owner, repo string, commentID int64, reaction string) (*Reaction, *Response, error) { - if err := c.checkServerVersionGreaterThanOrEqual(version1_11_0); err != nil { + if err := escapeValidatePathSegments(&owner, &repo); err != nil { return nil, nil, err } reactionResponse := new(Reaction) @@ -90,7 +90,7 @@ func (c *Client) PostIssueCommentReaction(owner, repo string, commentID int64, r // DeleteIssueCommentReaction remove a reaction from a comment of an issue func (c *Client) DeleteIssueCommentReaction(owner, repo string, commentID int64, reaction string) (*Response, error) { - if err := c.checkServerVersionGreaterThanOrEqual(version1_11_0); err != nil { + if err := escapeValidatePathSegments(&owner, &repo); err != nil { return nil, err } body, err := json.Marshal(&editReactionOption{Reaction: reaction}) diff --git a/vendor/code.gitea.io/sdk/gitea/issue_stopwatch.go b/vendor/code.gitea.io/sdk/gitea/issue_stopwatch.go index fac2c07ef..ebb0b8ae4 100644 --- a/vendor/code.gitea.io/sdk/gitea/issue_stopwatch.go +++ b/vendor/code.gitea.io/sdk/gitea/issue_stopwatch.go @@ -11,8 +11,13 @@ import ( // StopWatch represents a running stopwatch of an issue / pr type StopWatch struct { - Created time.Time `json:"created"` - IssueIndex int64 `json:"issue_index"` + Created time.Time `json:"created"` + Seconds int64 `json:"seconds"` + Duration string `json:"duration"` + IssueIndex int64 `json:"issue_index"` + IssueTitle string `json:"issue_title"` + RepoOwnerName string `json:"repo_owner_name"` + RepoName string `json:"repo_name"` } // GetMyStopwatches list all stopwatches @@ -24,6 +29,9 @@ func (c *Client) GetMyStopwatches() ([]*StopWatch, *Response, error) { // DeleteIssueStopwatch delete / cancel a specific stopwatch func (c *Client) DeleteIssueStopwatch(owner, repo string, index int64) (*Response, error) { + if err := escapeValidatePathSegments(&owner, &repo); err != nil { + return nil, err + } _, resp, err := c.getResponse("DELETE", fmt.Sprintf("/repos/%s/%s/issues/%d/stopwatch/delete", owner, repo, index), nil, nil) return resp, err } @@ -31,6 +39,9 @@ func (c *Client) DeleteIssueStopwatch(owner, repo string, index int64) (*Respons // StartIssueStopWatch starts a stopwatch for an existing issue for a given // repository func (c *Client) StartIssueStopWatch(owner, repo string, index int64) (*Response, error) { + if err := escapeValidatePathSegments(&owner, &repo); err != nil { + return nil, err + } _, resp, err := c.getResponse("POST", fmt.Sprintf("/repos/%s/%s/issues/%d/stopwatch/start", owner, repo, index), nil, nil) return resp, err } @@ -38,6 +49,9 @@ func (c *Client) StartIssueStopWatch(owner, repo string, index int64) (*Response // StopIssueStopWatch stops an existing stopwatch for an issue in a given // repository func (c *Client) StopIssueStopWatch(owner, repo string, index int64) (*Response, error) { + if err := escapeValidatePathSegments(&owner, &repo); err != nil { + return nil, err + } _, resp, err := c.getResponse("POST", fmt.Sprintf("/repos/%s/%s/issues/%d/stopwatch/stop", owner, repo, index), nil, nil) return resp, err } diff --git a/vendor/code.gitea.io/sdk/gitea/issue_subscription.go b/vendor/code.gitea.io/sdk/gitea/issue_subscription.go index 0af4228c6..86853c718 100644 --- a/vendor/code.gitea.io/sdk/gitea/issue_subscription.go +++ b/vendor/code.gitea.io/sdk/gitea/issue_subscription.go @@ -11,7 +11,7 @@ import ( // GetIssueSubscribers get list of users who subscribed on an issue func (c *Client) GetIssueSubscribers(owner, repo string, index int64) ([]*User, *Response, error) { - if err := c.checkServerVersionGreaterThanOrEqual(version1_11_0); err != nil { + if err := escapeValidatePathSegments(&owner, &repo); err != nil { return nil, nil, err } subscribers := make([]*User, 0, 10) @@ -21,7 +21,7 @@ func (c *Client) GetIssueSubscribers(owner, repo string, index int64) ([]*User, // AddIssueSubscription Subscribe user to issue func (c *Client) AddIssueSubscription(owner, repo string, index int64, user string) (*Response, error) { - if err := c.checkServerVersionGreaterThanOrEqual(version1_11_0); err != nil { + if err := escapeValidatePathSegments(&owner, &repo, &user); err != nil { return nil, err } status, resp, err := c.getStatusCode("PUT", fmt.Sprintf("/repos/%s/%s/issues/%d/subscriptions/%s", owner, repo, index, user), nil, nil) @@ -39,7 +39,7 @@ func (c *Client) AddIssueSubscription(owner, repo string, index int64, user stri // DeleteIssueSubscription unsubscribe user from issue func (c *Client) DeleteIssueSubscription(owner, repo string, index int64, user string) (*Response, error) { - if err := c.checkServerVersionGreaterThanOrEqual(version1_11_0); err != nil { + if err := escapeValidatePathSegments(&owner, &repo, &user); err != nil { return nil, err } status, resp, err := c.getStatusCode("DELETE", fmt.Sprintf("/repos/%s/%s/issues/%d/subscriptions/%s", owner, repo, index, user), nil, nil) @@ -57,6 +57,9 @@ func (c *Client) DeleteIssueSubscription(owner, repo string, index int64, user s // CheckIssueSubscription check if current user is subscribed to an issue func (c *Client) CheckIssueSubscription(owner, repo string, index int64) (*WatchInfo, *Response, error) { + if err := escapeValidatePathSegments(&owner, &repo); err != nil { + return nil, nil, err + } if err := c.checkServerVersionGreaterThanOrEqual(version1_12_0); err != nil { return nil, nil, err } diff --git a/vendor/code.gitea.io/sdk/gitea/issue_tracked_time.go b/vendor/code.gitea.io/sdk/gitea/issue_tracked_time.go index 9a9922e66..c55851623 100644 --- a/vendor/code.gitea.io/sdk/gitea/issue_tracked_time.go +++ b/vendor/code.gitea.io/sdk/gitea/issue_tracked_time.go @@ -8,6 +8,7 @@ import ( "bytes" "encoding/json" "fmt" + "net/url" "time" ) @@ -25,33 +26,50 @@ type TrackedTime struct { Issue *Issue `json:"issue"` } -// GetUserTrackedTimes list tracked times of a user -func (c *Client) GetUserTrackedTimes(owner, repo, user string) ([]*TrackedTime, *Response, error) { - if err := c.checkServerVersionGreaterThanOrEqual(version1_11_0); err != nil { - return nil, nil, err +// ListTrackedTimesOptions options for listing repository's tracked times +type ListTrackedTimesOptions struct { + ListOptions + Since time.Time + Before time.Time + // User filter is only used by ListRepoTrackedTimes !!! + User string +} + +// QueryEncode turns options into querystring argument +func (opt *ListTrackedTimesOptions) QueryEncode() string { + query := opt.getURLQuery() + + if !opt.Since.IsZero() { + query.Add("since", opt.Since.Format(time.RFC3339)) } - times := make([]*TrackedTime, 0, 10) - resp, err := c.getParsedResponse("GET", fmt.Sprintf("/repos/%s/%s/times/%s", owner, repo, user), nil, nil, ×) - return times, resp, err + if !opt.Before.IsZero() { + query.Add("before", opt.Before.Format(time.RFC3339)) + } + + if len(opt.User) != 0 { + query.Add("user", opt.User) + } + + return query.Encode() } -// GetRepoTrackedTimes list tracked times of a repository -func (c *Client) GetRepoTrackedTimes(owner, repo string) ([]*TrackedTime, *Response, error) { - if err := c.checkServerVersionGreaterThanOrEqual(version1_11_0); err != nil { +// ListRepoTrackedTimes list tracked times of a repository +func (c *Client) ListRepoTrackedTimes(owner, repo string, opt ListTrackedTimesOptions) ([]*TrackedTime, *Response, error) { + if err := escapeValidatePathSegments(&owner, &repo); err != nil { return nil, nil, err } - times := make([]*TrackedTime, 0, 10) - resp, err := c.getParsedResponse("GET", fmt.Sprintf("/repos/%s/%s/times", owner, repo), nil, nil, ×) + link, _ := url.Parse(fmt.Sprintf("/repos/%s/%s/times", owner, repo)) + opt.setDefaults() + link.RawQuery = opt.QueryEncode() + times := make([]*TrackedTime, 0, opt.PageSize) + resp, err := c.getParsedResponse("GET", link.String(), jsonHeader, nil, ×) return times, resp, err } // GetMyTrackedTimes list tracked times of the current user func (c *Client) GetMyTrackedTimes() ([]*TrackedTime, *Response, error) { - if err := c.checkServerVersionGreaterThanOrEqual(version1_11_0); err != nil { - return nil, nil, err - } times := make([]*TrackedTime, 0, 10) - resp, err := c.getParsedResponse("GET", "/user/times", nil, nil, ×) + resp, err := c.getParsedResponse("GET", "/user/times", jsonHeader, nil, ×) return times, resp, err } @@ -75,7 +93,7 @@ func (opt AddTimeOption) Validate() error { // AddTime adds time to issue with the given index func (c *Client) AddTime(owner, repo string, index int64, opt AddTimeOption) (*TrackedTime, *Response, error) { - if err := c.checkServerVersionGreaterThanOrEqual(version1_11_0); err != nil { + if err := escapeValidatePathSegments(&owner, &repo); err != nil { return nil, nil, err } if err := opt.Validate(); err != nil { @@ -92,36 +110,33 @@ func (c *Client) AddTime(owner, repo string, index int64, opt AddTimeOption) (*T return t, resp, err } -// ListTrackedTimesOptions options for listing repository's tracked times -type ListTrackedTimesOptions struct { - ListOptions -} - -// ListTrackedTimes list tracked times of a single issue for a given repository -func (c *Client) ListTrackedTimes(owner, repo string, index int64, opt ListTrackedTimesOptions) ([]*TrackedTime, *Response, error) { - if err := c.checkServerVersionGreaterThanOrEqual(version1_11_0); err != nil { +// ListIssueTrackedTimes list tracked times of a single issue for a given repository +func (c *Client) ListIssueTrackedTimes(owner, repo string, index int64, opt ListTrackedTimesOptions) ([]*TrackedTime, *Response, error) { + if err := escapeValidatePathSegments(&owner, &repo); err != nil { return nil, nil, err } + link, _ := url.Parse(fmt.Sprintf("/repos/%s/%s/issues/%d/times", owner, repo, index)) opt.setDefaults() + link.RawQuery = opt.QueryEncode() times := make([]*TrackedTime, 0, opt.PageSize) - resp, err := c.getParsedResponse("GET", fmt.Sprintf("/repos/%s/%s/issues/%d/times?%s", owner, repo, index, opt.getURLQuery().Encode()), nil, nil, ×) + resp, err := c.getParsedResponse("GET", link.String(), jsonHeader, nil, ×) return times, resp, err } // ResetIssueTime reset tracked time of a single issue for a given repository func (c *Client) ResetIssueTime(owner, repo string, index int64) (*Response, error) { - if err := c.checkServerVersionGreaterThanOrEqual(version1_11_0); err != nil { + if err := escapeValidatePathSegments(&owner, &repo); err != nil { return nil, err } - _, resp, err := c.getResponse("DELETE", fmt.Sprintf("/repos/%s/%s/issues/%d/times", owner, repo, index), nil, nil) + _, resp, err := c.getResponse("DELETE", fmt.Sprintf("/repos/%s/%s/issues/%d/times", owner, repo, index), jsonHeader, nil) return resp, err } // DeleteTime delete a specific tracked time by id of a single issue for a given repository func (c *Client) DeleteTime(owner, repo string, index, timeID int64) (*Response, error) { - if err := c.checkServerVersionGreaterThanOrEqual(version1_11_0); err != nil { + if err := escapeValidatePathSegments(&owner, &repo); err != nil { return nil, err } - _, resp, err := c.getResponse("DELETE", fmt.Sprintf("/repos/%s/%s/issues/%d/times/%d", owner, repo, index, timeID), nil, nil) + _, resp, err := c.getResponse("DELETE", fmt.Sprintf("/repos/%s/%s/issues/%d/times/%d", owner, repo, index, timeID), jsonHeader, nil) return resp, err } diff --git a/vendor/code.gitea.io/sdk/gitea/notifications.go b/vendor/code.gitea.io/sdk/gitea/notifications.go index 30b6b6d01..de53e2ce9 100644 --- a/vendor/code.gitea.io/sdk/gitea/notifications.go +++ b/vendor/code.gitea.io/sdk/gitea/notifications.go @@ -176,14 +176,17 @@ func (c *Client) ReadNotifications(opt MarkNotificationOptions) (*Response, erro } // ListRepoNotifications list users's notification threads on a specific repo -func (c *Client) ListRepoNotifications(owner, reponame string, opt ListNotificationOptions) ([]*NotificationThread, *Response, error) { +func (c *Client) ListRepoNotifications(owner, repo string, opt ListNotificationOptions) ([]*NotificationThread, *Response, error) { + if err := escapeValidatePathSegments(&owner, &repo); err != nil { + return nil, nil, err + } if err := c.checkServerVersionGreaterThanOrEqual(version1_12_0); err != nil { return nil, nil, err } if err := opt.Validate(c); err != nil { return nil, nil, err } - link, _ := url.Parse(fmt.Sprintf("/repos/%s/%s/notifications", owner, reponame)) + link, _ := url.Parse(fmt.Sprintf("/repos/%s/%s/notifications", owner, repo)) link.RawQuery = opt.QueryEncode() threads := make([]*NotificationThread, 0, 10) resp, err := c.getParsedResponse("GET", link.String(), nil, nil, &threads) @@ -191,14 +194,17 @@ func (c *Client) ListRepoNotifications(owner, reponame string, opt ListNotificat } // ReadRepoNotifications mark notification threads as read on a specific repo -func (c *Client) ReadRepoNotifications(owner, reponame string, opt MarkNotificationOptions) (*Response, error) { +func (c *Client) ReadRepoNotifications(owner, repo string, opt MarkNotificationOptions) (*Response, error) { + if err := escapeValidatePathSegments(&owner, &repo); err != nil { + return nil, err + } if err := c.checkServerVersionGreaterThanOrEqual(version1_12_0); err != nil { return nil, err } if err := opt.Validate(c); err != nil { return nil, err } - link, _ := url.Parse(fmt.Sprintf("/repos/%s/%s/notifications", owner, reponame)) + link, _ := url.Parse(fmt.Sprintf("/repos/%s/%s/notifications", owner, repo)) link.RawQuery = opt.QueryEncode() _, resp, err := c.getResponse("PUT", link.String(), nil, nil) return resp, err diff --git a/vendor/code.gitea.io/sdk/gitea/org.go b/vendor/code.gitea.io/sdk/gitea/org.go index ed6c678e6..b7c439bc4 100644 --- a/vendor/code.gitea.io/sdk/gitea/org.go +++ b/vendor/code.gitea.io/sdk/gitea/org.go @@ -52,6 +52,9 @@ func (c *Client) ListMyOrgs(opt ListOrgsOptions) ([]*Organization, *Response, er // ListUserOrgs list all of some user's organizations func (c *Client) ListUserOrgs(user string, opt ListOrgsOptions) ([]*Organization, *Response, error) { + if err := escapeValidatePathSegments(&user); err != nil { + return nil, nil, err + } opt.setDefaults() orgs := make([]*Organization, 0, opt.PageSize) resp, err := c.getParsedResponse("GET", fmt.Sprintf("/users/%s/orgs?%s", user, opt.getURLQuery().Encode()), nil, nil, &orgs) @@ -60,6 +63,9 @@ func (c *Client) ListUserOrgs(user string, opt ListOrgsOptions) ([]*Organization // GetOrg get one organization by name func (c *Client) GetOrg(orgname string) (*Organization, *Response, error) { + if err := escapeValidatePathSegments(&orgname); err != nil { + return nil, nil, err + } org := new(Organization) resp, err := c.getParsedResponse("GET", fmt.Sprintf("/orgs/%s", orgname), nil, nil, org) return org, resp, err @@ -124,6 +130,9 @@ func (opt EditOrgOption) Validate() error { // EditOrg modify one organization via options func (c *Client) EditOrg(orgname string, opt EditOrgOption) (*Response, error) { + if err := escapeValidatePathSegments(&orgname); err != nil { + return nil, err + } if err := opt.Validate(); err != nil { return nil, err } @@ -137,6 +146,9 @@ func (c *Client) EditOrg(orgname string, opt EditOrgOption) (*Response, error) { // DeleteOrg deletes an organization func (c *Client) DeleteOrg(orgname string) (*Response, error) { + if err := escapeValidatePathSegments(&orgname); err != nil { + return nil, err + } _, resp, err := c.getResponse("DELETE", fmt.Sprintf("/orgs/%s", orgname), jsonHeader, nil) return resp, err } diff --git a/vendor/code.gitea.io/sdk/gitea/org_member.go b/vendor/code.gitea.io/sdk/gitea/org_member.go index 0f5b54296..1eed90f6b 100644 --- a/vendor/code.gitea.io/sdk/gitea/org_member.go +++ b/vendor/code.gitea.io/sdk/gitea/org_member.go @@ -12,7 +12,10 @@ import ( // DeleteOrgMembership remove a member from an organization func (c *Client) DeleteOrgMembership(org, user string) (*Response, error) { - _, resp, err := c.getResponse("DELETE", fmt.Sprintf("/orgs/%s/members/%s", url.PathEscape(org), url.PathEscape(user)), nil, nil) + if err := escapeValidatePathSegments(&org, &user); err != nil { + return nil, err + } + _, resp, err := c.getResponse("DELETE", fmt.Sprintf("/orgs/%s/members/%s", org, user), nil, nil) return resp, err } @@ -23,10 +26,13 @@ type ListOrgMembershipOption struct { // ListOrgMembership list an organization's members func (c *Client) ListOrgMembership(org string, opt ListOrgMembershipOption) ([]*User, *Response, error) { + if err := escapeValidatePathSegments(&org); err != nil { + return nil, nil, err + } opt.setDefaults() users := make([]*User, 0, opt.PageSize) - link, _ := url.Parse(fmt.Sprintf("/orgs/%s/members", url.PathEscape(org))) + link, _ := url.Parse(fmt.Sprintf("/orgs/%s/members", org)) link.RawQuery = opt.getURLQuery().Encode() resp, err := c.getParsedResponse("GET", link.String(), jsonHeader, nil, &users) return users, resp, err @@ -34,10 +40,13 @@ func (c *Client) ListOrgMembership(org string, opt ListOrgMembershipOption) ([]* // ListPublicOrgMembership list an organization's members func (c *Client) ListPublicOrgMembership(org string, opt ListOrgMembershipOption) ([]*User, *Response, error) { + if err := escapeValidatePathSegments(&org); err != nil { + return nil, nil, err + } opt.setDefaults() users := make([]*User, 0, opt.PageSize) - link, _ := url.Parse(fmt.Sprintf("/orgs/%s/public_members", url.PathEscape(org))) + link, _ := url.Parse(fmt.Sprintf("/orgs/%s/public_members", org)) link.RawQuery = opt.getURLQuery().Encode() resp, err := c.getParsedResponse("GET", link.String(), jsonHeader, nil, &users) return users, resp, err @@ -45,7 +54,10 @@ func (c *Client) ListPublicOrgMembership(org string, opt ListOrgMembershipOption // CheckOrgMembership Check if a user is a member of an organization func (c *Client) CheckOrgMembership(org, user string) (bool, *Response, error) { - status, resp, err := c.getStatusCode("GET", fmt.Sprintf("/orgs/%s/members/%s", url.PathEscape(org), url.PathEscape(user)), nil, nil) + if err := escapeValidatePathSegments(&org, &user); err != nil { + return false, nil, err + } + status, resp, err := c.getStatusCode("GET", fmt.Sprintf("/orgs/%s/members/%s", org, user), nil, nil) if err != nil { return false, resp, err } @@ -61,7 +73,10 @@ func (c *Client) CheckOrgMembership(org, user string) (bool, *Response, error) { // CheckPublicOrgMembership Check if a user is a member of an organization func (c *Client) CheckPublicOrgMembership(org, user string) (bool, *Response, error) { - status, resp, err := c.getStatusCode("GET", fmt.Sprintf("/orgs/%s/public_members/%s", url.PathEscape(org), url.PathEscape(user)), nil, nil) + if err := escapeValidatePathSegments(&org, &user); err != nil { + return false, nil, err + } + status, resp, err := c.getStatusCode("GET", fmt.Sprintf("/orgs/%s/public_members/%s", org, user), nil, nil) if err != nil { return false, resp, err } @@ -77,15 +92,18 @@ func (c *Client) CheckPublicOrgMembership(org, user string) (bool, *Response, er // SetPublicOrgMembership publicize/conceal a user's membership func (c *Client) SetPublicOrgMembership(org, user string, visible bool) (*Response, error) { + if err := escapeValidatePathSegments(&org, &user); err != nil { + return nil, err + } var ( status int err error resp *Response ) if visible { - status, resp, err = c.getStatusCode("PUT", fmt.Sprintf("/orgs/%s/public_members/%s", url.PathEscape(org), url.PathEscape(user)), nil, nil) + status, resp, err = c.getStatusCode("PUT", fmt.Sprintf("/orgs/%s/public_members/%s", org, user), nil, nil) } else { - status, resp, err = c.getStatusCode("DELETE", fmt.Sprintf("/orgs/%s/public_members/%s", url.PathEscape(org), url.PathEscape(user)), nil, nil) + status, resp, err = c.getStatusCode("DELETE", fmt.Sprintf("/orgs/%s/public_members/%s", org, user), nil, nil) } if err != nil { return resp, err diff --git a/vendor/code.gitea.io/sdk/gitea/org_team.go b/vendor/code.gitea.io/sdk/gitea/org_team.go index 148d2c2c3..0373c6ed2 100644 --- a/vendor/code.gitea.io/sdk/gitea/org_team.go +++ b/vendor/code.gitea.io/sdk/gitea/org_team.go @@ -30,6 +30,9 @@ type ListTeamsOptions struct { // ListOrgTeams lists all teams of an organization func (c *Client) ListOrgTeams(org string, opt ListTeamsOptions) ([]*Team, *Response, error) { + if err := escapeValidatePathSegments(&org); err != nil { + return nil, nil, err + } opt.setDefaults() teams := make([]*Team, 0, opt.PageSize) resp, err := c.getParsedResponse("GET", fmt.Sprintf("/orgs/%s/teams?%s", org, opt.getURLQuery().Encode()), nil, nil, &teams) @@ -83,6 +86,9 @@ func (opt CreateTeamOption) Validate() error { // CreateTeam creates a team for an organization func (c *Client) CreateTeam(org string, opt CreateTeamOption) (*Team, *Response, error) { + if err := escapeValidatePathSegments(&org); err != nil { + return nil, nil, err + } if err := opt.Validate(); err != nil { return nil, nil, err } @@ -159,6 +165,9 @@ func (c *Client) ListTeamMembers(id int64, opt ListTeamMembersOptions) ([]*User, // GetTeamMember gets a member of a team func (c *Client) GetTeamMember(id int64, user string) (*User, *Response, error) { + if err := escapeValidatePathSegments(&user); err != nil { + return nil, nil, err + } m := new(User) resp, err := c.getParsedResponse("GET", fmt.Sprintf("/teams/%d/members/%s", id, user), nil, nil, m) return m, resp, err @@ -166,12 +175,18 @@ func (c *Client) GetTeamMember(id int64, user string) (*User, *Response, error) // AddTeamMember adds a member to a team func (c *Client) AddTeamMember(id int64, user string) (*Response, error) { + if err := escapeValidatePathSegments(&user); err != nil { + return nil, err + } _, resp, err := c.getResponse("PUT", fmt.Sprintf("/teams/%d/members/%s", id, user), nil, nil) return resp, err } // RemoveTeamMember removes a member from a team func (c *Client) RemoveTeamMember(id int64, user string) (*Response, error) { + if err := escapeValidatePathSegments(&user); err != nil { + return nil, err + } _, resp, err := c.getResponse("DELETE", fmt.Sprintf("/teams/%d/members/%s", id, user), nil, nil) return resp, err } @@ -191,12 +206,18 @@ func (c *Client) ListTeamRepositories(id int64, opt ListTeamRepositoriesOptions) // AddTeamRepository adds a repository to a team func (c *Client) AddTeamRepository(id int64, org, repo string) (*Response, error) { + if err := escapeValidatePathSegments(&org, &repo); err != nil { + return nil, err + } _, resp, err := c.getResponse("PUT", fmt.Sprintf("/teams/%d/repos/%s/%s", id, org, repo), nil, nil) return resp, err } // RemoveTeamRepository removes a repository from a team func (c *Client) RemoveTeamRepository(id int64, org, repo string) (*Response, error) { + if err := escapeValidatePathSegments(&org, &repo); err != nil { + return nil, err + } _, resp, err := c.getResponse("DELETE", fmt.Sprintf("/teams/%d/repos/%s/%s", id, org, repo), nil, nil) return resp, err } diff --git a/vendor/code.gitea.io/sdk/gitea/pull.go b/vendor/code.gitea.io/sdk/gitea/pull.go index c41ab3b01..7c946e891 100644 --- a/vendor/code.gitea.io/sdk/gitea/pull.go +++ b/vendor/code.gitea.io/sdk/gitea/pull.go @@ -99,19 +99,37 @@ func (opt *ListPullRequestsOptions) QueryEncode() string { // ListRepoPullRequests list PRs of one repository func (c *Client) ListRepoPullRequests(owner, repo string, opt ListPullRequestsOptions) ([]*PullRequest, *Response, error) { + if err := escapeValidatePathSegments(&owner, &repo); err != nil { + return nil, nil, err + } opt.setDefaults() prs := make([]*PullRequest, 0, opt.PageSize) link, _ := url.Parse(fmt.Sprintf("/repos/%s/%s/pulls", owner, repo)) link.RawQuery = opt.QueryEncode() resp, err := c.getParsedResponse("GET", link.String(), jsonHeader, nil, &prs) + if c.checkServerVersionGreaterThanOrEqual(version1_14_0) != nil { + for i := range prs { + if err := fixPullHeadSha(c, prs[i]); err != nil { + return prs, resp, err + } + } + } return prs, resp, err } // GetPullRequest get information of one PR func (c *Client) GetPullRequest(owner, repo string, index int64) (*PullRequest, *Response, error) { + if err := escapeValidatePathSegments(&owner, &repo); err != nil { + return nil, nil, err + } pr := new(PullRequest) resp, err := c.getParsedResponse("GET", fmt.Sprintf("/repos/%s/%s/pulls/%d", owner, repo, index), nil, nil, pr) + if c.checkServerVersionGreaterThanOrEqual(version1_14_0) != nil { + if err := fixPullHeadSha(c, pr); err != nil { + return pr, resp, err + } + } return pr, resp, err } @@ -130,6 +148,9 @@ type CreatePullRequestOption struct { // CreatePullRequest create pull request with options func (c *Client) CreatePullRequest(owner, repo string, opt CreatePullRequestOption) (*PullRequest, *Response, error) { + if err := escapeValidatePathSegments(&owner, &repo); err != nil { + return nil, nil, err + } body, err := json.Marshal(&opt) if err != nil { return nil, nil, err @@ -169,6 +190,9 @@ func (opt EditPullRequestOption) Validate(c *Client) error { // EditPullRequest modify pull request with PR id and options func (c *Client) EditPullRequest(owner, repo string, index int64, opt EditPullRequestOption) (*PullRequest, *Response, error) { + if err := escapeValidatePathSegments(&owner, &repo); err != nil { + return nil, nil, err + } if err := opt.Validate(c); err != nil { return nil, nil, err } @@ -202,6 +226,9 @@ func (opt MergePullRequestOption) Validate(c *Client) error { // MergePullRequest merge a PR to repository by PR id func (c *Client) MergePullRequest(owner, repo string, index int64, opt MergePullRequestOption) (bool, *Response, error) { + if err := escapeValidatePathSegments(&owner, &repo); err != nil { + return false, nil, err + } if err := opt.Validate(c); err != nil { return false, nil, err } @@ -218,6 +245,9 @@ func (c *Client) MergePullRequest(owner, repo string, index int64, opt MergePull // IsPullRequestMerged test if one PR is merged to one repository func (c *Client) IsPullRequestMerged(owner, repo string, index int64) (bool, *Response, error) { + if err := escapeValidatePathSegments(&owner, &repo); err != nil { + return false, nil, err + } status, resp, err := c.getStatusCode("GET", fmt.Sprintf("/repos/%s/%s/pulls/%d/merge", owner, repo, index), nil, nil) if err != nil { @@ -229,6 +259,9 @@ func (c *Client) IsPullRequestMerged(owner, repo string, index int64) (bool, *Re // getPullRequestDiffOrPatch gets the patch or diff file as bytes for a PR func (c *Client) getPullRequestDiffOrPatch(owner, repo, kind string, index int64) ([]byte, *Response, error) { + if err := escapeValidatePathSegments(&owner, &repo, &kind); err != nil { + return nil, nil, err + } if err := c.checkServerVersionGreaterThanOrEqual(version1_13_0); err != nil { r, _, err2 := c.GetRepo(owner, repo) if err2 != nil { @@ -251,3 +284,23 @@ func (c *Client) GetPullRequestPatch(owner, repo string, index int64) ([]byte, * func (c *Client) GetPullRequestDiff(owner, repo string, index int64) ([]byte, *Response, error) { return c.getPullRequestDiffOrPatch(owner, repo, "diff", index) } + +// fixPullHeadSha is a workaround for https://github.com/go-gitea/gitea/issues/12675 +// When no head sha is available, this is because the branch got deleted in the base repo. +// pr.Head.Ref points in this case not to the head repo branch name, but the base repo ref, +// which stays available to resolve the commit sha. This is fixed for gitea >= 1.14.0 +func fixPullHeadSha(client *Client, pr *PullRequest) error { + if pr.Base != nil && pr.Base.Repository != nil && pr.Base.Repository.Owner != nil && + pr.Head != nil && pr.Head.Ref != "" && pr.Head.Sha == "" { + owner := pr.Base.Repository.Owner.UserName + repo := pr.Base.Repository.Name + refs, _, err := client.GetRepoRefs(owner, repo, pr.Head.Ref) + if err != nil { + return err + } else if len(refs) == 0 { + return fmt.Errorf("unable to resolve PR ref '%s'", pr.Head.Ref) + } + pr.Head.Sha = refs[0].Object.SHA + } + return nil +} diff --git a/vendor/code.gitea.io/sdk/gitea/pull_review.go b/vendor/code.gitea.io/sdk/gitea/pull_review.go index fc0c22c2d..fa7921b02 100644 --- a/vendor/code.gitea.io/sdk/gitea/pull_review.go +++ b/vendor/code.gitea.io/sdk/gitea/pull_review.go @@ -33,15 +33,19 @@ const ( // PullReview represents a pull request review type PullReview struct { - ID int64 `json:"id"` - Reviewer *User `json:"user"` - State ReviewStateType `json:"state"` - Body string `json:"body"` - CommitID string `json:"commit_id"` - Stale bool `json:"stale"` - Official bool `json:"official"` - CodeCommentsCount int `json:"comments_count"` - Submitted time.Time `json:"submitted_at"` + ID int64 `json:"id"` + Reviewer *User `json:"user"` + ReviewerTeam *Team `json:"team"` + State ReviewStateType `json:"state"` + Body string `json:"body"` + CommitID string `json:"commit_id"` + // Stale indicates if the pull has changed since the review + Stale bool `json:"stale"` + // Official indicates if the review counts towards the required approval limit, if PR base is a protected branch + Official bool `json:"official"` + Dismissed bool `json:"dismissed"` + CodeCommentsCount int `json:"comments_count"` + Submitted time.Time `json:"submitted_at"` HTMLURL string `json:"html_url"` HTMLPullURL string `json:"pull_request_url"` @@ -93,6 +97,17 @@ type SubmitPullReviewOptions struct { Body string `json:"body"` } +// DismissPullReviewOptions are options to dismiss a pull review +type DismissPullReviewOptions struct { + Message string `json:"message"` +} + +// PullReviewRequestOptions are options to add or remove pull review requests +type PullReviewRequestOptions struct { + Reviewers []string `json:"reviewers"` + TeamReviewers []string `json:"team_reviewers"` +} + // ListPullReviewsOptions options for listing PullReviews type ListPullReviewsOptions struct { ListOptions @@ -132,6 +147,9 @@ func (opt CreatePullReviewComment) Validate() error { // ListPullReviews lists all reviews of a pull request func (c *Client) ListPullReviews(owner, repo string, index int64, opt ListPullReviewsOptions) ([]*PullReview, *Response, error) { + if err := escapeValidatePathSegments(&owner, &repo); err != nil { + return nil, nil, err + } if err := c.checkServerVersionGreaterThanOrEqual(version1_12_0); err != nil { return nil, nil, err } @@ -147,6 +165,9 @@ func (c *Client) ListPullReviews(owner, repo string, index int64, opt ListPullRe // GetPullReview gets a specific review of a pull request func (c *Client) GetPullReview(owner, repo string, index, id int64) (*PullReview, *Response, error) { + if err := escapeValidatePathSegments(&owner, &repo); err != nil { + return nil, nil, err + } if err := c.checkServerVersionGreaterThanOrEqual(version1_12_0); err != nil { return nil, nil, err } @@ -158,6 +179,9 @@ func (c *Client) GetPullReview(owner, repo string, index, id int64) (*PullReview // ListPullReviewComments lists all comments of a pull request review func (c *Client) ListPullReviewComments(owner, repo string, index, id int64) ([]*PullReviewComment, *Response, error) { + if err := escapeValidatePathSegments(&owner, &repo); err != nil { + return nil, nil, err + } if err := c.checkServerVersionGreaterThanOrEqual(version1_12_0); err != nil { return nil, nil, err } @@ -170,6 +194,9 @@ func (c *Client) ListPullReviewComments(owner, repo string, index, id int64) ([] // DeletePullReview delete a specific review from a pull request func (c *Client) DeletePullReview(owner, repo string, index, id int64) (*Response, error) { + if err := escapeValidatePathSegments(&owner, &repo); err != nil { + return nil, err + } if err := c.checkServerVersionGreaterThanOrEqual(version1_12_0); err != nil { return nil, err } @@ -180,6 +207,9 @@ func (c *Client) DeletePullReview(owner, repo string, index, id int64) (*Respons // CreatePullReview create a review to an pull request func (c *Client) CreatePullReview(owner, repo string, index int64, opt CreatePullReviewOptions) (*PullReview, *Response, error) { + if err := escapeValidatePathSegments(&owner, &repo); err != nil { + return nil, nil, err + } if err := c.checkServerVersionGreaterThanOrEqual(version1_12_0); err != nil { return nil, nil, err } @@ -200,6 +230,9 @@ func (c *Client) CreatePullReview(owner, repo string, index int64, opt CreatePul // SubmitPullReview submit a pending review to an pull request func (c *Client) SubmitPullReview(owner, repo string, index, id int64, opt SubmitPullReviewOptions) (*PullReview, *Response, error) { + if err := escapeValidatePathSegments(&owner, &repo); err != nil { + return nil, nil, err + } if err := c.checkServerVersionGreaterThanOrEqual(version1_12_0); err != nil { return nil, nil, err } @@ -217,3 +250,75 @@ func (c *Client) SubmitPullReview(owner, repo string, index, id int64, opt Submi jsonHeader, bytes.NewReader(body), r) return r, resp, err } + +// CreateReviewRequests create review requests to an pull request +func (c *Client) CreateReviewRequests(owner, repo string, index int64, opt PullReviewRequestOptions) (*Response, error) { + if err := escapeValidatePathSegments(&owner, &repo); err != nil { + return nil, err + } + if err := c.checkServerVersionGreaterThanOrEqual(version1_14_0); err != nil { + return nil, err + } + body, err := json.Marshal(&opt) + if err != nil { + return nil, err + } + + _, resp, err := c.getResponse("POST", + fmt.Sprintf("/repos/%s/%s/pulls/%d/requested_reviewers", owner, repo, index), + jsonHeader, bytes.NewReader(body)) + return resp, err +} + +// DeleteReviewRequests delete review requests to an pull request +func (c *Client) DeleteReviewRequests(owner, repo string, index int64, opt PullReviewRequestOptions) (*Response, error) { + if err := escapeValidatePathSegments(&owner, &repo); err != nil { + return nil, err + } + if err := c.checkServerVersionGreaterThanOrEqual(version1_14_0); err != nil { + return nil, err + } + body, err := json.Marshal(&opt) + if err != nil { + return nil, err + } + + _, resp, err := c.getResponse("DELETE", + fmt.Sprintf("/repos/%s/%s/pulls/%d/requested_reviewers", owner, repo, index), + jsonHeader, bytes.NewReader(body)) + return resp, err +} + +// DismissPullReview dismiss a review for a pull request +func (c *Client) DismissPullReview(owner, repo string, index, id int64, opt DismissPullReviewOptions) (*Response, error) { + if err := escapeValidatePathSegments(&owner, &repo); err != nil { + return nil, err + } + if err := c.checkServerVersionGreaterThanOrEqual(version1_14_0); err != nil { + return nil, err + } + body, err := json.Marshal(&opt) + if err != nil { + return nil, err + } + + _, resp, err := c.getResponse("POST", + fmt.Sprintf("/repos/%s/%s/pulls/%d/reviews/%d/dismissals", owner, repo, index, id), + jsonHeader, bytes.NewReader(body)) + return resp, err +} + +// UnDismissPullReview cancel to dismiss a review for a pull request +func (c *Client) UnDismissPullReview(owner, repo string, index, id int64) (*Response, error) { + if err := escapeValidatePathSegments(&owner, &repo); err != nil { + return nil, err + } + if err := c.checkServerVersionGreaterThanOrEqual(version1_14_0); err != nil { + return nil, err + } + + _, resp, err := c.getResponse("POST", + fmt.Sprintf("/repos/%s/%s/pulls/%d/reviews/%d/undismissals", owner, repo, index, id), + jsonHeader, nil) + return resp, err +} diff --git a/vendor/code.gitea.io/sdk/gitea/release.go b/vendor/code.gitea.io/sdk/gitea/release.go index d8d28c5bd..7d36e7106 100644 --- a/vendor/code.gitea.io/sdk/gitea/release.go +++ b/vendor/code.gitea.io/sdk/gitea/release.go @@ -21,6 +21,7 @@ type Release struct { Title string `json:"name"` Note string `json:"body"` URL string `json:"url"` + HTMLURL string `json:"html_url"` TarURL string `json:"tarball_url"` ZipURL string `json:"zipball_url"` IsDraft bool `json:"draft"` @@ -37,32 +38,41 @@ type ListReleasesOptions struct { } // ListReleases list releases of a repository -func (c *Client) ListReleases(user, repo string, opt ListReleasesOptions) ([]*Release, *Response, error) { +func (c *Client) ListReleases(owner, repo string, opt ListReleasesOptions) ([]*Release, *Response, error) { + if err := escapeValidatePathSegments(&owner, &repo); err != nil { + return nil, nil, err + } opt.setDefaults() releases := make([]*Release, 0, opt.PageSize) resp, err := c.getParsedResponse("GET", - fmt.Sprintf("/repos/%s/%s/releases?%s", user, repo, opt.getURLQuery().Encode()), + fmt.Sprintf("/repos/%s/%s/releases?%s", owner, repo, opt.getURLQuery().Encode()), nil, nil, &releases) return releases, resp, err } // GetRelease get a release of a repository by id -func (c *Client) GetRelease(user, repo string, id int64) (*Release, *Response, error) { +func (c *Client) GetRelease(owner, repo string, id int64) (*Release, *Response, error) { + if err := escapeValidatePathSegments(&owner, &repo); err != nil { + return nil, nil, err + } r := new(Release) resp, err := c.getParsedResponse("GET", - fmt.Sprintf("/repos/%s/%s/releases/%d", user, repo, id), + fmt.Sprintf("/repos/%s/%s/releases/%d", owner, repo, id), jsonHeader, nil, &r) return r, resp, err } // GetReleaseByTag get a release of a repository by tag -func (c *Client) GetReleaseByTag(user, repo string, tag string) (*Release, *Response, error) { +func (c *Client) GetReleaseByTag(owner, repo string, tag string) (*Release, *Response, error) { if c.checkServerVersionGreaterThanOrEqual(version1_13_0) != nil { - return c.fallbackGetReleaseByTag(user, repo, tag) + return c.fallbackGetReleaseByTag(owner, repo, tag) + } + if err := escapeValidatePathSegments(&owner, &repo, &tag); err != nil { + return nil, nil, err } r := new(Release) resp, err := c.getParsedResponse("GET", - fmt.Sprintf("/repos/%s/%s/releases/tags/%s", user, repo, tag), + fmt.Sprintf("/repos/%s/%s/releases/tags/%s", owner, repo, tag), nil, nil, &r) return r, resp, err } @@ -86,7 +96,10 @@ func (opt CreateReleaseOption) Validate() error { } // CreateRelease create a release -func (c *Client) CreateRelease(user, repo string, opt CreateReleaseOption) (*Release, *Response, error) { +func (c *Client) CreateRelease(owner, repo string, opt CreateReleaseOption) (*Release, *Response, error) { + if err := escapeValidatePathSegments(&owner, &repo); err != nil { + return nil, nil, err + } if err := opt.Validate(); err != nil { return nil, nil, err } @@ -96,7 +109,7 @@ func (c *Client) CreateRelease(user, repo string, opt CreateReleaseOption) (*Rel } r := new(Release) resp, err := c.getParsedResponse("POST", - fmt.Sprintf("/repos/%s/%s/releases", user, repo), + fmt.Sprintf("/repos/%s/%s/releases", owner, repo), jsonHeader, bytes.NewReader(body), r) return r, resp, err } @@ -112,30 +125,50 @@ type EditReleaseOption struct { } // EditRelease edit a release -func (c *Client) EditRelease(user, repo string, id int64, form EditReleaseOption) (*Release, *Response, error) { +func (c *Client) EditRelease(owner, repo string, id int64, form EditReleaseOption) (*Release, *Response, error) { + if err := escapeValidatePathSegments(&owner, &repo); err != nil { + return nil, nil, err + } body, err := json.Marshal(form) if err != nil { return nil, nil, err } r := new(Release) resp, err := c.getParsedResponse("PATCH", - fmt.Sprintf("/repos/%s/%s/releases/%d", user, repo, id), + fmt.Sprintf("/repos/%s/%s/releases/%d", owner, repo, id), jsonHeader, bytes.NewReader(body), r) return r, resp, err } -// DeleteRelease delete a release from a repository +// DeleteRelease delete a release from a repository, keeping its tag func (c *Client) DeleteRelease(user, repo string, id int64) (*Response, error) { + if err := escapeValidatePathSegments(&user, &repo); err != nil { + return nil, err + } _, resp, err := c.getResponse("DELETE", fmt.Sprintf("/repos/%s/%s/releases/%d", user, repo, id), nil, nil) return resp, err } +// DeleteReleaseByTag deletes a release frm a repository by tag +func (c *Client) DeleteReleaseByTag(user, repo string, tag string) (*Response, error) { + if err := escapeValidatePathSegments(&user, &repo, &tag); err != nil { + return nil, err + } + if err := c.checkServerVersionGreaterThanOrEqual(version1_14_0); err != nil { + return nil, err + } + _, resp, err := c.getResponse("DELETE", + fmt.Sprintf("/repos/%s/%s/releases/tags/%s", user, repo, tag), + nil, nil) + return resp, err +} + // fallbackGetReleaseByTag is fallback for old gitea installations ( < 1.13.0 ) -func (c *Client) fallbackGetReleaseByTag(user, repo string, tag string) (*Release, *Response, error) { +func (c *Client) fallbackGetReleaseByTag(owner, repo string, tag string) (*Release, *Response, error) { for i := 1; ; i++ { - rl, resp, err := c.ListReleases(user, repo, ListReleasesOptions{ListOptions{Page: i}}) + rl, resp, err := c.ListReleases(owner, repo, ListReleasesOptions{ListOptions{Page: i}}) if err != nil { return nil, resp, err } diff --git a/vendor/code.gitea.io/sdk/gitea/repo.go b/vendor/code.gitea.io/sdk/gitea/repo.go index a09f5a651..67bd95630 100644 --- a/vendor/code.gitea.io/sdk/gitea/repo.go +++ b/vendor/code.gitea.io/sdk/gitea/repo.go @@ -9,6 +9,7 @@ import ( "bytes" "encoding/json" "fmt" + "io" "net/url" "strings" "time" @@ -21,42 +22,77 @@ type Permission struct { Pull bool `json:"pull"` } +// InternalTracker represents settings for internal tracker +type InternalTracker struct { + // Enable time tracking (Built-in issue tracker) + EnableTimeTracker bool `json:"enable_time_tracker"` + // Let only contributors track time (Built-in issue tracker) + AllowOnlyContributorsToTrackTime bool `json:"allow_only_contributors_to_track_time"` + // Enable dependencies for issues and pull requests (Built-in issue tracker) + EnableIssueDependencies bool `json:"enable_issue_dependencies"` +} + +// ExternalTracker represents settings for external tracker +type ExternalTracker struct { + // URL of external issue tracker. + ExternalTrackerURL string `json:"external_tracker_url"` + // External Issue Tracker URL Format. Use the placeholders {user}, {repo} and {index} for the username, repository name and issue index. + ExternalTrackerFormat string `json:"external_tracker_format"` + // External Issue Tracker Number Format, either `numeric` or `alphanumeric` + ExternalTrackerStyle string `json:"external_tracker_style"` +} + +// ExternalWiki represents setting for external wiki +type ExternalWiki struct { + // URL of external wiki. + ExternalWikiURL string `json:"external_wiki_url"` +} + // Repository represents a repository type Repository struct { - ID int64 `json:"id"` - Owner *User `json:"owner"` - Name string `json:"name"` - FullName string `json:"full_name"` - Description string `json:"description"` - Empty bool `json:"empty"` - Private bool `json:"private"` - Fork bool `json:"fork"` - Parent *Repository `json:"parent"` - Mirror bool `json:"mirror"` - Size int `json:"size"` - HTMLURL string `json:"html_url"` - SSHURL string `json:"ssh_url"` - CloneURL string `json:"clone_url"` - OriginalURL string `json:"original_url"` - Website string `json:"website"` - Stars int `json:"stars_count"` - Forks int `json:"forks_count"` - Watchers int `json:"watchers_count"` - OpenIssues int `json:"open_issues_count"` - DefaultBranch string `json:"default_branch"` - Archived bool `json:"archived"` - Created time.Time `json:"created_at"` - Updated time.Time `json:"updated_at"` - Permissions *Permission `json:"permissions,omitempty"` - HasIssues bool `json:"has_issues"` - HasWiki bool `json:"has_wiki"` - HasPullRequests bool `json:"has_pull_requests"` - IgnoreWhitespaceConflicts bool `json:"ignore_whitespace_conflicts"` - AllowMerge bool `json:"allow_merge_commits"` - AllowRebase bool `json:"allow_rebase"` - AllowRebaseMerge bool `json:"allow_rebase_explicit"` - AllowSquash bool `json:"allow_squash_merge"` - AvatarURL string `json:"avatar_url"` + ID int64 `json:"id"` + Owner *User `json:"owner"` + Name string `json:"name"` + FullName string `json:"full_name"` + Description string `json:"description"` + Empty bool `json:"empty"` + Private bool `json:"private"` + Fork bool `json:"fork"` + Template bool `json:"template"` + Parent *Repository `json:"parent"` + Mirror bool `json:"mirror"` + Size int `json:"size"` + HTMLURL string `json:"html_url"` + SSHURL string `json:"ssh_url"` + CloneURL string `json:"clone_url"` + OriginalURL string `json:"original_url"` + Website string `json:"website"` + Stars int `json:"stars_count"` + Forks int `json:"forks_count"` + Watchers int `json:"watchers_count"` + OpenIssues int `json:"open_issues_count"` + OpenPulls int `json:"open_pr_counter"` + Releases int `json:"release_counter"` + DefaultBranch string `json:"default_branch"` + Archived bool `json:"archived"` + Created time.Time `json:"created_at"` + Updated time.Time `json:"updated_at"` + Permissions *Permission `json:"permissions,omitempty"` + HasIssues bool `json:"has_issues"` + InternalTracker *InternalTracker `json:"internal_tracker,omitempty"` + ExternalTracker *ExternalTracker `json:"external_tracker,omitempty"` + HasWiki bool `json:"has_wiki"` + ExternalWiki *ExternalWiki `json:"external_wiki,omitempty"` + HasPullRequests bool `json:"has_pull_requests"` + HasProjects bool `json:"has_projects"` + IgnoreWhitespaceConflicts bool `json:"ignore_whitespace_conflicts"` + AllowMerge bool `json:"allow_merge_commits"` + AllowRebase bool `json:"allow_rebase"` + AllowRebaseMerge bool `json:"allow_rebase_explicit"` + AllowSquash bool `json:"allow_squash_merge"` + AvatarURL string `json:"avatar_url"` + Internal bool `json:"internal"` + MirrorInterval string `json:"mirror_interval"` } // RepoType represent repo type @@ -102,6 +138,9 @@ func (c *Client) ListMyRepos(opt ListReposOptions) ([]*Repository, *Response, er // ListUserRepos list all repositories of one user by user's name func (c *Client) ListUserRepos(user string, opt ListReposOptions) ([]*Repository, *Response, error) { + if err := escapeValidatePathSegments(&user); err != nil { + return nil, nil, err + } opt.setDefaults() repos := make([]*Repository, 0, opt.PageSize) resp, err := c.getParsedResponse("GET", fmt.Sprintf("/users/%s/repos?%s", user, opt.getURLQuery().Encode()), nil, nil, &repos) @@ -115,6 +154,9 @@ type ListOrgReposOptions struct { // ListOrgRepos list all repositories of one organization by organization's name func (c *Client) ListOrgRepos(org string, opt ListOrgReposOptions) ([]*Repository, *Response, error) { + if err := escapeValidatePathSegments(&org); err != nil { + return nil, nil, err + } opt.setDefaults() repos := make([]*Repository, 0, opt.PageSize) resp, err := c.getParsedResponse("GET", fmt.Sprintf("/orgs/%s/repos?%s", org, opt.getURLQuery().Encode()), nil, nil, &repos) @@ -315,6 +357,9 @@ func (c *Client) CreateRepo(opt CreateRepoOption) (*Repository, *Response, error // CreateOrgRepo creates an organization repository for authenticated user. func (c *Client) CreateOrgRepo(org string, opt CreateRepoOption) (*Repository, *Response, error) { + if err := escapeValidatePathSegments(&org); err != nil { + return nil, nil, err + } if err := opt.Validate(c); err != nil { return nil, nil, err } @@ -329,6 +374,9 @@ func (c *Client) CreateOrgRepo(org string, opt CreateRepoOption) (*Repository, * // GetRepo returns information of a repository of given owner. func (c *Client) GetRepo(owner, reponame string) (*Repository, *Response, error) { + if err := escapeValidatePathSegments(&owner, &reponame); err != nil { + return nil, nil, err + } repo := new(Repository) resp, err := c.getParsedResponse("GET", fmt.Sprintf("/repos/%s/%s", owner, reponame), nil, nil, repo) return repo, resp, err @@ -346,14 +394,24 @@ type EditRepoOption struct { // Note: you will get a 422 error if the organization restricts changing repository visibility to organization // owners and a non-owner tries to change the value of private. Private *bool `json:"private,omitempty"` + // either `true` to make this repository a template or `false` to make it a normal repository + Template *bool `json:"template,omitempty"` // either `true` to enable issues for this repository or `false` to disable them. HasIssues *bool `json:"has_issues,omitempty"` + // set this structure to configure internal issue tracker (requires has_issues) + InternalTracker *InternalTracker `json:"internal_tracker,omitempty"` + // set this structure to use external issue tracker (requires has_issues) + ExternalTracker *ExternalTracker `json:"external_tracker,omitempty"` // either `true` to enable the wiki for this repository or `false` to disable it. HasWiki *bool `json:"has_wiki,omitempty"` + // set this structure to use external wiki instead of internal (requires has_wiki) + ExternalWiki *ExternalWiki `json:"external_wiki,omitempty"` // sets the default branch for this repository. DefaultBranch *string `json:"default_branch,omitempty"` // either `true` to allow pull requests, or `false` to prevent pull request. HasPullRequests *bool `json:"has_pull_requests,omitempty"` + // either `true` to enable project unit, or `false` to disable them. + HasProjects *bool `json:"has_projects,omitempty"` // either `true` to ignore whitespace for conflicts, or `false` to not ignore whitespace. `has_pull_requests` must be `true`. IgnoreWhitespaceConflicts *bool `json:"ignore_whitespace_conflicts,omitempty"` // either `true` to allow merging pull requests with a merge commit, or `false` to prevent merging pull requests with merge commits. `has_pull_requests` must be `true`. @@ -366,10 +424,15 @@ type EditRepoOption struct { AllowSquash *bool `json:"allow_squash_merge,omitempty"` // set to `true` to archive this repository. Archived *bool `json:"archived,omitempty"` + // set to a string like `8h30m0s` to set the mirror interval time + MirrorInterval *string `json:"mirror_interval,omitempty"` } // EditRepo edit the properties of a repository func (c *Client) EditRepo(owner, reponame string, opt EditRepoOption) (*Repository, *Response, error) { + if err := escapeValidatePathSegments(&owner, &reponame); err != nil { + return nil, nil, err + } body, err := json.Marshal(&opt) if err != nil { return nil, nil, err @@ -381,18 +444,27 @@ func (c *Client) EditRepo(owner, reponame string, opt EditRepoOption) (*Reposito // DeleteRepo deletes a repository of user or organization. func (c *Client) DeleteRepo(owner, repo string) (*Response, error) { + if err := escapeValidatePathSegments(&owner, &repo); err != nil { + return nil, err + } _, resp, err := c.getResponse("DELETE", fmt.Sprintf("/repos/%s/%s", owner, repo), nil, nil) return resp, err } // MirrorSync adds a mirrored repository to the mirror sync queue. func (c *Client) MirrorSync(owner, repo string) (*Response, error) { + if err := escapeValidatePathSegments(&owner, &repo); err != nil { + return nil, err + } _, resp, err := c.getResponse("POST", fmt.Sprintf("/repos/%s/%s/mirror-sync", owner, repo), nil, nil) return resp, err } // GetRepoLanguages return language stats of a repo func (c *Client) GetRepoLanguages(owner, repo string) (map[string]int64, *Response, error) { + if err := escapeValidatePathSegments(&owner, &repo); err != nil { + return nil, nil, err + } langMap := make(map[string]int64) data, resp, err := c.getResponse("GET", fmt.Sprintf("/repos/%s/%s/languages", owner, repo), jsonHeader, nil) @@ -418,5 +490,30 @@ const ( // GetArchive get an archive of a repository by git reference // e.g.: ref -> master, 70b7c74b33, v1.2.1, ... func (c *Client) GetArchive(owner, repo, ref string, ext ArchiveType) ([]byte, *Response, error) { - return c.getResponse("GET", fmt.Sprintf("/repos/%s/%s/archive/%s%s", owner, repo, url.PathEscape(ref), ext), nil, nil) + if err := escapeValidatePathSegments(&owner, &repo); err != nil { + return nil, nil, err + } + ref = pathEscapeSegments(ref) + return c.getResponse("GET", fmt.Sprintf("/repos/%s/%s/archive/%s%s", owner, repo, ref, ext), nil, nil) +} + +// GetArchiveReader gets a `git archive` for a particular tree-ish git reference +// such as a branch name (`master`), a commit hash (`70b7c74b33`), a tag +// (`v1.2.1`). The archive is returned as a byte stream in a ReadCloser. It is +// the responsibility of the client to close the reader. +func (c *Client) GetArchiveReader(owner, repo, ref string, ext ArchiveType) (io.ReadCloser, *Response, error) { + if err := escapeValidatePathSegments(&owner, &repo); err != nil { + return nil, nil, err + } + ref = pathEscapeSegments(ref) + resp, err := c.doRequest("GET", fmt.Sprintf("/repos/%s/%s/archive/%s%s", owner, repo, ref, ext), nil, nil) + if err != nil { + return nil, resp, err + } + + if _, err := statusCodeToErr(resp); err != nil { + return nil, resp, err + } + + return resp.Body, resp, nil } diff --git a/vendor/code.gitea.io/sdk/gitea/repo_branch.go b/vendor/code.gitea.io/sdk/gitea/repo_branch.go index 6b0eec27e..0b7e873c4 100644 --- a/vendor/code.gitea.io/sdk/gitea/repo_branch.go +++ b/vendor/code.gitea.io/sdk/gitea/repo_branch.go @@ -20,9 +20,6 @@ type PayloadUser struct { UserName string `json:"username"` } -// FIXME: consider using same format as API when commits API are added. -// applies to PayloadCommit and PayloadCommitVerification - // PayloadCommit represents a commit type PayloadCommit struct { // sha1 hash of the commit @@ -66,6 +63,9 @@ type ListRepoBranchesOptions struct { // ListRepoBranches list all the branches of one repository func (c *Client) ListRepoBranches(user, repo string, opt ListRepoBranchesOptions) ([]*Branch, *Response, error) { + if err := escapeValidatePathSegments(&user, &repo); err != nil { + return nil, nil, err + } opt.setDefaults() branches := make([]*Branch, 0, opt.PageSize) resp, err := c.getParsedResponse("GET", fmt.Sprintf("/repos/%s/%s/branches?%s", user, repo, opt.getURLQuery().Encode()), nil, nil, &branches) @@ -74,6 +74,9 @@ func (c *Client) ListRepoBranches(user, repo string, opt ListRepoBranchesOptions // GetRepoBranch get one branch's information of one repository func (c *Client) GetRepoBranch(user, repo, branch string) (*Branch, *Response, error) { + if err := escapeValidatePathSegments(&user, &repo, &branch); err != nil { + return nil, nil, err + } b := new(Branch) resp, err := c.getParsedResponse("GET", fmt.Sprintf("/repos/%s/%s/branches/%s", user, repo, branch), nil, nil, &b) if err != nil { @@ -84,6 +87,9 @@ func (c *Client) GetRepoBranch(user, repo, branch string) (*Branch, *Response, e // DeleteRepoBranch delete a branch in a repository func (c *Client) DeleteRepoBranch(user, repo, branch string) (bool, *Response, error) { + if err := escapeValidatePathSegments(&user, &repo, &branch); err != nil { + return false, nil, err + } if err := c.checkServerVersionGreaterThanOrEqual(version1_12_0); err != nil { return false, nil, err } @@ -118,6 +124,9 @@ func (opt CreateBranchOption) Validate() error { // CreateBranch creates a branch for a user's repository func (c *Client) CreateBranch(owner, repo string, opt CreateBranchOption) (*Branch, *Response, error) { + if err := escapeValidatePathSegments(&owner, &repo); err != nil { + return nil, nil, err + } if err := c.checkServerVersionGreaterThanOrEqual(version1_13_0); err != nil { return nil, nil, err } diff --git a/vendor/code.gitea.io/sdk/gitea/repo_branch_protection.go b/vendor/code.gitea.io/sdk/gitea/repo_branch_protection.go index 1e520807a..22bd7b962 100644 --- a/vendor/code.gitea.io/sdk/gitea/repo_branch_protection.go +++ b/vendor/code.gitea.io/sdk/gitea/repo_branch_protection.go @@ -14,75 +14,78 @@ import ( // BranchProtection represents a branch protection for a repository type BranchProtection struct { - BranchName string `json:"branch_name"` - EnablePush bool `json:"enable_push"` - EnablePushWhitelist bool `json:"enable_push_whitelist"` - PushWhitelistUsernames []string `json:"push_whitelist_usernames"` - PushWhitelistTeams []string `json:"push_whitelist_teams"` - PushWhitelistDeployKeys bool `json:"push_whitelist_deploy_keys"` - EnableMergeWhitelist bool `json:"enable_merge_whitelist"` - MergeWhitelistUsernames []string `json:"merge_whitelist_usernames"` - MergeWhitelistTeams []string `json:"merge_whitelist_teams"` - EnableStatusCheck bool `json:"enable_status_check"` - StatusCheckContexts []string `json:"status_check_contexts"` - RequiredApprovals int64 `json:"required_approvals"` - EnableApprovalsWhitelist bool `json:"enable_approvals_whitelist"` - ApprovalsWhitelistUsernames []string `json:"approvals_whitelist_username"` - ApprovalsWhitelistTeams []string `json:"approvals_whitelist_teams"` - BlockOnRejectedReviews bool `json:"block_on_rejected_reviews"` - BlockOnOutdatedBranch bool `json:"block_on_outdated_branch"` - DismissStaleApprovals bool `json:"dismiss_stale_approvals"` - RequireSignedCommits bool `json:"require_signed_commits"` - ProtectedFilePatterns string `json:"protected_file_patterns"` - Created time.Time `json:"created_at"` - Updated time.Time `json:"updated_at"` + BranchName string `json:"branch_name"` + EnablePush bool `json:"enable_push"` + EnablePushWhitelist bool `json:"enable_push_whitelist"` + PushWhitelistUsernames []string `json:"push_whitelist_usernames"` + PushWhitelistTeams []string `json:"push_whitelist_teams"` + PushWhitelistDeployKeys bool `json:"push_whitelist_deploy_keys"` + EnableMergeWhitelist bool `json:"enable_merge_whitelist"` + MergeWhitelistUsernames []string `json:"merge_whitelist_usernames"` + MergeWhitelistTeams []string `json:"merge_whitelist_teams"` + EnableStatusCheck bool `json:"enable_status_check"` + StatusCheckContexts []string `json:"status_check_contexts"` + RequiredApprovals int64 `json:"required_approvals"` + EnableApprovalsWhitelist bool `json:"enable_approvals_whitelist"` + ApprovalsWhitelistUsernames []string `json:"approvals_whitelist_username"` + ApprovalsWhitelistTeams []string `json:"approvals_whitelist_teams"` + BlockOnRejectedReviews bool `json:"block_on_rejected_reviews"` + BlockOnOfficialReviewRequests bool `json:"block_on_official_review_requests"` + BlockOnOutdatedBranch bool `json:"block_on_outdated_branch"` + DismissStaleApprovals bool `json:"dismiss_stale_approvals"` + RequireSignedCommits bool `json:"require_signed_commits"` + ProtectedFilePatterns string `json:"protected_file_patterns"` + Created time.Time `json:"created_at"` + Updated time.Time `json:"updated_at"` } // CreateBranchProtectionOption options for creating a branch protection type CreateBranchProtectionOption struct { - BranchName string `json:"branch_name"` - EnablePush bool `json:"enable_push"` - EnablePushWhitelist bool `json:"enable_push_whitelist"` - PushWhitelistUsernames []string `json:"push_whitelist_usernames"` - PushWhitelistTeams []string `json:"push_whitelist_teams"` - PushWhitelistDeployKeys bool `json:"push_whitelist_deploy_keys"` - EnableMergeWhitelist bool `json:"enable_merge_whitelist"` - MergeWhitelistUsernames []string `json:"merge_whitelist_usernames"` - MergeWhitelistTeams []string `json:"merge_whitelist_teams"` - EnableStatusCheck bool `json:"enable_status_check"` - StatusCheckContexts []string `json:"status_check_contexts"` - RequiredApprovals int64 `json:"required_approvals"` - EnableApprovalsWhitelist bool `json:"enable_approvals_whitelist"` - ApprovalsWhitelistUsernames []string `json:"approvals_whitelist_username"` - ApprovalsWhitelistTeams []string `json:"approvals_whitelist_teams"` - BlockOnRejectedReviews bool `json:"block_on_rejected_reviews"` - BlockOnOutdatedBranch bool `json:"block_on_outdated_branch"` - DismissStaleApprovals bool `json:"dismiss_stale_approvals"` - RequireSignedCommits bool `json:"require_signed_commits"` - ProtectedFilePatterns string `json:"protected_file_patterns"` + BranchName string `json:"branch_name"` + EnablePush bool `json:"enable_push"` + EnablePushWhitelist bool `json:"enable_push_whitelist"` + PushWhitelistUsernames []string `json:"push_whitelist_usernames"` + PushWhitelistTeams []string `json:"push_whitelist_teams"` + PushWhitelistDeployKeys bool `json:"push_whitelist_deploy_keys"` + EnableMergeWhitelist bool `json:"enable_merge_whitelist"` + MergeWhitelistUsernames []string `json:"merge_whitelist_usernames"` + MergeWhitelistTeams []string `json:"merge_whitelist_teams"` + EnableStatusCheck bool `json:"enable_status_check"` + StatusCheckContexts []string `json:"status_check_contexts"` + RequiredApprovals int64 `json:"required_approvals"` + EnableApprovalsWhitelist bool `json:"enable_approvals_whitelist"` + ApprovalsWhitelistUsernames []string `json:"approvals_whitelist_username"` + ApprovalsWhitelistTeams []string `json:"approvals_whitelist_teams"` + BlockOnRejectedReviews bool `json:"block_on_rejected_reviews"` + BlockOnOfficialReviewRequests bool `json:"block_on_official_review_requests"` + BlockOnOutdatedBranch bool `json:"block_on_outdated_branch"` + DismissStaleApprovals bool `json:"dismiss_stale_approvals"` + RequireSignedCommits bool `json:"require_signed_commits"` + ProtectedFilePatterns string `json:"protected_file_patterns"` } // EditBranchProtectionOption options for editing a branch protection type EditBranchProtectionOption struct { - EnablePush *bool `json:"enable_push"` - EnablePushWhitelist *bool `json:"enable_push_whitelist"` - PushWhitelistUsernames []string `json:"push_whitelist_usernames"` - PushWhitelistTeams []string `json:"push_whitelist_teams"` - PushWhitelistDeployKeys *bool `json:"push_whitelist_deploy_keys"` - EnableMergeWhitelist *bool `json:"enable_merge_whitelist"` - MergeWhitelistUsernames []string `json:"merge_whitelist_usernames"` - MergeWhitelistTeams []string `json:"merge_whitelist_teams"` - EnableStatusCheck *bool `json:"enable_status_check"` - StatusCheckContexts []string `json:"status_check_contexts"` - RequiredApprovals *int64 `json:"required_approvals"` - EnableApprovalsWhitelist *bool `json:"enable_approvals_whitelist"` - ApprovalsWhitelistUsernames []string `json:"approvals_whitelist_username"` - ApprovalsWhitelistTeams []string `json:"approvals_whitelist_teams"` - BlockOnRejectedReviews *bool `json:"block_on_rejected_reviews"` - BlockOnOutdatedBranch *bool `json:"block_on_outdated_branch"` - DismissStaleApprovals *bool `json:"dismiss_stale_approvals"` - RequireSignedCommits *bool `json:"require_signed_commits"` - ProtectedFilePatterns *string `json:"protected_file_patterns"` + EnablePush *bool `json:"enable_push"` + EnablePushWhitelist *bool `json:"enable_push_whitelist"` + PushWhitelistUsernames []string `json:"push_whitelist_usernames"` + PushWhitelistTeams []string `json:"push_whitelist_teams"` + PushWhitelistDeployKeys *bool `json:"push_whitelist_deploy_keys"` + EnableMergeWhitelist *bool `json:"enable_merge_whitelist"` + MergeWhitelistUsernames []string `json:"merge_whitelist_usernames"` + MergeWhitelistTeams []string `json:"merge_whitelist_teams"` + EnableStatusCheck *bool `json:"enable_status_check"` + StatusCheckContexts []string `json:"status_check_contexts"` + RequiredApprovals *int64 `json:"required_approvals"` + EnableApprovalsWhitelist *bool `json:"enable_approvals_whitelist"` + ApprovalsWhitelistUsernames []string `json:"approvals_whitelist_username"` + ApprovalsWhitelistTeams []string `json:"approvals_whitelist_teams"` + BlockOnRejectedReviews *bool `json:"block_on_rejected_reviews"` + BlockOnOfficialReviewRequests *bool `json:"block_on_official_review_requests"` + BlockOnOutdatedBranch *bool `json:"block_on_outdated_branch"` + DismissStaleApprovals *bool `json:"dismiss_stale_approvals"` + RequireSignedCommits *bool `json:"require_signed_commits"` + ProtectedFilePatterns *string `json:"protected_file_patterns"` } // ListBranchProtectionsOptions list branch protection options @@ -92,6 +95,9 @@ type ListBranchProtectionsOptions struct { // ListBranchProtections list branch protections for a repo func (c *Client) ListBranchProtections(owner, repo string, opt ListBranchProtectionsOptions) ([]*BranchProtection, *Response, error) { + if err := escapeValidatePathSegments(&owner, &repo); err != nil { + return nil, nil, err + } if err := c.checkServerVersionGreaterThanOrEqual(version1_12_0); err != nil { return nil, nil, err } @@ -104,6 +110,9 @@ func (c *Client) ListBranchProtections(owner, repo string, opt ListBranchProtect // GetBranchProtection gets a branch protection func (c *Client) GetBranchProtection(owner, repo, name string) (*BranchProtection, *Response, error) { + if err := escapeValidatePathSegments(&owner, &repo, &name); err != nil { + return nil, nil, err + } if err := c.checkServerVersionGreaterThanOrEqual(version1_12_0); err != nil { return nil, nil, err } @@ -114,6 +123,9 @@ func (c *Client) GetBranchProtection(owner, repo, name string) (*BranchProtectio // CreateBranchProtection creates a branch protection for a repo func (c *Client) CreateBranchProtection(owner, repo string, opt CreateBranchProtectionOption) (*BranchProtection, *Response, error) { + if err := escapeValidatePathSegments(&owner, &repo); err != nil { + return nil, nil, err + } if err := c.checkServerVersionGreaterThanOrEqual(version1_12_0); err != nil { return nil, nil, err } @@ -128,6 +140,9 @@ func (c *Client) CreateBranchProtection(owner, repo string, opt CreateBranchProt // EditBranchProtection edits a branch protection for a repo func (c *Client) EditBranchProtection(owner, repo, name string, opt EditBranchProtectionOption) (*BranchProtection, *Response, error) { + if err := escapeValidatePathSegments(&owner, &repo, &name); err != nil { + return nil, nil, err + } if err := c.checkServerVersionGreaterThanOrEqual(version1_12_0); err != nil { return nil, nil, err } @@ -142,6 +157,9 @@ func (c *Client) EditBranchProtection(owner, repo, name string, opt EditBranchPr // DeleteBranchProtection deletes a branch protection for a repo func (c *Client) DeleteBranchProtection(owner, repo, name string) (*Response, error) { + if err := escapeValidatePathSegments(&owner, &repo, &name); err != nil { + return nil, err + } if err := c.checkServerVersionGreaterThanOrEqual(version1_12_0); err != nil { return nil, err } diff --git a/vendor/code.gitea.io/sdk/gitea/repo_collaborator.go b/vendor/code.gitea.io/sdk/gitea/repo_collaborator.go index 63c4eafd5..2019e22db 100644 --- a/vendor/code.gitea.io/sdk/gitea/repo_collaborator.go +++ b/vendor/code.gitea.io/sdk/gitea/repo_collaborator.go @@ -17,6 +17,9 @@ type ListCollaboratorsOptions struct { // ListCollaborators list a repository's collaborators func (c *Client) ListCollaborators(user, repo string, opt ListCollaboratorsOptions) ([]*User, *Response, error) { + if err := escapeValidatePathSegments(&user, &repo); err != nil { + return nil, nil, err + } opt.setDefaults() collaborators := make([]*User, 0, opt.PageSize) resp, err := c.getParsedResponse("GET", @@ -27,6 +30,9 @@ func (c *Client) ListCollaborators(user, repo string, opt ListCollaboratorsOptio // IsCollaborator check if a user is a collaborator of a repository func (c *Client) IsCollaborator(user, repo, collaborator string) (bool, *Response, error) { + if err := escapeValidatePathSegments(&user, &repo, &collaborator); err != nil { + return false, nil, err + } status, resp, err := c.getStatusCode("GET", fmt.Sprintf("/repos/%s/%s/collaborators/%s", user, repo, collaborator), nil, nil) if err != nil { return false, resp, err @@ -78,6 +84,9 @@ func (opt AddCollaboratorOption) Validate() error { // AddCollaborator add some user as a collaborator of a repository func (c *Client) AddCollaborator(user, repo, collaborator string, opt AddCollaboratorOption) (*Response, error) { + if err := escapeValidatePathSegments(&user, &repo, &collaborator); err != nil { + return nil, err + } if err := opt.Validate(); err != nil { return nil, err } @@ -91,6 +100,9 @@ func (c *Client) AddCollaborator(user, repo, collaborator string, opt AddCollabo // DeleteCollaborator remove a collaborator from a repository func (c *Client) DeleteCollaborator(user, repo, collaborator string) (*Response, error) { + if err := escapeValidatePathSegments(&user, &repo, &collaborator); err != nil { + return nil, err + } _, resp, err := c.getResponse("DELETE", fmt.Sprintf("/repos/%s/%s/collaborators/%s", user, repo, collaborator), nil, nil) return resp, err diff --git a/vendor/code.gitea.io/sdk/gitea/repo_commit.go b/vendor/code.gitea.io/sdk/gitea/repo_commit.go index 4b90b9cb6..9bb65b3b1 100644 --- a/vendor/code.gitea.io/sdk/gitea/repo_commit.go +++ b/vendor/code.gitea.io/sdk/gitea/repo_commit.go @@ -42,11 +42,12 @@ type RepoCommit struct { // Commit contains information generated from a Git commit. type Commit struct { *CommitMeta - HTMLURL string `json:"html_url"` - RepoCommit *RepoCommit `json:"commit"` - Author *User `json:"author"` - Committer *User `json:"committer"` - Parents []*CommitMeta `json:"parents"` + HTMLURL string `json:"html_url"` + RepoCommit *RepoCommit `json:"commit"` + Author *User `json:"author"` + Committer *User `json:"committer"` + Parents []*CommitMeta `json:"parents"` + Files []*CommitAffectedFiles `json:"files"` } // CommitDateOptions store dates for GIT_AUTHOR_DATE and GIT_COMMITTER_DATE @@ -55,8 +56,16 @@ type CommitDateOptions struct { Committer time.Time `json:"committer"` } +// CommitAffectedFiles store information about files affected by the commit +type CommitAffectedFiles struct { + Filename string `json:"filename"` +} + // GetSingleCommit returns a single commit func (c *Client) GetSingleCommit(user, repo, commitID string) (*Commit, *Response, error) { + if err := escapeValidatePathSegments(&user, &repo, &commitID); err != nil { + return nil, nil, err + } commit := new(Commit) resp, err := c.getParsedResponse("GET", fmt.Sprintf("/repos/%s/%s/git/commits/%s", user, repo, commitID), nil, nil, &commit) return commit, resp, err @@ -80,6 +89,9 @@ func (opt *ListCommitOptions) QueryEncode() string { // ListRepoCommits return list of commits from a repo func (c *Client) ListRepoCommits(user, repo string, opt ListCommitOptions) ([]*Commit, *Response, error) { + if err := escapeValidatePathSegments(&user, &repo); err != nil { + return nil, nil, err + } link, _ := url.Parse(fmt.Sprintf("/repos/%s/%s/commits", user, repo)) opt.setDefaults() commits := make([]*Commit, 0, opt.PageSize) diff --git a/vendor/code.gitea.io/sdk/gitea/repo_file.go b/vendor/code.gitea.io/sdk/gitea/repo_file.go index b104980a8..6f99ea06b 100644 --- a/vendor/code.gitea.io/sdk/gitea/repo_file.go +++ b/vendor/code.gitea.io/sdk/gitea/repo_file.go @@ -9,6 +9,8 @@ import ( "bytes" "encoding/json" "fmt" + "net/url" + "strings" ) // FileOptions options for all file APIs @@ -23,6 +25,8 @@ type FileOptions struct { Author Identity `json:"author"` Committer Identity `json:"committer"` Dates CommitDateOptions `json:"dates"` + // Add a Signed-off-by trailer by the committer at the end of the commit log message. + Signoff bool `json:"signoff"` } // CreateFileOptions options for creating files @@ -113,25 +117,65 @@ type FileDeleteResponse struct { } // GetFile downloads a file of repository, ref can be branch/tag/commit. -// e.g.: ref -> master, tree -> macaron.go(no leading slash) -func (c *Client) GetFile(user, repo, ref, tree string) ([]byte, *Response, error) { - return c.getResponse("GET", fmt.Sprintf("/repos/%s/%s/raw/%s/%s", user, repo, ref, tree), nil, nil) +// e.g.: ref -> master, filepath -> README.md (no leading slash) +func (c *Client) GetFile(owner, repo, ref, filepath string) ([]byte, *Response, error) { + if err := escapeValidatePathSegments(&owner, &repo); err != nil { + return nil, nil, err + } + filepath = pathEscapeSegments(filepath) + if c.checkServerVersionGreaterThanOrEqual(version1_14_0) != nil { + ref = pathEscapeSegments(ref) + return c.getResponse("GET", fmt.Sprintf("/repos/%s/%s/raw/%s/%s", owner, repo, ref, filepath), nil, nil) + } + return c.getResponse("GET", fmt.Sprintf("/repos/%s/%s/raw/%s?ref=%s", owner, repo, filepath, url.QueryEscape(ref)), nil, nil) } -// GetContents get the metadata and contents (if a file) of an entry in a repository, or a list of entries if a dir +// GetContents get the metadata and contents of a file in a repository // ref is optional func (c *Client) GetContents(owner, repo, ref, filepath string) (*ContentsResponse, *Response, error) { + data, resp, err := c.getDirOrFileContents(owner, repo, ref, filepath) + if err != nil { + return nil, resp, err + } cr := new(ContentsResponse) - resp, err := c.getParsedResponse("GET", fmt.Sprintf("/repos/%s/%s/contents/%s?ref=%s", owner, repo, filepath, ref), jsonHeader, nil, cr) + if json.Unmarshal(data, &cr) != nil { + return nil, resp, fmt.Errorf("expect file, got directory") + } return cr, resp, err } +// ListContents gets a list of entries in a dir +// ref is optional +func (c *Client) ListContents(owner, repo, ref, filepath string) ([]*ContentsResponse, *Response, error) { + data, resp, err := c.getDirOrFileContents(owner, repo, ref, filepath) + if err != nil { + return nil, resp, err + } + crl := make([]*ContentsResponse, 0) + if json.Unmarshal(data, &crl) != nil { + return nil, resp, fmt.Errorf("expect directory, got file") + } + return crl, resp, err +} + +func (c *Client) getDirOrFileContents(owner, repo, ref, filepath string) ([]byte, *Response, error) { + if err := escapeValidatePathSegments(&owner, &repo); err != nil { + return nil, nil, err + } + filepath = pathEscapeSegments(strings.TrimPrefix(filepath, "/")) + return c.getResponse("GET", fmt.Sprintf("/repos/%s/%s/contents/%s?ref=%s", owner, repo, filepath, url.QueryEscape(ref)), jsonHeader, nil) +} + // CreateFile create a file in a repository func (c *Client) CreateFile(owner, repo, filepath string, opt CreateFileOptions) (*FileResponse, *Response, error) { var err error if opt.BranchName, err = c.setDefaultBranchForOldVersions(owner, repo, opt.BranchName); err != nil { return nil, nil, err } + if err := escapeValidatePathSegments(&owner, &repo); err != nil { + return nil, nil, err + } + filepath = pathEscapeSegments(filepath) body, err := json.Marshal(&opt) if err != nil { @@ -149,6 +193,11 @@ func (c *Client) UpdateFile(owner, repo, filepath string, opt UpdateFileOptions) return nil, nil, err } + if err := escapeValidatePathSegments(&owner, &repo); err != nil { + return nil, nil, err + } + filepath = pathEscapeSegments(filepath) + body, err := json.Marshal(&opt) if err != nil { return nil, nil, err @@ -164,6 +213,10 @@ func (c *Client) DeleteFile(owner, repo, filepath string, opt DeleteFileOptions) if opt.BranchName, err = c.setDefaultBranchForOldVersions(owner, repo, opt.BranchName); err != nil { return nil, err } + if err := escapeValidatePathSegments(&owner, &repo); err != nil { + return nil, err + } + filepath = pathEscapeSegments(filepath) body, err := json.Marshal(&opt) if err != nil { diff --git a/vendor/code.gitea.io/sdk/gitea/repo_key.go b/vendor/code.gitea.io/sdk/gitea/repo_key.go index cfdfe0cd4..ee2ff4084 100644 --- a/vendor/code.gitea.io/sdk/gitea/repo_key.go +++ b/vendor/code.gitea.io/sdk/gitea/repo_key.go @@ -46,6 +46,9 @@ func (opt *ListDeployKeysOptions) QueryEncode() string { // ListDeployKeys list all the deploy keys of one repository func (c *Client) ListDeployKeys(user, repo string, opt ListDeployKeysOptions) ([]*DeployKey, *Response, error) { + if err := escapeValidatePathSegments(&user, &repo); err != nil { + return nil, nil, err + } link, _ := url.Parse(fmt.Sprintf("/repos/%s/%s/keys", user, repo)) opt.setDefaults() link.RawQuery = opt.QueryEncode() @@ -56,6 +59,9 @@ func (c *Client) ListDeployKeys(user, repo string, opt ListDeployKeysOptions) ([ // GetDeployKey get one deploy key with key id func (c *Client) GetDeployKey(user, repo string, keyID int64) (*DeployKey, *Response, error) { + if err := escapeValidatePathSegments(&user, &repo); err != nil { + return nil, nil, err + } key := new(DeployKey) resp, err := c.getParsedResponse("GET", fmt.Sprintf("/repos/%s/%s/keys/%d", user, repo, keyID), nil, nil, &key) return key, resp, err @@ -63,6 +69,9 @@ func (c *Client) GetDeployKey(user, repo string, keyID int64) (*DeployKey, *Resp // CreateDeployKey options when create one deploy key func (c *Client) CreateDeployKey(user, repo string, opt CreateKeyOption) (*DeployKey, *Response, error) { + if err := escapeValidatePathSegments(&user, &repo); err != nil { + return nil, nil, err + } body, err := json.Marshal(&opt) if err != nil { return nil, nil, err @@ -74,6 +83,9 @@ func (c *Client) CreateDeployKey(user, repo string, opt CreateKeyOption) (*Deplo // DeleteDeployKey delete deploy key with key id func (c *Client) DeleteDeployKey(owner, repo string, keyID int64) (*Response, error) { + if err := escapeValidatePathSegments(&owner, &repo); err != nil { + return nil, err + } _, resp, err := c.getResponse("DELETE", fmt.Sprintf("/repos/%s/%s/keys/%d", owner, repo, keyID), nil, nil) return resp, err } diff --git a/vendor/code.gitea.io/sdk/gitea/repo_migrate.go b/vendor/code.gitea.io/sdk/gitea/repo_migrate.go index 518c6ae64..91f19d6ae 100644 --- a/vendor/code.gitea.io/sdk/gitea/repo_migrate.go +++ b/vendor/code.gitea.io/sdk/gitea/repo_migrate.go @@ -22,10 +22,8 @@ const ( GitServiceGitlab GitServiceType = "gitlab" // GitServiceGitea represents a gitea service GitServiceGitea GitServiceType = "gitea" - - // Not supported jet - // // GitServiceGogs represents a gogs service - // GitServiceGogs GitServiceType = "gogs" + // GitServiceGogs represents a gogs service + GitServiceGogs GitServiceType = "gogs" ) // MigrateRepoOption options for migrating a repository from an external service @@ -33,21 +31,22 @@ type MigrateRepoOption struct { RepoName string `json:"repo_name"` RepoOwner string `json:"repo_owner"` // deprecated use RepoOwner - RepoOwnerID int64 `json:"uid"` - CloneAddr string `json:"clone_addr"` - Service GitServiceType `json:"service"` - AuthUsername string `json:"auth_username"` - AuthPassword string `json:"auth_password"` - AuthToken string `json:"auth_token"` - Mirror bool `json:"mirror"` - Private bool `json:"private"` - Description string `json:"description"` - Wiki bool `json:"wiki"` - Milestones bool `json:"milestones"` - Labels bool `json:"labels"` - Issues bool `json:"issues"` - PullRequests bool `json:"pull_requests"` - Releases bool `json:"releases"` + RepoOwnerID int64 `json:"uid"` + CloneAddr string `json:"clone_addr"` + Service GitServiceType `json:"service"` + AuthUsername string `json:"auth_username"` + AuthPassword string `json:"auth_password"` + AuthToken string `json:"auth_token"` + Mirror bool `json:"mirror"` + Private bool `json:"private"` + Description string `json:"description"` + Wiki bool `json:"wiki"` + Milestones bool `json:"milestones"` + Labels bool `json:"labels"` + Issues bool `json:"issues"` + PullRequests bool `json:"pull_requests"` + Releases bool `json:"releases"` + MirrorInterval string `json:"mirror_interval"` } // Validate the MigrateRepoOption struct @@ -67,17 +66,24 @@ func (opt *MigrateRepoOption) Validate(c *Client) error { switch opt.Service { case GitServiceGithub: if len(opt.AuthToken) == 0 { - return fmt.Errorf("github require token authentication") + return fmt.Errorf("github requires token authentication") } case GitServiceGitlab, GitServiceGitea: if len(opt.AuthToken) == 0 { - return fmt.Errorf("%s require token authentication", opt.Service) + return fmt.Errorf("%s requires token authentication", opt.Service) } // Gitlab is supported since 1.12.0 but api cant handle it until 1.13.0 // https://github.com/go-gitea/gitea/pull/12672 if c.checkServerVersionGreaterThanOrEqual(version1_13_0) != nil { return fmt.Errorf("migrate from service %s need gitea >= 1.13.0", opt.Service) } + case GitServiceGogs: + if len(opt.AuthToken) == 0 { + return fmt.Errorf("gogs requires token authentication") + } + if c.checkServerVersionGreaterThanOrEqual(version1_14_0) != nil { + return fmt.Errorf("migrate from service gogs need gitea >= 1.14.0") + } } return nil } diff --git a/vendor/code.gitea.io/sdk/gitea/repo_refs.go b/vendor/code.gitea.io/sdk/gitea/repo_refs.go index fa1698a49..c954a80ef 100644 --- a/vendor/code.gitea.io/sdk/gitea/repo_refs.go +++ b/vendor/code.gitea.io/sdk/gitea/repo_refs.go @@ -27,7 +27,11 @@ type GitObject struct { // GetRepoRef get one ref's information of one repository func (c *Client) GetRepoRef(user, repo, ref string) (*Reference, *Response, error) { + if err := escapeValidatePathSegments(&user, &repo); err != nil { + return nil, nil, err + } ref = strings.TrimPrefix(ref, "refs/") + ref = pathEscapeSegments(ref) r := new(Reference) resp, err := c.getParsedResponse("GET", fmt.Sprintf("/repos/%s/%s/git/refs/%s", user, repo, ref), nil, nil, &r) if _, ok := err.(*json.UnmarshalTypeError); ok { @@ -42,7 +46,12 @@ func (c *Client) GetRepoRef(user, repo, ref string) (*Reference, *Response, erro // GetRepoRefs get list of ref's information of one repository func (c *Client) GetRepoRefs(user, repo, ref string) ([]*Reference, *Response, error) { + if err := escapeValidatePathSegments(&user, &repo); err != nil { + return nil, nil, err + } ref = strings.TrimPrefix(ref, "refs/") + ref = pathEscapeSegments(ref) + data, resp, err := c.getResponse("GET", fmt.Sprintf("/repos/%s/%s/git/refs/%s", user, repo, ref), nil, nil) if err != nil { return nil, resp, err diff --git a/vendor/code.gitea.io/sdk/gitea/repo_stars.go b/vendor/code.gitea.io/sdk/gitea/repo_stars.go new file mode 100644 index 000000000..01243c250 --- /dev/null +++ b/vendor/code.gitea.io/sdk/gitea/repo_stars.go @@ -0,0 +1,96 @@ +// Copyright 2021 The Gitea Authors. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file. + +package gitea + +import ( + "fmt" + "net/http" +) + +// ListStargazersOptions options for listing a repository's stargazers +type ListStargazersOptions struct { + ListOptions +} + +// ListRepoStargazers list a repository's stargazers +func (c *Client) ListRepoStargazers(user, repo string, opt ListStargazersOptions) ([]*User, *Response, error) { + if err := escapeValidatePathSegments(&user, &repo); err != nil { + return nil, nil, err + } + opt.setDefaults() + stargazers := make([]*User, 0, opt.PageSize) + resp, err := c.getParsedResponse("GET", fmt.Sprintf("/repos/%s/%s/stargazers?%s", user, repo, opt.getURLQuery().Encode()), nil, nil, &stargazers) + return stargazers, resp, err +} + +// GetStarredRepos returns the repos that the given user has starred +func (c *Client) GetStarredRepos(user string) ([]*Repository, *Response, error) { + if err := escapeValidatePathSegments(&user); err != nil { + return nil, nil, err + } + repos := make([]*Repository, 0, 10) + resp, err := c.getParsedResponse("GET", fmt.Sprintf("/users/%s/starred", user), jsonHeader, nil, &repos) + return repos, resp, err +} + +// GetMyStarredRepos returns the repos that the authenticated user has starred +func (c *Client) GetMyStarredRepos() ([]*Repository, *Response, error) { + repos := make([]*Repository, 0, 10) + resp, err := c.getParsedResponse("GET", "/user/starred", jsonHeader, nil, &repos) + return repos, resp, err +} + +// IsRepoStarring returns whether the authenticated user has starred the repo or not +func (c *Client) IsRepoStarring(user, repo string) (bool, *Response, error) { + if err := escapeValidatePathSegments(&user, &repo); err != nil { + return false, nil, err + } + _, resp, err := c.getResponse("GET", fmt.Sprintf("/user/starred/%s/%s", user, repo), jsonHeader, nil) + if resp != nil { + switch resp.StatusCode { + case http.StatusNotFound: + return false, resp, nil + case http.StatusNoContent: + return true, resp, nil + default: + return false, resp, fmt.Errorf("unexpected status code '%d'", resp.StatusCode) + } + } + return false, nil, err +} + +// StarRepo star specified repo as the authenticated user +func (c *Client) StarRepo(user, repo string) (*Response, error) { + if err := escapeValidatePathSegments(&user, &repo); err != nil { + return nil, err + } + _, resp, err := c.getResponse("PUT", fmt.Sprintf("/user/starred/%s/%s", user, repo), jsonHeader, nil) + if resp != nil { + switch resp.StatusCode { + case http.StatusNoContent: + return resp, nil + default: + return resp, fmt.Errorf("unexpected status code '%d'", resp.StatusCode) + } + } + return nil, err +} + +// UnStarRepo remove star to specified repo as the authenticated user +func (c *Client) UnStarRepo(user, repo string) (*Response, error) { + if err := escapeValidatePathSegments(&user, &repo); err != nil { + return nil, err + } + _, resp, err := c.getResponse("DELETE", fmt.Sprintf("/user/starred/%s/%s", user, repo), jsonHeader, nil) + if resp != nil { + switch resp.StatusCode { + case http.StatusNoContent: + return resp, nil + default: + return resp, fmt.Errorf("unexpected status code '%d'", resp.StatusCode) + } + } + return nil, err +} diff --git a/vendor/code.gitea.io/sdk/gitea/repo_tag.go b/vendor/code.gitea.io/sdk/gitea/repo_tag.go index 19eed5b9a..0a3c806a4 100644 --- a/vendor/code.gitea.io/sdk/gitea/repo_tag.go +++ b/vendor/code.gitea.io/sdk/gitea/repo_tag.go @@ -24,8 +24,25 @@ type ListRepoTagsOptions struct { // ListRepoTags list all the branches of one repository func (c *Client) ListRepoTags(user, repo string, opt ListRepoTagsOptions) ([]*Tag, *Response, error) { + if err := escapeValidatePathSegments(&user, &repo); err != nil { + return nil, nil, err + } opt.setDefaults() tags := make([]*Tag, 0, opt.PageSize) resp, err := c.getParsedResponse("GET", fmt.Sprintf("/repos/%s/%s/tags?%s", user, repo, opt.getURLQuery().Encode()), nil, nil, &tags) return tags, resp, err } + +// DeleteTag deletes a tag from a repository, if no release refers to it +func (c *Client) DeleteTag(user, repo string, tag string) (*Response, error) { + if err := escapeValidatePathSegments(&user, &repo, &tag); err != nil { + return nil, err + } + if err := c.checkServerVersionGreaterThanOrEqual(version1_14_0); err != nil { + return nil, err + } + _, resp, err := c.getResponse("DELETE", + fmt.Sprintf("/repos/%s/%s/tags/%s", user, repo, tag), + nil, nil) + return resp, err +} diff --git a/vendor/code.gitea.io/sdk/gitea/repo_topics.go b/vendor/code.gitea.io/sdk/gitea/repo_topics.go index fd05d0899..92f2228cd 100644 --- a/vendor/code.gitea.io/sdk/gitea/repo_topics.go +++ b/vendor/code.gitea.io/sdk/gitea/repo_topics.go @@ -22,6 +22,9 @@ type topicsList struct { // ListRepoTopics list all repository's topics func (c *Client) ListRepoTopics(user, repo string, opt ListRepoTopicsOptions) ([]string, *Response, error) { + if err := escapeValidatePathSegments(&user, &repo); err != nil { + return nil, nil, err + } opt.setDefaults() list := new(topicsList) @@ -34,9 +37,10 @@ func (c *Client) ListRepoTopics(user, repo string, opt ListRepoTopicsOptions) ([ // SetRepoTopics replaces the list of repo's topics func (c *Client) SetRepoTopics(user, repo string, list []string) (*Response, error) { - + if err := escapeValidatePathSegments(&user, &repo); err != nil { + return nil, err + } l := topicsList{Topics: list} - body, err := json.Marshal(&l) if err != nil { return nil, err @@ -47,12 +51,18 @@ func (c *Client) SetRepoTopics(user, repo string, list []string) (*Response, err // AddRepoTopic adds a topic to a repo's topics list func (c *Client) AddRepoTopic(user, repo, topic string) (*Response, error) { + if err := escapeValidatePathSegments(&user, &repo, &topic); err != nil { + return nil, err + } _, resp, err := c.getResponse("PUT", fmt.Sprintf("/repos/%s/%s/topics/%s", user, repo, topic), nil, nil) return resp, err } // DeleteRepoTopic deletes a topic from repo's topics list func (c *Client) DeleteRepoTopic(user, repo, topic string) (*Response, error) { + if err := escapeValidatePathSegments(&user, &repo, &topic); err != nil { + return nil, err + } _, resp, err := c.getResponse("DELETE", fmt.Sprintf("/repos/%s/%s/topics/%s", user, repo, topic), nil, nil) return resp, err } diff --git a/vendor/code.gitea.io/sdk/gitea/repo_transfer.go b/vendor/code.gitea.io/sdk/gitea/repo_transfer.go index d8d661bc4..be06010a7 100644 --- a/vendor/code.gitea.io/sdk/gitea/repo_transfer.go +++ b/vendor/code.gitea.io/sdk/gitea/repo_transfer.go @@ -20,6 +20,9 @@ type TransferRepoOption struct { // TransferRepo transfers the ownership of a repository func (c *Client) TransferRepo(owner, reponame string, opt TransferRepoOption) (*Repository, *Response, error) { + if err := escapeValidatePathSegments(&owner, &reponame); err != nil { + return nil, nil, err + } if err := c.checkServerVersionGreaterThanOrEqual(version1_12_0); err != nil { return nil, nil, err } diff --git a/vendor/code.gitea.io/sdk/gitea/repo_tree.go b/vendor/code.gitea.io/sdk/gitea/repo_tree.go index ce36e460b..452394a3c 100644 --- a/vendor/code.gitea.io/sdk/gitea/repo_tree.go +++ b/vendor/code.gitea.io/sdk/gitea/repo_tree.go @@ -31,6 +31,9 @@ type GitTreeResponse struct { // GetTrees downloads a file of repository, ref can be branch/tag/commit. // e.g.: ref -> master, tree -> macaron.go(no leading slash) func (c *Client) GetTrees(user, repo, ref string, recursive bool) (*GitTreeResponse, *Response, error) { + if err := escapeValidatePathSegments(&user, &repo, &ref); err != nil { + return nil, nil, err + } trees := new(GitTreeResponse) var path = fmt.Sprintf("/repos/%s/%s/git/trees/%s", user, repo, ref) if recursive { diff --git a/vendor/code.gitea.io/sdk/gitea/repo_watch.go b/vendor/code.gitea.io/sdk/gitea/repo_watch.go index 7358705fe..f499aff22 100644 --- a/vendor/code.gitea.io/sdk/gitea/repo_watch.go +++ b/vendor/code.gitea.io/sdk/gitea/repo_watch.go @@ -22,6 +22,9 @@ type WatchInfo struct { // GetWatchedRepos list all the watched repos of user func (c *Client) GetWatchedRepos(user string) ([]*Repository, *Response, error) { + if err := escapeValidatePathSegments(&user); err != nil { + return nil, nil, err + } repos := make([]*Repository, 0, 10) resp, err := c.getParsedResponse("GET", fmt.Sprintf("/users/%s/subscriptions", user), nil, nil, &repos) return repos, resp, err @@ -35,8 +38,11 @@ func (c *Client) GetMyWatchedRepos() ([]*Repository, *Response, error) { } // CheckRepoWatch check if the current user is watching a repo -func (c *Client) CheckRepoWatch(repoUser, repoName string) (bool, *Response, error) { - status, resp, err := c.getStatusCode("GET", fmt.Sprintf("/repos/%s/%s/subscription", repoUser, repoName), nil, nil) +func (c *Client) CheckRepoWatch(owner, repo string) (bool, *Response, error) { + if err := escapeValidatePathSegments(&owner, &repo); err != nil { + return false, nil, err + } + status, resp, err := c.getStatusCode("GET", fmt.Sprintf("/repos/%s/%s/subscription", owner, repo), nil, nil) if err != nil { return false, resp, err } @@ -51,8 +57,11 @@ func (c *Client) CheckRepoWatch(repoUser, repoName string) (bool, *Response, err } // WatchRepo start to watch a repository -func (c *Client) WatchRepo(repoUser, repoName string) (*Response, error) { - status, resp, err := c.getStatusCode("PUT", fmt.Sprintf("/repos/%s/%s/subscription", repoUser, repoName), nil, nil) +func (c *Client) WatchRepo(owner, repo string) (*Response, error) { + if err := escapeValidatePathSegments(&owner, &repo); err != nil { + return nil, err + } + status, resp, err := c.getStatusCode("PUT", fmt.Sprintf("/repos/%s/%s/subscription", owner, repo), nil, nil) if err != nil { return resp, err } @@ -63,8 +72,11 @@ func (c *Client) WatchRepo(repoUser, repoName string) (*Response, error) { } // UnWatchRepo stop to watch a repository -func (c *Client) UnWatchRepo(repoUser, repoName string) (*Response, error) { - status, resp, err := c.getStatusCode("DELETE", fmt.Sprintf("/repos/%s/%s/subscription", repoUser, repoName), nil, nil) +func (c *Client) UnWatchRepo(owner, repo string) (*Response, error) { + if err := escapeValidatePathSegments(&owner, &repo); err != nil { + return nil, err + } + status, resp, err := c.getStatusCode("DELETE", fmt.Sprintf("/repos/%s/%s/subscription", owner, repo), nil, nil) if err != nil { return resp, err } diff --git a/vendor/code.gitea.io/sdk/gitea/settings.go b/vendor/code.gitea.io/sdk/gitea/settings.go index 9fa0a7ae7..134d2ad99 100644 --- a/vendor/code.gitea.io/sdk/gitea/settings.go +++ b/vendor/code.gitea.io/sdk/gitea/settings.go @@ -6,13 +6,15 @@ package gitea // GlobalUISettings represent the global ui settings of a gitea instance witch is exposed by API type GlobalUISettings struct { + DefaultTheme string `json:"default_theme"` AllowedReactions []string `json:"allowed_reactions"` } // GlobalRepoSettings represent the global repository settings of a gitea instance witch is exposed by API type GlobalRepoSettings struct { - MirrorsDisabled bool `json:"mirrors_disabled"` - HTTPGitDisabled bool `json:"http_git_disabled"` + MirrorsDisabled bool `json:"mirrors_disabled"` + HTTPGitDisabled bool `json:"http_git_disabled"` + MigrationsDisabled bool `json:"migrations_disabled"` } // GlobalAPISettings contains global api settings exposed by it diff --git a/vendor/code.gitea.io/sdk/gitea/status.go b/vendor/code.gitea.io/sdk/gitea/status.go index 7c23b891e..fe5d9711f 100644 --- a/vendor/code.gitea.io/sdk/gitea/status.go +++ b/vendor/code.gitea.io/sdk/gitea/status.go @@ -8,6 +8,7 @@ import ( "bytes" "encoding/json" "fmt" + "net/url" "time" ) @@ -51,12 +52,15 @@ type CreateStatusOption struct { // CreateStatus creates a new Status for a given Commit func (c *Client) CreateStatus(owner, repo, sha string, opts CreateStatusOption) (*Status, *Response, error) { + if err := escapeValidatePathSegments(&owner, &repo); err != nil { + return nil, nil, err + } body, err := json.Marshal(&opts) if err != nil { return nil, nil, err } status := new(Status) - resp, err := c.getParsedResponse("POST", fmt.Sprintf("/repos/%s/%s/statuses/%s", owner, repo, sha), jsonHeader, bytes.NewReader(body), status) + resp, err := c.getParsedResponse("POST", fmt.Sprintf("/repos/%s/%s/statuses/%s", owner, repo, url.QueryEscape(sha)), jsonHeader, bytes.NewReader(body), status) return status, resp, err } @@ -65,11 +69,14 @@ type ListStatusesOption struct { ListOptions } -// ListStatuses returns all statuses for a given Commit -func (c *Client) ListStatuses(owner, repo, sha string, opt ListStatusesOption) ([]*Status, *Response, error) { +// ListStatuses returns all statuses for a given Commit by ref +func (c *Client) ListStatuses(owner, repo, ref string, opt ListStatusesOption) ([]*Status, *Response, error) { + if err := escapeValidatePathSegments(&owner, &repo, &ref); err != nil { + return nil, nil, err + } opt.setDefaults() statuses := make([]*Status, 0, opt.PageSize) - resp, err := c.getParsedResponse("GET", fmt.Sprintf("/repos/%s/%s/commits/%s/statuses?%s", owner, repo, sha, opt.getURLQuery().Encode()), nil, nil, &statuses) + resp, err := c.getParsedResponse("GET", fmt.Sprintf("/repos/%s/%s/commits/%s/statuses?%s", owner, repo, ref, opt.getURLQuery().Encode()), jsonHeader, nil, &statuses) return statuses, resp, err } @@ -85,8 +92,17 @@ type CombinedStatus struct { } // GetCombinedStatus returns the CombinedStatus for a given Commit -func (c *Client) GetCombinedStatus(owner, repo, sha string) (*CombinedStatus, *Response, error) { +func (c *Client) GetCombinedStatus(owner, repo, ref string) (*CombinedStatus, *Response, error) { + if err := escapeValidatePathSegments(&owner, &repo, &ref); err != nil { + return nil, nil, err + } status := new(CombinedStatus) - resp, err := c.getParsedResponse("GET", fmt.Sprintf("/repos/%s/%s/commits/%s/status", owner, repo, sha), nil, nil, status) + resp, err := c.getParsedResponse("GET", fmt.Sprintf("/repos/%s/%s/commits/%s/status", owner, repo, ref), jsonHeader, nil, status) + + // gitea api return empty body if nothing here jet + if resp != nil && resp.StatusCode == 200 && err != nil { + return status, resp, nil + } + return status, resp, err } diff --git a/vendor/code.gitea.io/sdk/gitea/user.go b/vendor/code.gitea.io/sdk/gitea/user.go index e909c6861..209523632 100644 --- a/vendor/code.gitea.io/sdk/gitea/user.go +++ b/vendor/code.gitea.io/sdk/gitea/user.go @@ -30,6 +30,9 @@ type User struct { // GetUserInfo get user info by user's name func (c *Client) GetUserInfo(user string) (*User, *Response, error) { + if err := escapeValidatePathSegments(&user); err != nil { + return nil, nil, err + } u := new(User) resp, err := c.getParsedResponse("GET", fmt.Sprintf("/users/%s", user), nil, nil, u) return u, resp, err diff --git a/vendor/code.gitea.io/sdk/gitea/user_app.go b/vendor/code.gitea.io/sdk/gitea/user_app.go index 7f7696dc4..2921eea7d 100644 --- a/vendor/code.gitea.io/sdk/gitea/user_app.go +++ b/vendor/code.gitea.io/sdk/gitea/user_app.go @@ -9,6 +9,7 @@ import ( "bytes" "encoding/json" "fmt" + "net/url" "reflect" ) @@ -27,12 +28,15 @@ type ListAccessTokensOptions struct { // ListAccessTokens lists all the access tokens of user func (c *Client) ListAccessTokens(opts ListAccessTokensOptions) ([]*AccessToken, *Response, error) { - if len(c.username) == 0 { + c.mutex.RLock() + username := c.username + c.mutex.RUnlock() + if len(username) == 0 { return nil, nil, fmt.Errorf("\"username\" not set: only BasicAuth allowed") } opts.setDefaults() tokens := make([]*AccessToken, 0, opts.PageSize) - resp, err := c.getParsedResponse("GET", fmt.Sprintf("/users/%s/tokens?%s", c.username, opts.getURLQuery().Encode()), jsonHeader, nil, &tokens) + resp, err := c.getParsedResponse("GET", fmt.Sprintf("/users/%s/tokens?%s", url.PathEscape(username), opts.getURLQuery().Encode()), jsonHeader, nil, &tokens) return tokens, resp, err } @@ -43,7 +47,10 @@ type CreateAccessTokenOption struct { // CreateAccessToken create one access token with options func (c *Client) CreateAccessToken(opt CreateAccessTokenOption) (*AccessToken, *Response, error) { - if len(c.username) == 0 { + c.mutex.RLock() + username := c.username + c.mutex.RUnlock() + if len(username) == 0 { return nil, nil, fmt.Errorf("\"username\" not set: only BasicAuth allowed") } body, err := json.Marshal(&opt) @@ -51,13 +58,16 @@ func (c *Client) CreateAccessToken(opt CreateAccessTokenOption) (*AccessToken, * return nil, nil, err } t := new(AccessToken) - resp, err := c.getParsedResponse("POST", fmt.Sprintf("/users/%s/tokens", c.username), jsonHeader, bytes.NewReader(body), t) + resp, err := c.getParsedResponse("POST", fmt.Sprintf("/users/%s/tokens", url.PathEscape(username)), jsonHeader, bytes.NewReader(body), t) return t, resp, err } // DeleteAccessToken delete token, identified by ID and if not available by name func (c *Client) DeleteAccessToken(value interface{}) (*Response, error) { - if len(c.username) == 0 { + c.mutex.RLock() + username := c.username + c.mutex.RUnlock() + if len(username) == 0 { return nil, fmt.Errorf("\"username\" not set: only BasicAuth allowed") } @@ -75,6 +85,6 @@ func (c *Client) DeleteAccessToken(value interface{}) (*Response, error) { return nil, fmt.Errorf("only string and int64 supported") } - _, resp, err := c.getResponse("DELETE", fmt.Sprintf("/users/%s/tokens/%s", c.username, token), jsonHeader, nil) + _, resp, err := c.getResponse("DELETE", fmt.Sprintf("/users/%s/tokens/%s", url.PathEscape(username), url.PathEscape(token)), jsonHeader, nil) return resp, err } diff --git a/vendor/code.gitea.io/sdk/gitea/user_follow.go b/vendor/code.gitea.io/sdk/gitea/user_follow.go index c8bafc01e..7bd340ca2 100644 --- a/vendor/code.gitea.io/sdk/gitea/user_follow.go +++ b/vendor/code.gitea.io/sdk/gitea/user_follow.go @@ -21,6 +21,9 @@ func (c *Client) ListMyFollowers(opt ListFollowersOptions) ([]*User, *Response, // ListFollowers list all the followers of one user func (c *Client) ListFollowers(user string, opt ListFollowersOptions) ([]*User, *Response, error) { + if err := escapeValidatePathSegments(&user); err != nil { + return nil, nil, err + } opt.setDefaults() users := make([]*User, 0, opt.PageSize) resp, err := c.getParsedResponse("GET", fmt.Sprintf("/users/%s/followers?%s", user, opt.getURLQuery().Encode()), nil, nil, &users) @@ -42,6 +45,9 @@ func (c *Client) ListMyFollowing(opt ListFollowingOptions) ([]*User, *Response, // ListFollowing list all the users the user followed func (c *Client) ListFollowing(user string, opt ListFollowingOptions) ([]*User, *Response, error) { + if err := escapeValidatePathSegments(&user); err != nil { + return nil, nil, err + } opt.setDefaults() users := make([]*User, 0, opt.PageSize) resp, err := c.getParsedResponse("GET", fmt.Sprintf("/users/%s/following?%s", user, opt.getURLQuery().Encode()), nil, nil, &users) @@ -50,24 +56,38 @@ func (c *Client) ListFollowing(user string, opt ListFollowingOptions) ([]*User, // IsFollowing if current user followed the target func (c *Client) IsFollowing(target string) (bool, *Response) { + if err := escapeValidatePathSegments(&target); err != nil { + // ToDo return err + return false, nil + } _, resp, err := c.getResponse("GET", fmt.Sprintf("/user/following/%s", target), nil, nil) return err == nil, resp } // IsUserFollowing if the user followed the target func (c *Client) IsUserFollowing(user, target string) (bool, *Response) { + if err := escapeValidatePathSegments(&user, &target); err != nil { + // ToDo return err + return false, nil + } _, resp, err := c.getResponse("GET", fmt.Sprintf("/users/%s/following/%s", user, target), nil, nil) return err == nil, resp } // Follow set current user follow the target func (c *Client) Follow(target string) (*Response, error) { + if err := escapeValidatePathSegments(&target); err != nil { + return nil, err + } _, resp, err := c.getResponse("PUT", fmt.Sprintf("/user/following/%s", target), nil, nil) return resp, err } // Unfollow set current user unfollow the target func (c *Client) Unfollow(target string) (*Response, error) { + if err := escapeValidatePathSegments(&target); err != nil { + return nil, err + } _, resp, err := c.getResponse("DELETE", fmt.Sprintf("/user/following/%s", target), nil, nil) return resp, err } diff --git a/vendor/code.gitea.io/sdk/gitea/user_gpgkey.go b/vendor/code.gitea.io/sdk/gitea/user_gpgkey.go index d3d64b41e..6c1b9d10f 100644 --- a/vendor/code.gitea.io/sdk/gitea/user_gpgkey.go +++ b/vendor/code.gitea.io/sdk/gitea/user_gpgkey.go @@ -40,6 +40,9 @@ type ListGPGKeysOptions struct { // ListGPGKeys list all the GPG keys of the user func (c *Client) ListGPGKeys(user string, opt ListGPGKeysOptions) ([]*GPGKey, *Response, error) { + if err := escapeValidatePathSegments(&user); err != nil { + return nil, nil, err + } opt.setDefaults() keys := make([]*GPGKey, 0, opt.PageSize) resp, err := c.getParsedResponse("GET", fmt.Sprintf("/users/%s/gpg_keys?%s", user, opt.getURLQuery().Encode()), nil, nil, &keys) diff --git a/vendor/code.gitea.io/sdk/gitea/user_key.go b/vendor/code.gitea.io/sdk/gitea/user_key.go index d005f00be..02795baef 100644 --- a/vendor/code.gitea.io/sdk/gitea/user_key.go +++ b/vendor/code.gitea.io/sdk/gitea/user_key.go @@ -31,6 +31,9 @@ type ListPublicKeysOptions struct { // ListPublicKeys list all the public keys of the user func (c *Client) ListPublicKeys(user string, opt ListPublicKeysOptions) ([]*PublicKey, *Response, error) { + if err := escapeValidatePathSegments(&user); err != nil { + return nil, nil, err + } opt.setDefaults() keys := make([]*PublicKey, 0, opt.PageSize) resp, err := c.getParsedResponse("GET", fmt.Sprintf("/users/%s/keys?%s", user, opt.getURLQuery().Encode()), nil, nil, &keys) diff --git a/vendor/code.gitea.io/sdk/gitea/version.go b/vendor/code.gitea.io/sdk/gitea/version.go index 747117ccc..ed8a2ae5d 100644 --- a/vendor/code.gitea.io/sdk/gitea/version.go +++ b/vendor/code.gitea.io/sdk/gitea/version.go @@ -22,14 +22,8 @@ func (c *Client) ServerVersion() (string, *Response, error) { // CheckServerVersionConstraint validates that the login's server satisfies a // given version constraint such as ">= 1.11.0+dev" func (c *Client) CheckServerVersionConstraint(constraint string) error { - c.versionLock.RLock() - if c.serverVersion == nil { - c.versionLock.RUnlock() - if err := c.loadClientServerVersion(); err != nil { - return err - } - } else { - c.versionLock.RUnlock() + if err := c.loadServerVersion(); err != nil { + return err } check, err := version.NewConstraint(constraint) @@ -37,48 +31,48 @@ func (c *Client) CheckServerVersionConstraint(constraint string) error { return err } if !check.Check(c.serverVersion) { - return fmt.Errorf("gitea server at %s does not satisfy version constraint %s", c.url, constraint) + c.mutex.RLock() + url := c.url + c.mutex.RUnlock() + return fmt.Errorf("gitea server at %s does not satisfy version constraint %s", url, constraint) } return nil } // predefined versions only have to be parsed by library once var ( - version1_10_0, _ = version.NewVersion("1.10.0") version1_11_0, _ = version.NewVersion("1.11.0") version1_12_0, _ = version.NewVersion("1.12.0") version1_13_0, _ = version.NewVersion("1.13.0") + version1_14_0, _ = version.NewVersion("1.14.0") ) // checkServerVersionGreaterThanOrEqual is internally used to speed up things and ignore issues with prerelease func (c *Client) checkServerVersionGreaterThanOrEqual(v *version.Version) error { - c.versionLock.RLock() - if c.serverVersion == nil { - c.versionLock.RUnlock() - if err := c.loadClientServerVersion(); err != nil { - return err - } - } else { - c.versionLock.RUnlock() + if err := c.loadServerVersion(); err != nil { + return err } if !c.serverVersion.GreaterThanOrEqual(v) { - return fmt.Errorf("gitea server at %s is older than %s", c.url, v.Original()) + c.mutex.RLock() + url := c.url + c.mutex.RUnlock() + return fmt.Errorf("gitea server at %s is older than %s", url, v.Original()) } return nil } -// loadClientServerVersion init the serverVersion variable -func (c *Client) loadClientServerVersion() error { - c.versionLock.Lock() - defer c.versionLock.Unlock() - - raw, _, err := c.ServerVersion() - if err != nil { - return err - } - if c.serverVersion, err = version.NewVersion(raw); err != nil { - return err - } - return nil +// loadServerVersion init the serverVersion variable +func (c *Client) loadServerVersion() (err error) { + c.getVersionOnce.Do(func() { + raw, _, err2 := c.ServerVersion() + if err2 != nil { + err = err2 + return + } + if c.serverVersion, err = version.NewVersion(raw); err != nil { + return + } + }) + return } diff --git a/vendor/modules.txt b/vendor/modules.txt index 7069aaffe..fa1792b72 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -5,7 +5,7 @@ cloud.google.com/go/compute/metadata ## explicit code.gitea.io/gitea-vet code.gitea.io/gitea-vet/checks -# code.gitea.io/sdk/gitea v0.13.2 +# code.gitea.io/sdk/gitea v0.14.0 ## explicit code.gitea.io/sdk/gitea # gitea.com/go-chi/binding v0.0.0-20210301195521-1fe1c9a555e7