Skip to content

Commit

Permalink
Merge branch 'master' into fix-storage
Browse files Browse the repository at this point in the history
  • Loading branch information
6543 committed Dec 21, 2020
2 parents 7a5b201 + 09304db commit c9219de
Show file tree
Hide file tree
Showing 24 changed files with 176 additions and 67 deletions.
2 changes: 2 additions & 0 deletions custom/conf/app.example.ini
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,8 @@ DEFAULT_REPO_UNITS = repo.code,repo.releases,repo.issues,repo.pulls,repo.wiki,re
PREFIX_ARCHIVE_FILES = true
; Disable the creation of new mirrors. Pre-existing mirrors remain valid.
DISABLE_MIRRORS = false
; Disable migrating feature.
DISABLE_MIGRATIONS = false
; The default branch name of new repositories
DEFAULT_BRANCH = master
; Allow adoption of unadopted repositories
Expand Down
1 change: 1 addition & 0 deletions docs/content/doc/advanced/config-cheat-sheet.en-us.md
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ Values containing `#` or `;` must be quoted using `` ` `` or `"""`.
- `DEFAULT_REPO_UNITS`: **repo.code,repo.releases,repo.issues,repo.pulls,repo.wiki,repo.projects**: Comma separated list of default repo units. Allowed values: \[repo.code, repo.releases, repo.issues, repo.pulls, repo.wiki, repo.projects\]. Note: Code and Releases can currently not be deactivated. If you specify default repo units you should still list them for future compatibility. External wiki and issue tracker can't be enabled by default as it requires additional settings. Disabled repo units will not be added to new repositories regardless if it is in the default list.
- `PREFIX_ARCHIVE_FILES`: **true**: Prefix archive files by placing them in a directory named after the repository.
- `DISABLE_MIRRORS`: **false**: Disable the creation of **new** mirrors. Pre-existing mirrors remain valid.
- `DISABLE_MIGRATIONS`: **false**: Disable migrating feature.
- `DEFAULT_BRANCH`: **master**: Default branch name of all repositories.
- `ALLOW_ADOPTION_OF_UNADOPTED_REPOSITORIES`: **false**: Allow non-admin users to adopt unadopted repositories
- `ALLOW_DELETION_OF_UNADOPTED_REPOSITORIES`: **false**: Allow non-admin users to delete unadopted repositories
Expand Down
5 changes: 3 additions & 2 deletions integrations/api_settings_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,9 @@ func TestAPIExposedSettings(t *testing.T) {

DecodeJSON(t, resp, &repo)
assert.EqualValues(t, &api.GeneralRepoSettings{
MirrorsDisabled: setting.Repository.DisableMirrors,
HTTPGitDisabled: setting.Repository.DisableHTTPGit,
MirrorsDisabled: setting.Repository.DisableMirrors,
HTTPGitDisabled: setting.Repository.DisableHTTPGit,
MigrationsDisabled: setting.Repository.DisableMigrations,
}, repo)

attachment := new(api.GeneralAttachmentSettings)
Expand Down
69 changes: 43 additions & 26 deletions models/issue.go
Original file line number Diff line number Diff line change
Expand Up @@ -1847,30 +1847,43 @@ func (issue *Issue) ResolveMentionsByVisibility(ctx DBContext, doer *User, menti
if err = issue.loadRepo(ctx.e); err != nil {
return
}
resolved := make(map[string]bool, 20)
names := make([]string, 0, 20)

resolved := make(map[string]bool, 10)
var mentionTeams []string

if err := issue.Repo.getOwner(ctx.e); err != nil {
return nil, err
}

repoOwnerIsOrg := issue.Repo.Owner.IsOrganization()
if repoOwnerIsOrg {
mentionTeams = make([]string, 0, 5)
}

resolved[doer.LowerName] = true
for _, name := range mentions {
name := strings.ToLower(name)
if _, ok := resolved[name]; ok {
continue
}
resolved[name] = false
names = append(names, name)
}

if err := issue.Repo.getOwner(ctx.e); err != nil {
return nil, err
if repoOwnerIsOrg && strings.Contains(name, "/") {
names := strings.Split(name, "/")
if len(names) < 2 || names[0] != issue.Repo.Owner.LowerName {
continue
}
mentionTeams = append(mentionTeams, names[1])
resolved[name] = true
} else {
resolved[name] = false
}
}

if issue.Repo.Owner.IsOrganization() {
// Since there can be users with names that match the name of a team,
// if the team exists and can read the issue, the team takes precedence.
teams := make([]*Team, 0, len(names))
if issue.Repo.Owner.IsOrganization() && len(mentionTeams) > 0 {
teams := make([]*Team, 0, len(mentionTeams))
if err := ctx.e.
Join("INNER", "team_repo", "team_repo.team_id = team.id").
Where("team_repo.repo_id=?", issue.Repo.ID).
In("team.lower_name", names).
In("team.lower_name", mentionTeams).
Find(&teams); err != nil {
return nil, fmt.Errorf("find mentioned teams: %v", err)
}
Expand All @@ -1883,7 +1896,7 @@ func (issue *Issue) ResolveMentionsByVisibility(ctx DBContext, doer *User, menti
for _, team := range teams {
if team.Authorize >= AccessModeOwner {
checked = append(checked, team.ID)
resolved[team.LowerName] = true
resolved[issue.Repo.Owner.LowerName+"/"+team.LowerName] = true
continue
}
has, err := ctx.e.Get(&TeamUnit{OrgID: issue.Repo.Owner.ID, TeamID: team.ID, Type: unittype})
Expand All @@ -1892,7 +1905,7 @@ func (issue *Issue) ResolveMentionsByVisibility(ctx DBContext, doer *User, menti
}
if has {
checked = append(checked, team.ID)
resolved[team.LowerName] = true
resolved[issue.Repo.Owner.LowerName+"/"+team.LowerName] = true
}
}
if len(checked) != 0 {
Expand All @@ -1916,24 +1929,28 @@ func (issue *Issue) ResolveMentionsByVisibility(ctx DBContext, doer *User, menti
}
}
}
}

// Remove names already in the list to avoid querying the database if pending names remain
names = make([]string, 0, len(resolved))
for name, already := range resolved {
if !already {
names = append(names, name)
}
}
if len(names) == 0 {
return
// Remove names already in the list to avoid querying the database if pending names remain
mentionUsers := make([]string, 0, len(resolved))
for name, already := range resolved {
if !already {
mentionUsers = append(mentionUsers, name)
}
}
if len(mentionUsers) == 0 {
return
}

if users == nil {
users = make([]*User, 0, len(mentionUsers))
}

unchecked := make([]*User, 0, len(names))
unchecked := make([]*User, 0, len(mentionUsers))
if err := ctx.e.
Where("`user`.is_active = ?", true).
And("`user`.prohibit_login = ?", false).
In("`user`.lower_name", names).
In("`user`.lower_name", mentionUsers).
Find(&unchecked); err != nil {
return nil, fmt.Errorf("find mentioned users: %v", err)
}
Expand Down
2 changes: 1 addition & 1 deletion models/issue_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -400,5 +400,5 @@ func TestIssue_ResolveMentions(t *testing.T) {
// Private repo, not a team member
testSuccess("user17", "big_test_private_4", "user20", []string{"user5"}, []int64{})
// Private repo, whole team
testSuccess("user17", "big_test_private_4", "user15", []string{"owners"}, []int64{18})
testSuccess("user17", "big_test_private_4", "user15", []string{"user17/owners"}, []int64{18})
}
1 change: 1 addition & 0 deletions modules/context/context.go
Original file line number Diff line number Diff line change
Expand Up @@ -343,6 +343,7 @@ func Contexter() macaron.Handler {

ctx.Data["EnableSwagger"] = setting.API.EnableSwagger
ctx.Data["EnableOpenIDSignIn"] = setting.Service.EnableOpenIDSignIn
ctx.Data["DisableMigrations"] = setting.Repository.DisableMigrations

c.Map(ctx)
}
Expand Down
5 changes: 4 additions & 1 deletion modules/cron/tasks_basic.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (
"code.gitea.io/gitea/models"
"code.gitea.io/gitea/modules/migrations"
repository_service "code.gitea.io/gitea/modules/repository"
"code.gitea.io/gitea/modules/setting"
mirror_service "code.gitea.io/gitea/services/mirror"
)

Expand Down Expand Up @@ -115,5 +116,7 @@ func initBasicTasks() {
registerArchiveCleanup()
registerSyncExternalUsers()
registerDeletedBranchesCleanup()
registerUpdateMigrationPosterID()
if !setting.Repository.DisableMigrations {
registerUpdateMigrationPosterID()
}
}
12 changes: 8 additions & 4 deletions modules/markup/html.go
Original file line number Diff line number Diff line change
Expand Up @@ -596,11 +596,15 @@ func mentionProcessor(ctx *postProcessCtx, node *html.Node) {
mention := node.Data[loc.Start:loc.End]
var teams string
teams, ok := ctx.metas["teams"]
if ok && strings.Contains(teams, ","+strings.ToLower(mention[1:])+",") {
replaceContent(node, loc.Start, loc.End, createLink(util.URLJoin(setting.AppURL, "org", ctx.metas["org"], "teams", mention[1:]), mention, "mention"))
} else {
replaceContent(node, loc.Start, loc.End, createLink(util.URLJoin(setting.AppURL, mention[1:]), mention, "mention"))
// team mention should follow @orgName/teamName style
if ok && strings.Contains(mention, "/") {
mentionOrgAndTeam := strings.Split(mention, "/")
if mentionOrgAndTeam[0][1:] == ctx.metas["org"] && strings.Contains(teams, ","+strings.ToLower(mentionOrgAndTeam[1])+",") {
replaceContent(node, loc.Start, loc.End, createLink(util.URLJoin(setting.AppURL, "org", ctx.metas["org"], "teams", mentionOrgAndTeam[1]), mention, "mention"))
}
return
}
replaceContent(node, loc.Start, loc.End, createLink(util.URLJoin(setting.AppURL, mention[1:]), mention, "mention"))
}

func shortLinkProcessor(ctx *postProcessCtx, node *html.Node) {
Expand Down
4 changes: 2 additions & 2 deletions modules/references/references.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@ var (
// While fast, this is also incorrect and lead to false positives.
// TODO: fix invalid linking issue

// mentionPattern matches all mentions in the form of "@user"
mentionPattern = regexp.MustCompile(`(?:\s|^|\(|\[)(@[0-9a-zA-Z-_]+|@[0-9a-zA-Z-_][0-9a-zA-Z-_.]+[0-9a-zA-Z-_])(?:\s|[:,;.?!]\s|[:,;.?!]?$|\)|\])`)
// mentionPattern matches all mentions in the form of "@user" or "@org/team"
mentionPattern = regexp.MustCompile(`(?:\s|^|\(|\[)(@[0-9a-zA-Z-_]+|@[0-9a-zA-Z-_]+\/?[0-9a-zA-Z-_]+|@[0-9a-zA-Z-_][0-9a-zA-Z-_.]+\/?[0-9a-zA-Z-_.]+[0-9a-zA-Z-_])(?:\s|[:,;.?!]\s|[:,;.?!]?$|\)|\])`)
// issueNumericPattern matches string that references to a numeric issue, e.g. #1287
issueNumericPattern = regexp.MustCompile(`(?:\s|^|\(|\[)([#!][0-9]+)(?:\s|$|\)|\]|[:;,.?!]\s|[:;,.?!]$)`)
// issueAlphanumericPattern matches string that references to an alphanumeric issue, e.g. ABC-1234
Expand Down
2 changes: 2 additions & 0 deletions modules/references/references_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -325,6 +325,7 @@ func TestRegExp_mentionPattern(t *testing.T) {
{"@gitea.", "@gitea"},
{"@gitea,", "@gitea"},
{"@gitea;", "@gitea"},
{"@gitea/team1;", "@gitea/team1"},
}
falseTestCases := []string{
"@ 0",
Expand All @@ -340,6 +341,7 @@ func TestRegExp_mentionPattern(t *testing.T) {
"@gitea?this",
"@gitea,this",
"@gitea;this",
"@gitea/team1/more",
}

for _, testCase := range trueTestCases {
Expand Down
2 changes: 2 additions & 0 deletions modules/setting/repository.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ var (
DefaultRepoUnits []string
PrefixArchiveFiles bool
DisableMirrors bool
DisableMigrations bool
DefaultBranch string
AllowAdoptionOfUnadoptedRepositories bool
AllowDeleteOfUnadoptedRepositories bool
Expand Down Expand Up @@ -152,6 +153,7 @@ var (
DefaultRepoUnits: []string{},
PrefixArchiveFiles: true,
DisableMirrors: false,
DisableMigrations: false,
DefaultBranch: "master",

// Repository editor settings
Expand Down
5 changes: 3 additions & 2 deletions modules/structs/settings.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,9 @@ package structs

// GeneralRepoSettings contains global repository settings exposed by API
type GeneralRepoSettings 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"`
}

// GeneralUISettings contains global ui settings exposed by API
Expand Down
2 changes: 2 additions & 0 deletions options/locale/locale_zh-TW.ini
Original file line number Diff line number Diff line change
Expand Up @@ -652,6 +652,7 @@ email_notifications.submit=套用郵件偏好設定

[repo]
owner=擁有者
owner_helper=組織可能因為儲存庫數量上限而未列入此選單。
repo_name=儲存庫名稱
repo_name_helper=好的儲存庫名稱通常是簡短的、好記的、且獨特的。
repo_size=儲存庫大小
Expand Down Expand Up @@ -1129,6 +1130,7 @@ issues.start_tracking_short=開始
issues.start_tracking=開始時間追蹤
issues.start_tracking_history=`開始工作 %s`
issues.tracker_auto_close=當這個問題被關閉時,自動停止計時器
issues.tracking_already_started=`您已在<a href="%s">另一個問題</a>上開始時間追蹤!`
issues.stop_tracking=停止
issues.stop_tracking_history=`結束工作 %s`
issues.add_time=手動新增時間
Expand Down
2 changes: 2 additions & 0 deletions routers/admin/users.go
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,7 @@ func EditUser(ctx *context.Context) {
ctx.Data["PageIsAdmin"] = true
ctx.Data["PageIsAdminUsers"] = true
ctx.Data["DisableRegularOrgCreation"] = setting.Admin.DisableRegularOrgCreation
ctx.Data["DisableMigrations"] = setting.Repository.DisableMigrations

prepareUserInfo(ctx)
if ctx.Written() {
Expand All @@ -205,6 +206,7 @@ func EditUserPost(ctx *context.Context, form auth.AdminEditUserForm) {
ctx.Data["Title"] = ctx.Tr("admin.users.edit_account")
ctx.Data["PageIsAdmin"] = true
ctx.Data["PageIsAdminUsers"] = true
ctx.Data["DisableMigrations"] = setting.Repository.DisableMigrations

u := prepareUserInfo(ctx)
if ctx.Written() {
Expand Down
5 changes: 5 additions & 0 deletions routers/api/v1/repo/migrate.go
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,11 @@ func Migrate(ctx *context.APIContext, form api.MigrateRepoOptions) {
return
}

if setting.Repository.DisableMigrations {
ctx.Error(http.StatusForbidden, "MigrationsGlobalDisabled", fmt.Errorf("the site administrator has disabled migrations"))
return
}

var opts = migrations.MigrateOptions{
CloneAddr: remoteAddr,
RepoName: form.RepoName,
Expand Down
5 changes: 3 additions & 2 deletions routers/api/v1/settings/settings.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,8 +57,9 @@ func GetGeneralRepoSettings(ctx *context.APIContext) {
// "200":
// "$ref": "#/responses/GeneralRepoSettings"
ctx.JSON(http.StatusOK, api.GeneralRepoSettings{
MirrorsDisabled: setting.Repository.DisableMirrors,
HTTPGitDisabled: setting.Repository.DisableHTTPGit,
MirrorsDisabled: setting.Repository.DisableMirrors,
HTTPGitDisabled: setting.Repository.DisableHTTPGit,
MigrationsDisabled: setting.Repository.DisableMigrations,
})
}

Expand Down
47 changes: 47 additions & 0 deletions routers/repo/issue.go
Original file line number Diff line number Diff line change
Expand Up @@ -274,6 +274,11 @@ func issues(ctx *context.Context, milestoneID, projectID int64, isPullOption uti
return
}

handleTeamMentions(ctx)
if ctx.Written() {
return
}

labels, err := models.GetLabelsByRepoID(repo.ID, "", models.ListOptions{})
if err != nil {
ctx.ServerError("GetLabelsByRepoID", err)
Expand Down Expand Up @@ -410,6 +415,11 @@ func RetrieveRepoMilestonesAndAssignees(ctx *context.Context, repo *models.Repos
ctx.ServerError("GetAssignees", err)
return
}

handleTeamMentions(ctx)
if ctx.Written() {
return
}
}

func retrieveProjects(ctx *context.Context, repo *models.Repository) {
Expand Down Expand Up @@ -2445,3 +2455,40 @@ func combineLabelComments(issue *models.Issue) {
i--
}
}

// get all teams that current user can mention
func handleTeamMentions(ctx *context.Context) {
if ctx.User == nil || !ctx.Repo.Owner.IsOrganization() {
return
}

isAdmin := false
var err error
// Admin has super access.
if ctx.User.IsAdmin {
isAdmin = true
} else {
isAdmin, err = ctx.Repo.Owner.IsOwnedBy(ctx.User.ID)
if err != nil {
ctx.ServerError("IsOwnedBy", err)
return
}
}

if isAdmin {
if err := ctx.Repo.Owner.GetTeams(&models.SearchTeamOptions{}); err != nil {
ctx.ServerError("GetTeams", err)
return
}
} else {
ctx.Repo.Owner.Teams, err = ctx.Repo.Owner.GetUserTeams(ctx.User.ID)
if err != nil {
ctx.ServerError("GetUserTeams", err)
return
}
}

ctx.Data["MentionableTeams"] = ctx.Repo.Owner.Teams
ctx.Data["MentionableTeamsOrg"] = ctx.Repo.Owner.Name
ctx.Data["MentionableTeamsOrgAvator"] = ctx.Repo.Owner.RelAvatarLink()
}
Loading

0 comments on commit c9219de

Please sign in to comment.