Skip to content

Commit e259244

Browse files
committed
Merge remote-tracking branch 'origin/master' into ensure-user-email-is-stored-in-email-address-table
* origin/master: [UI] Hide consecutive additions and removals of the same label (go-gitea#13315) [skip ci] Updated translations via Crowdin Fix send mail (go-gitea#13312) [skip ci] Updated translations via Crowdin Deny wrong pull (go-gitea#13308) Group Label Changed Comments in timeline (go-gitea#13304) [skip ci] Updated translations via Crowdin Attempt to handle unready PR in tests (go-gitea#13305) go-gitea#12897 - add mastodon provider (go-gitea#13293) [skip ci] Updated translations via Crowdin Fix Storage mapping (go-gitea#13297) Update Mirror IsEmpty status on synchronize (go-gitea#13185) Fix bug isEnd detection on getIssues/getPullRequests (go-gitea#13299) systemd service: Add commented PATH environment option for Git prefix (go-gitea#13170) Sendmail command (go-gitea#13079) Various UI and arc-green fixes (go-gitea#13291)
2 parents 111e507 + 8e368e7 commit e259244

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

51 files changed

+943
-98
lines changed

cmd/admin.go

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ var (
3434
subcmdRepoSyncReleases,
3535
subcmdRegenerate,
3636
subcmdAuth,
37+
subcmdSendMail,
3738
},
3839
}
3940

@@ -282,6 +283,28 @@ var (
282283
Action: runAddOauth,
283284
Flags: oauthCLIFlags,
284285
}
286+
287+
subcmdSendMail = cli.Command{
288+
Name: "sendmail",
289+
Usage: "Send a message to all users",
290+
Action: runSendMail,
291+
Flags: []cli.Flag{
292+
cli.StringFlag{
293+
Name: "title",
294+
Usage: `a title of a message`,
295+
Value: "",
296+
},
297+
cli.StringFlag{
298+
Name: "content",
299+
Usage: "a content of a message",
300+
Value: "",
301+
},
302+
cli.BoolFlag{
303+
Name: "force,f",
304+
Usage: "A flag to bypass a confirmation step",
305+
},
306+
},
307+
}
285308
)
286309

287310
func runChangePassword(c *cli.Context) error {

cmd/cmd.go

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ package cmd
99
import (
1010
"errors"
1111
"fmt"
12+
"strings"
1213

1314
"code.gitea.io/gitea/models"
1415
"code.gitea.io/gitea/modules/setting"
@@ -32,6 +33,25 @@ func argsSet(c *cli.Context, args ...string) error {
3233
return nil
3334
}
3435

36+
// confirm waits for user input which confirms an action
37+
func confirm() (bool, error) {
38+
var response string
39+
40+
_, err := fmt.Scanln(&response)
41+
if err != nil {
42+
return false, err
43+
}
44+
45+
switch strings.ToLower(response) {
46+
case "y", "yes":
47+
return true, nil
48+
case "n", "no":
49+
return false, nil
50+
default:
51+
return false, errors.New(response + " isn't a correct confirmation string")
52+
}
53+
}
54+
3555
func initDB() error {
3656
return initDBDisableConsole(false)
3757
}

cmd/mailer.go

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
// Copyright 2020 The Gitea Authors. All rights reserved.
2+
// Use of this source code is governed by a MIT-style
3+
// license that can be found in the LICENSE file.
4+
5+
package cmd
6+
7+
import (
8+
"fmt"
9+
"net/http"
10+
11+
"code.gitea.io/gitea/modules/private"
12+
"code.gitea.io/gitea/modules/setting"
13+
"github.com/urfave/cli"
14+
)
15+
16+
func runSendMail(c *cli.Context) error {
17+
setting.NewContext()
18+
19+
if err := argsSet(c, "title"); err != nil {
20+
return err
21+
}
22+
23+
subject := c.String("title")
24+
confirmSkiped := c.Bool("force")
25+
body := c.String("content")
26+
27+
if !confirmSkiped {
28+
if len(body) == 0 {
29+
fmt.Print("warning: Content is empty")
30+
}
31+
32+
fmt.Print("Proceed with sending email? [Y/n] ")
33+
isConfirmed, err := confirm()
34+
if err != nil {
35+
return err
36+
} else if !isConfirmed {
37+
fmt.Println("The mail was not sent")
38+
return nil
39+
}
40+
}
41+
42+
status, message := private.SendEmail(subject, body, nil)
43+
if status != http.StatusOK {
44+
fmt.Printf("error: %s\n", message)
45+
return nil
46+
}
47+
48+
fmt.Printf("Success: %s\n", message)
49+
50+
return nil
51+
}

contrib/systemd/gitea.service

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,12 @@ WorkingDirectory=/var/lib/gitea/
5757
ExecStart=/usr/local/bin/gitea web --config /etc/gitea/app.ini
5858
Restart=always
5959
Environment=USER=git HOME=/home/git GITEA_WORK_DIR=/var/lib/gitea
60+
# If you install Git to directory prefix other than default PATH (which happens
61+
# for example if you install other versions of Git side-to-side with
62+
# distribution version), uncomment below line and add that prefix to PATH
63+
# Don't forget to place git-lfs binary on the PATH below if you want to enable
64+
# Git LFS support
65+
#Environment=PATH=/path/to/git/bin:/bin:/sbin:/usr/bin:/usr/sbin
6066
# If you want to bind Gitea to a port below 1024, uncomment
6167
# the two values below, or use socket activation to pass Gitea its ports as above
6268
###

go.sum

Lines changed: 54 additions & 0 deletions
Large diffs are not rendered by default.

integrations/api_helper_for_declarative_test.go

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,17 @@
55
package integrations
66

77
import (
8+
"context"
89
"encoding/json"
910
"fmt"
1011
"io/ioutil"
1112
"net/http"
1213
"testing"
14+
"time"
1315

1416
"code.gitea.io/gitea/models"
1517
"code.gitea.io/gitea/modules/auth"
18+
"code.gitea.io/gitea/modules/queue"
1619
api "code.gitea.io/gitea/modules/structs"
1720

1821
"github.com/stretchr/testify/assert"
@@ -225,11 +228,25 @@ func doAPIMergePullRequest(ctx APITestContext, owner, repo string, index int64)
225228
Do: string(models.MergeStyleMerge),
226229
})
227230

228-
if ctx.ExpectedCode != 0 {
229-
ctx.Session.MakeRequest(t, req, ctx.ExpectedCode)
230-
return
231+
resp := ctx.Session.MakeRequest(t, req, NoExpectedStatus)
232+
233+
if resp.Code == http.StatusMethodNotAllowed {
234+
err := api.APIError{}
235+
DecodeJSON(t, resp, &err)
236+
assert.EqualValues(t, "Please try again later", err.Message)
237+
queue.GetManager().FlushAll(context.Background(), 5*time.Second)
238+
resp = ctx.Session.MakeRequest(t, req, NoExpectedStatus)
239+
}
240+
241+
expected := ctx.ExpectedCode
242+
if expected == 0 {
243+
expected = 200
244+
}
245+
246+
if !assert.EqualValues(t, expected, resp.Code,
247+
"Request: %s %s", req.Method, req.URL.String()) {
248+
logUnexpectedResponse(t, resp)
231249
}
232-
ctx.Session.MakeRequest(t, req, 200)
233250
}
234251
}
235252

models/issue_comment.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,9 @@ type Comment struct {
124124
IssueID int64 `xorm:"INDEX"`
125125
Issue *Issue `xorm:"-"`
126126
LabelID int64
127-
Label *Label `xorm:"-"`
127+
Label *Label `xorm:"-"`
128+
AddedLabels []*Label `xorm:"-"`
129+
RemovedLabels []*Label `xorm:"-"`
128130
OldProjectID int64
129131
ProjectID int64
130132
OldProject *Project `xorm:"-"`

models/oauth2.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,11 @@ var OAuth2Providers = map[string]OAuth2Provider{
5959
},
6060
},
6161
"yandex": {Name: "yandex", DisplayName: "Yandex", Image: "/img/auth/yandex.png"},
62+
"mastodon": {Name: "mastodon", DisplayName: "Mastodon", Image: "/img/auth/mastodon.png",
63+
CustomURLMapping: &oauth2.CustomURLMapping{
64+
AuthURL: oauth2.GetDefaultAuthURL("mastodon"),
65+
},
66+
},
6267
}
6368

6469
// OAuth2DefaultCustomURLMappings contains the map of default URL's for OAuth2 providers that are allowed to have custom urls
@@ -69,6 +74,7 @@ var OAuth2DefaultCustomURLMappings = map[string]*oauth2.CustomURLMapping{
6974
"gitlab": OAuth2Providers["gitlab"].CustomURLMapping,
7075
"gitea": OAuth2Providers["gitea"].CustomURLMapping,
7176
"nextcloud": OAuth2Providers["nextcloud"].CustomURLMapping,
77+
"mastodon": OAuth2Providers["mastodon"].CustomURLMapping,
7278
}
7379

7480
// GetActiveOAuth2ProviderLoginSources returns all actived LoginOAuth2 sources

modules/auth/oauth2/oauth2.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ import (
2323
"github.com/markbates/goth/providers/github"
2424
"github.com/markbates/goth/providers/gitlab"
2525
"github.com/markbates/goth/providers/google"
26+
"github.com/markbates/goth/providers/mastodon"
2627
"github.com/markbates/goth/providers/nextcloud"
2728
"github.com/markbates/goth/providers/openidConnect"
2829
"github.com/markbates/goth/providers/twitter"
@@ -213,6 +214,12 @@ func createProvider(providerName, providerType, clientID, clientSecret, openIDCo
213214
case "yandex":
214215
// See https://tech.yandex.com/passport/doc/dg/reference/response-docpage/
215216
provider = yandex.New(clientID, clientSecret, callbackURL, "login:email", "login:info", "login:avatar")
217+
case "mastodon":
218+
instanceURL := mastodon.InstanceURL
219+
if customURLMapping != nil && len(customURLMapping.AuthURL) > 0 {
220+
instanceURL = customURLMapping.AuthURL
221+
}
222+
provider = mastodon.NewCustomisedURL(clientID, clientSecret, callbackURL, instanceURL)
216223
}
217224

218225
// always set the name if provider is created so we can support multiple setups of 1 provider
@@ -249,6 +256,8 @@ func GetDefaultAuthURL(provider string) string {
249256
return gitea.AuthURL
250257
case "nextcloud":
251258
return nextcloud.AuthURL
259+
case "mastodon":
260+
return mastodon.InstanceURL
252261
}
253262
return ""
254263
}

modules/migrations/github.go

Lines changed: 30 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -65,23 +65,25 @@ func (f *GithubDownloaderV3Factory) GitServiceType() structs.GitServiceType {
6565
// GithubDownloaderV3 implements a Downloader interface to get repository informations
6666
// from github via APIv3
6767
type GithubDownloaderV3 struct {
68-
ctx context.Context
69-
client *github.Client
70-
repoOwner string
71-
repoName string
72-
userName string
73-
password string
74-
rate *github.Rate
68+
ctx context.Context
69+
client *github.Client
70+
repoOwner string
71+
repoName string
72+
userName string
73+
password string
74+
rate *github.Rate
75+
maxPerPage int
7576
}
7677

7778
// NewGithubDownloaderV3 creates a github Downloader via github v3 API
7879
func NewGithubDownloaderV3(ctx context.Context, baseURL, userName, password, token, repoOwner, repoName string) *GithubDownloaderV3 {
7980
var downloader = GithubDownloaderV3{
80-
userName: userName,
81-
password: password,
82-
ctx: ctx,
83-
repoOwner: repoOwner,
84-
repoName: repoName,
81+
userName: userName,
82+
password: password,
83+
ctx: ctx,
84+
repoOwner: repoOwner,
85+
repoName: repoName,
86+
maxPerPage: 100,
8587
}
8688

8789
client := &http.Client{
@@ -177,7 +179,7 @@ func (g *GithubDownloaderV3) GetTopics() ([]string, error) {
177179

178180
// GetMilestones returns milestones
179181
func (g *GithubDownloaderV3) GetMilestones() ([]*base.Milestone, error) {
180-
var perPage = 100
182+
var perPage = g.maxPerPage
181183
var milestones = make([]*base.Milestone, 0, perPage)
182184
for i := 1; ; i++ {
183185
g.sleep()
@@ -233,7 +235,7 @@ func convertGithubLabel(label *github.Label) *base.Label {
233235

234236
// GetLabels returns labels
235237
func (g *GithubDownloaderV3) GetLabels() ([]*base.Label, error) {
236-
var perPage = 100
238+
var perPage = g.maxPerPage
237239
var labels = make([]*base.Label, 0, perPage)
238240
for i := 1; ; i++ {
239241
g.sleep()
@@ -304,7 +306,7 @@ func (g *GithubDownloaderV3) convertGithubRelease(rel *github.RepositoryRelease)
304306

305307
// GetReleases returns releases
306308
func (g *GithubDownloaderV3) GetReleases() ([]*base.Release, error) {
307-
var perPage = 100
309+
var perPage = g.maxPerPage
308310
var releases = make([]*base.Release, 0, perPage)
309311
for i := 1; ; i++ {
310312
g.sleep()
@@ -342,6 +344,9 @@ func (g *GithubDownloaderV3) GetAsset(_ string, _, id int64) (io.ReadCloser, err
342344

343345
// GetIssues returns issues according start and limit
344346
func (g *GithubDownloaderV3) GetIssues(page, perPage int) ([]*base.Issue, bool, error) {
347+
if perPage > g.maxPerPage {
348+
perPage = g.maxPerPage
349+
}
345350
opt := &github.IssueListByRepoOptions{
346351
Sort: "created",
347352
Direction: "asc",
@@ -429,15 +434,15 @@ func (g *GithubDownloaderV3) GetIssues(page, perPage int) ([]*base.Issue, bool,
429434
// GetComments returns comments according issueNumber
430435
func (g *GithubDownloaderV3) GetComments(issueNumber int64) ([]*base.Comment, error) {
431436
var (
432-
allComments = make([]*base.Comment, 0, 100)
437+
allComments = make([]*base.Comment, 0, g.maxPerPage)
433438
created = "created"
434439
asc = "asc"
435440
)
436441
opt := &github.IssueListCommentsOptions{
437442
Sort: &created,
438443
Direction: &asc,
439444
ListOptions: github.ListOptions{
440-
PerPage: 100,
445+
PerPage: g.maxPerPage,
441446
},
442447
}
443448
for {
@@ -459,7 +464,7 @@ func (g *GithubDownloaderV3) GetComments(issueNumber int64) ([]*base.Comment, er
459464
g.sleep()
460465
res, resp, err := g.client.Reactions.ListIssueCommentReactions(g.ctx, g.repoOwner, g.repoName, comment.GetID(), &github.ListOptions{
461466
Page: i,
462-
PerPage: 100,
467+
PerPage: g.maxPerPage,
463468
})
464469
if err != nil {
465470
return nil, err
@@ -497,6 +502,9 @@ func (g *GithubDownloaderV3) GetComments(issueNumber int64) ([]*base.Comment, er
497502

498503
// GetPullRequests returns pull requests according page and perPage
499504
func (g *GithubDownloaderV3) GetPullRequests(page, perPage int) ([]*base.PullRequest, bool, error) {
505+
if perPage > g.maxPerPage {
506+
perPage = g.maxPerPage
507+
}
500508
opt := &github.PullRequestListOptions{
501509
Sort: "created",
502510
Direction: "asc",
@@ -650,7 +658,7 @@ func (g *GithubDownloaderV3) convertGithubReviewComments(cs []*github.PullReques
650658
g.sleep()
651659
res, resp, err := g.client.Reactions.ListPullRequestCommentReactions(g.ctx, g.repoOwner, g.repoName, c.GetID(), &github.ListOptions{
652660
Page: i,
653-
PerPage: 100,
661+
PerPage: g.maxPerPage,
654662
})
655663
if err != nil {
656664
return nil, err
@@ -687,9 +695,9 @@ func (g *GithubDownloaderV3) convertGithubReviewComments(cs []*github.PullReques
687695

688696
// GetReviews returns pull requests review
689697
func (g *GithubDownloaderV3) GetReviews(pullRequestNumber int64) ([]*base.Review, error) {
690-
var allReviews = make([]*base.Review, 0, 100)
698+
var allReviews = make([]*base.Review, 0, g.maxPerPage)
691699
opt := &github.ListOptions{
692-
PerPage: 100,
700+
PerPage: g.maxPerPage,
693701
}
694702
for {
695703
g.sleep()
@@ -703,7 +711,7 @@ func (g *GithubDownloaderV3) GetReviews(pullRequestNumber int64) ([]*base.Review
703711
r.IssueIndex = pullRequestNumber
704712
// retrieve all review comments
705713
opt2 := &github.ListOptions{
706-
PerPage: 100,
714+
PerPage: g.maxPerPage,
707715
}
708716
for {
709717
g.sleep()

0 commit comments

Comments
 (0)