aboutsummaryrefslogtreecommitdiff
path: root/routers
diff options
context:
space:
mode:
authorAnthony Wang2023-02-20 22:21:24 +0000
committerAnthony Wang2023-02-20 22:21:24 +0000
commitdc20c2832871f6462990751ea802e14b02bf41b0 (patch)
tree71bfef0694e6c0f8284438c290521d7297f24eab /routers
parent07df0a6b1c97be4b03d23d5dfa047a108de36592 (diff)
parentef11d41639dd1e89676e395068ee453312560adb (diff)
Merge remote-tracking branch 'origin/main' into forgejo-federation
Diffstat (limited to 'routers')
-rw-r--r--routers/api/packages/api.go15
-rw-r--r--routers/api/packages/container/manifest.go26
-rw-r--r--routers/api/packages/nuget/nuget.go53
-rw-r--r--routers/api/v1/activitypub/person.go2
-rw-r--r--routers/api/v1/admin/org.go4
-rw-r--r--routers/api/v1/admin/user.go17
-rw-r--r--routers/api/v1/org/label.go4
-rw-r--r--routers/api/v1/org/member.go2
-rw-r--r--routers/api/v1/org/org.go10
-rw-r--r--routers/api/v1/org/team.go18
-rw-r--r--routers/api/v1/repo/branch.go6
-rw-r--r--routers/api/v1/repo/collaborators.go8
-rw-r--r--routers/api/v1/repo/commits.go4
-rw-r--r--routers/api/v1/repo/hook.go6
-rw-r--r--routers/api/v1/repo/issue_comment.go10
-rw-r--r--routers/api/v1/repo/issue_reaction.go12
-rw-r--r--routers/api/v1/repo/issue_subscription.go2
-rw-r--r--routers/api/v1/repo/label.go4
-rw-r--r--routers/api/v1/repo/main_test.go4
-rw-r--r--routers/api/v1/repo/notes.go2
-rw-r--r--routers/api/v1/repo/pull.go2
-rw-r--r--routers/api/v1/repo/pull_review.go2
-rw-r--r--routers/api/v1/repo/release.go10
-rw-r--r--routers/api/v1/repo/release_attachment.go2
-rw-r--r--routers/api/v1/repo/release_tags.go2
-rw-r--r--routers/api/v1/repo/repo.go6
-rw-r--r--routers/api/v1/repo/star.go2
-rw-r--r--routers/api/v1/repo/subscriber.go2
-rw-r--r--routers/api/v1/repo/tag.go2
-rw-r--r--routers/api/v1/repo/teams.go4
-rw-r--r--routers/api/v1/repo/transfer.go2
-rw-r--r--routers/api/v1/user/follower.go2
-rw-r--r--routers/api/v1/user/key.go13
-rw-r--r--routers/api/v1/user/repo.go4
-rw-r--r--routers/api/v1/user/user.go6
-rw-r--r--routers/common/middleware.go7
-rw-r--r--routers/init.go6
-rw-r--r--routers/install/install.go11
-rw-r--r--routers/install/setting.go14
-rw-r--r--routers/private/hook_verification.go2
-rw-r--r--routers/private/manager.go6
-rw-r--r--routers/private/ssh_log.go2
-rw-r--r--routers/web/admin/config.go14
-rw-r--r--routers/web/admin/users.go2
-rw-r--r--routers/web/auth/auth.go2
-rw-r--r--routers/web/auth/linkaccount.go2
-rw-r--r--routers/web/auth/oauth.go4
-rw-r--r--routers/web/auth/oauth_test.go4
-rw-r--r--routers/web/auth/openid.go2
-rw-r--r--routers/web/auth/password.go4
-rw-r--r--routers/web/org/org_labels.go2
-rw-r--r--routers/web/org/projects.go4
-rw-r--r--routers/web/org/teams.go2
-rw-r--r--routers/web/repo/actions/actions.go2
-rw-r--r--routers/web/repo/blame.go6
-rw-r--r--routers/web/repo/commit.go8
-rw-r--r--routers/web/repo/compare.go20
-rw-r--r--routers/web/repo/http.go4
-rw-r--r--routers/web/repo/issue.go50
-rw-r--r--routers/web/repo/issue_content_history.go2
-rw-r--r--routers/web/repo/issue_dependency.go4
-rw-r--r--routers/web/repo/issue_label.go18
-rw-r--r--routers/web/repo/issue_lock.go10
-rw-r--r--routers/web/repo/issue_stopwatch.go4
-rw-r--r--routers/web/repo/issue_timetrack.go4
-rw-r--r--routers/web/repo/issue_watch.go2
-rw-r--r--routers/web/repo/projects.go24
-rw-r--r--routers/web/repo/pull.go8
-rw-r--r--routers/web/repo/pull_review.go2
-rw-r--r--routers/web/repo/release.go2
-rw-r--r--routers/web/repo/repo.go2
-rw-r--r--routers/web/repo/search.go2
-rw-r--r--routers/web/repo/setting.go3
-rw-r--r--routers/web/repo/view.go183
-rw-r--r--routers/web/repo/webhook.go2
-rw-r--r--routers/web/user/avatar.go4
-rw-r--r--routers/web/user/home.go5
-rw-r--r--routers/web/user/package.go2
-rw-r--r--routers/web/user/profile.go2
-rw-r--r--routers/web/user/search.go2
-rw-r--r--routers/web/user/setting/account.go2
-rw-r--r--routers/web/webfinger.go4
82 files changed, 436 insertions, 307 deletions
diff --git a/routers/api/packages/api.go b/routers/api/packages/api.go
index 9f77367d6..0e3d8b7a0 100644
--- a/routers/api/packages/api.go
+++ b/routers/api/packages/api.go
@@ -286,9 +286,18 @@ func CommonRoutes(ctx gocontext.Context) *web.Route {
}, reqPackageAccess(perm.AccessModeWrite))
r.Get("/symbols/{filename}/{guid:[0-9a-fA-F]{32}[fF]{8}}/{filename2}", nuget.DownloadSymbolFile)
r.Get("/Packages(Id='{id:[^']+}',Version='{version:[^']+}')", nuget.RegistrationLeafV2)
- r.Get("/Packages()", nuget.SearchServiceV2)
- r.Get("/FindPackagesById()", nuget.EnumeratePackageVersionsV2)
- r.Get("/Search()", nuget.SearchServiceV2)
+ r.Group("/Packages()", func() {
+ r.Get("", nuget.SearchServiceV2)
+ r.Get("/$count", nuget.SearchServiceV2Count)
+ })
+ r.Group("/FindPackagesById()", func() {
+ r.Get("", nuget.EnumeratePackageVersionsV2)
+ r.Get("/$count", nuget.EnumeratePackageVersionsV2Count)
+ })
+ r.Group("/Search()", func() {
+ r.Get("", nuget.SearchServiceV2)
+ r.Get("/$count", nuget.SearchServiceV2Count)
+ })
}, reqPackageAccess(perm.AccessModeRead))
})
r.Group("/npm", func() {
diff --git a/routers/api/packages/container/manifest.go b/routers/api/packages/container/manifest.go
index 6167d00f3..e36c6a851 100644
--- a/routers/api/packages/container/manifest.go
+++ b/routers/api/packages/container/manifest.go
@@ -17,6 +17,7 @@ import (
user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/json"
"code.gitea.io/gitea/modules/log"
+ "code.gitea.io/gitea/modules/notification"
packages_module "code.gitea.io/gitea/modules/packages"
container_module "code.gitea.io/gitea/modules/packages/container"
"code.gitea.io/gitea/modules/util"
@@ -71,11 +72,9 @@ func processManifest(mci *manifestCreationInfo, buf *packages_module.HashedBuffe
}
if isImageManifestMediaType(mci.MediaType) {
- d, err := processImageManifest(mci, buf)
- return d, err
+ return processImageManifest(mci, buf)
} else if isImageIndexMediaType(mci.MediaType) {
- d, err := processImageManifestIndex(mci, buf)
- return d, err
+ return processImageManifestIndex(mci, buf)
}
return "", errManifestInvalid
}
@@ -182,6 +181,10 @@ func processImageManifest(mci *manifestCreationInfo, buf *packages_module.Hashed
return err
}
+ if err := notifyPackageCreate(mci.Creator, pv); err != nil {
+ return err
+ }
+
manifestDigest = digest
return nil
@@ -271,6 +274,10 @@ func processImageManifestIndex(mci *manifestCreationInfo, buf *packages_module.H
return err
}
+ if err := notifyPackageCreate(mci.Creator, pv); err != nil {
+ return err
+ }
+
manifestDigest = digest
return nil
@@ -282,6 +289,17 @@ func processImageManifestIndex(mci *manifestCreationInfo, buf *packages_module.H
return manifestDigest, nil
}
+func notifyPackageCreate(doer *user_model.User, pv *packages_model.PackageVersion) error {
+ pd, err := packages_model.GetPackageDescriptor(db.DefaultContext, pv)
+ if err != nil {
+ return err
+ }
+
+ notification.NotifyPackageCreate(db.DefaultContext, doer, pd)
+
+ return nil
+}
+
func createPackageAndVersion(ctx context.Context, mci *manifestCreationInfo, metadata *container_module.Metadata) (*packages_model.PackageVersion, error) {
created := true
p := &packages_model.Package{
diff --git a/routers/api/packages/nuget/nuget.go b/routers/api/packages/nuget/nuget.go
index 6423db7d3..3418bf995 100644
--- a/routers/api/packages/nuget/nuget.go
+++ b/routers/api/packages/nuget/nuget.go
@@ -10,6 +10,7 @@ import (
"io"
"net/http"
"regexp"
+ "strconv"
"strings"
"code.gitea.io/gitea/models/db"
@@ -94,8 +95,7 @@ func FeedCapabilityResource(ctx *context.Context) {
var searchTermExtract = regexp.MustCompile(`'([^']+)'`)
-// https://github.com/NuGet/NuGet.Client/blob/dev/src/NuGet.Core/NuGet.Protocol/LegacyFeed/V2FeedQueryBuilder.cs
-func SearchServiceV2(ctx *context.Context) {
+func getSearchTerm(ctx *context.Context) string {
searchTerm := strings.Trim(ctx.FormTrim("searchTerm"), "'")
if searchTerm == "" {
// $filter contains a query like:
@@ -106,7 +106,11 @@ func SearchServiceV2(ctx *context.Context) {
searchTerm = strings.TrimSpace(match[1])
}
}
+ return searchTerm
+}
+// https://github.com/NuGet/NuGet.Client/blob/dev/src/NuGet.Core/NuGet.Protocol/LegacyFeed/V2FeedQueryBuilder.cs
+func SearchServiceV2(ctx *context.Context) {
skip, take := ctx.FormInt("skip"), ctx.FormInt("take")
if skip == 0 {
skip = ctx.FormInt("$skip")
@@ -116,9 +120,11 @@ func SearchServiceV2(ctx *context.Context) {
}
pvs, total, err := packages_model.SearchVersions(ctx, &packages_model.PackageSearchOptions{
- OwnerID: ctx.Package.Owner.ID,
- Type: packages_model.TypeNuGet,
- Name: packages_model.SearchValue{Value: searchTerm},
+ OwnerID: ctx.Package.Owner.ID,
+ Type: packages_model.TypeNuGet,
+ Name: packages_model.SearchValue{
+ Value: getSearchTerm(ctx),
+ },
IsInternal: util.OptionalBoolFalse,
Paginator: db.NewAbsoluteListOptions(
skip,
@@ -145,6 +151,24 @@ func SearchServiceV2(ctx *context.Context) {
xmlResponse(ctx, http.StatusOK, resp)
}
+// http://docs.oasis-open.org/odata/odata/v4.0/errata03/os/complete/part2-url-conventions/odata-v4.0-errata03-os-part2-url-conventions-complete.html#_Toc453752351
+func SearchServiceV2Count(ctx *context.Context) {
+ count, err := packages_model.CountVersions(ctx, &packages_model.PackageSearchOptions{
+ OwnerID: ctx.Package.Owner.ID,
+ Type: packages_model.TypeNuGet,
+ Name: packages_model.SearchValue{
+ Value: getSearchTerm(ctx),
+ },
+ IsInternal: util.OptionalBoolFalse,
+ })
+ if err != nil {
+ apiError(ctx, http.StatusInternalServerError, err)
+ return
+ }
+
+ ctx.PlainText(http.StatusOK, strconv.FormatInt(count, 10))
+}
+
// https://docs.microsoft.com/en-us/nuget/api/search-query-service-resource#search-for-packages
func SearchServiceV3(ctx *context.Context) {
pvs, count, err := packages_model.SearchVersions(ctx, &packages_model.PackageSearchOptions{
@@ -288,6 +312,25 @@ func EnumeratePackageVersionsV2(ctx *context.Context) {
xmlResponse(ctx, http.StatusOK, resp)
}
+// http://docs.oasis-open.org/odata/odata/v4.0/errata03/os/complete/part2-url-conventions/odata-v4.0-errata03-os-part2-url-conventions-complete.html#_Toc453752351
+func EnumeratePackageVersionsV2Count(ctx *context.Context) {
+ count, err := packages_model.CountVersions(ctx, &packages_model.PackageSearchOptions{
+ OwnerID: ctx.Package.Owner.ID,
+ Type: packages_model.TypeNuGet,
+ Name: packages_model.SearchValue{
+ ExactMatch: true,
+ Value: strings.Trim(ctx.FormTrim("id"), "'"),
+ },
+ IsInternal: util.OptionalBoolFalse,
+ })
+ if err != nil {
+ apiError(ctx, http.StatusInternalServerError, err)
+ return
+ }
+
+ ctx.PlainText(http.StatusOK, strconv.FormatInt(count, 10))
+}
+
// https://docs.microsoft.com/en-us/nuget/api/package-base-address-resource#enumerate-package-versions
func EnumeratePackageVersionsV3(ctx *context.Context) {
packageName := ctx.Params("id")
diff --git a/routers/api/v1/activitypub/person.go b/routers/api/v1/activitypub/person.go
index 5d27674fa..04ce74c28 100644
--- a/routers/api/v1/activitypub/person.go
+++ b/routers/api/v1/activitypub/person.go
@@ -59,7 +59,7 @@ func Person(ctx *context.APIContext) {
person.Icon = ap.Image{
Type: ap.ImageType,
MediaType: "image/png",
- URL: ap.IRI(ctx.ContextUser.AvatarFullLinkWithSize(2048)),
+ URL: ap.IRI(ctx.ContextUser.AvatarFullLinkWithSize(ctx, 2048)),
}
person.Inbox = ap.IRI(iri + "/inbox")
diff --git a/routers/api/v1/admin/org.go b/routers/api/v1/admin/org.go
index ff6624418..6d50a1267 100644
--- a/routers/api/v1/admin/org.go
+++ b/routers/api/v1/admin/org.go
@@ -74,7 +74,7 @@ func CreateOrg(ctx *context.APIContext) {
return
}
- ctx.JSON(http.StatusCreated, convert.ToOrganization(org))
+ ctx.JSON(http.StatusCreated, convert.ToOrganization(ctx, org))
}
// GetAllOrgs API for getting information of all the organizations
@@ -114,7 +114,7 @@ func GetAllOrgs(ctx *context.APIContext) {
}
orgs := make([]*api.Organization, len(users))
for i := range users {
- orgs[i] = convert.ToOrganization(organization.OrgFromUser(users[i]))
+ orgs[i] = convert.ToOrganization(ctx, organization.OrgFromUser(users[i]))
}
ctx.SetLinkHeader(int(maxResults), listOptions.PageSize)
diff --git a/routers/api/v1/admin/user.go b/routers/api/v1/admin/user.go
index 6b48ce4a9..1fbdab3e5 100644
--- a/routers/api/v1/admin/user.go
+++ b/routers/api/v1/admin/user.go
@@ -15,11 +15,12 @@ import (
"code.gitea.io/gitea/models/auth"
"code.gitea.io/gitea/models/db"
user_model "code.gitea.io/gitea/models/user"
+ "code.gitea.io/gitea/modules/auth/password"
"code.gitea.io/gitea/modules/context"
"code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/password"
"code.gitea.io/gitea/modules/setting"
api "code.gitea.io/gitea/modules/structs"
+ "code.gitea.io/gitea/modules/timeutil"
"code.gitea.io/gitea/modules/util"
"code.gitea.io/gitea/modules/web"
"code.gitea.io/gitea/routers/api/v1/user"
@@ -120,6 +121,14 @@ func CreateUser(ctx *context.APIContext) {
overwriteDefault.Visibility = &visibility
}
+ // Update the user creation timestamp. This can only be done after the user
+ // record has been inserted into the database; the insert intself will always
+ // set the creation timestamp to "now".
+ if form.Created != nil {
+ u.CreatedUnix = timeutil.TimeStamp(form.Created.Unix())
+ u.UpdatedUnix = u.CreatedUnix
+ }
+
if err := user_model.CreateUser(u, overwriteDefault); err != nil {
if user_model.IsErrUserAlreadyExist(err) ||
user_model.IsErrEmailAlreadyUsed(err) ||
@@ -140,7 +149,7 @@ func CreateUser(ctx *context.APIContext) {
if form.SendNotify {
mailer.SendRegisterNotifyMail(u)
}
- ctx.JSON(http.StatusCreated, convert.ToUser(u, ctx.Doer))
+ ctx.JSON(http.StatusCreated, convert.ToUser(ctx, u, ctx.Doer))
}
// EditUser api for modifying a user's information
@@ -280,7 +289,7 @@ func EditUser(ctx *context.APIContext) {
}
log.Trace("Account profile updated by admin (%s): %s", ctx.Doer.Name, ctx.ContextUser.Name)
- ctx.JSON(http.StatusOK, convert.ToUser(ctx.ContextUser, ctx.Doer))
+ ctx.JSON(http.StatusOK, convert.ToUser(ctx, ctx.ContextUser, ctx.Doer))
}
// DeleteUser api for deleting a user
@@ -441,7 +450,7 @@ func GetAllUsers(ctx *context.APIContext) {
results := make([]*api.User, len(users))
for i := range users {
- results[i] = convert.ToUser(users[i], ctx.Doer)
+ results[i] = convert.ToUser(ctx, users[i], ctx.Doer)
}
ctx.SetLinkHeader(int(maxResults), listOptions.PageSize)
diff --git a/routers/api/v1/org/label.go b/routers/api/v1/org/label.go
index 5d0455cdd..938fe79df 100644
--- a/routers/api/v1/org/label.go
+++ b/routers/api/v1/org/label.go
@@ -94,6 +94,7 @@ func CreateLabel(ctx *context.APIContext) {
label := &issues_model.Label{
Name: form.Name,
+ Exclusive: form.Exclusive,
Color: form.Color,
OrgID: ctx.Org.Organization.ID,
Description: form.Description,
@@ -195,6 +196,9 @@ func EditLabel(ctx *context.APIContext) {
if form.Name != nil {
label.Name = *form.Name
}
+ if form.Exclusive != nil {
+ label.Exclusive = *form.Exclusive
+ }
if form.Color != nil {
label.Color = strings.Trim(*form.Color, " ")
if len(label.Color) == 6 {
diff --git a/routers/api/v1/org/member.go b/routers/api/v1/org/member.go
index 33c994497..e4afd7f3c 100644
--- a/routers/api/v1/org/member.go
+++ b/routers/api/v1/org/member.go
@@ -39,7 +39,7 @@ func listMembers(ctx *context.APIContext, publicOnly bool) {
apiMembers := make([]*api.User, len(members))
for i, member := range members {
- apiMembers[i] = convert.ToUser(member, ctx.Doer)
+ apiMembers[i] = convert.ToUser(ctx, member, ctx.Doer)
}
ctx.SetTotalCountHeader(count)
diff --git a/routers/api/v1/org/org.go b/routers/api/v1/org/org.go
index a1b071d48..75420dcc4 100644
--- a/routers/api/v1/org/org.go
+++ b/routers/api/v1/org/org.go
@@ -42,7 +42,7 @@ func listUserOrgs(ctx *context.APIContext, u *user_model.User) {
apiOrgs := make([]*api.Organization, len(orgs))
for i := range orgs {
- apiOrgs[i] = convert.ToOrganization(orgs[i])
+ apiOrgs[i] = convert.ToOrganization(ctx, orgs[i])
}
ctx.SetLinkHeader(int(maxResults), listOptions.PageSize)
@@ -211,7 +211,7 @@ func GetAll(ctx *context.APIContext) {
}
orgs := make([]*api.Organization, len(publicOrgs))
for i := range publicOrgs {
- orgs[i] = convert.ToOrganization(organization.OrgFromUser(publicOrgs[i]))
+ orgs[i] = convert.ToOrganization(ctx, organization.OrgFromUser(publicOrgs[i]))
}
ctx.SetLinkHeader(int(maxResults), listOptions.PageSize)
@@ -274,7 +274,7 @@ func Create(ctx *context.APIContext) {
return
}
- ctx.JSON(http.StatusCreated, convert.ToOrganization(org))
+ ctx.JSON(http.StatusCreated, convert.ToOrganization(ctx, org))
}
// Get get an organization
@@ -298,7 +298,7 @@ func Get(ctx *context.APIContext) {
ctx.NotFound("HasOrgOrUserVisible", nil)
return
}
- ctx.JSON(http.StatusOK, convert.ToOrganization(ctx.Org.Organization))
+ ctx.JSON(http.StatusOK, convert.ToOrganization(ctx, ctx.Org.Organization))
}
// Edit change an organization's information
@@ -344,7 +344,7 @@ func Edit(ctx *context.APIContext) {
return
}
- ctx.JSON(http.StatusOK, convert.ToOrganization(org))
+ ctx.JSON(http.StatusOK, convert.ToOrganization(ctx, org))
}
// Delete an organization
diff --git a/routers/api/v1/org/team.go b/routers/api/v1/org/team.go
index 8f87e8276..0c6926759 100644
--- a/routers/api/v1/org/team.go
+++ b/routers/api/v1/org/team.go
@@ -58,7 +58,7 @@ func ListTeams(ctx *context.APIContext) {
return
}
- apiTeams, err := convert.ToTeams(teams, false)
+ apiTeams, err := convert.ToTeams(ctx, teams, false)
if err != nil {
ctx.Error(http.StatusInternalServerError, "ConvertToTeams", err)
return
@@ -97,7 +97,7 @@ func ListUserTeams(ctx *context.APIContext) {
return
}
- apiTeams, err := convert.ToTeams(teams, true)
+ apiTeams, err := convert.ToTeams(ctx, teams, true)
if err != nil {
ctx.Error(http.StatusInternalServerError, "ConvertToTeams", err)
return
@@ -125,7 +125,7 @@ func GetTeam(ctx *context.APIContext) {
// "200":
// "$ref": "#/responses/Team"
- apiTeam, err := convert.ToTeam(ctx.Org.Team)
+ apiTeam, err := convert.ToTeam(ctx, ctx.Org.Team)
if err != nil {
ctx.InternalServerError(err)
return
@@ -223,7 +223,7 @@ func CreateTeam(ctx *context.APIContext) {
return
}
- apiTeam, err := convert.ToTeam(team)
+ apiTeam, err := convert.ToTeam(ctx, team)
if err != nil {
ctx.InternalServerError(err)
return
@@ -256,7 +256,7 @@ func EditTeam(ctx *context.APIContext) {
form := web.GetForm(ctx).(*api.EditTeamOption)
team := ctx.Org.Team
- if err := team.GetUnits(); err != nil {
+ if err := team.LoadUnits(ctx); err != nil {
ctx.InternalServerError(err)
return
}
@@ -306,7 +306,7 @@ func EditTeam(ctx *context.APIContext) {
return
}
- apiTeam, err := convert.ToTeam(team)
+ apiTeam, err := convert.ToTeam(ctx, team)
if err != nil {
ctx.InternalServerError(err)
return
@@ -383,7 +383,7 @@ func GetTeamMembers(ctx *context.APIContext) {
members := make([]*api.User, len(teamMembers))
for i, member := range teamMembers {
- members[i] = convert.ToUser(member, ctx.Doer)
+ members[i] = convert.ToUser(ctx, member, ctx.Doer)
}
ctx.SetTotalCountHeader(int64(ctx.Org.Team.NumMembers))
@@ -428,7 +428,7 @@ func GetTeamMember(ctx *context.APIContext) {
ctx.NotFound()
return
}
- ctx.JSON(http.StatusOK, convert.ToUser(u, ctx.Doer))
+ ctx.JSON(http.StatusOK, convert.ToUser(ctx, u, ctx.Doer))
}
// AddTeamMember api for add a member to a team
@@ -779,7 +779,7 @@ func SearchTeam(ctx *context.APIContext) {
return
}
- apiTeams, err := convert.ToTeams(teams, false)
+ apiTeams, err := convert.ToTeams(ctx, teams, false)
if err != nil {
ctx.InternalServerError(err)
return
diff --git a/routers/api/v1/repo/branch.go b/routers/api/v1/repo/branch.go
index eacec6a60..8acaeaffb 100644
--- a/routers/api/v1/repo/branch.go
+++ b/routers/api/v1/repo/branch.go
@@ -76,7 +76,7 @@ func GetBranch(ctx *context.APIContext) {
return
}
- br, err := convert.ToBranch(ctx.Repo.Repository, branch, c, branchProtection, ctx.Doer, ctx.Repo.IsAdmin())
+ br, err := convert.ToBranch(ctx, ctx.Repo.Repository, branch, c, branchProtection, ctx.Doer, ctx.Repo.IsAdmin())
if err != nil {
ctx.Error(http.StatusInternalServerError, "convert.ToBranch", err)
return
@@ -212,7 +212,7 @@ func CreateBranch(ctx *context.APIContext) {
return
}
- br, err := convert.ToBranch(ctx.Repo.Repository, branch, commit, branchProtection, ctx.Doer, ctx.Repo.IsAdmin())
+ br, err := convert.ToBranch(ctx, ctx.Repo.Repository, branch, commit, branchProtection, ctx.Doer, ctx.Repo.IsAdmin())
if err != nil {
ctx.Error(http.StatusInternalServerError, "convert.ToBranch", err)
return
@@ -284,7 +284,7 @@ func ListBranches(ctx *context.APIContext) {
}
branchProtection := rules.GetFirstMatched(branches[i].Name)
- apiBranch, err := convert.ToBranch(ctx.Repo.Repository, branches[i], c, branchProtection, ctx.Doer, ctx.Repo.IsAdmin())
+ apiBranch, err := convert.ToBranch(ctx, ctx.Repo.Repository, branches[i], c, branchProtection, ctx.Doer, ctx.Repo.IsAdmin())
if err != nil {
ctx.Error(http.StatusInternalServerError, "convert.ToBranch", err)
return
diff --git a/routers/api/v1/repo/collaborators.go b/routers/api/v1/repo/collaborators.go
index 293778420..942d4c799 100644
--- a/routers/api/v1/repo/collaborators.go
+++ b/routers/api/v1/repo/collaborators.go
@@ -65,7 +65,7 @@ func ListCollaborators(ctx *context.APIContext) {
users := make([]*api.User, len(collaborators))
for i, collaborator := range collaborators {
- users[i] = convert.ToUser(collaborator.User, ctx.Doer)
+ users[i] = convert.ToUser(ctx, collaborator.User, ctx.Doer)
}
ctx.SetTotalCountHeader(count)
@@ -287,7 +287,7 @@ func GetRepoPermissions(ctx *context.APIContext) {
return
}
- ctx.JSON(http.StatusOK, convert.ToUserAndPermission(collaborator, ctx.ContextUser, permission.AccessMode))
+ ctx.JSON(http.StatusOK, convert.ToUserAndPermission(ctx, collaborator, ctx.ContextUser, permission.AccessMode))
}
// GetReviewers return all users that can be requested to review in this repo
@@ -317,7 +317,7 @@ func GetReviewers(ctx *context.APIContext) {
ctx.Error(http.StatusInternalServerError, "ListCollaborators", err)
return
}
- ctx.JSON(http.StatusOK, convert.ToUsers(ctx.Doer, reviewers))
+ ctx.JSON(http.StatusOK, convert.ToUsers(ctx, ctx.Doer, reviewers))
}
// GetAssignees return all users that have write access and can be assigned to issues
@@ -347,5 +347,5 @@ func GetAssignees(ctx *context.APIContext) {
ctx.Error(http.StatusInternalServerError, "ListCollaborators", err)
return
}
- ctx.JSON(http.StatusOK, convert.ToUsers(ctx.Doer, assignees))
+ ctx.JSON(http.StatusOK, convert.ToUsers(ctx, ctx.Doer, assignees))
}
diff --git a/routers/api/v1/repo/commits.go b/routers/api/v1/repo/commits.go
index 68a92ca2a..22b013e7d 100644
--- a/routers/api/v1/repo/commits.go
+++ b/routers/api/v1/repo/commits.go
@@ -69,7 +69,7 @@ func getCommit(ctx *context.APIContext, identifier string) {
return
}
- json, err := convert.ToCommit(ctx.Repo.Repository, ctx.Repo.GitRepo, commit, nil, true)
+ json, err := convert.ToCommit(ctx, ctx.Repo.Repository, ctx.Repo.GitRepo, commit, nil, true)
if err != nil {
ctx.Error(http.StatusInternalServerError, "toCommit", err)
return
@@ -217,7 +217,7 @@ func GetAllCommits(ctx *context.APIContext) {
for i, commit := range commits {
// Create json struct
- apiCommits[i], err = convert.ToCommit(ctx.Repo.Repository, ctx.Repo.GitRepo, commit, userCache, stat)
+ apiCommits[i], err = convert.ToCommit(ctx, ctx.Repo.Repository, ctx.Repo.GitRepo, commit, userCache, stat)
if err != nil {
ctx.Error(http.StatusInternalServerError, "toCommit", err)
return
diff --git a/routers/api/v1/repo/hook.go b/routers/api/v1/repo/hook.go
index 100a28d7f..fd54d1f74 100644
--- a/routers/api/v1/repo/hook.go
+++ b/routers/api/v1/repo/hook.go
@@ -174,7 +174,7 @@ func TestHook(ctx *context.APIContext) {
return
}
- commit := convert.ToPayloadCommit(ctx.Repo.Repository, ctx.Repo.Commit)
+ commit := convert.ToPayloadCommit(ctx, ctx.Repo.Repository, ctx.Repo.Commit)
commitID := ctx.Repo.Commit.ID.String()
if err := webhook_service.PrepareWebhook(ctx, hook, webhook_module.HookEventPush, &api.PushPayload{
@@ -186,8 +186,8 @@ func TestHook(ctx *context.APIContext) {
TotalCommits: 1,
HeadCommit: commit,
Repo: convert.ToRepo(ctx, ctx.Repo.Repository, perm.AccessModeNone),
- Pusher: convert.ToUserWithAccessMode(ctx.Doer, perm.AccessModeNone),
- Sender: convert.ToUserWithAccessMode(ctx.Doer, perm.AccessModeNone),
+ Pusher: convert.ToUserWithAccessMode(ctx, ctx.Doer, perm.AccessModeNone),
+ Sender: convert.ToUserWithAccessMode(ctx, ctx.Doer, perm.AccessModeNone),
}); err != nil {
ctx.Error(http.StatusInternalServerError, "PrepareWebhook: ", err)
return
diff --git a/routers/api/v1/repo/issue_comment.go b/routers/api/v1/repo/issue_comment.go
index 40c92998d..3d14343d4 100644
--- a/routers/api/v1/repo/issue_comment.go
+++ b/routers/api/v1/repo/issue_comment.go
@@ -103,7 +103,7 @@ func ListIssueComments(ctx *context.APIContext) {
apiComments := make([]*api.Comment, len(comments))
for i, comment := range comments {
comment.Issue = issue
- apiComments[i] = convert.ToComment(comments[i])
+ apiComments[i] = convert.ToComment(ctx, comments[i])
}
ctx.SetTotalCountHeader(totalCount)
@@ -308,7 +308,7 @@ func ListRepoIssueComments(ctx *context.APIContext) {
return
}
for i := range comments {
- apiComments[i] = convert.ToComment(comments[i])
+ apiComments[i] = convert.ToComment(ctx, comments[i])
}
ctx.SetTotalCountHeader(totalCount)
@@ -368,7 +368,7 @@ func CreateIssueComment(ctx *context.APIContext) {
return
}
- ctx.JSON(http.StatusCreated, convert.ToComment(comment))
+ ctx.JSON(http.StatusCreated, convert.ToComment(ctx, comment))
}
// GetIssueComment Get a comment by ID
@@ -436,7 +436,7 @@ func GetIssueComment(ctx *context.APIContext) {
return
}
- ctx.JSON(http.StatusOK, convert.ToComment(comment))
+ ctx.JSON(http.StatusOK, convert.ToComment(ctx, comment))
}
// EditIssueComment modify a comment of an issue
@@ -561,7 +561,7 @@ func editIssueComment(ctx *context.APIContext, form api.EditIssueCommentOption)
return
}
- ctx.JSON(http.StatusOK, convert.ToComment(comment))
+ ctx.JSON(http.StatusOK, convert.ToComment(ctx, comment))
}
// DeleteIssueComment delete a comment from an issue
diff --git a/routers/api/v1/repo/issue_reaction.go b/routers/api/v1/repo/issue_reaction.go
index 1b998a535..921f6e53f 100644
--- a/routers/api/v1/repo/issue_reaction.go
+++ b/routers/api/v1/repo/issue_reaction.go
@@ -80,7 +80,7 @@ func GetIssueCommentReactions(ctx *context.APIContext) {
var result []api.Reaction
for _, r := range reactions {
result = append(result, api.Reaction{
- User: convert.ToUser(r.User, ctx.Doer),
+ User: convert.ToUser(ctx, r.User, ctx.Doer),
Reaction: r.Type,
Created: r.CreatedUnix.AsTime(),
})
@@ -202,7 +202,7 @@ func changeIssueCommentReaction(ctx *context.APIContext, form api.EditReactionOp
ctx.Error(http.StatusForbidden, err.Error(), err)
} else if issues_model.IsErrReactionAlreadyExist(err) {
ctx.JSON(http.StatusOK, api.Reaction{
- User: convert.ToUser(ctx.Doer, ctx.Doer),
+ User: convert.ToUser(ctx, ctx.Doer, ctx.Doer),
Reaction: reaction.Type,
Created: reaction.CreatedUnix.AsTime(),
})
@@ -213,7 +213,7 @@ func changeIssueCommentReaction(ctx *context.APIContext, form api.EditReactionOp
}
ctx.JSON(http.StatusCreated, api.Reaction{
- User: convert.ToUser(ctx.Doer, ctx.Doer),
+ User: convert.ToUser(ctx, ctx.Doer, ctx.Doer),
Reaction: reaction.Type,
Created: reaction.CreatedUnix.AsTime(),
})
@@ -298,7 +298,7 @@ func GetIssueReactions(ctx *context.APIContext) {
var result []api.Reaction
for _, r := range reactions {
result = append(result, api.Reaction{
- User: convert.ToUser(r.User, ctx.Doer),
+ User: convert.ToUser(ctx, r.User, ctx.Doer),
Reaction: r.Type,
Created: r.CreatedUnix.AsTime(),
})
@@ -412,7 +412,7 @@ func changeIssueReaction(ctx *context.APIContext, form api.EditReactionOption, i
ctx.Error(http.StatusForbidden, err.Error(), err)
} else if issues_model.IsErrReactionAlreadyExist(err) {
ctx.JSON(http.StatusOK, api.Reaction{
- User: convert.ToUser(ctx.Doer, ctx.Doer),
+ User: convert.ToUser(ctx, ctx.Doer, ctx.Doer),
Reaction: reaction.Type,
Created: reaction.CreatedUnix.AsTime(),
})
@@ -423,7 +423,7 @@ func changeIssueReaction(ctx *context.APIContext, form api.EditReactionOption, i
}
ctx.JSON(http.StatusCreated, api.Reaction{
- User: convert.ToUser(ctx.Doer, ctx.Doer),
+ User: convert.ToUser(ctx, ctx.Doer, ctx.Doer),
Reaction: reaction.Type,
Created: reaction.CreatedUnix.AsTime(),
})
diff --git a/routers/api/v1/repo/issue_subscription.go b/routers/api/v1/repo/issue_subscription.go
index 6d22c8265..107119eb0 100644
--- a/routers/api/v1/repo/issue_subscription.go
+++ b/routers/api/v1/repo/issue_subscription.go
@@ -280,7 +280,7 @@ func GetIssueSubscribers(ctx *context.APIContext) {
}
apiUsers := make([]*api.User, 0, len(users))
for _, v := range users {
- apiUsers = append(apiUsers, convert.ToUser(v, ctx.Doer))
+ apiUsers = append(apiUsers, convert.ToUser(ctx, v, ctx.Doer))
}
count, err := issues_model.CountIssueWatchers(ctx, issue.ID)
diff --git a/routers/api/v1/repo/label.go b/routers/api/v1/repo/label.go
index 411c0274e..a06d26e83 100644
--- a/routers/api/v1/repo/label.go
+++ b/routers/api/v1/repo/label.go
@@ -156,6 +156,7 @@ func CreateLabel(ctx *context.APIContext) {
label := &issues_model.Label{
Name: form.Name,
+ Exclusive: form.Exclusive,
Color: form.Color,
RepoID: ctx.Repo.Repository.ID,
Description: form.Description,
@@ -218,6 +219,9 @@ func EditLabel(ctx *context.APIContext) {
if form.Name != nil {
label.Name = *form.Name
}
+ if form.Exclusive != nil {
+ label.Exclusive = *form.Exclusive
+ }
if form.Color != nil {
label.Color = strings.Trim(*form.Color, " ")
if len(label.Color) == 6 {
diff --git a/routers/api/v1/repo/main_test.go b/routers/api/v1/repo/main_test.go
index 543fb922d..c7466c493 100644
--- a/routers/api/v1/repo/main_test.go
+++ b/routers/api/v1/repo/main_test.go
@@ -13,8 +13,8 @@ import (
)
func TestMain(m *testing.M) {
- setting.LoadForTest()
- setting.NewQueueService()
+ setting.InitProviderAndLoadCommonSettingsForTest()
+ setting.LoadQueueSettings()
unittest.MainTest(m, &unittest.TestOptions{
GiteaRootPath: filepath.Join("..", "..", "..", ".."),
SetUp: webhook_service.Init,
diff --git a/routers/api/v1/repo/notes.go b/routers/api/v1/repo/notes.go
index 8eaa503ff..2d1f3291f 100644
--- a/routers/api/v1/repo/notes.go
+++ b/routers/api/v1/repo/notes.go
@@ -68,7 +68,7 @@ func getNote(ctx *context.APIContext, identifier string) {
return
}
- cmt, err := convert.ToCommit(ctx.Repo.Repository, ctx.Repo.GitRepo, note.Commit, nil, true)
+ cmt, err := convert.ToCommit(ctx, ctx.Repo.Repository, ctx.Repo.GitRepo, note.Commit, nil, true)
if err != nil {
ctx.Error(http.StatusInternalServerError, "ToCommit", err)
return
diff --git a/routers/api/v1/repo/pull.go b/routers/api/v1/repo/pull.go
index 8164b3869..7005725cf 100644
--- a/routers/api/v1/repo/pull.go
+++ b/routers/api/v1/repo/pull.go
@@ -1311,7 +1311,7 @@ func GetPullRequestCommits(ctx *context.APIContext) {
apiCommits := make([]*api.Commit, 0, end-start)
for i := start; i < end; i++ {
- apiCommit, err := convert.ToCommit(ctx.Repo.Repository, baseGitRepo, commits[i], userCache, true)
+ apiCommit, err := convert.ToCommit(ctx, ctx.Repo.Repository, baseGitRepo, commits[i], userCache, true)
if err != nil {
ctx.ServerError("toCommit", err)
return
diff --git a/routers/api/v1/repo/pull_review.go b/routers/api/v1/repo/pull_review.go
index 96dc1fc2d..f6acaa780 100644
--- a/routers/api/v1/repo/pull_review.go
+++ b/routers/api/v1/repo/pull_review.go
@@ -673,7 +673,7 @@ func apiReviewRequest(ctx *context.APIContext, opts api.PullReviewRequestOptions
for _, r := range opts.Reviewers {
var reviewer *user_model.User
if strings.Contains(r, "@") {
- reviewer, err = user_model.GetUserByEmail(r)
+ reviewer, err = user_model.GetUserByEmail(ctx, r)
} else {
reviewer, err = user_model.GetUserByName(ctx, r)
}
diff --git a/routers/api/v1/repo/release.go b/routers/api/v1/repo/release.go
index c01e66150..e9693dd05 100644
--- a/routers/api/v1/repo/release.go
+++ b/routers/api/v1/repo/release.go
@@ -64,7 +64,7 @@ func GetRelease(ctx *context.APIContext) {
ctx.Error(http.StatusInternalServerError, "LoadAttributes", err)
return
}
- ctx.JSON(http.StatusOK, convert.ToRelease(release))
+ ctx.JSON(http.StatusOK, convert.ToRelease(ctx, release))
}
// GetLatestRelease gets the most recent non-prerelease, non-draft release of a repository, sorted by created_at
@@ -105,7 +105,7 @@ func GetLatestRelease(ctx *context.APIContext) {
ctx.Error(http.StatusInternalServerError, "LoadAttributes", err)
return
}
- ctx.JSON(http.StatusOK, convert.ToRelease(release))
+ ctx.JSON(http.StatusOK, convert.ToRelease(ctx, release))
}
// ListReleases list a repository's releases
@@ -174,7 +174,7 @@ func ListReleases(ctx *context.APIContext) {
ctx.Error(http.StatusInternalServerError, "LoadAttributes", err)
return
}
- rels[i] = convert.ToRelease(release)
+ rels[i] = convert.ToRelease(ctx, release)
}
filteredCount, err := repo_model.CountReleasesByRepoID(ctx.Repo.Repository.ID, opts)
@@ -272,7 +272,7 @@ func CreateRelease(ctx *context.APIContext) {
return
}
}
- ctx.JSON(http.StatusCreated, convert.ToRelease(rel))
+ ctx.JSON(http.StatusCreated, convert.ToRelease(ctx, rel))
}
// EditRelease edit a release
@@ -357,7 +357,7 @@ func EditRelease(ctx *context.APIContext) {
ctx.Error(http.StatusInternalServerError, "LoadAttributes", err)
return
}
- ctx.JSON(http.StatusOK, convert.ToRelease(rel))
+ ctx.JSON(http.StatusOK, convert.ToRelease(ctx, rel))
}
// DeleteRelease delete a release from a repository
diff --git a/routers/api/v1/repo/release_attachment.go b/routers/api/v1/repo/release_attachment.go
index 5aaea693c..597578aac 100644
--- a/routers/api/v1/repo/release_attachment.go
+++ b/routers/api/v1/repo/release_attachment.go
@@ -117,7 +117,7 @@ func ListReleaseAttachments(ctx *context.APIContext) {
ctx.Error(http.StatusInternalServerError, "LoadAttributes", err)
return
}
- ctx.JSON(http.StatusOK, convert.ToRelease(release).Attachments)
+ ctx.JSON(http.StatusOK, convert.ToRelease(ctx, release).Attachments)
}
// CreateReleaseAttachment creates an attachment and saves the given file
diff --git a/routers/api/v1/repo/release_tags.go b/routers/api/v1/repo/release_tags.go
index 7cc846fdc..051ee8f22 100644
--- a/routers/api/v1/repo/release_tags.go
+++ b/routers/api/v1/repo/release_tags.go
@@ -63,7 +63,7 @@ func GetReleaseByTag(ctx *context.APIContext) {
ctx.Error(http.StatusInternalServerError, "LoadAttributes", err)
return
}
- ctx.JSON(http.StatusOK, convert.ToRelease(release))
+ ctx.JSON(http.StatusOK, convert.ToRelease(ctx, release))
}
// DeleteReleaseByTag delete a release from a repository by tag name
diff --git a/routers/api/v1/repo/repo.go b/routers/api/v1/repo/repo.go
index 1426d1dbc..0395198e2 100644
--- a/routers/api/v1/repo/repo.go
+++ b/routers/api/v1/repo/repo.go
@@ -201,7 +201,7 @@ func Search(ctx *context.APIContext) {
results := make([]*api.Repository, len(repos))
for i, repo := range repos {
- if err = repo.GetOwner(ctx); err != nil {
+ if err = repo.LoadOwner(ctx); err != nil {
ctx.JSON(http.StatusInternalServerError, api.SearchError{
OK: false,
Error: err.Error(),
@@ -863,6 +863,7 @@ func updateRepoUnits(ctx *context.APIContext, opts api.EditRepoOption) error {
AllowRebaseUpdate: true,
DefaultDeleteBranchAfterMerge: false,
DefaultMergeStyle: repo_model.MergeStyleMerge,
+ DefaultAllowMaintainerEdit: false,
}
} else {
config = unit.PullRequestsConfig()
@@ -898,6 +899,9 @@ func updateRepoUnits(ctx *context.APIContext, opts api.EditRepoOption) error {
if opts.DefaultMergeStyle != nil {
config.DefaultMergeStyle = repo_model.MergeStyle(*opts.DefaultMergeStyle)
}
+ if opts.DefaultAllowMaintainerEdit != nil {
+ config.DefaultAllowMaintainerEdit = *opts.DefaultAllowMaintainerEdit
+ }
units = append(units, repo_model.RepoUnit{
RepoID: repo.ID,
diff --git a/routers/api/v1/repo/star.go b/routers/api/v1/repo/star.go
index c7b2eb01f..e4cf0ffab 100644
--- a/routers/api/v1/repo/star.go
+++ b/routers/api/v1/repo/star.go
@@ -50,7 +50,7 @@ func ListStargazers(ctx *context.APIContext) {
}
users := make([]*api.User, len(stargazers))
for i, stargazer := range stargazers {
- users[i] = convert.ToUser(stargazer, ctx.Doer)
+ users[i] = convert.ToUser(ctx, stargazer, ctx.Doer)
}
ctx.SetTotalCountHeader(int64(ctx.Repo.Repository.NumStars))
diff --git a/routers/api/v1/repo/subscriber.go b/routers/api/v1/repo/subscriber.go
index 6cd369898..613fbee40 100644
--- a/routers/api/v1/repo/subscriber.go
+++ b/routers/api/v1/repo/subscriber.go
@@ -50,7 +50,7 @@ func ListSubscribers(ctx *context.APIContext) {
}
users := make([]*api.User, len(subscribers))
for i, subscriber := range subscribers {
- users[i] = convert.ToUser(subscriber, ctx.Doer)
+ users[i] = convert.ToUser(ctx, subscriber, ctx.Doer)
}
ctx.SetTotalCountHeader(int64(ctx.Repo.Repository.NumWatches))
diff --git a/routers/api/v1/repo/tag.go b/routers/api/v1/repo/tag.go
index cb65e2b65..b28b6b0b9 100644
--- a/routers/api/v1/repo/tag.go
+++ b/routers/api/v1/repo/tag.go
@@ -107,7 +107,7 @@ func GetAnnotatedTag(ctx *context.APIContext) {
if err != nil {
ctx.Error(http.StatusBadRequest, "GetAnnotatedTag", err)
}
- ctx.JSON(http.StatusOK, convert.ToAnnotatedTag(ctx.Repo.Repository, tag, commit))
+ ctx.JSON(http.StatusOK, convert.ToAnnotatedTag(ctx, ctx.Repo.Repository, tag, commit))
}
}
diff --git a/routers/api/v1/repo/teams.go b/routers/api/v1/repo/teams.go
index eafe4236e..01292f18d 100644
--- a/routers/api/v1/repo/teams.go
+++ b/routers/api/v1/repo/teams.go
@@ -47,7 +47,7 @@ func ListTeams(ctx *context.APIContext) {
return
}
- apiTeams, err := convert.ToTeams(teams, false)
+ apiTeams, err := convert.ToTeams(ctx, teams, false)
if err != nil {
ctx.InternalServerError(err)
return
@@ -98,7 +98,7 @@ func IsTeam(ctx *context.APIContext) {
}
if models.HasRepository(team, ctx.Repo.Repository.ID) {
- apiTeam, err := convert.ToTeam(team)
+ apiTeam, err := convert.ToTeam(ctx, team)
if err != nil {
ctx.InternalServerError(err)
return
diff --git a/routers/api/v1/repo/transfer.go b/routers/api/v1/repo/transfer.go
index aec398da7..ded8edd41 100644
--- a/routers/api/v1/repo/transfer.go
+++ b/routers/api/v1/repo/transfer.go
@@ -81,7 +81,7 @@ func Transfer(ctx *context.APIContext) {
return
}
- org := convert.ToOrganization(organization.OrgFromUser(newOwner))
+ org := convert.ToOrganization(ctx, organization.OrgFromUser(newOwner))
for _, tID := range *opts.TeamIDs {
team, err := organization.GetTeamByID(ctx, tID)
if err != nil {
diff --git a/routers/api/v1/user/follower.go b/routers/api/v1/user/follower.go
index a05d5fc22..b7b8484a3 100644
--- a/routers/api/v1/user/follower.go
+++ b/routers/api/v1/user/follower.go
@@ -18,7 +18,7 @@ import (
func responseAPIUsers(ctx *context.APIContext, users []*user_model.User) {
apiUsers := make([]*api.User, len(users))
for i := range users {
- apiUsers[i] = convert.ToUser(users[i], ctx.Doer)
+ apiUsers[i] = convert.ToUser(ctx, users[i], ctx.Doer)
}
ctx.JSON(http.StatusOK, &apiUsers)
}
diff --git a/routers/api/v1/user/key.go b/routers/api/v1/user/key.go
index 8aad69884..f90c65817 100644
--- a/routers/api/v1/user/key.go
+++ b/routers/api/v1/user/key.go
@@ -4,6 +4,7 @@
package user
import (
+ std_ctx "context"
"net/http"
asymkey_model "code.gitea.io/gitea/models/asymkey"
@@ -21,20 +22,20 @@ import (
)
// appendPrivateInformation appends the owner and key type information to api.PublicKey
-func appendPrivateInformation(apiKey *api.PublicKey, key *asymkey_model.PublicKey, defaultUser *user_model.User) (*api.PublicKey, error) {
+func appendPrivateInformation(ctx std_ctx.Context, apiKey *api.PublicKey, key *asymkey_model.PublicKey, defaultUser *user_model.User) (*api.PublicKey, error) {
if key.Type == asymkey_model.KeyTypeDeploy {
apiKey.KeyType = "deploy"
} else if key.Type == asymkey_model.KeyTypeUser {
apiKey.KeyType = "user"
if defaultUser.ID == key.OwnerID {
- apiKey.Owner = convert.ToUser(defaultUser, defaultUser)
+ apiKey.Owner = convert.ToUser(ctx, defaultUser, defaultUser)
} else {
user, err := user_model.GetUserByID(db.DefaultContext, key.OwnerID)
if err != nil {
return apiKey, err
}
- apiKey.Owner = convert.ToUser(user, user)
+ apiKey.Owner = convert.ToUser(ctx, user, user)
}
} else {
apiKey.KeyType = "unknown"
@@ -87,7 +88,7 @@ func listPublicKeys(ctx *context.APIContext, user *user_model.User) {
for i := range keys {
apiKeys[i] = convert.ToPublicKey(apiLink, keys[i])
if ctx.Doer.IsAdmin || ctx.Doer.ID == keys[i].OwnerID {
- apiKeys[i], _ = appendPrivateInformation(apiKeys[i], keys[i], user)
+ apiKeys[i], _ = appendPrivateInformation(ctx, apiKeys[i], keys[i], user)
}
}
@@ -187,7 +188,7 @@ func GetPublicKey(ctx *context.APIContext) {
apiLink := composePublicKeysAPILink()
apiKey := convert.ToPublicKey(apiLink, key)
if ctx.Doer.IsAdmin || ctx.Doer.ID == key.OwnerID {
- apiKey, _ = appendPrivateInformation(apiKey, key, ctx.Doer)
+ apiKey, _ = appendPrivateInformation(ctx, apiKey, key, ctx.Doer)
}
ctx.JSON(http.StatusOK, apiKey)
}
@@ -208,7 +209,7 @@ func CreateUserPublicKey(ctx *context.APIContext, form api.CreateKeyOption, uid
apiLink := composePublicKeysAPILink()
apiKey := convert.ToPublicKey(apiLink, key)
if ctx.Doer.IsAdmin || ctx.Doer.ID == key.OwnerID {
- apiKey, _ = appendPrivateInformation(apiKey, key, ctx.Doer)
+ apiKey, _ = appendPrivateInformation(ctx, apiKey, key, ctx.Doer)
}
ctx.JSON(http.StatusCreated, apiKey)
}
diff --git a/routers/api/v1/user/repo.go b/routers/api/v1/user/repo.go
index d566c072f..dcb14780a 100644
--- a/routers/api/v1/user/repo.go
+++ b/routers/api/v1/user/repo.go
@@ -119,8 +119,8 @@ func ListMyRepos(ctx *context.APIContext) {
results := make([]*api.Repository, len(repos))
for i, repo := range repos {
- if err = repo.GetOwner(ctx); err != nil {
- ctx.Error(http.StatusInternalServerError, "GetOwner", err)
+ if err = repo.LoadOwner(ctx); err != nil {
+ ctx.Error(http.StatusInternalServerError, "LoadOwner", err)
return
}
accessMode, err := access_model.AccessLevel(ctx, ctx.Doer, repo)
diff --git a/routers/api/v1/user/user.go b/routers/api/v1/user/user.go
index 55f3df40b..6fd4b3a95 100644
--- a/routers/api/v1/user/user.go
+++ b/routers/api/v1/user/user.go
@@ -74,7 +74,7 @@ func Search(ctx *context.APIContext) {
ctx.JSON(http.StatusOK, map[string]interface{}{
"ok": true,
- "data": convert.ToUsers(ctx.Doer, users),
+ "data": convert.ToUsers(ctx, ctx.Doer, users),
})
}
@@ -102,7 +102,7 @@ func GetInfo(ctx *context.APIContext) {
ctx.NotFound("GetUserByName", user_model.ErrUserNotExist{Name: ctx.Params(":username")})
return
}
- ctx.JSON(http.StatusOK, convert.ToUser(ctx.ContextUser, ctx.Doer))
+ ctx.JSON(http.StatusOK, convert.ToUser(ctx, ctx.ContextUser, ctx.Doer))
}
// GetAuthenticatedUser get current user's information
@@ -116,7 +116,7 @@ func GetAuthenticatedUser(ctx *context.APIContext) {
// "200":
// "$ref": "#/responses/User"
- ctx.JSON(http.StatusOK, convert.ToUser(ctx.Doer, ctx.Doer))
+ ctx.JSON(http.StatusOK, convert.ToUser(ctx, ctx.Doer, ctx.Doer))
}
// GetUserHeatmapData is the handler to get a users heatmap
diff --git a/routers/common/middleware.go b/routers/common/middleware.go
index 0c7838b0e..4f9d43c36 100644
--- a/routers/common/middleware.go
+++ b/routers/common/middleware.go
@@ -8,6 +8,7 @@ import (
"net/http"
"strings"
+ "code.gitea.io/gitea/modules/cache"
"code.gitea.io/gitea/modules/context"
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/process"
@@ -28,7 +29,7 @@ func Middlewares() []func(http.Handler) http.Handler {
ctx, _, finished := process.GetManager().AddTypedContext(req.Context(), fmt.Sprintf("%s: %s", req.Method, req.RequestURI), process.RequestProcessType, true)
defer finished()
- next.ServeHTTP(context.NewResponse(resp), req.WithContext(ctx))
+ next.ServeHTTP(context.NewResponse(resp), req.WithContext(cache.WithCacheContext(ctx)))
})
},
}
@@ -49,11 +50,11 @@ func Middlewares() []func(http.Handler) http.Handler {
handlers = append(handlers, middleware.StripSlashes)
- if !setting.DisableRouterLog {
+ if !setting.Log.DisableRouterLog {
handlers = append(handlers, routing.NewLoggerHandler())
}
- if setting.EnableAccessLog {
+ if setting.Log.EnableAccessLog {
handlers = append(handlers, context.AccessLogger())
}
diff --git a/routers/init.go b/routers/init.go
index ab2e2a0bb..6a51de669 100644
--- a/routers/init.go
+++ b/routers/init.go
@@ -73,7 +73,7 @@ func mustInitCtx(ctx context.Context, fn func(ctx context.Context) error) {
// InitGitServices init new services for git, this is also called in `contrib/pr/checkout.go`
func InitGitServices() {
- setting.NewServices()
+ setting.LoadSettings()
mustInit(storage.Init)
mustInit(repo_service.Init)
}
@@ -119,7 +119,7 @@ func GlobalInitInstalled(ctx context.Context) {
log.Info("AppPath: %s", setting.AppPath)
log.Info("AppWorkPath: %s", setting.AppWorkPath)
log.Info("Custom path: %s", setting.CustomPath)
- log.Info("Log path: %s", setting.LogRootPath)
+ log.Info("Log path: %s", setting.Log.RootPath)
log.Info("Configuration file: %s", setting.CustomConf)
log.Info("Run Mode: %s", util.ToTitleCase(setting.RunMode))
log.Info("Gitea v%s%s", setting.AppVer, setting.AppBuiltWith)
@@ -127,7 +127,7 @@ func GlobalInitInstalled(ctx context.Context) {
// Setup i18n
translation.InitLocales(ctx)
- setting.NewServices()
+ setting.LoadSettings()
mustInit(storage.Init)
mailer.NewContext(ctx)
diff --git a/routers/install/install.go b/routers/install/install.go
index e9fa844a0..a3d64e5f7 100644
--- a/routers/install/install.go
+++ b/routers/install/install.go
@@ -20,6 +20,7 @@ import (
"code.gitea.io/gitea/models/migrations"
system_model "code.gitea.io/gitea/models/system"
user_model "code.gitea.io/gitea/models/user"
+ "code.gitea.io/gitea/modules/auth/password/hash"
"code.gitea.io/gitea/modules/base"
"code.gitea.io/gitea/modules/context"
"code.gitea.io/gitea/modules/generate"
@@ -79,7 +80,7 @@ func Init(ctx goctx.Context) func(next http.Handler) http.Handler {
"AllLangs": translation.AllLangs(),
"PageStartTime": startTime,
- "PasswordHashAlgorithms": user_model.AvailableHashAlgorithms,
+ "PasswordHashAlgorithms": hash.RecommendedHashAlgorithms,
},
}
defer ctx.Close()
@@ -133,7 +134,7 @@ func Install(ctx *context.Context) {
form.SSHPort = setting.SSH.Port
form.HTTPPort = setting.HTTPPort
form.AppURL = setting.AppURL
- form.LogRootPath = setting.LogRootPath
+ form.LogRootPath = setting.Log.RootPath
// E-mail service settings
if setting.MailService != nil {
@@ -441,11 +442,11 @@ func SubmitInstall(ctx *context.Context) {
cfg.Section("server").Key("OFFLINE_MODE").SetValue(fmt.Sprint(form.OfflineMode))
// if you are reinstalling, this maybe not right because of missing version
- if err := system_model.SetSettingNoVersion(system_model.KeyPictureDisableGravatar, strconv.FormatBool(form.DisableGravatar)); err != nil {
+ if err := system_model.SetSettingNoVersion(ctx, system_model.KeyPictureDisableGravatar, strconv.FormatBool(form.DisableGravatar)); err != nil {
ctx.RenderWithErr(ctx.Tr("install.save_config_failed", err), tplInstall, &form)
return
}
- if err := system_model.SetSettingNoVersion(system_model.KeyPictureEnableFederatedAvatar, strconv.FormatBool(form.EnableFederatedAvatar)); err != nil {
+ if err := system_model.SetSettingNoVersion(ctx, system_model.KeyPictureEnableFederatedAvatar, strconv.FormatBool(form.EnableFederatedAvatar)); err != nil {
ctx.RenderWithErr(ctx.Tr("install.save_config_failed", err), tplInstall, &form)
return
}
@@ -466,7 +467,7 @@ func SubmitInstall(ctx *context.Context) {
cfg.Section("session").Key("PROVIDER").SetValue("file")
cfg.Section("log").Key("MODE").SetValue("console")
- cfg.Section("log").Key("LEVEL").SetValue(setting.LogLevel.String())
+ cfg.Section("log").Key("LEVEL").SetValue(setting.Log.Level.String())
cfg.Section("log").Key("ROOT_PATH").SetValue(form.LogRootPath)
cfg.Section("log").Key("ROUTER").SetValue("console")
diff --git a/routers/install/setting.go b/routers/install/setting.go
index b76219f45..68984f1e7 100644
--- a/routers/install/setting.go
+++ b/routers/install/setting.go
@@ -15,20 +15,21 @@ import (
// PreloadSettings preloads the configuration to check if we need to run install
func PreloadSettings(ctx context.Context) bool {
- setting.LoadAllowEmpty()
+ setting.InitProviderAllowEmpty()
+ setting.LoadCommonSettings()
if !setting.InstallLock {
log.Info("AppPath: %s", setting.AppPath)
log.Info("AppWorkPath: %s", setting.AppWorkPath)
log.Info("Custom path: %s", setting.CustomPath)
- log.Info("Log path: %s", setting.LogRootPath)
+ log.Info("Log path: %s", setting.Log.RootPath)
log.Info("Configuration file: %s", setting.CustomConf)
log.Info("Prepare to run install page")
translation.InitLocales(ctx)
if setting.EnableSQLite3 {
log.Info("SQLite3 is supported")
}
- setting.InitDBConfig()
- setting.NewServicesForInstall()
+
+ setting.LoadSettingsForInstall()
svg.Init()
}
@@ -37,8 +38,9 @@ func PreloadSettings(ctx context.Context) bool {
// reloadSettings reloads the existing settings and starts up the database
func reloadSettings(ctx context.Context) {
- setting.LoadFromExisting()
- setting.InitDBConfig()
+ setting.InitProviderFromExistingFile()
+ setting.LoadCommonSettings()
+ setting.LoadDBSetting()
if setting.InstallLock {
if err := common.InitDBEngine(ctx); err == nil {
log.Info("ORM engine initialization successful!")
diff --git a/routers/private/hook_verification.go b/routers/private/hook_verification.go
index 7b9550dfd..8ccde4f3d 100644
--- a/routers/private/hook_verification.go
+++ b/routers/private/hook_verification.go
@@ -101,7 +101,7 @@ func readAndVerifyCommit(sha string, repo *git.Repository, env []string) error {
if err != nil {
return err
}
- verification := asymkey_model.ParseCommitWithSignature(commit)
+ verification := asymkey_model.ParseCommitWithSignature(ctx, commit)
if !verification.Verified {
cancel()
return &errUnverifiedCommit{
diff --git a/routers/private/manager.go b/routers/private/manager.go
index f15da298d..a56fe9d12 100644
--- a/routers/private/manager.go
+++ b/routers/private/manager.go
@@ -116,11 +116,11 @@ func AddLogger(ctx *context.PrivateContext) {
}
if _, ok := opts.Config["level"]; !ok {
- opts.Config["level"] = setting.LogLevel
+ opts.Config["level"] = setting.Log.Level
}
if _, ok := opts.Config["stacktraceLevel"]; !ok {
- opts.Config["stacktraceLevel"] = setting.StacktraceLogLevel
+ opts.Config["stacktraceLevel"] = setting.Log.StacktraceLogLevel
}
if opts.Mode == "file" {
@@ -135,7 +135,7 @@ func AddLogger(ctx *context.PrivateContext) {
}
}
- bufferLen := setting.Cfg.Section("log").Key("BUFFER_LEN").MustInt64(10000)
+ bufferLen := setting.Log.BufferLength
byteConfig, err := json.Marshal(opts.Config)
if err != nil {
log.Error("Failed to marshal log configuration: %v %v", opts.Config, err)
diff --git a/routers/private/ssh_log.go b/routers/private/ssh_log.go
index 54604ad55..eacfa18f0 100644
--- a/routers/private/ssh_log.go
+++ b/routers/private/ssh_log.go
@@ -15,7 +15,7 @@ import (
// SSHLog hook to response ssh log
func SSHLog(ctx *context.PrivateContext) {
- if !setting.EnableSSHLog {
+ if !setting.Log.EnableSSHLog {
ctx.Status(http.StatusOK)
return
}
diff --git a/routers/web/admin/config.go b/routers/web/admin/config.go
index 1f71e8178..2566cbe42 100644
--- a/routers/web/admin/config.go
+++ b/routers/web/admin/config.go
@@ -117,7 +117,7 @@ func Config(ctx *context.Context) {
ctx.Data["AppUrl"] = setting.AppURL
ctx.Data["Domain"] = setting.Domain
ctx.Data["OfflineMode"] = setting.OfflineMode
- ctx.Data["DisableRouterLog"] = setting.DisableRouterLog
+ ctx.Data["DisableRouterLog"] = setting.Log.DisableRouterLog
ctx.Data["RunUser"] = setting.RunUser
ctx.Data["RunMode"] = util.ToTitleCase(setting.RunMode)
ctx.Data["GitVersion"] = git.VersionInfo()
@@ -125,7 +125,7 @@ func Config(ctx *context.Context) {
ctx.Data["RepoRootPath"] = setting.RepoRootPath
ctx.Data["CustomRootPath"] = setting.CustomPath
ctx.Data["StaticRootPath"] = setting.StaticRootPath
- ctx.Data["LogRootPath"] = setting.LogRootPath
+ ctx.Data["LogRootPath"] = setting.Log.RootPath
ctx.Data["ScriptType"] = setting.ScriptType
ctx.Data["ReverseProxyAuthUser"] = setting.ReverseProxyAuthUser
ctx.Data["ReverseProxyAuthEmail"] = setting.ReverseProxyAuthEmail
@@ -183,10 +183,10 @@ func Config(ctx *context.Context) {
ctx.Data["EnvVars"] = envVars
ctx.Data["Loggers"] = setting.GetLogDescriptions()
- ctx.Data["EnableAccessLog"] = setting.EnableAccessLog
- ctx.Data["AccessLogTemplate"] = setting.AccessLogTemplate
- ctx.Data["DisableRouterLog"] = setting.DisableRouterLog
- ctx.Data["EnableXORMLog"] = setting.EnableXORMLog
+ ctx.Data["EnableAccessLog"] = setting.Log.EnableAccessLog
+ ctx.Data["AccessLogTemplate"] = setting.Log.AccessLogTemplate
+ ctx.Data["DisableRouterLog"] = setting.Log.DisableRouterLog
+ ctx.Data["EnableXORMLog"] = setting.Log.EnableXORMLog
ctx.Data["LogSQL"] = setting.Database.LogSQL
ctx.HTML(http.StatusOK, tplConfig)
@@ -213,7 +213,7 @@ func ChangeConfig(ctx *context.Context) {
}
}
- if err := system_model.SetSetting(&system_model.Setting{
+ if err := system_model.SetSetting(ctx, &system_model.Setting{
SettingKey: key,
SettingValue: value,
Version: version,
diff --git a/routers/web/admin/users.go b/routers/web/admin/users.go
index 38969dada..1bb9d0480 100644
--- a/routers/web/admin/users.go
+++ b/routers/web/admin/users.go
@@ -14,10 +14,10 @@ import (
"code.gitea.io/gitea/models/auth"
"code.gitea.io/gitea/models/db"
user_model "code.gitea.io/gitea/models/user"
+ "code.gitea.io/gitea/modules/auth/password"
"code.gitea.io/gitea/modules/base"
"code.gitea.io/gitea/modules/context"
"code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/password"
"code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/modules/util"
"code.gitea.io/gitea/modules/web"
diff --git a/routers/web/auth/auth.go b/routers/web/auth/auth.go
index 48b7dc686..5fba63281 100644
--- a/routers/web/auth/auth.go
+++ b/routers/web/auth/auth.go
@@ -13,11 +13,11 @@ import (
"code.gitea.io/gitea/models/auth"
"code.gitea.io/gitea/models/db"
user_model "code.gitea.io/gitea/models/user"
+ "code.gitea.io/gitea/modules/auth/password"
"code.gitea.io/gitea/modules/base"
"code.gitea.io/gitea/modules/context"
"code.gitea.io/gitea/modules/eventsource"
"code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/password"
"code.gitea.io/gitea/modules/session"
"code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/modules/timeutil"
diff --git a/routers/web/auth/linkaccount.go b/routers/web/auth/linkaccount.go
index 47a0daa06..865bcca15 100644
--- a/routers/web/auth/linkaccount.go
+++ b/routers/web/auth/linkaccount.go
@@ -59,7 +59,7 @@ func LinkAccount(ctx *context.Context) {
ctx.Data["email"] = email
if len(email) != 0 {
- u, err := user_model.GetUserByEmail(email)
+ u, err := user_model.GetUserByEmail(ctx, email)
if err != nil && !user_model.IsErrUserNotExist(err) {
ctx.ServerError("UserSignIn", err)
return
diff --git a/routers/web/auth/oauth.go b/routers/web/auth/oauth.go
index a11417da1..7de63dbe9 100644
--- a/routers/web/auth/oauth.go
+++ b/routers/web/auth/oauth.go
@@ -225,7 +225,7 @@ func newAccessTokenResponse(ctx stdContext.Context, grant *auth.OAuth2Grant, ser
idToken.Name = user.GetDisplayName()
idToken.PreferredUsername = user.Name
idToken.Profile = user.HTMLURL()
- idToken.Picture = user.AvatarLink()
+ idToken.Picture = user.AvatarLink(ctx)
idToken.Website = user.Website
idToken.Locale = user.Language
idToken.UpdatedAt = user.UpdatedUnix
@@ -286,7 +286,7 @@ func InfoOAuth(ctx *context.Context) {
Name: ctx.Doer.FullName,
Username: ctx.Doer.Name,
Email: ctx.Doer.Email,
- Picture: ctx.Doer.AvatarLink(),
+ Picture: ctx.Doer.AvatarLink(ctx),
}
groups, err := getOAuthGroupsForUser(ctx.Doer)
diff --git a/routers/web/auth/oauth_test.go b/routers/web/auth/oauth_test.go
index 5116b4fc7..62f723600 100644
--- a/routers/web/auth/oauth_test.go
+++ b/routers/web/auth/oauth_test.go
@@ -69,7 +69,7 @@ func TestNewAccessTokenResponse_OIDCToken(t *testing.T) {
assert.Equal(t, user.Name, oidcToken.Name)
assert.Equal(t, user.Name, oidcToken.PreferredUsername)
assert.Equal(t, user.HTMLURL(), oidcToken.Profile)
- assert.Equal(t, user.AvatarLink(), oidcToken.Picture)
+ assert.Equal(t, user.AvatarLink(db.DefaultContext), oidcToken.Picture)
assert.Equal(t, user.Website, oidcToken.Website)
assert.Equal(t, user.UpdatedUnix, oidcToken.UpdatedAt)
assert.Equal(t, user.Email, oidcToken.Email)
@@ -87,7 +87,7 @@ func TestNewAccessTokenResponse_OIDCToken(t *testing.T) {
assert.Equal(t, user.FullName, oidcToken.Name)
assert.Equal(t, user.Name, oidcToken.PreferredUsername)
assert.Equal(t, user.HTMLURL(), oidcToken.Profile)
- assert.Equal(t, user.AvatarLink(), oidcToken.Picture)
+ assert.Equal(t, user.AvatarLink(db.DefaultContext), oidcToken.Picture)
assert.Equal(t, user.Website, oidcToken.Website)
assert.Equal(t, user.UpdatedUnix, oidcToken.UpdatedAt)
assert.Equal(t, user.Email, oidcToken.Email)
diff --git a/routers/web/auth/openid.go b/routers/web/auth/openid.go
index f544b6535..aff2e5f78 100644
--- a/routers/web/auth/openid.go
+++ b/routers/web/auth/openid.go
@@ -197,7 +197,7 @@ func signInOpenIDVerify(ctx *context.Context) {
log.Trace("User has email=%s and nickname=%s", email, nickname)
if email != "" {
- u, err = user_model.GetUserByEmail(email)
+ u, err = user_model.GetUserByEmail(ctx, email)
if err != nil {
if !user_model.IsErrUserNotExist(err) {
ctx.RenderWithErr(err.Error(), tplSignInOpenID, &forms.SignInOpenIDForm{
diff --git a/routers/web/auth/password.go b/routers/web/auth/password.go
index e546c77bc..a5aa9c534 100644
--- a/routers/web/auth/password.go
+++ b/routers/web/auth/password.go
@@ -9,10 +9,10 @@ import (
"code.gitea.io/gitea/models/auth"
user_model "code.gitea.io/gitea/models/user"
+ "code.gitea.io/gitea/modules/auth/password"
"code.gitea.io/gitea/modules/base"
"code.gitea.io/gitea/modules/context"
"code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/password"
"code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/modules/timeutil"
"code.gitea.io/gitea/modules/web"
@@ -59,7 +59,7 @@ func ForgotPasswdPost(ctx *context.Context) {
email := ctx.FormString("email")
ctx.Data["Email"] = email
- u, err := user_model.GetUserByEmail(email)
+ u, err := user_model.GetUserByEmail(ctx, email)
if err != nil {
if user_model.IsErrUserNotExist(err) {
ctx.Data["ResetPwdCodeLives"] = timeutil.MinutesToFriendly(setting.Service.ResetPwdCodeLives, ctx.Locale)
diff --git a/routers/web/org/org_labels.go b/routers/web/org/org_labels.go
index 1c910a93a..e96627762 100644
--- a/routers/web/org/org_labels.go
+++ b/routers/web/org/org_labels.go
@@ -45,6 +45,7 @@ func NewLabel(ctx *context.Context) {
l := &issues_model.Label{
OrgID: ctx.Org.Organization.ID,
Name: form.Title,
+ Exclusive: form.Exclusive,
Description: form.Description,
Color: form.Color,
}
@@ -70,6 +71,7 @@ func UpdateLabel(ctx *context.Context) {
}
l.Name = form.Title
+ l.Exclusive = form.Exclusive
l.Description = form.Description
l.Color = form.Color
if err := issues_model.UpdateLabel(l); err != nil {
diff --git a/routers/web/org/projects.go b/routers/web/org/projects.go
index 1ce44d486..6449d12de 100644
--- a/routers/web/org/projects.go
+++ b/routers/web/org/projects.go
@@ -121,7 +121,7 @@ func canWriteUnit(ctx *context.Context) bool {
// NewProject render creating a project page
func NewProject(ctx *context.Context) {
ctx.Data["Title"] = ctx.Tr("repo.projects.new")
- ctx.Data["ProjectTypes"] = project_model.GetProjectsConfig()
+ ctx.Data["BoardTypes"] = project_model.GetBoardConfig()
ctx.Data["CanWriteProjects"] = canWriteUnit(ctx)
ctx.Data["HomeLink"] = ctx.ContextUser.HomeLink()
shared_user.RenderUserHeader(ctx)
@@ -137,7 +137,7 @@ func NewProjectPost(ctx *context.Context) {
if ctx.HasError() {
ctx.Data["CanWriteProjects"] = canWriteUnit(ctx)
ctx.Data["PageIsViewProjects"] = true
- ctx.Data["ProjectTypes"] = project_model.GetProjectsConfig()
+ ctx.Data["BoardTypes"] = project_model.GetBoardConfig()
ctx.HTML(http.StatusOK, tplProjectsNew)
return
}
diff --git a/routers/web/org/teams.go b/routers/web/org/teams.go
index d9754633b..1ed798014 100644
--- a/routers/web/org/teams.go
+++ b/routers/web/org/teams.go
@@ -401,7 +401,7 @@ func SearchTeam(ctx *context.Context) {
return
}
- apiTeams, err := convert.ToTeams(teams, false)
+ apiTeams, err := convert.ToTeams(ctx, teams, false)
if err != nil {
log.Error("convert ToTeams failed: %v", err)
ctx.JSON(http.StatusInternalServerError, map[string]interface{}{
diff --git a/routers/web/repo/actions/actions.go b/routers/web/repo/actions/actions.go
index 146bf27da..e5496676a 100644
--- a/routers/web/repo/actions/actions.go
+++ b/routers/web/repo/actions/actions.go
@@ -70,7 +70,7 @@ func List(ctx *context.Context) {
}
ctx.Data["workflows"] = workflows
- ctx.Data["RepoLink"] = ctx.Repo.Repository.HTMLURL()
+ ctx.Data["RepoLink"] = ctx.Repo.Repository.Link()
page := ctx.FormInt("page")
if page <= 0 {
diff --git a/routers/web/repo/blame.go b/routers/web/repo/blame.go
index def7cfcad..3546334ed 100644
--- a/routers/web/repo/blame.go
+++ b/routers/web/repo/blame.go
@@ -199,7 +199,7 @@ func processBlameParts(ctx *context.Context, blameParts []git.BlamePart) (map[st
}
// populate commit email addresses to later look up avatars.
- for _, c := range user_model.ValidateCommitsWithEmails(commits) {
+ for _, c := range user_model.ValidateCommitsWithEmails(ctx, commits) {
commitNames[c.ID.String()] = c
}
@@ -262,9 +262,9 @@ func renderBlame(ctx *context.Context, blameParts []git.BlamePart, commitNames m
var avatar string
if commit.User != nil {
- avatar = string(templates.Avatar(commit.User, 18, "mr-3"))
+ avatar = string(templates.Avatar(ctx, commit.User, 18, "gt-mr-3"))
} else {
- avatar = string(templates.AvatarByEmail(commit.Author.Email, commit.Author.Name, 18, "mr-3"))
+ avatar = string(templates.AvatarByEmail(ctx, commit.Author.Email, commit.Author.Name, 18, "gt-mr-3"))
}
br.Avatar = gotemplate.HTML(avatar)
diff --git a/routers/web/repo/commit.go b/routers/web/repo/commit.go
index 9f94159d0..843b1d8df 100644
--- a/routers/web/repo/commit.go
+++ b/routers/web/repo/commit.go
@@ -138,7 +138,7 @@ func Graph(ctx *context.Context) {
return
}
- if err := graph.LoadAndProcessCommits(ctx.Repo.Repository, ctx.Repo.GitRepo); err != nil {
+ if err := graph.LoadAndProcessCommits(ctx, ctx.Repo.Repository, ctx.Repo.GitRepo); err != nil {
ctx.ServerError("LoadAndProcessCommits", err)
return
}
@@ -343,9 +343,9 @@ func Diff(ctx *context.Context) {
ctx.Data["CommitStatus"] = git_model.CalcCommitStatus(statuses)
ctx.Data["CommitStatuses"] = statuses
- verification := asymkey_model.ParseCommitWithSignature(commit)
+ verification := asymkey_model.ParseCommitWithSignature(ctx, commit)
ctx.Data["Verification"] = verification
- ctx.Data["Author"] = user_model.ValidateCommitWithEmail(commit)
+ ctx.Data["Author"] = user_model.ValidateCommitWithEmail(ctx, commit)
ctx.Data["Parents"] = parents
ctx.Data["DiffNotAvailable"] = diff.NumFiles == 0
@@ -361,7 +361,7 @@ func Diff(ctx *context.Context) {
if err == nil {
ctx.Data["Note"] = string(charset.ToUTF8WithFallback(note.Message))
ctx.Data["NoteCommit"] = note.Commit
- ctx.Data["NoteAuthor"] = user_model.ValidateCommitWithEmail(note.Commit)
+ ctx.Data["NoteAuthor"] = user_model.ValidateCommitWithEmail(ctx, note.Commit)
}
ctx.Data["BranchName"], err = commit.GetBranchName()
diff --git a/routers/web/repo/compare.go b/routers/web/repo/compare.go
index c4b8c814e..f21611c63 100644
--- a/routers/web/repo/compare.go
+++ b/routers/web/repo/compare.go
@@ -43,8 +43,8 @@ const (
)
// setCompareContext sets context data.
-func setCompareContext(ctx *context.Context, base, head *git.Commit, headOwner, headName string) {
- ctx.Data["BaseCommit"] = base
+func setCompareContext(ctx *context.Context, before, head *git.Commit, headOwner, headName string) {
+ ctx.Data["BeforeCommit"] = before
ctx.Data["HeadCommit"] = head
ctx.Data["GetBlobByPathForCommit"] = func(commit *git.Commit, path string) *git.Blob {
@@ -59,7 +59,7 @@ func setCompareContext(ctx *context.Context, base, head *git.Commit, headOwner,
return blob
}
- setPathsCompareContext(ctx, base, head, headOwner, headName)
+ setPathsCompareContext(ctx, before, head, headOwner, headName)
setImageCompareContext(ctx)
setCsvCompareContext(ctx)
}
@@ -279,7 +279,7 @@ func ParseCompareInfo(ctx *context.Context) *CompareInfo {
}
return nil
}
- if err := ci.HeadRepo.GetOwner(ctx); err != nil {
+ if err := ci.HeadRepo.LoadOwner(ctx); err != nil {
if user_model.IsErrUserNotExist(err) {
ctx.NotFound("GetUserByName", nil)
} else {
@@ -629,9 +629,8 @@ func PrepareCompareDiff(
}
baseGitRepo := ctx.Repo.GitRepo
- baseCommitID := ci.CompareInfo.BaseCommitID
- baseCommit, err := baseGitRepo.GetCommit(baseCommitID)
+ beforeCommit, err := baseGitRepo.GetCommit(beforeCommitID)
if err != nil {
ctx.ServerError("GetCommit", err)
return false
@@ -668,7 +667,7 @@ func PrepareCompareDiff(
ctx.Data["Username"] = ci.HeadUser.Name
ctx.Data["Reponame"] = ci.HeadRepo.Name
- setCompareContext(ctx, baseCommit, headCommit, ci.HeadUser.Name, repo.Name)
+ setCompareContext(ctx, beforeCommit, headCommit, ci.HeadUser.Name, repo.Name)
return false
}
@@ -820,6 +819,13 @@ func CompareDiff(ctx *context.Context) {
ctx.Data["HasIssuesOrPullsWritePermission"] = ctx.Repo.CanWrite(unit.TypePullRequests)
+ if unit, err := ctx.Repo.Repository.GetUnit(ctx, unit.TypePullRequests); err == nil {
+ config := unit.PullRequestsConfig()
+ ctx.Data["AllowMaintainerEdit"] = config.DefaultAllowMaintainerEdit
+ } else {
+ ctx.Data["AllowMaintainerEdit"] = false
+ }
+
ctx.HTML(http.StatusOK, tplCompare)
}
diff --git a/routers/web/repo/http.go b/routers/web/repo/http.go
index e82b94b9e..9d4ffccc6 100644
--- a/routers/web/repo/http.go
+++ b/routers/web/repo/http.go
@@ -146,8 +146,8 @@ func httpBase(ctx *context.Context) (h *serviceHandler) {
// don't allow anonymous pulls if organization is not public
if isPublicPull {
- if err := repo.GetOwner(ctx); err != nil {
- ctx.ServerError("GetOwner", err)
+ if err := repo.LoadOwner(ctx); err != nil {
+ ctx.ServerError("LoadOwner", err)
return
}
diff --git a/routers/web/repo/issue.go b/routers/web/repo/issue.go
index e6a416234..d740b9344 100644
--- a/routers/web/repo/issue.go
+++ b/routers/web/repo/issue.go
@@ -100,7 +100,7 @@ func MustAllowUserComment(ctx *context.Context) {
if issue.IsLocked && !ctx.Repo.CanWriteIssuesOrPulls(issue.IsPull) && !ctx.Doer.IsAdmin {
ctx.Flash.Error(ctx.Tr("repo.issues.comment_on_locked"))
- ctx.Redirect(issue.HTMLURL())
+ ctx.Redirect(issue.Link())
return
}
}
@@ -332,8 +332,24 @@ func issues(ctx *context.Context, milestoneID, projectID int64, isPullOption uti
labels = append(labels, orgLabels...)
}
+ // Get the exclusive scope for every label ID
+ labelExclusiveScopes := make([]string, 0, len(labelIDs))
+ for _, labelID := range labelIDs {
+ foundExclusiveScope := false
+ for _, label := range labels {
+ if label.ID == labelID || label.ID == -labelID {
+ labelExclusiveScopes = append(labelExclusiveScopes, label.ExclusiveScope())
+ foundExclusiveScope = true
+ break
+ }
+ }
+ if !foundExclusiveScope {
+ labelExclusiveScopes = append(labelExclusiveScopes, "")
+ }
+ }
+
for _, l := range labels {
- l.LoadSelectedLabelsAfterClick(labelIDs)
+ l.LoadSelectedLabelsAfterClick(labelIDs, labelExclusiveScopes)
}
ctx.Data["Labels"] = labels
ctx.Data["NumLabels"] = len(labels)
@@ -927,7 +943,7 @@ func NewIssueChooseTemplate(ctx *context.Context) {
if len(issueTemplates) == 0 {
// The "issues/new" and "issues/new/choose" share the same query parameters "project" and "milestone", if no template here, just redirect to the "issues/new" page with these parameters.
- ctx.Redirect(fmt.Sprintf("%s/issues/new?%s", ctx.Repo.Repository.HTMLURL(), ctx.Req.URL.RawQuery), http.StatusSeeOther)
+ ctx.Redirect(fmt.Sprintf("%s/issues/new?%s", ctx.Repo.Repository.Link(), ctx.Req.URL.RawQuery), http.StatusSeeOther)
return
}
@@ -950,11 +966,11 @@ func DeleteIssue(ctx *context.Context) {
}
if issue.IsPull {
- ctx.Redirect(fmt.Sprintf("%s/pulls", ctx.Repo.Repository.HTMLURL()), http.StatusSeeOther)
+ ctx.Redirect(fmt.Sprintf("%s/pulls", ctx.Repo.Repository.Link()), http.StatusSeeOther)
return
}
- ctx.Redirect(fmt.Sprintf("%s/issues", ctx.Repo.Repository.HTMLURL()), http.StatusSeeOther)
+ ctx.Redirect(fmt.Sprintf("%s/issues", ctx.Repo.Repository.Link()), http.StatusSeeOther)
}
// ValidateRepoMetas check and returns repository's meta information
@@ -1142,7 +1158,11 @@ func NewIssuePost(ctx *context.Context) {
}
// roleDescriptor returns the Role Descriptor for a comment in/with the given repo, poster and issue
-func roleDescriptor(ctx stdCtx.Context, repo *repo_model.Repository, poster *user_model.User, issue *issues_model.Issue) (issues_model.RoleDescriptor, error) {
+func roleDescriptor(ctx stdCtx.Context, repo *repo_model.Repository, poster *user_model.User, issue *issues_model.Issue, hasOriginalAuthor bool) (issues_model.RoleDescriptor, error) {
+ if hasOriginalAuthor {
+ return issues_model.RoleDescriptorNone, nil
+ }
+
perm, err := access_model.GetUserRepoPermission(ctx, repo, poster)
if err != nil {
return issues_model.RoleDescriptorNone, err
@@ -1425,7 +1445,7 @@ func ViewIssue(ctx *context.Context) {
return
}
// Add link to the issue of the already running stopwatch
- ctx.Data["OtherStopwatchURL"] = otherIssue.HTMLURL()
+ ctx.Data["OtherStopwatchURL"] = otherIssue.Link()
}
}
ctx.Data["CanUseTimetracker"] = ctx.Repo.CanUseTimetracker(issue, ctx.Doer)
@@ -1444,7 +1464,7 @@ func ViewIssue(ctx *context.Context) {
// check if dependencies can be created across repositories
ctx.Data["AllowCrossRepositoryDependencies"] = setting.Service.AllowCrossRepositoryDependencies
- if issue.ShowRole, err = roleDescriptor(ctx, repo, issue.Poster, issue); err != nil {
+ if issue.ShowRole, err = roleDescriptor(ctx, repo, issue.Poster, issue, issue.HasOriginalAuthor()); err != nil {
ctx.ServerError("roleDescriptor", err)
return
}
@@ -1483,7 +1503,7 @@ func ViewIssue(ctx *context.Context) {
continue
}
- comment.ShowRole, err = roleDescriptor(ctx, repo, comment.Poster, issue)
+ comment.ShowRole, err = roleDescriptor(ctx, repo, comment.Poster, issue, comment.HasOriginalAuthor())
if err != nil {
ctx.ServerError("roleDescriptor", err)
return
@@ -1582,7 +1602,7 @@ func ViewIssue(ctx *context.Context) {
continue
}
- c.ShowRole, err = roleDescriptor(ctx, repo, c.Poster, issue)
+ c.ShowRole, err = roleDescriptor(ctx, repo, c.Poster, issue, c.HasOriginalAuthor())
if err != nil {
ctx.ServerError("roleDescriptor", err)
return
@@ -2153,8 +2173,8 @@ func UpdatePullReviewRequest(ctx *context.Context) {
}
if reviewID < 0 {
// negative reviewIDs represent team requests
- if err := issue.Repo.GetOwner(ctx); err != nil {
- ctx.ServerError("issue.Repo.GetOwner", err)
+ if err := issue.Repo.LoadOwner(ctx); err != nil {
+ ctx.ServerError("issue.Repo.LoadOwner", err)
return
}
@@ -2658,7 +2678,7 @@ func NewComment(ctx *context.Context) {
if issue.IsLocked && !ctx.Repo.CanWriteIssuesOrPulls(issue.IsPull) && !ctx.Doer.IsAdmin {
ctx.Flash.Error(ctx.Tr("repo.issues.comment_on_locked"))
- ctx.Redirect(issue.HTMLURL())
+ ctx.Redirect(issue.Link())
return
}
@@ -2669,7 +2689,7 @@ func NewComment(ctx *context.Context) {
if ctx.HasError() {
ctx.Flash.Error(ctx.Data["ErrorMsg"].(string))
- ctx.Redirect(issue.HTMLURL())
+ ctx.Redirect(issue.Link())
return
}
@@ -3272,5 +3292,5 @@ func handleTeamMentions(ctx *context.Context) {
ctx.Data["MentionableTeams"] = teams
ctx.Data["MentionableTeamsOrg"] = ctx.Repo.Owner.Name
- ctx.Data["MentionableTeamsOrgAvatar"] = ctx.Repo.Owner.AvatarLink()
+ ctx.Data["MentionableTeamsOrgAvatar"] = ctx.Repo.Owner.AvatarLink(ctx)
}
diff --git a/routers/web/repo/issue_content_history.go b/routers/web/repo/issue_content_history.go
index 3e6b31f8f..7e5295e75 100644
--- a/routers/web/repo/issue_content_history.go
+++ b/routers/web/repo/issue_content_history.go
@@ -71,7 +71,7 @@ func GetContentHistoryList(ctx *context.Context) {
}
src := html.EscapeString(item.UserAvatarLink)
- class := avatars.DefaultAvatarClass + " mr-3"
+ class := avatars.DefaultAvatarClass + " gt-mr-3"
name := html.EscapeString(username)
avatarHTML := string(templates.AvatarHTML(src, 28, class, username))
timeSinceText := string(timeutil.TimeSinceUnix(item.EditedUnix, ctx.Locale))
diff --git a/routers/web/repo/issue_dependency.go b/routers/web/repo/issue_dependency.go
index 41c127be9..365d9609d 100644
--- a/routers/web/repo/issue_dependency.go
+++ b/routers/web/repo/issue_dependency.go
@@ -34,7 +34,7 @@ func AddDependency(ctx *context.Context) {
}
// Redirect
- defer ctx.Redirect(issue.HTMLURL())
+ defer ctx.Redirect(issue.Link())
// Dependency
dep, err := issues_model.GetIssueByID(ctx, depID)
@@ -124,5 +124,5 @@ func RemoveDependency(ctx *context.Context) {
}
// Redirect
- ctx.Redirect(issue.HTMLURL())
+ ctx.Redirect(issue.Link())
}
diff --git a/routers/web/repo/issue_label.go b/routers/web/repo/issue_label.go
index 66e8920bd..d4fece9f0 100644
--- a/routers/web/repo/issue_label.go
+++ b/routers/web/repo/issue_label.go
@@ -113,6 +113,7 @@ func NewLabel(ctx *context.Context) {
l := &issues_model.Label{
RepoID: ctx.Repo.Repository.ID,
Name: form.Title,
+ Exclusive: form.Exclusive,
Description: form.Description,
Color: form.Color,
}
@@ -138,6 +139,7 @@ func UpdateLabel(ctx *context.Context) {
}
l.Name = form.Title
+ l.Exclusive = form.Exclusive
l.Description = form.Description
l.Color = form.Color
if err := issues_model.UpdateLabel(l); err != nil {
@@ -175,7 +177,7 @@ func UpdateIssueLabel(ctx *context.Context) {
return
}
}
- case "attach", "detach", "toggle":
+ case "attach", "detach", "toggle", "toggle-alt":
label, err := issues_model.GetLabelByID(ctx, ctx.FormInt64("id"))
if err != nil {
if issues_model.IsErrRepoLabelNotExist(err) {
@@ -189,12 +191,18 @@ func UpdateIssueLabel(ctx *context.Context) {
if action == "toggle" {
// detach if any issues already have label, otherwise attach
action = "attach"
- for _, issue := range issues {
- if issues_model.HasIssueLabel(ctx, issue.ID, label.ID) {
- action = "detach"
- break
+ if label.ExclusiveScope() == "" {
+ for _, issue := range issues {
+ if issues_model.HasIssueLabel(ctx, issue.ID, label.ID) {
+ action = "detach"
+ break
+ }
}
}
+ } else if action == "toggle-alt" {
+ // always detach with alt key pressed, to be able to remove
+ // scoped labels
+ action = "detach"
}
if action == "attach" {
diff --git a/routers/web/repo/issue_lock.go b/routers/web/repo/issue_lock.go
index 10db968a2..08b76e555 100644
--- a/routers/web/repo/issue_lock.go
+++ b/routers/web/repo/issue_lock.go
@@ -21,13 +21,13 @@ func LockIssue(ctx *context.Context) {
if issue.IsLocked {
ctx.Flash.Error(ctx.Tr("repo.issues.lock_duplicate"))
- ctx.Redirect(issue.HTMLURL())
+ ctx.Redirect(issue.Link())
return
}
if !form.HasValidReason() {
ctx.Flash.Error(ctx.Tr("repo.issues.lock.unknown_reason"))
- ctx.Redirect(issue.HTMLURL())
+ ctx.Redirect(issue.Link())
return
}
@@ -40,7 +40,7 @@ func LockIssue(ctx *context.Context) {
return
}
- ctx.Redirect(issue.HTMLURL())
+ ctx.Redirect(issue.Link())
}
// UnlockIssue unlocks a previously locked issue.
@@ -52,7 +52,7 @@ func UnlockIssue(ctx *context.Context) {
if !issue.IsLocked {
ctx.Flash.Error(ctx.Tr("repo.issues.unlock_error"))
- ctx.Redirect(issue.HTMLURL())
+ ctx.Redirect(issue.Link())
return
}
@@ -64,5 +64,5 @@ func UnlockIssue(ctx *context.Context) {
return
}
- ctx.Redirect(issue.HTMLURL())
+ ctx.Redirect(issue.Link())
}
diff --git a/routers/web/repo/issue_stopwatch.go b/routers/web/repo/issue_stopwatch.go
index d2a7a12a1..3d20b08b4 100644
--- a/routers/web/repo/issue_stopwatch.go
+++ b/routers/web/repo/issue_stopwatch.go
@@ -40,7 +40,7 @@ func IssueStopwatch(c *context.Context) {
c.Flash.Success(c.Tr("repo.issues.tracker_auto_close"))
}
- url := issue.HTMLURL()
+ url := issue.Link()
c.Redirect(url, http.StatusSeeOther)
}
@@ -72,7 +72,7 @@ func CancelStopwatch(c *context.Context) {
})
}
- url := issue.HTMLURL()
+ url := issue.Link()
c.Redirect(url, http.StatusSeeOther)
}
diff --git a/routers/web/repo/issue_timetrack.go b/routers/web/repo/issue_timetrack.go
index 6e9d3673c..7dc7d0797 100644
--- a/routers/web/repo/issue_timetrack.go
+++ b/routers/web/repo/issue_timetrack.go
@@ -26,7 +26,7 @@ func AddTimeManually(c *context.Context) {
c.NotFound("CanUseTimetracker", nil)
return
}
- url := issue.HTMLURL()
+ url := issue.Link()
if c.HasError() {
c.Flash.Error(c.GetErrMsg())
@@ -83,5 +83,5 @@ func DeleteTime(c *context.Context) {
}
c.Flash.Success(c.Tr("repo.issues.del_time_history", util.SecToTime(t.Time)))
- c.Redirect(issue.HTMLURL())
+ c.Redirect(issue.Link())
}
diff --git a/routers/web/repo/issue_watch.go b/routers/web/repo/issue_watch.go
index c23dbf062..1837c2b63 100644
--- a/routers/web/repo/issue_watch.go
+++ b/routers/web/repo/issue_watch.go
@@ -52,5 +52,5 @@ func IssueWatch(ctx *context.Context) {
return
}
- ctx.Redirect(issue.HTMLURL())
+ ctx.Redirect(issue.Link())
}
diff --git a/routers/web/repo/projects.go b/routers/web/repo/projects.go
index 3becf799c..967b81c60 100644
--- a/routers/web/repo/projects.go
+++ b/routers/web/repo/projects.go
@@ -13,6 +13,7 @@ import (
issues_model "code.gitea.io/gitea/models/issues"
"code.gitea.io/gitea/models/perm"
project_model "code.gitea.io/gitea/models/project"
+ attachment_model "code.gitea.io/gitea/models/repo"
"code.gitea.io/gitea/models/unit"
"code.gitea.io/gitea/modules/base"
"code.gitea.io/gitea/modules/context"
@@ -123,7 +124,8 @@ func Projects(ctx *context.Context) {
// NewProject render creating a project page
func NewProject(ctx *context.Context) {
ctx.Data["Title"] = ctx.Tr("repo.projects.new")
- ctx.Data["ProjectTypes"] = project_model.GetProjectsConfig()
+ ctx.Data["BoardTypes"] = project_model.GetBoardConfig()
+ ctx.Data["CardTypes"] = project_model.GetCardConfig()
ctx.Data["CanWriteProjects"] = ctx.Repo.Permission.CanWrite(unit.TypeProjects)
ctx.HTML(http.StatusOK, tplProjectsNew)
}
@@ -135,7 +137,8 @@ func NewProjectPost(ctx *context.Context) {
if ctx.HasError() {
ctx.Data["CanWriteProjects"] = ctx.Repo.Permission.CanWrite(unit.TypeProjects)
- ctx.Data["ProjectTypes"] = project_model.GetProjectsConfig()
+ ctx.Data["BoardTypes"] = project_model.GetBoardConfig()
+ ctx.Data["CardTypes"] = project_model.GetCardConfig()
ctx.HTML(http.StatusOK, tplProjectsNew)
return
}
@@ -146,6 +149,7 @@ func NewProjectPost(ctx *context.Context) {
Description: form.Content,
CreatorID: ctx.Doer.ID,
BoardType: form.BoardType,
+ CardType: form.CardType,
Type: project_model.TypeRepository,
}); err != nil {
ctx.ServerError("NewProject", err)
@@ -212,6 +216,7 @@ func EditProject(ctx *context.Context) {
ctx.Data["Title"] = ctx.Tr("repo.projects.edit")
ctx.Data["PageIsEditProjects"] = true
ctx.Data["CanWriteProjects"] = ctx.Repo.Permission.CanWrite(unit.TypeProjects)
+ ctx.Data["CardTypes"] = project_model.GetCardConfig()
p, err := project_model.GetProjectByID(ctx, ctx.ParamsInt64(":id"))
if err != nil {
@@ -229,6 +234,7 @@ func EditProject(ctx *context.Context) {
ctx.Data["title"] = p.Title
ctx.Data["content"] = p.Description
+ ctx.Data["card_type"] = p.CardType
ctx.HTML(http.StatusOK, tplProjectsNew)
}
@@ -239,6 +245,7 @@ func EditProjectPost(ctx *context.Context) {
ctx.Data["Title"] = ctx.Tr("repo.projects.edit")
ctx.Data["PageIsEditProjects"] = true
ctx.Data["CanWriteProjects"] = ctx.Repo.Permission.CanWrite(unit.TypeProjects)
+ ctx.Data["CardTypes"] = project_model.GetCardConfig()
if ctx.HasError() {
ctx.HTML(http.StatusOK, tplProjectsNew)
@@ -261,6 +268,7 @@ func EditProjectPost(ctx *context.Context) {
p.Title = form.Title
p.Description = form.Content
+ p.CardType = form.CardType
if err = project_model.UpdateProject(ctx, p); err != nil {
ctx.ServerError("UpdateProjects", err)
return
@@ -302,6 +310,18 @@ func ViewProject(ctx *context.Context) {
return
}
+ if project.CardType != project_model.CardTypeTextOnly {
+ issuesAttachmentMap := make(map[int64][]*attachment_model.Attachment)
+ for _, issuesList := range issuesMap {
+ for _, issue := range issuesList {
+ if issueAttachment, err := attachment_model.GetAttachmentsByIssueIDImagesLatest(ctx, issue.ID); err == nil {
+ issuesAttachmentMap[issue.ID] = issueAttachment
+ }
+ }
+ }
+ ctx.Data["issuesAttachmentMap"] = issuesAttachmentMap
+ }
+
linkedPrsMap := make(map[int64][]*issues_model.Issue)
for _, issuesList := range issuesMap {
for _, issue := range issuesList {
diff --git a/routers/web/repo/pull.go b/routers/web/repo/pull.go
index ad17005d9..c7a59da8a 100644
--- a/routers/web/repo/pull.go
+++ b/routers/web/repo/pull.go
@@ -119,8 +119,8 @@ func getForkRepository(ctx *context.Context) *repo_model.Repository {
return nil
}
- if err := forkRepo.GetOwner(ctx); err != nil {
- ctx.ServerError("GetOwner", err)
+ if err := forkRepo.LoadOwner(ctx); err != nil {
+ ctx.ServerError("LoadOwner", err)
return nil
}
@@ -1315,8 +1315,8 @@ func CleanUpPullRequest(ctx *context.Context) {
} else if err = pr.LoadBaseRepo(ctx); err != nil {
ctx.ServerError("LoadBaseRepo", err)
return
- } else if err = pr.HeadRepo.GetOwner(ctx); err != nil {
- ctx.ServerError("HeadRepo.GetOwner", err)
+ } else if err = pr.HeadRepo.LoadOwner(ctx); err != nil {
+ ctx.ServerError("HeadRepo.LoadOwner", err)
return
}
diff --git a/routers/web/repo/pull_review.go b/routers/web/repo/pull_review.go
index 9f4cdde86..d43a786c5 100644
--- a/routers/web/repo/pull_review.go
+++ b/routers/web/repo/pull_review.go
@@ -98,7 +98,7 @@ func CreateCodeComment(ctx *context.Context) {
renderConversation(ctx, comment)
return
}
- ctx.Redirect(comment.HTMLURL())
+ ctx.Redirect(comment.Link())
}
// UpdateResolveConversation add or remove an Conversation resolved mark
diff --git a/routers/web/repo/release.go b/routers/web/repo/release.go
index 5204b5fd0..e969fdc5a 100644
--- a/routers/web/repo/release.go
+++ b/routers/web/repo/release.go
@@ -295,7 +295,7 @@ func LatestRelease(ctx *context.Context) {
return
}
- ctx.Redirect(release.HTMLURL())
+ ctx.Redirect(release.Link())
}
// NewRelease render creating or edit release page
diff --git a/routers/web/repo/repo.go b/routers/web/repo/repo.go
index 1b1887d65..aeac7cfa3 100644
--- a/routers/web/repo/repo.go
+++ b/routers/web/repo/repo.go
@@ -344,7 +344,7 @@ func acceptOrRejectRepoTransfer(ctx *context.Context, accept bool) error {
ctx.Flash.Success(ctx.Tr("repo.settings.transfer.rejected"))
}
- ctx.Redirect(ctx.Repo.Repository.HTMLURL())
+ ctx.Redirect(ctx.Repo.Repository.Link())
return nil
}
diff --git a/routers/web/repo/search.go b/routers/web/repo/search.go
index 137f38d40..a04319847 100644
--- a/routers/web/repo/search.go
+++ b/routers/web/repo/search.go
@@ -54,7 +54,7 @@ func Search(ctx *context.Context) {
ctx.Data["CodeIndexerUnavailable"] = !code_indexer.IsAvailable()
}
- ctx.Data["SourcePath"] = ctx.Repo.Repository.HTMLURL()
+ ctx.Data["SourcePath"] = ctx.Repo.Repository.Link()
ctx.Data["SearchResults"] = searchResults
ctx.Data["SearchResultLanguages"] = searchResultLanguages
diff --git a/routers/web/repo/setting.go b/routers/web/repo/setting.go
index 5c30795f2..387a91741 100644
--- a/routers/web/repo/setting.go
+++ b/routers/web/repo/setting.go
@@ -529,6 +529,7 @@ func SettingsPost(ctx *context.Context) {
AllowRebaseUpdate: form.PullsAllowRebaseUpdate,
DefaultDeleteBranchAfterMerge: form.DefaultDeleteBranchAfterMerge,
DefaultMergeStyle: repo_model.MergeStyle(form.PullsDefaultMergeStyle),
+ DefaultAllowMaintainerEdit: form.DefaultAllowMaintainerEdit,
},
})
} else if !unit_model.TypePullRequests.UnitGlobalDisabled() {
@@ -649,7 +650,7 @@ func SettingsPost(ctx *context.Context) {
ctx.Error(http.StatusNotFound)
return
}
- if err := repo.GetOwner(ctx); err != nil {
+ if err := repo.LoadOwner(ctx); err != nil {
ctx.ServerError("Convert Fork", err)
return
}
diff --git a/routers/web/repo/view.go b/routers/web/repo/view.go
index f31490237..e3c61fa40 100644
--- a/routers/web/repo/view.go
+++ b/routers/web/repo/view.go
@@ -56,18 +56,15 @@ type namedBlob struct {
blob *git.Blob
}
+// locate a README for a tree in one of the supported paths.
+//
+// entries is passed to reduce calls to ListEntries(), so
+// this has precondition:
+//
+// entries == ctx.Repo.Commit.SubTree(ctx.Repo.TreePath).ListEntries()
+//
// FIXME: There has to be a more efficient way of doing this
-func getReadmeFileFromPath(ctx *context.Context, commit *git.Commit, treePath string) (*namedBlob, error) {
- tree, err := commit.SubTree(treePath)
- if err != nil {
- return nil, err
- }
-
- entries, err := tree.ListEntries()
- if err != nil {
- return nil, err
- }
-
+func findReadmeFileInEntries(ctx *context.Context, entries []*git.TreeEntry) (*namedBlob, error) {
// Create a list of extensions in priority order
// 1. Markdown files - with and without localisation - e.g. README.en-us.md or README.md
// 2. Txt files - e.g. README.txt
@@ -75,16 +72,38 @@ func getReadmeFileFromPath(ctx *context.Context, commit *git.Commit, treePath st
exts := append(localizedExtensions(".md", ctx.Language()), ".txt", "") // sorted by priority
extCount := len(exts)
readmeFiles := make([]*namedBlob, extCount+1)
+
+ docsEntries := make([]*git.TreeEntry, 3) // (one of docs/, .gitea/ or .github/)
for _, entry := range entries {
if entry.IsDir() {
+ // as a special case for the top-level repo introduction README,
+ // fall back to subfolders, looking for e.g. docs/README.md, .gitea/README.zh-CN.txt, .github/README.txt, ...
+ // (note that docsEntries is ignored unless we are at the root)
+ lowerName := strings.ToLower(entry.Name())
+ switch lowerName {
+ case "docs":
+ if entry.Name() == "docs" || docsEntries[0] == nil {
+ docsEntries[0] = entry
+ }
+ case ".gitea":
+ if entry.Name() == ".gitea" || docsEntries[1] == nil {
+ docsEntries[1] = entry
+ }
+ case ".github":
+ if entry.Name() == ".github" || docsEntries[2] == nil {
+ docsEntries[2] = entry
+ }
+ }
continue
}
- if i, ok := markup.IsReadmeFileExtension(entry.Name(), exts...); ok {
+ if i, ok := util.IsReadmeFileExtension(entry.Name(), exts...); ok {
+ log.Debug("Potential readme file: %s", entry.Name())
if readmeFiles[i] == nil || base.NaturalSortLess(readmeFiles[i].name, entry.Blob().Name()) {
name := entry.Name()
isSymlink := entry.IsLink()
target := entry
if isSymlink {
+ var err error
target, err = entry.FollowLinks()
if err != nil && !git.IsErrBadLink(err) {
return nil, err
@@ -107,6 +126,33 @@ func getReadmeFileFromPath(ctx *context.Context, commit *git.Commit, treePath st
break
}
}
+
+ if ctx.Repo.TreePath == "" && readmeFile == nil {
+ for _, subTreeEntry := range docsEntries {
+ if subTreeEntry == nil {
+ continue
+ }
+ subTree := subTreeEntry.Tree()
+ if subTree == nil {
+ // this should be impossible; if subTreeEntry exists so should this.
+ continue
+ }
+ var err error
+ childEntries, err := subTree.ListEntries()
+ if err != nil {
+ return nil, err
+ }
+ readmeFile, err = findReadmeFileInEntries(ctx, childEntries)
+ if err != nil && !git.IsErrNotExist(err) {
+ return nil, err
+ }
+ if readmeFile != nil {
+ readmeFile.name = subTreeEntry.Name() + "/" + readmeFile.name
+ break
+ }
+ }
+ }
+
return readmeFile, nil
}
@@ -127,12 +173,20 @@ func renderDirectory(ctx *context.Context, treeLink string) {
ctx.Data["CanUploadFile"] = setting.Repository.Upload.Enabled && !ctx.Repo.Repository.IsArchived
}
- readmeFile, readmeTreelink := findReadmeFile(ctx, entries, treeLink)
- if ctx.Written() || readmeFile == nil {
+ if ctx.Written() {
+ return
+ }
+
+ readmeFile, err := findReadmeFileInEntries(ctx, entries)
+ if err != nil {
+ ctx.ServerError("findReadmeFileInEntries", err)
+ return
+ }
+ if readmeFile == nil {
return
}
- renderReadmeFile(ctx, readmeFile, readmeTreelink)
+ renderReadmeFile(ctx, readmeFile, treeLink)
}
// localizedExtensions prepends the provided language code with and without a
@@ -157,89 +211,6 @@ func localizedExtensions(ext, languageCode string) (localizedExts []string) {
return []string{lowerLangCode + ext, ext}
}
-func findReadmeFile(ctx *context.Context, entries git.Entries, treeLink string) (*namedBlob, string) {
- // Create a list of extensions in priority order
- // 1. Markdown files - with and without localisation - e.g. README.en-us.md or README.md
- // 2. Txt files - e.g. README.txt
- // 3. No extension - e.g. README
- exts := append(localizedExtensions(".md", ctx.Language()), ".txt", "") // sorted by priority
- extCount := len(exts)
- readmeFiles := make([]*namedBlob, extCount+1)
-
- docsEntries := make([]*git.TreeEntry, 3) // (one of docs/, .gitea/ or .github/)
- for _, entry := range entries {
- if entry.IsDir() {
- lowerName := strings.ToLower(entry.Name())
- switch lowerName {
- case "docs":
- if entry.Name() == "docs" || docsEntries[0] == nil {
- docsEntries[0] = entry
- }
- case ".gitea":
- if entry.Name() == ".gitea" || docsEntries[1] == nil {
- docsEntries[1] = entry
- }
- case ".github":
- if entry.Name() == ".github" || docsEntries[2] == nil {
- docsEntries[2] = entry
- }
- }
- continue
- }
-
- if i, ok := markup.IsReadmeFileExtension(entry.Name(), exts...); ok {
- log.Debug("Potential readme file: %s", entry.Name())
- name := entry.Name()
- isSymlink := entry.IsLink()
- target := entry
- if isSymlink {
- var err error
- target, err = entry.FollowLinks()
- if err != nil && !git.IsErrBadLink(err) {
- ctx.ServerError("FollowLinks", err)
- return nil, ""
- }
- }
- if target != nil && (target.IsExecutable() || target.IsRegular()) {
- readmeFiles[i] = &namedBlob{
- name,
- isSymlink,
- target.Blob(),
- }
- }
- }
- }
-
- var readmeFile *namedBlob
- readmeTreelink := treeLink
- for _, f := range readmeFiles {
- if f != nil {
- readmeFile = f
- break
- }
- }
-
- if ctx.Repo.TreePath == "" && readmeFile == nil {
- for _, entry := range docsEntries {
- if entry == nil {
- continue
- }
- var err error
- readmeFile, err = getReadmeFileFromPath(ctx, ctx.Repo.Commit, entry.GetSubJumpablePathName())
- if err != nil {
- ctx.ServerError("getReadmeFileFromPath", err)
- return nil, ""
- }
- if readmeFile != nil {
- readmeFile.name = entry.Name() + "/" + readmeFile.name
- readmeTreelink = treeLink + "/" + util.PathEscapeSegments(entry.GetSubJumpablePathName())
- break
- }
- }
- }
- return readmeFile, readmeTreelink
-}
-
type fileInfo struct {
isTextFile bool
isLFSFile bool
@@ -318,7 +289,7 @@ func renderReadmeFile(ctx *context.Context, readmeFile *namedBlob, readmeTreelin
if fInfo.isLFSFile {
filenameBase64 := base64.RawURLEncoding.EncodeToString([]byte(readmeFile.name))
- ctx.Data["RawFileLink"] = fmt.Sprintf("%s.git/info/lfs/objects/%s/%s", ctx.Repo.Repository.HTMLURL(), url.PathEscape(fInfo.lfsMeta.Oid), url.PathEscape(filenameBase64))
+ ctx.Data["RawFileLink"] = fmt.Sprintf("%s.git/info/lfs/objects/%s/%s", ctx.Repo.Repository.Link(), url.PathEscape(fInfo.lfsMeta.Oid), url.PathEscape(filenameBase64))
}
if !fInfo.isTextFile {
@@ -342,7 +313,7 @@ func renderReadmeFile(ctx *context.Context, readmeFile *namedBlob, readmeTreelin
ctx.Data["EscapeStatus"], ctx.Data["FileContent"], err = markupRender(ctx, &markup.RenderContext{
Ctx: ctx,
RelativePath: path.Join(ctx.Repo.TreePath, readmeFile.name), // ctx.Repo.TreePath is the directory not the Readme so we must append the Readme filename (and path).
- URLPrefix: readmeTreelink,
+ URLPrefix: path.Dir(readmeTreelink),
Metas: ctx.Repo.Repository.ComposeDocumentMetas(),
GitRepo: ctx.Repo.GitRepo,
}, rd)
@@ -452,7 +423,7 @@ func renderFile(ctx *context.Context, entry *git.TreeEntry, treeLink, rawLink st
rd := charset.ToUTF8WithFallbackReader(io.MultiReader(bytes.NewReader(buf), dataRc))
shouldRenderSource := ctx.FormString("display") == "source"
- readmeExist := markup.IsReadmeFile(blob.Name())
+ readmeExist := util.IsReadmeFileName(blob.Name())
ctx.Data["ReadmeExist"] = readmeExist
markupType := markup.Type(blob.Name())
@@ -738,7 +709,7 @@ func Home(ctx *context.Context) {
}
ctx.Data["EnableFeed"] = true
- ctx.Data["FeedURL"] = ctx.Repo.Repository.HTMLURL()
+ ctx.Data["FeedURL"] = ctx.Repo.Repository.Link()
}
checkHomeCodeViewable(ctx)
@@ -840,7 +811,7 @@ func renderDirectoryFiles(ctx *context.Context, timeout time.Duration) git.Entri
ctx.Data["LatestCommit"] = latestCommit
if latestCommit != nil {
- verification := asymkey_model.ParseCommitWithSignature(latestCommit)
+ verification := asymkey_model.ParseCommitWithSignature(ctx, latestCommit)
if err := asymkey_model.CalculateTrustStatus(verification, ctx.Repo.Repository.GetTrustModel(), func(user *user_model.User) (bool, error) {
return repo_model.IsOwnerMemberCollaborator(ctx.Repo.Repository, user.ID)
@@ -849,7 +820,7 @@ func renderDirectoryFiles(ctx *context.Context, timeout time.Duration) git.Entri
return nil
}
ctx.Data["LatestCommitVerification"] = verification
- ctx.Data["LatestCommitUser"] = user_model.ValidateCommitWithEmail(latestCommit)
+ ctx.Data["LatestCommitUser"] = user_model.ValidateCommitWithEmail(ctx, latestCommit)
statuses, _, err := git_model.GetLatestCommitStatus(ctx, ctx.Repo.Repository.ID, latestCommit.ID.String(), db.ListOptions{})
if err != nil {
@@ -1062,8 +1033,8 @@ func Forks(ctx *context.Context) {
}
for _, fork := range forks {
- if err = fork.GetOwner(ctx); err != nil {
- ctx.ServerError("GetOwner", err)
+ if err = fork.LoadOwner(ctx); err != nil {
+ ctx.ServerError("LoadOwner", err)
return
}
}
diff --git a/routers/web/repo/webhook.go b/routers/web/repo/webhook.go
index d3826c3f3..d27d0f1bf 100644
--- a/routers/web/repo/webhook.go
+++ b/routers/web/repo/webhook.go
@@ -660,7 +660,7 @@ func TestWebhook(ctx *context.Context) {
}
}
- apiUser := convert.ToUserWithAccessMode(ctx.Doer, perm.AccessModeNone)
+ apiUser := convert.ToUserWithAccessMode(ctx, ctx.Doer, perm.AccessModeNone)
apiCommit := &api.PayloadCommit{
ID: commit.ID.String(),
diff --git a/routers/web/user/avatar.go b/routers/web/user/avatar.go
index 20c2ef3e4..2dba74822 100644
--- a/routers/web/user/avatar.go
+++ b/routers/web/user/avatar.go
@@ -41,7 +41,7 @@ func AvatarByUserName(ctx *context.Context) {
user = user_model.NewGhostUser()
}
- cacheableRedirect(ctx, user.AvatarLinkWithSize(size))
+ cacheableRedirect(ctx, user.AvatarLinkWithSize(ctx, size))
}
// AvatarByEmailHash redirects the browser to the email avatar link
@@ -53,5 +53,5 @@ func AvatarByEmailHash(ctx *context.Context) {
return
}
size := ctx.FormInt("size")
- cacheableRedirect(ctx, avatars.GenerateEmailAvatarFinalLink(email, size))
+ cacheableRedirect(ctx, avatars.GenerateEmailAvatarFinalLink(ctx, email, size))
}
diff --git a/routers/web/user/home.go b/routers/web/user/home.go
index 36d9d4f01..4f45c1d5c 100644
--- a/routers/web/user/home.go
+++ b/routers/web/user/home.go
@@ -338,6 +338,11 @@ func buildIssueOverview(ctx *context.Context, unitType unit.Type) {
filterMode int
)
+ // Default to recently updated, unlike repository issues list
+ if sortType == "" {
+ sortType = "recentupdate"
+ }
+
// --------------------------------------------------------------------------------
// Distinguish User from Organization.
// Org:
diff --git a/routers/web/user/package.go b/routers/web/user/package.go
index ed4f0dd79..a9acc5281 100644
--- a/routers/web/user/package.go
+++ b/routers/web/user/package.go
@@ -376,7 +376,7 @@ func PackageSettingsPost(ctx *context.Context) {
ctx.Flash.Success(ctx.Tr("packages.settings.delete.success"))
}
- ctx.Redirect(ctx.Package.Owner.HTMLURL() + "/-/packages")
+ ctx.Redirect(ctx.Package.Owner.HomeLink() + "/-/packages")
return
}
}
diff --git a/routers/web/user/profile.go b/routers/web/user/profile.go
index f2a6f5b50..503562220 100644
--- a/routers/web/user/profile.go
+++ b/routers/web/user/profile.go
@@ -48,7 +48,7 @@ func Profile(ctx *context.Context) {
}
// advertise feed via meta tag
- ctx.Data["FeedURL"] = ctx.ContextUser.HTMLURL()
+ ctx.Data["FeedURL"] = ctx.ContextUser.HomeLink()
// Show OpenID URIs
openIDs, err := user_model.GetUserOpenIDs(ctx.ContextUser.ID)
diff --git a/routers/web/user/search.go b/routers/web/user/search.go
index f9b0e0735..c5c3aa75f 100644
--- a/routers/web/user/search.go
+++ b/routers/web/user/search.go
@@ -38,6 +38,6 @@ func Search(ctx *context.Context) {
ctx.JSON(http.StatusOK, map[string]interface{}{
"ok": true,
- "data": convert.ToUsers(ctx.Doer, users),
+ "data": convert.ToUsers(ctx, ctx.Doer, users),
})
}
diff --git a/routers/web/user/setting/account.go b/routers/web/user/setting/account.go
index dbaa8fd35..0e48013b0 100644
--- a/routers/web/user/setting/account.go
+++ b/routers/web/user/setting/account.go
@@ -11,10 +11,10 @@ import (
"code.gitea.io/gitea/models"
user_model "code.gitea.io/gitea/models/user"
+ "code.gitea.io/gitea/modules/auth/password"
"code.gitea.io/gitea/modules/base"
"code.gitea.io/gitea/modules/context"
"code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/password"
"code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/modules/timeutil"
"code.gitea.io/gitea/modules/web"
diff --git a/routers/web/webfinger.go b/routers/web/webfinger.go
index 13b93edae..c5ebce555 100644
--- a/routers/web/webfinger.go
+++ b/routers/web/webfinger.go
@@ -46,7 +46,7 @@ func WebfingerQuery(ctx *context.Context) {
u, err = user_model.GetUserByName(ctx, parts[0])
case "mailto":
- u, err = user_model.GetUserByEmailContext(ctx, resource.Opaque)
+ u, err = user_model.GetUserByEmail(ctx, resource.Opaque)
if u != nil && u.KeepEmailPrivate {
err = user_model.ErrUserNotExist{}
}
@@ -87,7 +87,7 @@ func WebfingerQuery(ctx *context.Context) {
},
{
Rel: "http://webfinger.net/rel/avatar",
- Href: u.AvatarLink(),
+ Href: u.AvatarLink(ctx),
},
{
Rel: "self",