Compare commits

..

8 Commits

Author SHA1 Message Date
techknowlogick
cfe6941905 1.5.0 changelog 2018-08-10 13:16:53 -04:00
Lunny Xiao
eb8c611b1d Site admin could create repos even MAX_CREATION_LIMIT=0 (#4645) (#4650)
* site admin could create repos even MAX_CREATION_LIMIT=0

* Optimize if structure
2018-08-09 06:31:57 +03:00
techknowlogick
b1eaeeb0cd Backport Remove link to GitHub issues in 404 template #4639 (#4644) 2018-08-08 16:20:05 -04:00
SagePtr
15a403bf97 Push whitelist now doesn't apply to branch deletion (#4601) (#4640) 2018-08-08 11:19:13 +03:00
Lunny Xiao
099028681e fix bugs when too many IN variables (#4594) (#4597) 2018-08-02 14:48:39 -04:00
Dingjun
940e30bcd4 fix panic issue on update avatar email (#4580) (#4590)
fix #4580

back port PR for release/v1.5,  refer to #4581
2018-08-01 21:34:57 +08:00
SagePtr
5a7830e0e8 Fix incorrect MergeWhitelistTeamIDs check in CanUserMerge function (#4519) (#4526) 2018-07-27 22:11:53 +03:00
SagePtr
dae065ea68 Fix out-of-transaction query in removeOrgUser (#4521) (#4524) 2018-07-27 08:57:49 -04:00
8 changed files with 227 additions and 108 deletions

View File

@@ -4,9 +4,11 @@ This changelog goes through all the changes that have been made in each release
without substantial changes to our git log; to see the highlights of what has without substantial changes to our git log; to see the highlights of what has
been added to each release, please refer to the [blog](https://blog.gitea.io). been added to each release, please refer to the [blog](https://blog.gitea.io).
## [1.5.0-RC2](https://github.com/go-gitea/gitea/releases/tag/v1.5.0-rc2) - 2018-07-21 ## [1.5.0](https://github.com/go-gitea/gitea/releases/tag/v1.5.0) - 2018-08-10
* SECURITY * SECURITY
* Check that repositories can only be migrated to own user or organizations (#4366) (#4370) * Check that repositories can only be migrated to own user or organizations (#4366) (#4370)
* Limit uploaded avatar image-size to 4096px x 3072px by default (#4353)
* Do not allow to reuse TOTP passcode (#3878)
* BUGFIXES * BUGFIXES
* Fix column droping for MSSQL that need new transaction for that (#4440) (#4484) * Fix column droping for MSSQL that need new transaction for that (#4440) (#4484)
* Redirect to correct page after using scratch token (#4458) (#4472) * Redirect to correct page after using scratch token (#4458) (#4472)
@@ -15,11 +17,12 @@ been added to each release, please refer to the [blog](https://blog.gitea.io).
* Add default merge options when adding new repository (#4369) (#4373) * Add default merge options when adding new repository (#4369) (#4373)
* Fix repository last updated time update when delete a user who watched the repo (#4363) (#4371) * Fix repository last updated time update when delete a user who watched the repo (#4363) (#4371)
* Fix html entity escaping in branch deletion message (#4471) (#4485) * Fix html entity escaping in branch deletion message (#4471) (#4485)
* Fix out-of-transaction query in removeOrgUser (#4521) (#4524)
## [1.5.0-RC1](https://github.com/go-gitea/gitea/releases/tag/v1.5.0-rc1) - 2018-07-04 * Fix incorrect MergeWhitelistTeamIDs check in CanUserMerge function (#4519)
* SECURITY * Fix panic issue on update avatar email (#4580) (#4590)
* Limit uploaded avatar image-size to 4096px x 3072px by default (#4353) * Fix bugs when too many IN variables (#4594) (#4597)
* Do not allow to reuse TOTP passcode (#3878) * Push whitelist now doesn't apply to branch deletion (#4601) (#4640)
* Site admin could create repos even MAX_CREATION_LIMIT=0 (#4645) (#4650)
* FEATURE * FEATURE
* Add cli commands to regen hooks & keys (#3979) * Add cli commands to regen hooks & keys (#3979)
* Add support for FIDO U2F (#3971) * Add support for FIDO U2F (#3971)

View File

@@ -74,7 +74,7 @@ func (protectBranch *ProtectedBranch) CanUserMerge(userID int64) bool {
return true return true
} }
if len(protectBranch.WhitelistTeamIDs) == 0 { if len(protectBranch.MergeWhitelistTeamIDs) == 0 {
return false return false
} }
@@ -184,6 +184,24 @@ func (repo *Repository) IsProtectedBranch(branchName string, doer *User) (bool,
BranchName: branchName, BranchName: branchName,
} }
has, err := x.Exist(protectedBranch)
if err != nil {
return true, err
}
return has, nil
}
// IsProtectedBranchForPush checks if branch is protected for push
func (repo *Repository) IsProtectedBranchForPush(branchName string, doer *User) (bool, error) {
if doer == nil {
return true, nil
}
protectedBranch := &ProtectedBranch{
RepoID: repo.ID,
BranchName: branchName,
}
has, err := x.Get(protectedBranch) has, err := x.Get(protectedBranch)
if err != nil { if err != nil {
return true, err return true, err

View File

@@ -9,6 +9,11 @@ import "fmt"
// IssueList defines a list of issues // IssueList defines a list of issues
type IssueList []*Issue type IssueList []*Issue
const (
// default variables number on IN () in SQL
defaultMaxInSize = 50
)
func (issues IssueList) getRepoIDs() []int64 { func (issues IssueList) getRepoIDs() []int64 {
repoIDs := make(map[int64]struct{}, len(issues)) repoIDs := make(map[int64]struct{}, len(issues))
for _, issue := range issues { for _, issue := range issues {
@@ -26,12 +31,21 @@ func (issues IssueList) loadRepositories(e Engine) ([]*Repository, error) {
repoIDs := issues.getRepoIDs() repoIDs := issues.getRepoIDs()
repoMaps := make(map[int64]*Repository, len(repoIDs)) repoMaps := make(map[int64]*Repository, len(repoIDs))
var left = len(repoIDs)
for left > 0 {
var limit = defaultMaxInSize
if left < limit {
limit = left
}
err := e. err := e.
In("id", repoIDs). In("id", repoIDs[:limit]).
Find(&repoMaps) Find(&repoMaps)
if err != nil { if err != nil {
return nil, fmt.Errorf("find repository: %v", err) return nil, fmt.Errorf("find repository: %v", err)
} }
left = left - limit
repoIDs = repoIDs[limit:]
}
for _, issue := range issues { for _, issue := range issues {
issue.Repo = repoMaps[issue.RepoID] issue.Repo = repoMaps[issue.RepoID]
@@ -61,12 +75,21 @@ func (issues IssueList) loadPosters(e Engine) error {
posterIDs := issues.getPosterIDs() posterIDs := issues.getPosterIDs()
posterMaps := make(map[int64]*User, len(posterIDs)) posterMaps := make(map[int64]*User, len(posterIDs))
var left = len(posterIDs)
for left > 0 {
var limit = defaultMaxInSize
if left < limit {
limit = left
}
err := e. err := e.
In("id", posterIDs). In("id", posterIDs[:limit]).
Find(&posterMaps) Find(&posterMaps)
if err != nil { if err != nil {
return err return err
} }
left = left - limit
posterIDs = posterIDs[limit:]
}
for _, issue := range issues { for _, issue := range issues {
if issue.PosterID <= 0 { if issue.PosterID <= 0 {
@@ -99,24 +122,35 @@ func (issues IssueList) loadLabels(e Engine) error {
} }
var issueLabels = make(map[int64][]*Label, len(issues)*3) var issueLabels = make(map[int64][]*Label, len(issues)*3)
var issueIDs = issues.getIssueIDs()
var left = len(issueIDs)
for left > 0 {
var limit = defaultMaxInSize
if left < limit {
limit = left
}
rows, err := e.Table("label"). rows, err := e.Table("label").
Join("LEFT", "issue_label", "issue_label.label_id = label.id"). Join("LEFT", "issue_label", "issue_label.label_id = label.id").
In("issue_label.issue_id", issues.getIssueIDs()). In("issue_label.issue_id", issueIDs[:limit]).
Asc("label.name"). Asc("label.name").
Rows(new(LabelIssue)) Rows(new(LabelIssue))
if err != nil { if err != nil {
return err return err
} }
defer rows.Close()
for rows.Next() { for rows.Next() {
var labelIssue LabelIssue var labelIssue LabelIssue
err = rows.Scan(&labelIssue) err = rows.Scan(&labelIssue)
if err != nil { if err != nil {
rows.Close()
return err return err
} }
issueLabels[labelIssue.IssueLabel.IssueID] = append(issueLabels[labelIssue.IssueLabel.IssueID], labelIssue.Label) issueLabels[labelIssue.IssueLabel.IssueID] = append(issueLabels[labelIssue.IssueLabel.IssueID], labelIssue.Label)
} }
rows.Close()
left = left - limit
issueIDs = issueIDs[limit:]
}
for _, issue := range issues { for _, issue := range issues {
issue.Labels = issueLabels[issue.ID] issue.Labels = issueLabels[issue.ID]
@@ -141,12 +175,21 @@ func (issues IssueList) loadMilestones(e Engine) error {
} }
milestoneMaps := make(map[int64]*Milestone, len(milestoneIDs)) milestoneMaps := make(map[int64]*Milestone, len(milestoneIDs))
var left = len(milestoneIDs)
for left > 0 {
var limit = defaultMaxInSize
if left < limit {
limit = left
}
err := e. err := e.
In("id", milestoneIDs). In("id", milestoneIDs[:limit]).
Find(&milestoneMaps) Find(&milestoneMaps)
if err != nil { if err != nil {
return err return err
} }
left = left - limit
milestoneIDs = milestoneIDs[limit:]
}
for _, issue := range issues { for _, issue := range issues {
issue.Milestone = milestoneMaps[issue.MilestoneID] issue.Milestone = milestoneMaps[issue.MilestoneID]
@@ -165,24 +208,36 @@ func (issues IssueList) loadAssignees(e Engine) error {
} }
var assignees = make(map[int64][]*User, len(issues)) var assignees = make(map[int64][]*User, len(issues))
var issueIDs = issues.getIssueIDs()
var left = len(issueIDs)
for left > 0 {
var limit = defaultMaxInSize
if left < limit {
limit = left
}
rows, err := e.Table("issue_assignees"). rows, err := e.Table("issue_assignees").
Join("INNER", "`user`", "`user`.id = `issue_assignees`.assignee_id"). Join("INNER", "`user`", "`user`.id = `issue_assignees`.assignee_id").
In("`issue_assignees`.issue_id", issues.getIssueIDs()). In("`issue_assignees`.issue_id", issueIDs[:limit]).
Rows(new(AssigneeIssue)) Rows(new(AssigneeIssue))
if err != nil { if err != nil {
return err return err
} }
defer rows.Close()
for rows.Next() { for rows.Next() {
var assigneeIssue AssigneeIssue var assigneeIssue AssigneeIssue
err = rows.Scan(&assigneeIssue) err = rows.Scan(&assigneeIssue)
if err != nil { if err != nil {
rows.Close()
return err return err
} }
assignees[assigneeIssue.IssueAssignee.IssueID] = append(assignees[assigneeIssue.IssueAssignee.IssueID], assigneeIssue.Assignee) assignees[assigneeIssue.IssueAssignee.IssueID] = append(assignees[assigneeIssue.IssueAssignee.IssueID], assigneeIssue.Assignee)
} }
rows.Close()
left = left - limit
issueIDs = issueIDs[limit:]
}
for _, issue := range issues { for _, issue := range issues {
issue.Assignees = assignees[issue.ID] issue.Assignees = assignees[issue.ID]
@@ -207,23 +262,34 @@ func (issues IssueList) loadPullRequests(e Engine) error {
} }
pullRequestMaps := make(map[int64]*PullRequest, len(issuesIDs)) pullRequestMaps := make(map[int64]*PullRequest, len(issuesIDs))
var left = len(issuesIDs)
for left > 0 {
var limit = defaultMaxInSize
if left < limit {
limit = left
}
rows, err := e. rows, err := e.
In("issue_id", issuesIDs). In("issue_id", issuesIDs[:limit]).
Rows(new(PullRequest)) Rows(new(PullRequest))
if err != nil { if err != nil {
return err return err
} }
defer rows.Close()
for rows.Next() { for rows.Next() {
var pr PullRequest var pr PullRequest
err = rows.Scan(&pr) err = rows.Scan(&pr)
if err != nil { if err != nil {
rows.Close()
return err return err
} }
pullRequestMaps[pr.IssueID] = &pr pullRequestMaps[pr.IssueID] = &pr
} }
rows.Close()
left = left - limit
issuesIDs = issuesIDs[limit:]
}
for _, issue := range issues { for _, issue := range issues {
issue.PullRequest = pullRequestMaps[issue.ID] issue.PullRequest = pullRequestMaps[issue.ID]
} }
@@ -236,24 +302,36 @@ func (issues IssueList) loadAttachments(e Engine) (err error) {
} }
var attachments = make(map[int64][]*Attachment, len(issues)) var attachments = make(map[int64][]*Attachment, len(issues))
var issuesIDs = issues.getIssueIDs()
var left = len(issuesIDs)
for left > 0 {
var limit = defaultMaxInSize
if left < limit {
limit = left
}
rows, err := e.Table("attachment"). rows, err := e.Table("attachment").
Join("INNER", "issue", "issue.id = attachment.issue_id"). Join("INNER", "issue", "issue.id = attachment.issue_id").
In("issue.id", issues.getIssueIDs()). In("issue.id", issuesIDs[:limit]).
Rows(new(Attachment)) Rows(new(Attachment))
if err != nil { if err != nil {
return err return err
} }
defer rows.Close()
for rows.Next() { for rows.Next() {
var attachment Attachment var attachment Attachment
err = rows.Scan(&attachment) err = rows.Scan(&attachment)
if err != nil { if err != nil {
rows.Close()
return err return err
} }
attachments[attachment.IssueID] = append(attachments[attachment.IssueID], &attachment) attachments[attachment.IssueID] = append(attachments[attachment.IssueID], &attachment)
} }
rows.Close()
left = left - limit
issuesIDs = issuesIDs[limit:]
}
for _, issue := range issues { for _, issue := range issues {
issue.Attachments = attachments[issue.ID] issue.Attachments = attachments[issue.ID]
} }
@@ -266,23 +344,34 @@ func (issues IssueList) loadComments(e Engine) (err error) {
} }
var comments = make(map[int64][]*Comment, len(issues)) var comments = make(map[int64][]*Comment, len(issues))
var issuesIDs = issues.getIssueIDs()
var left = len(issuesIDs)
for left > 0 {
var limit = defaultMaxInSize
if left < limit {
limit = left
}
rows, err := e.Table("comment"). rows, err := e.Table("comment").
Join("INNER", "issue", "issue.id = comment.issue_id"). Join("INNER", "issue", "issue.id = comment.issue_id").
In("issue.id", issues.getIssueIDs()). In("issue.id", issuesIDs[:limit]).
Rows(new(Comment)) Rows(new(Comment))
if err != nil { if err != nil {
return err return err
} }
defer rows.Close()
for rows.Next() { for rows.Next() {
var comment Comment var comment Comment
err = rows.Scan(&comment) err = rows.Scan(&comment)
if err != nil { if err != nil {
rows.Close()
return err return err
} }
comments[comment.IssueID] = append(comments[comment.IssueID], &comment) comments[comment.IssueID] = append(comments[comment.IssueID], &comment)
} }
rows.Close()
left = left - limit
issuesIDs = issuesIDs[limit:]
}
for _, issue := range issues { for _, issue := range issues {
issue.Comments = comments[issue.ID] issue.Comments = comments[issue.ID]
@@ -307,26 +396,36 @@ func (issues IssueList) loadTotalTrackedTimes(e Engine) (err error) {
} }
} }
var left = len(ids)
for left > 0 {
var limit = defaultMaxInSize
if left < limit {
limit = left
}
// select issue_id, sum(time) from tracked_time where issue_id in (<issue ids in current page>) group by issue_id // select issue_id, sum(time) from tracked_time where issue_id in (<issue ids in current page>) group by issue_id
rows, err := e.Table("tracked_time"). rows, err := e.Table("tracked_time").
Select("issue_id, sum(time) as time"). Select("issue_id, sum(time) as time").
In("issue_id", ids). In("issue_id", ids[:limit]).
GroupBy("issue_id"). GroupBy("issue_id").
Rows(new(totalTimesByIssue)) Rows(new(totalTimesByIssue))
if err != nil { if err != nil {
return err return err
} }
defer rows.Close()
for rows.Next() { for rows.Next() {
var totalTime totalTimesByIssue var totalTime totalTimesByIssue
err = rows.Scan(&totalTime) err = rows.Scan(&totalTime)
if err != nil { if err != nil {
rows.Close()
return err return err
} }
trackedTimes[totalTime.IssueID] = totalTime.Time trackedTimes[totalTime.IssueID] = totalTime.Time
} }
rows.Close()
left = left - limit
ids = ids[limit:]
}
for _, issue := range issues { for _, issue := range issues {
issue.TotalTrackedTime = trackedTimes[issue.ID] issue.TotalTrackedTime = trackedTimes[issue.ID]

View File

@@ -454,7 +454,7 @@ func AddOrgUser(orgID, uid int64) error {
func removeOrgUser(sess *xorm.Session, orgID, userID int64) error { func removeOrgUser(sess *xorm.Session, orgID, userID int64) error {
ou := new(OrgUser) ou := new(OrgUser)
has, err := x. has, err := sess.
Where("uid=?", userID). Where("uid=?", userID).
And("org_id=?", orgID). And("org_id=?", orgID).
Get(ou) Get(ou)

View File

@@ -1407,7 +1407,7 @@ func createRepository(e *xorm.Session, doer, u *User, repo *Repository) (err err
// CreateRepository creates a repository for the user/organization u. // CreateRepository creates a repository for the user/organization u.
func CreateRepository(doer, u *User, opts CreateRepoOptions) (_ *Repository, err error) { func CreateRepository(doer, u *User, opts CreateRepoOptions) (_ *Repository, err error) {
if !u.CanCreateRepo() { if !doer.IsAdmin && !u.CanCreateRepo() {
return nil, ErrReachLimitOfRepo{u.MaxRepoCreation} return nil, ErrReachLimitOfRepo{u.MaxRepoCreation}
} }

View File

@@ -85,9 +85,9 @@ func (r *Repository) CanCreateBranch() bool {
} }
// CanCommitToBranch returns true if repository is editable and user has proper access level // CanCommitToBranch returns true if repository is editable and user has proper access level
// and branch is not protected // and branch is not protected for push
func (r *Repository) CanCommitToBranch(doer *models.User) (bool, error) { func (r *Repository) CanCommitToBranch(doer *models.User) (bool, error) {
protectedBranch, err := r.Repository.IsProtectedBranch(r.BranchName, doer) protectedBranch, err := r.Repository.IsProtectedBranchForPush(r.BranchName, doer)
if err != nil { if err != nil {
return false, err return false, err
} }

View File

@@ -119,7 +119,7 @@ func UpdateAvatarSetting(ctx *context.Context, form auth.AvatarForm, ctxUser *mo
ctxUser.AvatarEmail = form.Gravatar ctxUser.AvatarEmail = form.Gravatar
} }
if form.Avatar.Filename != "" { if form.Avatar != nil && form.Avatar.Filename != "" {
fr, err := form.Avatar.Open() fr, err := form.Avatar.Open()
if err != nil { if err != nil {
return fmt.Errorf("Avatar.Open: %v", err) return fmt.Errorf("Avatar.Open: %v", err)

View File

@@ -4,6 +4,5 @@
<div class="ui divider"></div> <div class="ui divider"></div>
<br> <br>
{{if .ShowFooterVersion}}<p>Application Version: {{AppVer}}</p>{{end}} {{if .ShowFooterVersion}}<p>Application Version: {{AppVer}}</p>{{end}}
<p>If you think this is an error, please open an issue on <a href="https://github.com/go-gitea/gitea/issues/new">GitHub</a>.</p>
</div> </div>
{{template "base/footer" .}} {{template "base/footer" .}}