mirror of
https://github.com/go-gitea/gitea.git
synced 2026-09-22 04:33:42 +09:00
Merge branch 'master' into feature-activitypub
This commit is contained in:
+33
-11
@@ -35,10 +35,11 @@ import (
|
||||
)
|
||||
|
||||
const (
|
||||
tplDashboard base.TplName = "admin/dashboard"
|
||||
tplConfig base.TplName = "admin/config"
|
||||
tplMonitor base.TplName = "admin/monitor"
|
||||
tplQueue base.TplName = "admin/queue"
|
||||
tplDashboard base.TplName = "admin/dashboard"
|
||||
tplConfig base.TplName = "admin/config"
|
||||
tplMonitor base.TplName = "admin/monitor"
|
||||
tplStacktrace base.TplName = "admin/stacktrace"
|
||||
tplQueue base.TplName = "admin/queue"
|
||||
)
|
||||
|
||||
var sysStatus struct {
|
||||
@@ -149,7 +150,7 @@ func DashboardPost(ctx *context.Context) {
|
||||
if form.Op != "" {
|
||||
task := cron.GetTask(form.Op)
|
||||
if task != nil {
|
||||
go task.RunWithUser(ctx.User, nil)
|
||||
go task.RunWithUser(ctx.Doer, nil)
|
||||
ctx.Flash.Success(ctx.Tr("admin.dashboard.task.started", ctx.Tr("admin.dashboard."+form.Op)))
|
||||
} else {
|
||||
ctx.Flash.Error(ctx.Tr("admin.dashboard.task.unknown", form.Op))
|
||||
@@ -326,12 +327,33 @@ func Monitor(ctx *context.Context) {
|
||||
ctx.Data["Title"] = ctx.Tr("admin.monitor")
|
||||
ctx.Data["PageIsAdmin"] = true
|
||||
ctx.Data["PageIsAdminMonitor"] = true
|
||||
ctx.Data["Processes"] = process.GetManager().Processes(true)
|
||||
ctx.Data["Processes"], ctx.Data["ProcessCount"] = process.GetManager().Processes(false, true)
|
||||
ctx.Data["Entries"] = cron.ListTasks()
|
||||
ctx.Data["Queues"] = queue.GetManager().ManagedQueues()
|
||||
|
||||
ctx.HTML(http.StatusOK, tplMonitor)
|
||||
}
|
||||
|
||||
// GoroutineStacktrace show admin monitor goroutines page
|
||||
func GoroutineStacktrace(ctx *context.Context) {
|
||||
ctx.Data["Title"] = ctx.Tr("admin.monitor")
|
||||
ctx.Data["PageIsAdmin"] = true
|
||||
ctx.Data["PageIsAdminMonitor"] = true
|
||||
|
||||
processStacks, processCount, goroutineCount, err := process.GetManager().ProcessStacktraces(false, false)
|
||||
if err != nil {
|
||||
ctx.ServerError("GoroutineStacktrace", err)
|
||||
return
|
||||
}
|
||||
|
||||
ctx.Data["ProcessStacks"] = processStacks
|
||||
|
||||
ctx.Data["GoroutineCount"] = goroutineCount
|
||||
ctx.Data["ProcessCount"] = processCount
|
||||
|
||||
ctx.HTML(http.StatusOK, tplStacktrace)
|
||||
}
|
||||
|
||||
// MonitorCancel cancels a process
|
||||
func MonitorCancel(ctx *context.Context) {
|
||||
pid := ctx.Params("pid")
|
||||
@@ -346,7 +368,7 @@ func Queue(ctx *context.Context) {
|
||||
qid := ctx.ParamsInt64("qid")
|
||||
mq := queue.GetManager().GetManagedQueue(qid)
|
||||
if mq == nil {
|
||||
ctx.Status(404)
|
||||
ctx.Status(http.StatusNotFound)
|
||||
return
|
||||
}
|
||||
ctx.Data["Title"] = ctx.Tr("admin.monitor.queue", mq.Name)
|
||||
@@ -361,7 +383,7 @@ func WorkerCancel(ctx *context.Context) {
|
||||
qid := ctx.ParamsInt64("qid")
|
||||
mq := queue.GetManager().GetManagedQueue(qid)
|
||||
if mq == nil {
|
||||
ctx.Status(404)
|
||||
ctx.Status(http.StatusNotFound)
|
||||
return
|
||||
}
|
||||
pid := ctx.ParamsInt64("pid")
|
||||
@@ -377,7 +399,7 @@ func Flush(ctx *context.Context) {
|
||||
qid := ctx.ParamsInt64("qid")
|
||||
mq := queue.GetManager().GetManagedQueue(qid)
|
||||
if mq == nil {
|
||||
ctx.Status(404)
|
||||
ctx.Status(http.StatusNotFound)
|
||||
return
|
||||
}
|
||||
timeout, err := time.ParseDuration(ctx.FormString("timeout"))
|
||||
@@ -423,7 +445,7 @@ func AddWorkers(ctx *context.Context) {
|
||||
qid := ctx.ParamsInt64("qid")
|
||||
mq := queue.GetManager().GetManagedQueue(qid)
|
||||
if mq == nil {
|
||||
ctx.Status(404)
|
||||
ctx.Status(http.StatusNotFound)
|
||||
return
|
||||
}
|
||||
number := ctx.FormInt("number")
|
||||
@@ -453,7 +475,7 @@ func SetQueueSettings(ctx *context.Context) {
|
||||
qid := ctx.ParamsInt64("qid")
|
||||
mq := queue.GetManager().GetManagedQueue(qid)
|
||||
if mq == nil {
|
||||
ctx.Status(404)
|
||||
ctx.Status(http.StatusNotFound)
|
||||
return
|
||||
}
|
||||
if _, ok := mq.Managed.(queue.ManagedPool); !ok {
|
||||
|
||||
@@ -93,7 +93,7 @@ func NewAuthSource(ctx *context.Context) {
|
||||
ctx.Data["PageIsAdmin"] = true
|
||||
ctx.Data["PageIsAdminAuthentications"] = true
|
||||
|
||||
ctx.Data["type"] = auth.LDAP
|
||||
ctx.Data["type"] = auth.LDAP.Int()
|
||||
ctx.Data["CurrentTypeName"] = auth.Names[auth.LDAP]
|
||||
ctx.Data["CurrentSecurityProtocol"] = ldap.SecurityProtocolNames[ldap.SecurityProtocolUnencrypted]
|
||||
ctx.Data["smtp_auth"] = "PLAIN"
|
||||
@@ -112,7 +112,7 @@ func NewAuthSource(ctx *context.Context) {
|
||||
ctx.Data["SSPIDefaultLanguage"] = ""
|
||||
|
||||
// only the first as default
|
||||
ctx.Data["oauth2_provider"] = oauth2providers[0]
|
||||
ctx.Data["oauth2_provider"] = oauth2providers[0].Name
|
||||
|
||||
ctx.HTML(http.StatusOK, tplAuthNew)
|
||||
}
|
||||
@@ -253,9 +253,6 @@ func NewAuthSourcePost(ctx *context.Context) {
|
||||
ctx.Data["SSPISeparatorReplacement"] = "_"
|
||||
ctx.Data["SSPIDefaultLanguage"] = ""
|
||||
|
||||
// FIXME: most error path to render tplAuthNew will fail and result in 500
|
||||
// * template: admin/auth/new:17:68: executing "admin/auth/new" at <.type.Int>: can't evaluate field Int in type interface {}
|
||||
// * template: admin/auth/source/oauth:5:93: executing "admin/auth/source/oauth" at <.oauth2_provider.Name>: can't evaluate field Name in type interface {}
|
||||
hasTLS := false
|
||||
var config convert.Conversion
|
||||
switch auth.Type(form.Type) {
|
||||
@@ -313,7 +310,7 @@ func NewAuthSourcePost(ctx *context.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
log.Trace("Authentication created by admin(%s): %s", ctx.User.Name, form.Name)
|
||||
log.Trace("Authentication created by admin(%s): %s", ctx.Doer.Name, form.Name)
|
||||
|
||||
ctx.Flash.Success(ctx.Tr("admin.auths.new_success", form.Name))
|
||||
ctx.Redirect(setting.AppSubURL + "/admin/auths")
|
||||
@@ -416,7 +413,7 @@ func EditAuthSourcePost(ctx *context.Context) {
|
||||
}
|
||||
return
|
||||
}
|
||||
log.Trace("Authentication changed by admin(%s): %d", ctx.User.Name, source.ID)
|
||||
log.Trace("Authentication changed by admin(%s): %d", ctx.Doer.Name, source.ID)
|
||||
|
||||
ctx.Flash.Success(ctx.Tr("admin.auths.update_success"))
|
||||
ctx.Redirect(setting.AppSubURL + "/admin/auths/" + strconv.FormatInt(form.ID, 10))
|
||||
@@ -441,7 +438,7 @@ func DeleteAuthSource(ctx *context.Context) {
|
||||
})
|
||||
return
|
||||
}
|
||||
log.Trace("Authentication deleted by admin(%s): %d", ctx.User.Name, source.ID)
|
||||
log.Trace("Authentication deleted by admin(%s): %d", ctx.Doer.Name, source.ID)
|
||||
|
||||
ctx.Flash.Success(ctx.Tr("admin.auths.deletion_success"))
|
||||
ctx.JSON(http.StatusOK, map[string]interface{}{
|
||||
|
||||
@@ -87,7 +87,7 @@ func Emails(ctx *context.Context) {
|
||||
emails[i].SearchEmailResult = *baseEmails[i]
|
||||
// Don't let the admin deactivate its own primary email address
|
||||
// We already know the user is admin
|
||||
emails[i].CanChange = ctx.User.ID != emails[i].UID || !emails[i].IsPrimary
|
||||
emails[i].CanChange = ctx.Doer.ID != emails[i].UID || !emails[i].IsPrimary
|
||||
}
|
||||
}
|
||||
ctx.Data["Keyword"] = opts.Keyword
|
||||
|
||||
@@ -11,6 +11,7 @@ import (
|
||||
"code.gitea.io/gitea/modules/base"
|
||||
"code.gitea.io/gitea/modules/context"
|
||||
"code.gitea.io/gitea/modules/setting"
|
||||
"code.gitea.io/gitea/modules/util"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -34,7 +35,7 @@ func DefaultOrSystemWebhooks(ctx *context.Context) {
|
||||
|
||||
sys["Title"] = ctx.Tr("admin.systemhooks")
|
||||
sys["Description"] = ctx.Tr("admin.systemhooks.desc")
|
||||
sys["Webhooks"], err = webhook.GetSystemWebhooks()
|
||||
sys["Webhooks"], err = webhook.GetSystemWebhooks(util.OptionalBoolNone)
|
||||
sys["BaseLink"] = setting.AppSubURL + "/admin/hooks"
|
||||
sys["BaseLinkNew"] = setting.AppSubURL + "/admin/system-hooks"
|
||||
if err != nil {
|
||||
|
||||
@@ -12,5 +12,7 @@ import (
|
||||
)
|
||||
|
||||
func TestMain(m *testing.M) {
|
||||
unittest.MainTest(m, filepath.Join("..", "..", ".."))
|
||||
unittest.MainTest(m, &unittest.TestOptions{
|
||||
GiteaRootPath: filepath.Join("..", "..", ".."),
|
||||
})
|
||||
}
|
||||
|
||||
@@ -59,10 +59,10 @@ func DeleteNotices(ctx *context.Context) {
|
||||
|
||||
if err := admin_model.DeleteNoticesByIDs(ids); err != nil {
|
||||
ctx.Flash.Error("DeleteNoticesByIDs: " + err.Error())
|
||||
ctx.Status(500)
|
||||
ctx.Status(http.StatusInternalServerError)
|
||||
} else {
|
||||
ctx.Flash.Success(ctx.Tr("admin.notices.delete_success"))
|
||||
ctx.Status(200)
|
||||
ctx.Status(http.StatusOK)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -73,7 +73,7 @@ func EmptyNotices(ctx *context.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
log.Trace("System notices deleted by admin (%s): [start: %d]", ctx.User.Name, 0)
|
||||
log.Trace("System notices deleted by admin (%s): [start: %d]", ctx.Doer.Name, 0)
|
||||
ctx.Flash.Success(ctx.Tr("admin.notices.delete_success"))
|
||||
ctx.Redirect(setting.AppSubURL + "/admin/notices")
|
||||
}
|
||||
|
||||
@@ -26,7 +26,7 @@ func Organizations(ctx *context.Context) {
|
||||
ctx.Data["PageIsAdminOrganizations"] = true
|
||||
|
||||
explore.RenderUserSearch(ctx, &user_model.SearchUserOptions{
|
||||
Actor: ctx.User,
|
||||
Actor: ctx.Doer,
|
||||
Type: user_model.UserTypeOrganization,
|
||||
ListOptions: db.ListOptions{
|
||||
PageSize: setting.UI.Admin.OrgPagingNum,
|
||||
|
||||
@@ -0,0 +1,95 @@
|
||||
// Copyright 2014 The Gogs Authors. All rights reserved.
|
||||
// Use of this source code is governed by a MIT-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package admin
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"net/url"
|
||||
|
||||
"code.gitea.io/gitea/models/db"
|
||||
packages_model "code.gitea.io/gitea/models/packages"
|
||||
"code.gitea.io/gitea/modules/base"
|
||||
"code.gitea.io/gitea/modules/context"
|
||||
"code.gitea.io/gitea/modules/setting"
|
||||
packages_service "code.gitea.io/gitea/services/packages"
|
||||
)
|
||||
|
||||
const (
|
||||
tplPackagesList base.TplName = "admin/packages/list"
|
||||
)
|
||||
|
||||
// Packages shows all packages
|
||||
func Packages(ctx *context.Context) {
|
||||
page := ctx.FormInt("page")
|
||||
if page <= 1 {
|
||||
page = 1
|
||||
}
|
||||
query := ctx.FormTrim("q")
|
||||
packageType := ctx.FormTrim("type")
|
||||
sort := ctx.FormTrim("sort")
|
||||
|
||||
pvs, total, err := packages_model.SearchVersions(ctx, &packages_model.PackageSearchOptions{
|
||||
Type: packages_model.Type(packageType),
|
||||
Name: packages_model.SearchValue{Value: query},
|
||||
Sort: sort,
|
||||
Paginator: &db.ListOptions{
|
||||
PageSize: setting.UI.PackagesPagingNum,
|
||||
Page: page,
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
ctx.ServerError("SearchVersions", err)
|
||||
return
|
||||
}
|
||||
|
||||
pds, err := packages_model.GetPackageDescriptors(ctx, pvs)
|
||||
if err != nil {
|
||||
ctx.ServerError("GetPackageDescriptors", err)
|
||||
return
|
||||
}
|
||||
|
||||
totalBlobSize, err := packages_model.GetTotalBlobSize()
|
||||
if err != nil {
|
||||
ctx.ServerError("GetTotalBlobSize", err)
|
||||
return
|
||||
}
|
||||
|
||||
ctx.Data["Title"] = ctx.Tr("packages.title")
|
||||
ctx.Data["PageIsAdmin"] = true
|
||||
ctx.Data["PageIsAdminPackages"] = true
|
||||
ctx.Data["Query"] = query
|
||||
ctx.Data["PackageType"] = packageType
|
||||
ctx.Data["SortType"] = sort
|
||||
ctx.Data["PackageDescriptors"] = pds
|
||||
ctx.Data["Total"] = total
|
||||
ctx.Data["TotalBlobSize"] = totalBlobSize
|
||||
|
||||
pager := context.NewPagination(int(total), setting.UI.PackagesPagingNum, page, 5)
|
||||
pager.AddParamString("q", query)
|
||||
pager.AddParamString("type", packageType)
|
||||
pager.AddParamString("sort", sort)
|
||||
ctx.Data["Page"] = pager
|
||||
|
||||
ctx.HTML(http.StatusOK, tplPackagesList)
|
||||
}
|
||||
|
||||
// DeletePackageVersion deletes a package version
|
||||
func DeletePackageVersion(ctx *context.Context) {
|
||||
pv, err := packages_model.GetVersionByID(db.DefaultContext, ctx.FormInt64("id"))
|
||||
if err != nil {
|
||||
ctx.ServerError("GetRepositoryByID", err)
|
||||
return
|
||||
}
|
||||
|
||||
if err := packages_service.RemovePackageVersion(ctx.Doer, pv); err != nil {
|
||||
ctx.ServerError("RemovePackageVersion", err)
|
||||
return
|
||||
}
|
||||
|
||||
ctx.Flash.Success(ctx.Tr("packages.settings.delete.success"))
|
||||
ctx.JSON(http.StatusOK, map[string]interface{}{
|
||||
"redirect": setting.AppSubURL + "/admin/packages?page=" + url.QueryEscape(ctx.FormString("page")) + "&q=" + url.QueryEscape(ctx.FormString("q")) + "&type=" + url.QueryEscape(ctx.FormString("type")),
|
||||
})
|
||||
}
|
||||
@@ -52,7 +52,7 @@ func DeleteRepo(ctx *context.Context) {
|
||||
ctx.Repo.GitRepo.Close()
|
||||
}
|
||||
|
||||
if err := repo_service.DeleteRepository(ctx, ctx.User, repo, true); err != nil {
|
||||
if err := repo_service.DeleteRepository(ctx, ctx.Doer, repo, true); err != nil {
|
||||
ctx.ServerError("DeleteRepository", err)
|
||||
return
|
||||
}
|
||||
@@ -148,7 +148,7 @@ func AdoptOrDeleteRepository(ctx *context.Context) {
|
||||
if has || !isDir {
|
||||
// Fallthrough to failure mode
|
||||
} else if action == "adopt" {
|
||||
if _, err := repo_service.AdoptRepository(ctx.User, ctxUser, models.CreateRepoOptions{
|
||||
if _, err := repo_service.AdoptRepository(ctx.Doer, ctxUser, models.CreateRepoOptions{
|
||||
Name: dirSplit[1],
|
||||
IsPrivate: true,
|
||||
}); err != nil {
|
||||
@@ -157,7 +157,7 @@ func AdoptOrDeleteRepository(ctx *context.Context) {
|
||||
}
|
||||
ctx.Flash.Success(ctx.Tr("repo.adopt_preexisting_success", dir))
|
||||
} else if action == "delete" {
|
||||
if err := repo_service.DeleteUnadoptedRepository(ctx.User, ctxUser, dirSplit[1]); err != nil {
|
||||
if err := repo_service.DeleteUnadoptedRepository(ctx.Doer, ctxUser, dirSplit[1]); err != nil {
|
||||
ctx.ServerError("repository.AdoptRepository", err)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -63,7 +63,7 @@ func Users(ctx *context.Context) {
|
||||
}
|
||||
|
||||
explore.RenderUserSearch(ctx, &user_model.SearchUserOptions{
|
||||
Actor: ctx.User,
|
||||
Actor: ctx.Doer,
|
||||
Type: user_model.UserTypeIndividual,
|
||||
ListOptions: db.ListOptions{
|
||||
PageSize: setting.UI.Admin.UserPagingNum,
|
||||
@@ -125,10 +125,14 @@ func NewUserPost(ctx *context.Context) {
|
||||
Name: form.UserName,
|
||||
Email: form.Email,
|
||||
Passwd: form.Password,
|
||||
IsActive: true,
|
||||
LoginType: auth.Plain,
|
||||
}
|
||||
|
||||
overwriteDefault := &user_model.CreateUserOverwriteOptions{
|
||||
IsActive: util.OptionalBoolTrue,
|
||||
Visibility: &form.Visibility,
|
||||
}
|
||||
|
||||
if len(form.LoginType) > 0 {
|
||||
fields := strings.Split(form.LoginType, "-")
|
||||
if len(fields) == 2 {
|
||||
@@ -163,7 +167,7 @@ func NewUserPost(ctx *context.Context) {
|
||||
u.MustChangePassword = form.MustChangePassword
|
||||
}
|
||||
|
||||
if err := user_model.CreateUser(u, &user_model.CreateUserOverwriteOptions{Visibility: form.Visibility}); err != nil {
|
||||
if err := user_model.CreateUser(u, overwriteDefault); err != nil {
|
||||
switch {
|
||||
case user_model.IsErrUserAlreadyExist(err):
|
||||
ctx.Data["Err_UserName"] = true
|
||||
@@ -171,6 +175,9 @@ func NewUserPost(ctx *context.Context) {
|
||||
case user_model.IsErrEmailAlreadyUsed(err):
|
||||
ctx.Data["Err_Email"] = true
|
||||
ctx.RenderWithErr(ctx.Tr("form.email_been_used"), tplUserNew, &form)
|
||||
case user_model.IsErrEmailCharIsNotSupported(err):
|
||||
ctx.Data["Err_Email"] = true
|
||||
ctx.RenderWithErr(ctx.Tr("form.email_invalid"), tplUserNew, &form)
|
||||
case user_model.IsErrEmailInvalid(err):
|
||||
ctx.Data["Err_Email"] = true
|
||||
ctx.RenderWithErr(ctx.Tr("form.email_invalid"), tplUserNew, &form)
|
||||
@@ -188,7 +195,7 @@ func NewUserPost(ctx *context.Context) {
|
||||
}
|
||||
return
|
||||
}
|
||||
log.Trace("Account created by admin (%s): %s", ctx.User.Name, u.Name)
|
||||
log.Trace("Account created by admin (%s): %s", ctx.Doer.Name, u.Name)
|
||||
|
||||
// Send email notification.
|
||||
if form.SendNotify {
|
||||
@@ -376,7 +383,7 @@ func EditUserPost(ctx *context.Context) {
|
||||
u.Visibility = form.Visibility
|
||||
|
||||
// skip self Prohibit Login
|
||||
if ctx.User.ID == u.ID {
|
||||
if ctx.Doer.ID == u.ID {
|
||||
u.ProhibitLogin = false
|
||||
} else {
|
||||
u.ProhibitLogin = form.ProhibitLogin
|
||||
@@ -386,7 +393,8 @@ func EditUserPost(ctx *context.Context) {
|
||||
if user_model.IsErrEmailAlreadyUsed(err) {
|
||||
ctx.Data["Err_Email"] = true
|
||||
ctx.RenderWithErr(ctx.Tr("form.email_been_used"), tplUserEdit, &form)
|
||||
} else if user_model.IsErrEmailInvalid(err) {
|
||||
} else if user_model.IsErrEmailCharIsNotSupported(err) ||
|
||||
user_model.IsErrEmailInvalid(err) {
|
||||
ctx.Data["Err_Email"] = true
|
||||
ctx.RenderWithErr(ctx.Tr("form.email_invalid"), tplUserEdit, &form)
|
||||
} else {
|
||||
@@ -394,7 +402,7 @@ func EditUserPost(ctx *context.Context) {
|
||||
}
|
||||
return
|
||||
}
|
||||
log.Trace("Account profile updated by admin (%s): %s", ctx.User.Name, u.Name)
|
||||
log.Trace("Account profile updated by admin (%s): %s", ctx.Doer.Name, u.Name)
|
||||
|
||||
ctx.Flash.Success(ctx.Tr("admin.users.update_profile_success"))
|
||||
ctx.Redirect(setting.AppSubURL + "/admin/users/" + url.PathEscape(ctx.Params(":userid")))
|
||||
@@ -408,6 +416,15 @@ func DeleteUser(ctx *context.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
// admin should not delete themself
|
||||
if u.ID == ctx.Doer.ID {
|
||||
ctx.Flash.Error(ctx.Tr("admin.users.cannot_delete_self"))
|
||||
ctx.JSON(http.StatusOK, map[string]interface{}{
|
||||
"redirect": setting.AppSubURL + "/admin/users/" + url.PathEscape(ctx.Params(":userid")),
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
if err = user_service.DeleteUser(u); err != nil {
|
||||
switch {
|
||||
case models.IsErrUserOwnRepos(err):
|
||||
@@ -420,12 +437,17 @@ func DeleteUser(ctx *context.Context) {
|
||||
ctx.JSON(http.StatusOK, map[string]interface{}{
|
||||
"redirect": setting.AppSubURL + "/admin/users/" + url.PathEscape(ctx.Params(":userid")),
|
||||
})
|
||||
case models.IsErrUserOwnPackages(err):
|
||||
ctx.Flash.Error(ctx.Tr("admin.users.still_own_packages"))
|
||||
ctx.JSON(http.StatusOK, map[string]interface{}{
|
||||
"redirect": setting.AppSubURL + "/admin/users/" + ctx.Params(":userid"),
|
||||
})
|
||||
default:
|
||||
ctx.ServerError("DeleteUser", err)
|
||||
}
|
||||
return
|
||||
}
|
||||
log.Trace("Account deleted by admin (%s): %s", ctx.User.Name, u.Name)
|
||||
log.Trace("Account deleted by admin (%s): %s", ctx.Doer.Name, u.Name)
|
||||
|
||||
ctx.Flash.Success(ctx.Tr("admin.users.deletion_success"))
|
||||
ctx.JSON(http.StatusOK, map[string]interface{}{
|
||||
|
||||
@@ -27,7 +27,7 @@ func TestNewUserPost_MustChangePassword(t *testing.T) {
|
||||
ID: 2,
|
||||
}).(*user_model.User)
|
||||
|
||||
ctx.User = u
|
||||
ctx.Doer = u
|
||||
|
||||
username := "gitea"
|
||||
email := "gitea@gitea.io"
|
||||
@@ -64,7 +64,7 @@ func TestNewUserPost_MustChangePasswordFalse(t *testing.T) {
|
||||
ID: 2,
|
||||
}).(*user_model.User)
|
||||
|
||||
ctx.User = u
|
||||
ctx.Doer = u
|
||||
|
||||
username := "gitea"
|
||||
email := "gitea@gitea.io"
|
||||
@@ -101,7 +101,7 @@ func TestNewUserPost_InvalidEmail(t *testing.T) {
|
||||
ID: 2,
|
||||
}).(*user_model.User)
|
||||
|
||||
ctx.User = u
|
||||
ctx.Doer = u
|
||||
|
||||
username := "gitea"
|
||||
email := "gitea@gitea.io\r\n"
|
||||
@@ -131,7 +131,7 @@ func TestNewUserPost_VisibilityDefaultPublic(t *testing.T) {
|
||||
ID: 2,
|
||||
}).(*user_model.User)
|
||||
|
||||
ctx.User = u
|
||||
ctx.Doer = u
|
||||
|
||||
username := "gitea"
|
||||
email := "gitea@gitea.io"
|
||||
@@ -169,7 +169,7 @@ func TestNewUserPost_VisibilityPrivate(t *testing.T) {
|
||||
ID: 2,
|
||||
}).(*user_model.User)
|
||||
|
||||
ctx.User = u
|
||||
ctx.Doer = u
|
||||
|
||||
username := "gitea"
|
||||
email := "gitea@gitea.io"
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
// Copyright 2022 The Gitea Authors. All rights reserved.
|
||||
// Use of this source code is governed by a MIT-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build !windows
|
||||
|
||||
package web
|
||||
|
||||
import auth_service "code.gitea.io/gitea/services/auth"
|
||||
|
||||
func specialAdd(group *auth_service.Group) {}
|
||||
+31
-24
@@ -107,7 +107,7 @@ func resetLocale(ctx *context.Context, u *user_model.User) error {
|
||||
// If the user does not have a locale set, we save the current one.
|
||||
if len(u.Language) == 0 {
|
||||
u.Language = ctx.Locale.Language()
|
||||
if err := user_model.UpdateUserCols(db.DefaultContext, u, "language"); err != nil {
|
||||
if err := user_model.UpdateUserCols(ctx, u, "language"); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
@@ -195,7 +195,7 @@ func SignInPost(ctx *context.Context) {
|
||||
form := web.GetForm(ctx).(*forms.SignInForm)
|
||||
u, source, err := auth_service.UserSignIn(form.UserName, form.Password)
|
||||
if err != nil {
|
||||
if user_model.IsErrUserNotExist(err) {
|
||||
if user_model.IsErrUserNotExist(err) || user_model.IsErrEmailAddressNotExist(err) {
|
||||
ctx.RenderWithErr(ctx.Tr("form.username_password_incorrect"), tplSignIn, &form)
|
||||
log.Info("Failed authentication attempt for %s from %s: %v", form.UserName, ctx.RemoteAddr(), err)
|
||||
} else if user_model.IsErrEmailAlreadyUsed(err) {
|
||||
@@ -333,7 +333,7 @@ func handleSignInFull(ctx *context.Context, u *user_model.User, remember, obeyRe
|
||||
// If the user does not have a locale set, we save the current one.
|
||||
if len(u.Language) == 0 {
|
||||
u.Language = ctx.Locale.Language()
|
||||
if err := user_model.UpdateUserCols(db.DefaultContext, u, "language"); err != nil {
|
||||
if err := user_model.UpdateUserCols(ctx, u, "language"); err != nil {
|
||||
ctx.ServerError("UpdateUserCols Language", fmt.Errorf("Error updating user language [user: %d, locale: %s]", u.ID, u.Language))
|
||||
return setting.AppSubURL + "/"
|
||||
}
|
||||
@@ -345,12 +345,12 @@ func handleSignInFull(ctx *context.Context, u *user_model.User, remember, obeyRe
|
||||
ctx.Locale = middleware.Locale(ctx.Resp, ctx.Req)
|
||||
}
|
||||
|
||||
// Clear whatever CSRF has right now, force to generate a new one
|
||||
// Clear whatever CSRF cookie has right now, force to generate a new one
|
||||
middleware.DeleteCSRFCookie(ctx.Resp)
|
||||
|
||||
// Register last login
|
||||
u.SetLastLogin()
|
||||
if err := user_model.UpdateUserCols(db.DefaultContext, u, "last_login_unix"); err != nil {
|
||||
if err := user_model.UpdateUserCols(ctx, u, "last_login_unix"); err != nil {
|
||||
ctx.ServerError("UpdateUserCols", err)
|
||||
return setting.AppSubURL + "/"
|
||||
}
|
||||
@@ -393,8 +393,8 @@ func HandleSignOut(ctx *context.Context) {
|
||||
|
||||
// SignOut sign out from login status
|
||||
func SignOut(ctx *context.Context) {
|
||||
if ctx.User != nil {
|
||||
eventsource.GetManager().SendMessageBlocking(ctx.User.ID, &eventsource.Event{
|
||||
if ctx.Doer != nil {
|
||||
eventsource.GetManager().SendMessageBlocking(ctx.Doer.ID, &eventsource.Event{
|
||||
Name: "logout",
|
||||
Data: ctx.Session.ID(),
|
||||
})
|
||||
@@ -507,14 +507,12 @@ func SignUpPost(ctx *context.Context) {
|
||||
}
|
||||
|
||||
u := &user_model.User{
|
||||
Name: form.UserName,
|
||||
Email: form.Email,
|
||||
Passwd: form.Password,
|
||||
IsActive: !(setting.Service.RegisterEmailConfirm || setting.Service.RegisterManualConfirm),
|
||||
IsRestricted: setting.Service.DefaultUserIsRestricted,
|
||||
Name: form.UserName,
|
||||
Email: form.Email,
|
||||
Passwd: form.Password,
|
||||
}
|
||||
|
||||
if !createAndHandleCreatedUser(ctx, tplSignUp, form, u, nil, false) {
|
||||
if !createAndHandleCreatedUser(ctx, tplSignUp, form, u, nil, nil, false) {
|
||||
// error already handled
|
||||
return
|
||||
}
|
||||
@@ -525,8 +523,8 @@ func SignUpPost(ctx *context.Context) {
|
||||
|
||||
// createAndHandleCreatedUser calls createUserInContext and
|
||||
// then handleUserCreated.
|
||||
func createAndHandleCreatedUser(ctx *context.Context, tpl base.TplName, form interface{}, u *user_model.User, gothUser *goth.User, allowLink bool) bool {
|
||||
if !createUserInContext(ctx, tpl, form, u, gothUser, allowLink) {
|
||||
func createAndHandleCreatedUser(ctx *context.Context, tpl base.TplName, form interface{}, u *user_model.User, overwrites *user_model.CreateUserOverwriteOptions, gothUser *goth.User, allowLink bool) bool {
|
||||
if !createUserInContext(ctx, tpl, form, u, overwrites, gothUser, allowLink) {
|
||||
return false
|
||||
}
|
||||
return handleUserCreated(ctx, u, gothUser)
|
||||
@@ -534,8 +532,8 @@ func createAndHandleCreatedUser(ctx *context.Context, tpl base.TplName, form int
|
||||
|
||||
// createUserInContext creates a user and handles errors within a given context.
|
||||
// Optionally a template can be specified.
|
||||
func createUserInContext(ctx *context.Context, tpl base.TplName, form interface{}, u *user_model.User, gothUser *goth.User, allowLink bool) (ok bool) {
|
||||
if err := user_model.CreateUser(u); err != nil {
|
||||
func createUserInContext(ctx *context.Context, tpl base.TplName, form interface{}, u *user_model.User, overwrites *user_model.CreateUserOverwriteOptions, gothUser *goth.User, allowLink bool) (ok bool) {
|
||||
if err := user_model.CreateUser(u, overwrites); err != nil {
|
||||
if allowLink && (user_model.IsErrUserAlreadyExist(err) || user_model.IsErrEmailAlreadyUsed(err)) {
|
||||
if setting.OAuth2Client.AccountLinking == setting.OAuth2AccountLinkingAuto {
|
||||
var user *user_model.User
|
||||
@@ -573,6 +571,9 @@ func createUserInContext(ctx *context.Context, tpl base.TplName, form interface{
|
||||
case user_model.IsErrEmailAlreadyUsed(err):
|
||||
ctx.Data["Err_Email"] = true
|
||||
ctx.RenderWithErr(ctx.Tr("form.email_been_used"), tpl, form)
|
||||
case user_model.IsErrEmailCharIsNotSupported(err):
|
||||
ctx.Data["Err_Email"] = true
|
||||
ctx.RenderWithErr(ctx.Tr("form.email_invalid"), tpl, form)
|
||||
case user_model.IsErrEmailInvalid(err):
|
||||
ctx.Data["Err_Email"] = true
|
||||
ctx.RenderWithErr(ctx.Tr("form.email_invalid"), tpl, form)
|
||||
@@ -599,11 +600,11 @@ func createUserInContext(ctx *context.Context, tpl base.TplName, form interface{
|
||||
// sends a confirmation email if required.
|
||||
func handleUserCreated(ctx *context.Context, u *user_model.User, gothUser *goth.User) (ok bool) {
|
||||
// Auto-set admin for the only user.
|
||||
if user_model.CountUsers() == 1 {
|
||||
if user_model.CountUsers(nil) == 1 {
|
||||
u.IsAdmin = true
|
||||
u.IsActive = true
|
||||
u.SetLastLogin()
|
||||
if err := user_model.UpdateUserCols(db.DefaultContext, u, "is_admin", "is_active", "last_login_unix"); err != nil {
|
||||
if err := user_model.UpdateUserCols(ctx, u, "is_admin", "is_active", "last_login_unix"); err != nil {
|
||||
ctx.ServerError("UpdateUser", err)
|
||||
return
|
||||
}
|
||||
@@ -618,6 +619,12 @@ func handleUserCreated(ctx *context.Context, u *user_model.User, gothUser *goth.
|
||||
|
||||
// Send confirmation email
|
||||
if !u.IsActive && u.ID > 1 {
|
||||
if setting.Service.RegisterManualConfirm {
|
||||
ctx.Data["ManualActivationOnly"] = true
|
||||
ctx.HTML(http.StatusOK, TplActivate)
|
||||
return
|
||||
}
|
||||
|
||||
mailer.SendActivateAccountMail(ctx.Locale, u)
|
||||
|
||||
ctx.Data["IsSendRegisterMail"] = true
|
||||
@@ -640,19 +647,19 @@ func Activate(ctx *context.Context) {
|
||||
|
||||
if len(code) == 0 {
|
||||
ctx.Data["IsActivatePage"] = true
|
||||
if ctx.User == nil || ctx.User.IsActive {
|
||||
if ctx.Doer == nil || ctx.Doer.IsActive {
|
||||
ctx.NotFound("invalid user", nil)
|
||||
return
|
||||
}
|
||||
// Resend confirmation email.
|
||||
if setting.Service.RegisterEmailConfirm {
|
||||
if ctx.Cache.IsExist("MailResendLimit_" + ctx.User.LowerName) {
|
||||
if ctx.Cache.IsExist("MailResendLimit_" + ctx.Doer.LowerName) {
|
||||
ctx.Data["ResendLimited"] = true
|
||||
} else {
|
||||
ctx.Data["ActiveCodeLives"] = timeutil.MinutesToFriendly(setting.Service.ActiveCodeLives, ctx.Locale.Language())
|
||||
mailer.SendActivateAccountMail(ctx.Locale, ctx.User)
|
||||
mailer.SendActivateAccountMail(ctx.Locale, ctx.Doer)
|
||||
|
||||
if err := ctx.Cache.Put("MailResendLimit_"+ctx.User.LowerName, ctx.User.LowerName, 180); err != nil {
|
||||
if err := ctx.Cache.Put("MailResendLimit_"+ctx.Doer.LowerName, ctx.Doer.LowerName, 180); err != nil {
|
||||
log.Error("Set cache(MailResendLimit) fail: %v", err)
|
||||
}
|
||||
}
|
||||
@@ -724,7 +731,7 @@ func handleAccountActivation(ctx *context.Context, user *user_model.User) {
|
||||
ctx.ServerError("UpdateUser", err)
|
||||
return
|
||||
}
|
||||
if err := user_model.UpdateUserCols(db.DefaultContext, user, "is_active", "rands"); err != nil {
|
||||
if err := user_model.UpdateUserCols(ctx, user, "is_active", "rands"); err != nil {
|
||||
if user_model.IsErrUserNotExist(err) {
|
||||
ctx.NotFound("UpdateUserCols", err)
|
||||
} else {
|
||||
|
||||
@@ -283,13 +283,12 @@ func LinkAccountPostRegister(ctx *context.Context) {
|
||||
Name: form.UserName,
|
||||
Email: form.Email,
|
||||
Passwd: form.Password,
|
||||
IsActive: !(setting.Service.RegisterEmailConfirm || setting.Service.RegisterManualConfirm),
|
||||
LoginType: auth.OAuth2,
|
||||
LoginSource: authSource.ID,
|
||||
LoginName: gothUser.UserID,
|
||||
}
|
||||
|
||||
if !createAndHandleCreatedUser(ctx, tplLinkAccount, form, u, &gothUser, false) {
|
||||
if !createAndHandleCreatedUser(ctx, tplLinkAccount, form, u, nil, &gothUser, false) {
|
||||
// error already handled
|
||||
return
|
||||
}
|
||||
|
||||
@@ -12,5 +12,7 @@ import (
|
||||
)
|
||||
|
||||
func TestMain(m *testing.M) {
|
||||
unittest.MainTest(m, filepath.Join("..", "..", ".."))
|
||||
unittest.MainTest(m, &unittest.TestOptions{
|
||||
GiteaRootPath: filepath.Join("..", "..", ".."),
|
||||
})
|
||||
}
|
||||
|
||||
+29
-27
@@ -16,7 +16,6 @@ import (
|
||||
|
||||
"code.gitea.io/gitea/models"
|
||||
"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/base"
|
||||
"code.gitea.io/gitea/modules/context"
|
||||
@@ -25,6 +24,7 @@ import (
|
||||
"code.gitea.io/gitea/modules/session"
|
||||
"code.gitea.io/gitea/modules/setting"
|
||||
"code.gitea.io/gitea/modules/timeutil"
|
||||
"code.gitea.io/gitea/modules/util"
|
||||
"code.gitea.io/gitea/modules/web"
|
||||
"code.gitea.io/gitea/modules/web/middleware"
|
||||
auth_service "code.gitea.io/gitea/services/auth"
|
||||
@@ -267,21 +267,21 @@ type userInfoResponse struct {
|
||||
|
||||
// InfoOAuth manages request for userinfo endpoint
|
||||
func InfoOAuth(ctx *context.Context) {
|
||||
if ctx.User == nil || ctx.Data["AuthedMethod"] != (&auth_service.OAuth2{}).Name() {
|
||||
if ctx.Doer == nil || ctx.Data["AuthedMethod"] != (&auth_service.OAuth2{}).Name() {
|
||||
ctx.Resp.Header().Set("WWW-Authenticate", `Bearer realm=""`)
|
||||
ctx.PlainText(http.StatusUnauthorized, "no valid authorization")
|
||||
return
|
||||
}
|
||||
|
||||
response := &userInfoResponse{
|
||||
Sub: fmt.Sprint(ctx.User.ID),
|
||||
Name: ctx.User.FullName,
|
||||
Username: ctx.User.Name,
|
||||
Email: ctx.User.Email,
|
||||
Picture: ctx.User.AvatarLink(),
|
||||
Sub: fmt.Sprint(ctx.Doer.ID),
|
||||
Name: ctx.Doer.FullName,
|
||||
Username: ctx.Doer.Name,
|
||||
Email: ctx.Doer.Email,
|
||||
Picture: ctx.Doer.AvatarLink(),
|
||||
}
|
||||
|
||||
groups, err := getOAuthGroupsForUser(ctx.User)
|
||||
groups, err := getOAuthGroupsForUser(ctx.Doer)
|
||||
if err != nil {
|
||||
ctx.ServerError("Oauth groups for user", err)
|
||||
return
|
||||
@@ -317,7 +317,7 @@ func getOAuthGroupsForUser(user *user_model.User) ([]string, error) {
|
||||
|
||||
// IntrospectOAuth introspects an oauth token
|
||||
func IntrospectOAuth(ctx *context.Context) {
|
||||
if ctx.User == nil {
|
||||
if ctx.Doer == nil {
|
||||
ctx.Resp.Header().Set("WWW-Authenticate", `Bearer realm=""`)
|
||||
ctx.PlainText(http.StatusUnauthorized, "no valid authorization")
|
||||
return
|
||||
@@ -438,7 +438,7 @@ func AuthorizeOAuth(ctx *context.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
grant, err := app.GetGrantByUserID(ctx.User.ID)
|
||||
grant, err := app.GetGrantByUserID(ctx.Doer.ID)
|
||||
if err != nil {
|
||||
handleServerError(ctx, form.State, form.RedirectURI)
|
||||
return
|
||||
@@ -463,7 +463,7 @@ func AuthorizeOAuth(ctx *context.Context) {
|
||||
log.Error("Unable to update nonce: %v", err)
|
||||
}
|
||||
}
|
||||
ctx.Redirect(redirect.String(), 302)
|
||||
ctx.Redirect(redirect.String())
|
||||
return
|
||||
}
|
||||
|
||||
@@ -515,7 +515,7 @@ func GrantApplicationOAuth(ctx *context.Context) {
|
||||
ctx.ServerError("GetOAuth2ApplicationByClientID", err)
|
||||
return
|
||||
}
|
||||
grant, err := app.CreateGrant(ctx.User.ID, form.Scope)
|
||||
grant, err := app.CreateGrant(ctx.Doer.ID, form.Scope)
|
||||
if err != nil {
|
||||
handleAuthorizeError(ctx, AuthorizeError{
|
||||
State: form.State,
|
||||
@@ -545,7 +545,7 @@ func GrantApplicationOAuth(ctx *context.Context) {
|
||||
handleServerError(ctx, form.State, form.RedirectURI)
|
||||
return
|
||||
}
|
||||
ctx.Redirect(redirect.String(), 302)
|
||||
ctx.Redirect(redirect.String(), http.StatusSeeOther)
|
||||
}
|
||||
|
||||
// OIDCWellKnown generates JSON so OIDC clients know Gitea's capabilities
|
||||
@@ -753,7 +753,7 @@ func handleAuthorizeError(ctx *context.Context, authErr AuthorizeError, redirect
|
||||
if redirectURI == "" {
|
||||
log.Warn("Authorization failed: %v", authErr.ErrorDescription)
|
||||
ctx.Data["Error"] = authErr
|
||||
ctx.HTML(400, tplGrantError)
|
||||
ctx.HTML(http.StatusBadRequest, tplGrantError)
|
||||
return
|
||||
}
|
||||
redirect, err := url.Parse(redirectURI)
|
||||
@@ -766,7 +766,7 @@ func handleAuthorizeError(ctx *context.Context, authErr AuthorizeError, redirect
|
||||
q.Set("error_description", authErr.ErrorDescription)
|
||||
q.Set("state", authErr.State)
|
||||
redirect.RawQuery = q.Encode()
|
||||
ctx.Redirect(redirect.String(), 302)
|
||||
ctx.Redirect(redirect.String(), http.StatusSeeOther)
|
||||
}
|
||||
|
||||
// SignInOAuth handles the OAuth2 login buttons
|
||||
@@ -868,19 +868,21 @@ func SignInOAuthCallback(ctx *context.Context) {
|
||||
return
|
||||
}
|
||||
u = &user_model.User{
|
||||
Name: getUserName(&gothUser),
|
||||
FullName: gothUser.Name,
|
||||
Email: gothUser.Email,
|
||||
IsActive: !setting.OAuth2Client.RegisterEmailConfirm,
|
||||
LoginType: auth.OAuth2,
|
||||
LoginSource: authSource.ID,
|
||||
LoginName: gothUser.UserID,
|
||||
IsRestricted: setting.Service.DefaultUserIsRestricted,
|
||||
Name: getUserName(&gothUser),
|
||||
FullName: gothUser.Name,
|
||||
Email: gothUser.Email,
|
||||
LoginType: auth.OAuth2,
|
||||
LoginSource: authSource.ID,
|
||||
LoginName: gothUser.UserID,
|
||||
}
|
||||
|
||||
overwriteDefault := &user_model.CreateUserOverwriteOptions{
|
||||
IsActive: util.OptionalBoolOf(!setting.OAuth2Client.RegisterEmailConfirm),
|
||||
}
|
||||
|
||||
setUserGroupClaims(authSource, u, &gothUser)
|
||||
|
||||
if !createAndHandleCreatedUser(ctx, base.TplName(""), nil, u, &gothUser, setting.OAuth2Client.AccountLinking != setting.OAuth2AccountLinkingDisabled) {
|
||||
if !createAndHandleCreatedUser(ctx, base.TplName(""), nil, u, overwriteDefault, &gothUser, setting.OAuth2Client.AccountLinking != setting.OAuth2AccountLinkingDisabled) {
|
||||
// error already handled
|
||||
return
|
||||
}
|
||||
@@ -1008,7 +1010,7 @@ func handleOAuth2SignIn(ctx *context.Context, source *auth.Source, u *user_model
|
||||
log.Error("Error storing session: %v", err)
|
||||
}
|
||||
|
||||
// Clear whatever CSRF has right now, force to generate a new one
|
||||
// Clear whatever CSRF cookie has right now, force to generate a new one
|
||||
middleware.DeleteCSRFCookie(ctx.Resp)
|
||||
|
||||
// Register last login
|
||||
@@ -1021,7 +1023,7 @@ func handleOAuth2SignIn(ctx *context.Context, source *auth.Source, u *user_model
|
||||
cols = append(cols, "is_admin", "is_restricted")
|
||||
}
|
||||
|
||||
if err := user_model.UpdateUserCols(db.DefaultContext, u, cols...); err != nil {
|
||||
if err := user_model.UpdateUserCols(ctx, u, cols...); err != nil {
|
||||
ctx.ServerError("UpdateUserCols", err)
|
||||
return
|
||||
}
|
||||
@@ -1048,7 +1050,7 @@ func handleOAuth2SignIn(ctx *context.Context, source *auth.Source, u *user_model
|
||||
|
||||
changed := setUserGroupClaims(source, u, &gothUser)
|
||||
if changed {
|
||||
if err := user_model.UpdateUserCols(db.DefaultContext, u, "is_admin", "is_restricted"); err != nil {
|
||||
if err := user_model.UpdateUserCols(ctx, u, "is_admin", "is_restricted"); err != nil {
|
||||
ctx.ServerError("UpdateUserCols", err)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -423,12 +423,11 @@ func RegisterOpenIDPost(ctx *context.Context) {
|
||||
}
|
||||
|
||||
u := &user_model.User{
|
||||
Name: form.UserName,
|
||||
Email: form.Email,
|
||||
Passwd: password,
|
||||
IsActive: !(setting.Service.RegisterEmailConfirm || setting.Service.RegisterManualConfirm),
|
||||
Name: form.UserName,
|
||||
Email: form.Email,
|
||||
Passwd: password,
|
||||
}
|
||||
if !createUserInContext(ctx, tplSignUpOID, form, u, nil, false) {
|
||||
if !createUserInContext(ctx, tplSignUpOID, form, u, nil, nil, false) {
|
||||
// error already handled
|
||||
return
|
||||
}
|
||||
|
||||
@@ -9,7 +9,6 @@ import (
|
||||
"net/http"
|
||||
|
||||
"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/base"
|
||||
"code.gitea.io/gitea/modules/context"
|
||||
@@ -103,7 +102,7 @@ func commonResetPassword(ctx *context.Context) (*user_model.User, *auth.TwoFacto
|
||||
ctx.Data["Title"] = ctx.Tr("auth.reset_password")
|
||||
ctx.Data["Code"] = code
|
||||
|
||||
if nil != ctx.User {
|
||||
if nil != ctx.Doer {
|
||||
ctx.Data["user_signed_in"] = true
|
||||
}
|
||||
|
||||
@@ -133,8 +132,8 @@ func commonResetPassword(ctx *context.Context) (*user_model.User, *auth.TwoFacto
|
||||
// Show the user that they are affecting the account that they intended to
|
||||
ctx.Data["user_email"] = u.Email
|
||||
|
||||
if nil != ctx.User && u.ID != ctx.User.ID {
|
||||
ctx.Flash.Error(ctx.Tr("auth.reset_password_wrong_user", ctx.User.Email, u.Email))
|
||||
if nil != ctx.Doer && u.ID != ctx.Doer.ID {
|
||||
ctx.Flash.Error(ctx.Tr("auth.reset_password_wrong_user", ctx.Doer.Email, u.Email))
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
@@ -232,7 +231,7 @@ func ResetPasswdPost(ctx *context.Context) {
|
||||
return
|
||||
}
|
||||
u.MustChangePassword = false
|
||||
if err := user_model.UpdateUserCols(db.DefaultContext, u, "must_change_password", "passwd", "passwd_hash_algo", "rands", "salt"); err != nil {
|
||||
if err := user_model.UpdateUserCols(ctx, u, "must_change_password", "passwd", "passwd_hash_algo", "rands", "salt"); err != nil {
|
||||
ctx.ServerError("UpdateUser", err)
|
||||
return
|
||||
}
|
||||
@@ -283,7 +282,7 @@ func MustChangePasswordPost(ctx *context.Context) {
|
||||
ctx.HTML(http.StatusOK, tplMustChangePassword)
|
||||
return
|
||||
}
|
||||
u := ctx.User
|
||||
u := ctx.Doer
|
||||
// Make sure only requests for users who are eligible to change their password via
|
||||
// this method passes through
|
||||
if !u.MustChangePassword {
|
||||
@@ -327,7 +326,7 @@ func MustChangePasswordPost(ctx *context.Context) {
|
||||
|
||||
u.MustChangePassword = false
|
||||
|
||||
if err := user_model.UpdateUserCols(db.DefaultContext, u, "must_change_password", "passwd", "passwd_hash_algo", "salt"); err != nil {
|
||||
if err := user_model.UpdateUserCols(ctx, u, "must_change_password", "passwd", "passwd_hash_algo", "salt"); err != nil {
|
||||
ctx.ServerError("UpdateUser", err)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -39,7 +39,7 @@ func WebAuthn(ctx *context.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
ctx.HTML(200, tplWebAuthn)
|
||||
ctx.HTML(http.StatusOK, tplWebAuthn)
|
||||
}
|
||||
|
||||
// WebAuthnLoginAssertion submits a WebAuthn challenge to the browser
|
||||
@@ -166,5 +166,5 @@ func WebAuthnLoginAssertionPost(ctx *context.Context) {
|
||||
}
|
||||
}
|
||||
|
||||
ctx.JSON(200, map[string]string{"redirect": redirect})
|
||||
ctx.JSON(http.StatusOK, map[string]string{"redirect": redirect})
|
||||
}
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
// Copyright 2022 The Gitea Authors. All rights reserved.
|
||||
// Use of this source code is governed by a MIT-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package web
|
||||
|
||||
import (
|
||||
"code.gitea.io/gitea/models/auth"
|
||||
auth_service "code.gitea.io/gitea/services/auth"
|
||||
)
|
||||
|
||||
// specialAdd registers the SSPI auth method as the last method in the list.
|
||||
// The SSPI plugin is expected to be executed last, as it returns 401 status code if negotiation
|
||||
// fails (or if negotiation should continue), which would prevent other authentication methods
|
||||
// to execute at all.
|
||||
func specialAdd(group *auth_service.Group) {
|
||||
if auth.IsSSPIEnabled() {
|
||||
group.Add(&auth_service.SSPI{})
|
||||
}
|
||||
}
|
||||
+17
-18
@@ -11,7 +11,6 @@ import (
|
||||
"net/http"
|
||||
"os"
|
||||
"path"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"code.gitea.io/gitea/modules/context"
|
||||
@@ -28,6 +27,7 @@ import (
|
||||
)
|
||||
|
||||
func storageHandler(storageSetting setting.Storage, prefix string, objStore storage.ObjectStorage) func(next http.Handler) http.Handler {
|
||||
prefix = strings.Trim(prefix, "/")
|
||||
funcInfo := routing.GetFuncInfo(storageHandler, prefix)
|
||||
return func(next http.Handler) http.Handler {
|
||||
if storageSetting.ServeDirect {
|
||||
@@ -37,29 +37,32 @@ func storageHandler(storageSetting setting.Storage, prefix string, objStore stor
|
||||
return
|
||||
}
|
||||
|
||||
if !strings.HasPrefix(req.URL.RequestURI(), "/"+prefix) {
|
||||
if !strings.HasPrefix(req.URL.Path, "/"+prefix+"/") {
|
||||
next.ServeHTTP(w, req)
|
||||
return
|
||||
}
|
||||
routing.UpdateFuncInfo(req.Context(), funcInfo)
|
||||
|
||||
rPath := strings.TrimPrefix(req.URL.RequestURI(), "/"+prefix)
|
||||
rPath := strings.TrimPrefix(req.URL.Path, "/"+prefix+"/")
|
||||
rPath = path.Clean("/" + strings.ReplaceAll(rPath, "\\", "/"))[1:]
|
||||
|
||||
u, err := objStore.URL(rPath, path.Base(rPath))
|
||||
if err != nil {
|
||||
if os.IsNotExist(err) || errors.Is(err, os.ErrNotExist) {
|
||||
log.Warn("Unable to find %s %s", prefix, rPath)
|
||||
http.Error(w, "file not found", 404)
|
||||
http.Error(w, "file not found", http.StatusNotFound)
|
||||
return
|
||||
}
|
||||
log.Error("Error whilst getting URL for %s %s. Error: %v", prefix, rPath, err)
|
||||
http.Error(w, fmt.Sprintf("Error whilst getting URL for %s %s", prefix, rPath), 500)
|
||||
http.Error(w, fmt.Sprintf("Error whilst getting URL for %s %s", prefix, rPath), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
http.Redirect(
|
||||
w,
|
||||
req,
|
||||
u.String(),
|
||||
301,
|
||||
http.StatusPermanentRedirect,
|
||||
)
|
||||
})
|
||||
}
|
||||
@@ -70,22 +73,18 @@ func storageHandler(storageSetting setting.Storage, prefix string, objStore stor
|
||||
return
|
||||
}
|
||||
|
||||
prefix := strings.Trim(prefix, "/")
|
||||
|
||||
if !strings.HasPrefix(req.URL.EscapedPath(), "/"+prefix+"/") {
|
||||
if !strings.HasPrefix(req.URL.Path, "/"+prefix+"/") {
|
||||
next.ServeHTTP(w, req)
|
||||
return
|
||||
}
|
||||
routing.UpdateFuncInfo(req.Context(), funcInfo)
|
||||
|
||||
rPath := strings.TrimPrefix(req.URL.EscapedPath(), "/"+prefix+"/")
|
||||
rPath = strings.TrimPrefix(rPath, "/")
|
||||
rPath := strings.TrimPrefix(req.URL.Path, "/"+prefix+"/")
|
||||
rPath = path.Clean("/" + strings.ReplaceAll(rPath, "\\", "/"))[1:]
|
||||
if rPath == "" {
|
||||
http.Error(w, "file not found", 404)
|
||||
http.Error(w, "file not found", http.StatusNotFound)
|
||||
return
|
||||
}
|
||||
rPath = path.Clean("/" + filepath.ToSlash(rPath))
|
||||
rPath = rPath[1:]
|
||||
|
||||
fi, err := objStore.Stat(rPath)
|
||||
if err == nil && httpcache.HandleTimeCache(req, w, fi) {
|
||||
@@ -97,11 +96,11 @@ func storageHandler(storageSetting setting.Storage, prefix string, objStore stor
|
||||
if err != nil {
|
||||
if os.IsNotExist(err) || errors.Is(err, os.ErrNotExist) {
|
||||
log.Warn("Unable to find %s %s", prefix, rPath)
|
||||
http.Error(w, "file not found", 404)
|
||||
http.Error(w, "file not found", http.StatusNotFound)
|
||||
return
|
||||
}
|
||||
log.Error("Error whilst opening %s %s. Error: %v", prefix, rPath, err)
|
||||
http.Error(w, fmt.Sprintf("Error whilst opening %s %s", prefix, rPath), 500)
|
||||
http.Error(w, fmt.Sprintf("Error whilst opening %s %s", prefix, rPath), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
defer fr.Close()
|
||||
@@ -109,7 +108,7 @@ func storageHandler(storageSetting setting.Storage, prefix string, objStore stor
|
||||
_, err = io.Copy(w, fr)
|
||||
if err != nil {
|
||||
log.Error("Error whilst rendering %s %s. Error: %v", prefix, rPath, err)
|
||||
http.Error(w, fmt.Sprintf("Error whilst rendering %s %s", prefix, rPath), 500)
|
||||
http.Error(w, fmt.Sprintf("Error whilst rendering %s %s", prefix, rPath), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
})
|
||||
@@ -164,7 +163,7 @@ func Recovery() func(next http.Handler) http.Handler {
|
||||
if !setting.IsProd {
|
||||
store["ErrorMsg"] = combinedErr
|
||||
}
|
||||
err = rnd.HTML(w, 500, "status/500", templates.BaseVars().Merge(store))
|
||||
err = rnd.HTML(w, http.StatusInternalServerError, "status/500", templates.BaseVars().Merge(store))
|
||||
if err != nil {
|
||||
log.Error("%v", err)
|
||||
}
|
||||
|
||||
@@ -8,15 +8,10 @@ import (
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"code.gitea.io/gitea/models"
|
||||
"code.gitea.io/gitea/models/db"
|
||||
"code.gitea.io/gitea/modules/context"
|
||||
"code.gitea.io/gitea/modules/convert"
|
||||
"code.gitea.io/gitea/modules/eventsource"
|
||||
"code.gitea.io/gitea/modules/graceful"
|
||||
"code.gitea.io/gitea/modules/json"
|
||||
"code.gitea.io/gitea/modules/log"
|
||||
"code.gitea.io/gitea/modules/setting"
|
||||
"code.gitea.io/gitea/routers/web/auth"
|
||||
)
|
||||
|
||||
@@ -48,7 +43,7 @@ func Events(ctx *context.Context) {
|
||||
|
||||
shutdownCtx := graceful.GetManager().ShutdownContext()
|
||||
|
||||
uid := ctx.User.ID
|
||||
uid := ctx.Doer.ID
|
||||
|
||||
messageChan := eventsource.GetManager().Register(uid)
|
||||
|
||||
@@ -71,8 +66,6 @@ func Events(ctx *context.Context) {
|
||||
|
||||
timer := time.NewTicker(30 * time.Second)
|
||||
|
||||
stopwatchTimer := time.NewTicker(setting.UI.Notification.MinTimeout)
|
||||
|
||||
loop:
|
||||
for {
|
||||
select {
|
||||
@@ -82,7 +75,7 @@ loop:
|
||||
}
|
||||
_, err := event.WriteTo(ctx.Resp)
|
||||
if err != nil {
|
||||
log.Error("Unable to write to EventStream for user %s: %v", ctx.User.Name, err)
|
||||
log.Error("Unable to write to EventStream for user %s: %v", ctx.Doer.Name, err)
|
||||
go unregister()
|
||||
break loop
|
||||
}
|
||||
@@ -93,32 +86,6 @@ loop:
|
||||
case <-shutdownCtx.Done():
|
||||
go unregister()
|
||||
break loop
|
||||
case <-stopwatchTimer.C:
|
||||
sws, err := models.GetUserStopwatches(ctx.User.ID, db.ListOptions{})
|
||||
if err != nil {
|
||||
log.Error("Unable to GetUserStopwatches: %v", err)
|
||||
continue
|
||||
}
|
||||
apiSWs, err := convert.ToStopWatches(sws)
|
||||
if err != nil {
|
||||
log.Error("Unable to APIFormat stopwatches: %v", err)
|
||||
continue
|
||||
}
|
||||
dataBs, err := json.Marshal(apiSWs)
|
||||
if err != nil {
|
||||
log.Error("Unable to marshal stopwatches: %v", err)
|
||||
continue
|
||||
}
|
||||
_, err = (&eventsource.Event{
|
||||
Name: "stopwatches",
|
||||
Data: string(dataBs),
|
||||
}).WriteTo(ctx.Resp)
|
||||
if err != nil {
|
||||
log.Error("Unable to write to EventStream for user %s: %v", ctx.User.Name, err)
|
||||
go unregister()
|
||||
break loop
|
||||
}
|
||||
ctx.Resp.Flush()
|
||||
case event, ok := <-messageChan:
|
||||
if !ok {
|
||||
break loop
|
||||
@@ -145,7 +112,7 @@ loop:
|
||||
|
||||
_, err := event.WriteTo(ctx.Resp)
|
||||
if err != nil {
|
||||
log.Error("Unable to write to EventStream for user %s: %v", ctx.User.Name, err)
|
||||
log.Error("Unable to write to EventStream for user %s: %v", ctx.Doer.Name, err)
|
||||
go unregister()
|
||||
break loop
|
||||
}
|
||||
|
||||
@@ -24,7 +24,7 @@ const (
|
||||
// Code render explore code page
|
||||
func Code(ctx *context.Context) {
|
||||
if !setting.Indexer.RepoIndexerEnabled {
|
||||
ctx.Redirect(setting.AppSubURL+"/explore", 302)
|
||||
ctx.Redirect(setting.AppSubURL + "/explore")
|
||||
return
|
||||
}
|
||||
|
||||
@@ -49,13 +49,13 @@ func Code(ctx *context.Context) {
|
||||
err error
|
||||
isAdmin bool
|
||||
)
|
||||
if ctx.User != nil {
|
||||
isAdmin = ctx.User.IsAdmin
|
||||
if ctx.Doer != nil {
|
||||
isAdmin = ctx.Doer.IsAdmin
|
||||
}
|
||||
|
||||
// guest user or non-admin user
|
||||
if ctx.User == nil || !isAdmin {
|
||||
repoIDs, err = models.FindUserAccessibleRepoIDs(ctx.User)
|
||||
if ctx.Doer == nil || !isAdmin {
|
||||
repoIDs, err = models.FindUserAccessibleRepoIDs(ctx.Doer)
|
||||
if err != nil {
|
||||
ctx.ServerError("SearchResults", err)
|
||||
return
|
||||
@@ -69,7 +69,7 @@ func Code(ctx *context.Context) {
|
||||
)
|
||||
|
||||
// if non-admin login user, we need check UnitTypeCode at first
|
||||
if ctx.User != nil && len(repoIDs) > 0 {
|
||||
if ctx.Doer != nil && len(repoIDs) > 0 {
|
||||
repoMaps, err := repo_model.GetRepositoriesMapByIDs(repoIDs)
|
||||
if err != nil {
|
||||
ctx.ServerError("SearchResults", err)
|
||||
@@ -79,7 +79,7 @@ func Code(ctx *context.Context) {
|
||||
rightRepoMap := make(map[int64]*repo_model.Repository, len(repoMaps))
|
||||
repoIDs = make([]int64, 0, len(repoMaps))
|
||||
for id, repo := range repoMaps {
|
||||
if models.CheckRepoUnitUser(repo, ctx.User, unit.TypeCode) {
|
||||
if models.CheckRepoUnitUser(repo, ctx.Doer, unit.TypeCode) {
|
||||
rightRepoMap[id] = repo
|
||||
repoIDs = append(repoIDs, id)
|
||||
}
|
||||
@@ -98,7 +98,7 @@ func Code(ctx *context.Context) {
|
||||
ctx.Data["CodeIndexerUnavailable"] = !code_indexer.IsAvailable()
|
||||
}
|
||||
// if non-login user or isAdmin, no need to check UnitTypeCode
|
||||
} else if (ctx.User == nil && len(repoIDs) > 0) || isAdmin {
|
||||
} else if (ctx.Doer == nil && len(repoIDs) > 0) || isAdmin {
|
||||
total, searchResults, searchResultLanguages, err = code_indexer.PerformSearch(ctx, repoIDs, language, keyword, page, setting.UI.RepoSearchPagingNum, isMatch)
|
||||
if err != nil {
|
||||
if code_indexer.IsAvailable() {
|
||||
@@ -138,7 +138,6 @@ func Code(ctx *context.Context) {
|
||||
ctx.Data["queryType"] = queryType
|
||||
ctx.Data["SearchResults"] = searchResults
|
||||
ctx.Data["SearchResultLanguages"] = searchResultLanguages
|
||||
ctx.Data["RequireHighlightJS"] = true
|
||||
ctx.Data["PageIsViewCode"] = true
|
||||
|
||||
pager := context.NewPagination(total, setting.UI.RepoSearchPagingNum, page, 5)
|
||||
|
||||
@@ -27,12 +27,12 @@ func Organizations(ctx *context.Context) {
|
||||
ctx.Data["IsRepoIndexerEnabled"] = setting.Indexer.RepoIndexerEnabled
|
||||
|
||||
visibleTypes := []structs.VisibleType{structs.VisibleTypePublic}
|
||||
if ctx.User != nil {
|
||||
if ctx.Doer != nil {
|
||||
visibleTypes = append(visibleTypes, structs.VisibleTypeLimited, structs.VisibleTypePrivate)
|
||||
}
|
||||
|
||||
RenderUserSearch(ctx, &user_model.SearchUserOptions{
|
||||
Actor: ctx.User,
|
||||
Actor: ctx.Doer,
|
||||
Type: user_model.UserTypeOrganization,
|
||||
ListOptions: db.ListOptions{PageSize: setting.UI.ExplorePagingNum},
|
||||
Visible: visibleTypes,
|
||||
|
||||
@@ -86,7 +86,7 @@ func RenderRepoSearch(ctx *context.Context, opts *RepoSearchOptions) {
|
||||
Page: page,
|
||||
PageSize: opts.PageSize,
|
||||
},
|
||||
Actor: ctx.User,
|
||||
Actor: ctx.Doer,
|
||||
OrderBy: orderBy,
|
||||
Private: opts.Private,
|
||||
Keyword: keyword,
|
||||
@@ -124,14 +124,14 @@ func Repos(ctx *context.Context) {
|
||||
ctx.Data["IsRepoIndexerEnabled"] = setting.Indexer.RepoIndexerEnabled
|
||||
|
||||
var ownerID int64
|
||||
if ctx.User != nil && !ctx.User.IsAdmin {
|
||||
ownerID = ctx.User.ID
|
||||
if ctx.Doer != nil && !ctx.Doer.IsAdmin {
|
||||
ownerID = ctx.Doer.ID
|
||||
}
|
||||
|
||||
RenderRepoSearch(ctx, &RepoSearchOptions{
|
||||
PageSize: setting.UI.ExplorePagingNum,
|
||||
OwnerID: ownerID,
|
||||
Private: ctx.User != nil,
|
||||
Private: ctx.Doer != nil,
|
||||
TplName: tplExploreRepos,
|
||||
})
|
||||
}
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
// Copyright 2022 The Gitea Authors. All rights reserved.
|
||||
// Use of this source code is governed by a MIT-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package explore
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"code.gitea.io/gitea/models/db"
|
||||
repo_model "code.gitea.io/gitea/models/repo"
|
||||
"code.gitea.io/gitea/modules/context"
|
||||
"code.gitea.io/gitea/modules/convert"
|
||||
api "code.gitea.io/gitea/modules/structs"
|
||||
)
|
||||
|
||||
// TopicSearch search for creating topic
|
||||
func TopicSearch(ctx *context.Context) {
|
||||
opts := &repo_model.FindTopicOptions{
|
||||
Keyword: ctx.FormString("q"),
|
||||
ListOptions: db.ListOptions{
|
||||
Page: ctx.FormInt("page"),
|
||||
PageSize: convert.ToCorrectPageSize(ctx.FormInt("limit")),
|
||||
},
|
||||
}
|
||||
|
||||
topics, total, err := repo_model.FindTopics(opts)
|
||||
if err != nil {
|
||||
ctx.Error(http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
topicResponses := make([]*api.TopicResponse, len(topics))
|
||||
for i, topic := range topics {
|
||||
topicResponses[i] = convert.ToTopicResponse(topic)
|
||||
}
|
||||
|
||||
ctx.SetTotalCountHeader(total)
|
||||
ctx.JSON(http.StatusOK, map[string]interface{}{
|
||||
"topics": topicResponses,
|
||||
})
|
||||
}
|
||||
@@ -102,7 +102,7 @@ func Users(ctx *context.Context) {
|
||||
ctx.Data["IsRepoIndexerEnabled"] = setting.Indexer.RepoIndexerEnabled
|
||||
|
||||
RenderUserSearch(ctx, &user_model.SearchUserOptions{
|
||||
Actor: ctx.User,
|
||||
Actor: ctx.Doer,
|
||||
Type: user_model.UserTypeIndividual,
|
||||
ListOptions: db.ListOptions{PageSize: setting.UI.ExplorePagingNum},
|
||||
IsActive: util.OptionalBoolTrue,
|
||||
|
||||
@@ -7,12 +7,15 @@ package feed
|
||||
import (
|
||||
"fmt"
|
||||
"html"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"code.gitea.io/gitea/models"
|
||||
"code.gitea.io/gitea/modules/context"
|
||||
"code.gitea.io/gitea/modules/markup"
|
||||
"code.gitea.io/gitea/modules/markup/markdown"
|
||||
"code.gitea.io/gitea/modules/setting"
|
||||
"code.gitea.io/gitea/modules/templates"
|
||||
"code.gitea.io/gitea/modules/util"
|
||||
@@ -44,8 +47,27 @@ func toReleaseLink(act *models.Action) string {
|
||||
return act.GetRepoLink() + "/releases/tag/" + util.PathEscapeSegments(act.GetBranch())
|
||||
}
|
||||
|
||||
// renderMarkdown creates a minimal markdown render context from an action.
|
||||
// If rendering fails, the original markdown text is returned
|
||||
func renderMarkdown(ctx *context.Context, act *models.Action, content string) string {
|
||||
markdownCtx := &markup.RenderContext{
|
||||
Ctx: ctx,
|
||||
URLPrefix: act.GetRepoLink(),
|
||||
Type: markdown.MarkupName,
|
||||
Metas: map[string]string{
|
||||
"user": act.GetRepoUserName(),
|
||||
"repo": act.GetRepoName(),
|
||||
},
|
||||
}
|
||||
markdown, err := markdown.RenderString(markdownCtx, content)
|
||||
if err != nil {
|
||||
return content
|
||||
}
|
||||
return markdown
|
||||
}
|
||||
|
||||
// feedActionsToFeedItems convert gitea's Action feed to feeds Item
|
||||
func feedActionsToFeedItems(ctx *context.Context, actions []*models.Action) (items []*feeds.Item, err error) {
|
||||
func feedActionsToFeedItems(ctx *context.Context, actions models.ActionList) (items []*feeds.Item, err error) {
|
||||
for _, act := range actions {
|
||||
act.LoadActUser()
|
||||
|
||||
@@ -192,12 +214,12 @@ func feedActionsToFeedItems(ctx *context.Context, actions []*models.Action) (ite
|
||||
|
||||
case models.ActionCreateIssue, models.ActionCreatePullRequest:
|
||||
desc = strings.Join(act.GetIssueInfos(), "#")
|
||||
content = act.GetIssueContent()
|
||||
content = renderMarkdown(ctx, act, act.GetIssueContent())
|
||||
case models.ActionCommentIssue, models.ActionApprovePullRequest, models.ActionRejectPullRequest, models.ActionCommentPull:
|
||||
desc = act.GetIssueTitle()
|
||||
comment := act.GetIssueInfos()[1]
|
||||
if len(comment) != 0 {
|
||||
desc += "\n\n" + comment
|
||||
desc += "\n\n" + renderMarkdown(ctx, act, comment)
|
||||
}
|
||||
case models.ActionMergePullRequest:
|
||||
desc = act.GetIssueInfos()[1]
|
||||
@@ -226,3 +248,18 @@ func feedActionsToFeedItems(ctx *context.Context, actions []*models.Action) (ite
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// GetFeedType return if it is a feed request and altered name and feed type.
|
||||
func GetFeedType(name string, req *http.Request) (bool, string, string) {
|
||||
if strings.HasSuffix(name, ".rss") ||
|
||||
strings.Contains(req.Header.Get("Accept"), "application/rss+xml") {
|
||||
return true, strings.TrimSuffix(name, ".rss"), "rss"
|
||||
}
|
||||
|
||||
if strings.HasSuffix(name, ".atom") ||
|
||||
strings.Contains(req.Header.Get("Accept"), "application/atom+xml") {
|
||||
return true, strings.TrimSuffix(name, ".atom"), "atom"
|
||||
}
|
||||
|
||||
return false, name, ""
|
||||
}
|
||||
|
||||
+19
-46
@@ -9,70 +9,43 @@ import (
|
||||
"time"
|
||||
|
||||
"code.gitea.io/gitea/models"
|
||||
user_model "code.gitea.io/gitea/models/user"
|
||||
"code.gitea.io/gitea/modules/context"
|
||||
|
||||
"github.com/gorilla/feeds"
|
||||
)
|
||||
|
||||
// RetrieveFeeds loads feeds for the specified user
|
||||
func RetrieveFeeds(ctx *context.Context, options models.GetFeedsOptions) []*models.Action {
|
||||
actions, err := models.GetFeeds(options)
|
||||
if err != nil {
|
||||
ctx.ServerError("GetFeeds", err)
|
||||
return nil
|
||||
}
|
||||
|
||||
userCache := map[int64]*user_model.User{options.RequestedUser.ID: options.RequestedUser}
|
||||
if ctx.User != nil {
|
||||
userCache[ctx.User.ID] = ctx.User
|
||||
}
|
||||
for _, act := range actions {
|
||||
if act.ActUser != nil {
|
||||
userCache[act.ActUserID] = act.ActUser
|
||||
}
|
||||
}
|
||||
|
||||
for _, act := range actions {
|
||||
repoOwner, ok := userCache[act.Repo.OwnerID]
|
||||
if !ok {
|
||||
repoOwner, err = user_model.GetUserByID(act.Repo.OwnerID)
|
||||
if err != nil {
|
||||
if user_model.IsErrUserNotExist(err) {
|
||||
continue
|
||||
}
|
||||
ctx.ServerError("GetUserByID", err)
|
||||
return nil
|
||||
}
|
||||
userCache[repoOwner.ID] = repoOwner
|
||||
}
|
||||
act.Repo.Owner = repoOwner
|
||||
}
|
||||
return actions
|
||||
// ShowUserFeedRSS show user activity as RSS feed
|
||||
func ShowUserFeedRSS(ctx *context.Context) {
|
||||
showUserFeed(ctx, "rss")
|
||||
}
|
||||
|
||||
// ShowUserFeed show user activity as RSS / Atom feed
|
||||
func ShowUserFeed(ctx *context.Context, ctxUser *user_model.User, formatType string) {
|
||||
actions := RetrieveFeeds(ctx, models.GetFeedsOptions{
|
||||
RequestedUser: ctxUser,
|
||||
Actor: ctx.User,
|
||||
// ShowUserFeedAtom show user activity as Atom feed
|
||||
func ShowUserFeedAtom(ctx *context.Context) {
|
||||
showUserFeed(ctx, "atom")
|
||||
}
|
||||
|
||||
// showUserFeed show user activity as RSS / Atom feed
|
||||
func showUserFeed(ctx *context.Context, formatType string) {
|
||||
actions, err := models.GetFeeds(ctx, models.GetFeedsOptions{
|
||||
RequestedUser: ctx.ContextUser,
|
||||
Actor: ctx.Doer,
|
||||
IncludePrivate: false,
|
||||
OnlyPerformedBy: true,
|
||||
OnlyPerformedBy: !ctx.ContextUser.IsOrganization(),
|
||||
IncludeDeleted: false,
|
||||
Date: ctx.FormString("date"),
|
||||
})
|
||||
if ctx.Written() {
|
||||
if err != nil {
|
||||
ctx.ServerError("GetFeeds", err)
|
||||
return
|
||||
}
|
||||
|
||||
feed := &feeds.Feed{
|
||||
Title: ctx.Tr("home.feed_of", ctxUser.DisplayName()),
|
||||
Link: &feeds.Link{Href: ctxUser.HTMLURL()},
|
||||
Description: ctxUser.Description,
|
||||
Title: ctx.Tr("home.feed_of", ctx.ContextUser.DisplayName()),
|
||||
Link: &feeds.Link{Href: ctx.ContextUser.HTMLURL()},
|
||||
Description: ctx.ContextUser.Description,
|
||||
Created: time.Now(),
|
||||
}
|
||||
|
||||
var err error
|
||||
feed.Items, err = feedActionsToFeedItems(ctx, actions)
|
||||
if err != nil {
|
||||
ctx.ServerError("convert feed", err)
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
// Copyright 2022 The Gitea Authors. All rights reserved.
|
||||
// Use of this source code is governed by a MIT-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package feed
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"code.gitea.io/gitea/models"
|
||||
repo_model "code.gitea.io/gitea/models/repo"
|
||||
"code.gitea.io/gitea/modules/context"
|
||||
|
||||
"github.com/gorilla/feeds"
|
||||
)
|
||||
|
||||
// ShowRepoFeed shows user activity on the repo as RSS / Atom feed
|
||||
func ShowRepoFeed(ctx *context.Context, repo *repo_model.Repository, formatType string) {
|
||||
actions, err := models.GetFeeds(ctx, models.GetFeedsOptions{
|
||||
RequestedRepo: repo,
|
||||
Actor: ctx.Doer,
|
||||
IncludePrivate: true,
|
||||
Date: ctx.FormString("date"),
|
||||
})
|
||||
if err != nil {
|
||||
ctx.ServerError("GetFeeds", err)
|
||||
return
|
||||
}
|
||||
|
||||
feed := &feeds.Feed{
|
||||
Title: ctx.Tr("home.feed_of", repo.FullName()),
|
||||
Link: &feeds.Link{Href: repo.HTMLURL()},
|
||||
Description: repo.Description,
|
||||
Created: time.Now(),
|
||||
}
|
||||
|
||||
feed.Items, err = feedActionsToFeedItems(ctx, actions)
|
||||
if err != nil {
|
||||
ctx.ServerError("convert feed", err)
|
||||
return
|
||||
}
|
||||
|
||||
writeFeed(ctx, feed, formatType)
|
||||
}
|
||||
+17
-17
@@ -5,6 +5,8 @@
|
||||
package web
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"html"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"path"
|
||||
@@ -14,8 +16,6 @@ import (
|
||||
"code.gitea.io/gitea/modules/context"
|
||||
"code.gitea.io/gitea/modules/setting"
|
||||
"code.gitea.io/gitea/modules/util"
|
||||
|
||||
"github.com/unknwon/com"
|
||||
)
|
||||
|
||||
func goGet(ctx *context.Context) {
|
||||
@@ -48,7 +48,7 @@ func goGet(ctx *context.Context) {
|
||||
</body>
|
||||
</html>
|
||||
`))
|
||||
ctx.Status(400)
|
||||
ctx.Status(http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
branchName := setting.Repository.DefaultBranch
|
||||
@@ -65,23 +65,23 @@ func goGet(ctx *context.Context) {
|
||||
if appURL.Scheme == string(setting.HTTP) {
|
||||
insecure = "--insecure "
|
||||
}
|
||||
ctx.RespHeader().Set("Content-Type", "text/html")
|
||||
ctx.Status(http.StatusOK)
|
||||
_, _ = ctx.Write([]byte(com.Expand(`<!doctype html>
|
||||
|
||||
goGetImport := context.ComposeGoGetImport(ownerName, trimmedRepoName)
|
||||
goImportContent := fmt.Sprintf("%s git %s", goGetImport, repo_model.ComposeHTTPSCloneURL(ownerName, repoName) /*CloneLink*/)
|
||||
goSourceContent := fmt.Sprintf("%s _ %s %s", goGetImport, prefix+"{/dir}" /*GoDocDirectory*/, prefix+"{/dir}/{file}#L{line}" /*GoDocFile*/)
|
||||
goGetCli := fmt.Sprintf("go get %s%s", insecure, goGetImport)
|
||||
|
||||
res := fmt.Sprintf(`<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<meta name="go-import" content="{GoGetImport} git {CloneLink}">
|
||||
<meta name="go-source" content="{GoGetImport} _ {GoDocDirectory} {GoDocFile}">
|
||||
<meta name="go-import" content="%s">
|
||||
<meta name="go-source" content="%s">
|
||||
</head>
|
||||
<body>
|
||||
go get {Insecure}{GoGetImport}
|
||||
%s
|
||||
</body>
|
||||
</html>
|
||||
`, map[string]string{
|
||||
"GoGetImport": context.ComposeGoGetImport(ownerName, trimmedRepoName),
|
||||
"CloneLink": repo_model.ComposeHTTPSCloneURL(ownerName, repoName),
|
||||
"GoDocDirectory": prefix + "{/dir}",
|
||||
"GoDocFile": prefix + "{/dir}/{file}#L{line}",
|
||||
"Insecure": insecure,
|
||||
})))
|
||||
</html>`, html.EscapeString(goImportContent), html.EscapeString(goSourceContent), html.EscapeString(goGetCli))
|
||||
|
||||
ctx.RespHeader().Set("Content-Type", "text/html")
|
||||
_, _ = ctx.Write([]byte(res))
|
||||
}
|
||||
|
||||
@@ -0,0 +1,143 @@
|
||||
// Copyright 2022 The Gitea Authors. All rights reserved.
|
||||
// Use of this source code is governed by a MIT-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package healthcheck
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"os"
|
||||
"time"
|
||||
|
||||
"code.gitea.io/gitea/models/db"
|
||||
"code.gitea.io/gitea/modules/cache"
|
||||
"code.gitea.io/gitea/modules/json"
|
||||
"code.gitea.io/gitea/modules/log"
|
||||
"code.gitea.io/gitea/modules/setting"
|
||||
)
|
||||
|
||||
type status string
|
||||
|
||||
const (
|
||||
// pass healthy (acceptable aliases: "ok" to support Node's Terminus and "up" for Java's SpringBoot)
|
||||
// fail unhealthy (acceptable aliases: "error" to support Node's Terminus and "down" for Java's SpringBoot), and
|
||||
// warn healthy, with some concerns.
|
||||
//
|
||||
// ref https://datatracker.ietf.org/doc/html/draft-inadarei-api-health-check#section-3.1
|
||||
// status: (required) indicates whether the service status is acceptable
|
||||
// or not. API publishers SHOULD use following values for the field:
|
||||
// The value of the status field is case-insensitive and is tightly
|
||||
// related with the HTTP response code returned by the health endpoint.
|
||||
// For "pass" status, HTTP response code in the 2xx-3xx range MUST be
|
||||
// used. For "fail" status, HTTP response code in the 4xx-5xx range
|
||||
// MUST be used. In case of the "warn" status, endpoints MUST return
|
||||
// HTTP status in the 2xx-3xx range, and additional information SHOULD
|
||||
// be provided, utilizing optional fields of the response.
|
||||
pass status = "pass"
|
||||
fail status = "fail"
|
||||
warn status = "warn"
|
||||
)
|
||||
|
||||
func (s status) ToHTTPStatus() int {
|
||||
if s == pass || s == warn {
|
||||
return http.StatusOK
|
||||
}
|
||||
return http.StatusFailedDependency
|
||||
}
|
||||
|
||||
type checks map[string][]componentStatus
|
||||
|
||||
// response is the data returned by the health endpoint, which will be marshaled to JSON format
|
||||
type response struct {
|
||||
Status status `json:"status"`
|
||||
Description string `json:"description"` // a human-friendly description of the service
|
||||
Checks checks `json:"checks,omitempty"` // The Checks Object, should be omitted on installation route
|
||||
}
|
||||
|
||||
// componentStatus presents one status of a single check object
|
||||
// an object that provides detailed health statuses of additional downstream systems and endpoints
|
||||
// which can affect the overall health of the main API.
|
||||
type componentStatus struct {
|
||||
Status status `json:"status"`
|
||||
Time string `json:"time"` // the date-time, in ISO8601 format
|
||||
Output string `json:"output,omitempty"` // this field SHOULD be omitted for "pass" state.
|
||||
}
|
||||
|
||||
// Check is the health check API handler
|
||||
func Check(w http.ResponseWriter, r *http.Request) {
|
||||
rsp := response{
|
||||
Status: pass,
|
||||
Description: setting.AppName,
|
||||
Checks: make(checks),
|
||||
}
|
||||
|
||||
statuses := make([]status, 0)
|
||||
if setting.InstallLock {
|
||||
statuses = append(statuses, checkDatabase(rsp.Checks))
|
||||
statuses = append(statuses, checkCache(rsp.Checks))
|
||||
}
|
||||
for _, s := range statuses {
|
||||
if s != pass {
|
||||
rsp.Status = fail
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
data, _ := json.MarshalIndent(rsp, "", " ")
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
w.WriteHeader(rsp.Status.ToHTTPStatus())
|
||||
_, _ = w.Write(data)
|
||||
}
|
||||
|
||||
// database checks gitea database status
|
||||
func checkDatabase(checks checks) status {
|
||||
st := componentStatus{}
|
||||
if err := db.GetEngine(db.DefaultContext).Ping(); err != nil {
|
||||
st.Status = fail
|
||||
st.Time = getCheckTime()
|
||||
log.Error("database ping failed with error: %v", err)
|
||||
} else {
|
||||
st.Status = pass
|
||||
st.Time = getCheckTime()
|
||||
}
|
||||
|
||||
if setting.Database.UseSQLite3 && st.Status == pass {
|
||||
if !setting.EnableSQLite3 {
|
||||
st.Status = fail
|
||||
st.Time = getCheckTime()
|
||||
log.Error("SQLite3 health check failed with error: %v", "this Gitea binary is built without SQLite3 enabled")
|
||||
} else {
|
||||
if _, err := os.Stat(setting.Database.Path); err != nil {
|
||||
st.Status = fail
|
||||
st.Time = getCheckTime()
|
||||
log.Error("SQLite3 file exists check failed with error: %v", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
checks["database:ping"] = []componentStatus{st}
|
||||
return st.Status
|
||||
}
|
||||
|
||||
// cache checks gitea cache status
|
||||
func checkCache(checks checks) status {
|
||||
if !setting.CacheService.Enabled {
|
||||
return pass
|
||||
}
|
||||
|
||||
st := componentStatus{}
|
||||
if err := cache.Ping(); err != nil {
|
||||
st.Status = fail
|
||||
st.Time = getCheckTime()
|
||||
log.Error("cache ping failed with error: %v", err)
|
||||
} else {
|
||||
st.Status = pass
|
||||
st.Time = getCheckTime()
|
||||
}
|
||||
checks["cache:ping"] = []componentStatus{st}
|
||||
return st.Status
|
||||
}
|
||||
|
||||
func getCheckTime() string {
|
||||
return time.Now().UTC().Format(time.RFC3339)
|
||||
}
|
||||
+4
-4
@@ -25,14 +25,14 @@ const (
|
||||
// Home render home page
|
||||
func Home(ctx *context.Context) {
|
||||
if ctx.IsSigned {
|
||||
if !ctx.User.IsActive && setting.Service.RegisterEmailConfirm {
|
||||
if !ctx.Doer.IsActive && setting.Service.RegisterEmailConfirm {
|
||||
ctx.Data["Title"] = ctx.Tr("auth.active_your_account")
|
||||
ctx.HTML(http.StatusOK, auth.TplActivate)
|
||||
} else if !ctx.User.IsActive || ctx.User.ProhibitLogin {
|
||||
log.Info("Failed authentication attempt for %s from %s", ctx.User.Name, ctx.RemoteAddr())
|
||||
} else if !ctx.Doer.IsActive || ctx.Doer.ProhibitLogin {
|
||||
log.Info("Failed authentication attempt for %s from %s", ctx.Doer.Name, ctx.RemoteAddr())
|
||||
ctx.Data["Title"] = ctx.Tr("auth.prohibit_login")
|
||||
ctx.HTML(http.StatusOK, "user/auth/prohibit_login")
|
||||
} else if ctx.User.MustChangePassword {
|
||||
} else if ctx.Doer.MustChangePassword {
|
||||
ctx.Data["Title"] = ctx.Tr("auth.must_change_password")
|
||||
ctx.Data["ChangePasscodeLink"] = setting.AppSubURL + "/user/change_password"
|
||||
middleware.SetRedirectToCookie(ctx.Resp, setting.AppSubURL+ctx.Req.URL.RequestURI())
|
||||
|
||||
@@ -21,13 +21,13 @@ func Metrics(resp http.ResponseWriter, req *http.Request) {
|
||||
}
|
||||
header := req.Header.Get("Authorization")
|
||||
if header == "" {
|
||||
http.Error(resp, "", 401)
|
||||
http.Error(resp, "", http.StatusUnauthorized)
|
||||
return
|
||||
}
|
||||
got := []byte(header)
|
||||
want := []byte("Bearer " + setting.Metrics.Token)
|
||||
if subtle.ConstantTimeCompare(got, want) != 1 {
|
||||
http.Error(resp, "", 401)
|
||||
http.Error(resp, "", http.StatusUnauthorized)
|
||||
return
|
||||
}
|
||||
promhttp.Handler().ServeHTTP(resp, req)
|
||||
|
||||
@@ -0,0 +1,99 @@
|
||||
// Copyright 2014 The Gogs Authors. All rights reserved.
|
||||
// Copyright 2022 The Gitea Authors. All rights reserved.
|
||||
// Use of this source code is governed by a MIT-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package misc
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
"code.gitea.io/gitea/modules/context"
|
||||
"code.gitea.io/gitea/modules/markup"
|
||||
"code.gitea.io/gitea/modules/markup/markdown"
|
||||
"code.gitea.io/gitea/modules/setting"
|
||||
api "code.gitea.io/gitea/modules/structs"
|
||||
"code.gitea.io/gitea/modules/util"
|
||||
"code.gitea.io/gitea/modules/web"
|
||||
|
||||
"mvdan.cc/xurls/v2"
|
||||
)
|
||||
|
||||
// Markdown render markdown document to HTML
|
||||
func Markdown(ctx *context.Context) {
|
||||
// swagger:operation POST /markdown miscellaneous renderMarkdown
|
||||
// ---
|
||||
// summary: Render a markdown document as HTML
|
||||
// parameters:
|
||||
// - name: body
|
||||
// in: body
|
||||
// schema:
|
||||
// "$ref": "#/definitions/MarkdownOption"
|
||||
// consumes:
|
||||
// - application/json
|
||||
// produces:
|
||||
// - text/html
|
||||
// responses:
|
||||
// "200":
|
||||
// "$ref": "#/responses/MarkdownRender"
|
||||
// "422":
|
||||
// "$ref": "#/responses/validationError"
|
||||
|
||||
form := web.GetForm(ctx).(*api.MarkdownOption)
|
||||
|
||||
if ctx.HasAPIError() {
|
||||
ctx.Error(http.StatusUnprocessableEntity, "", ctx.GetErrMsg())
|
||||
return
|
||||
}
|
||||
|
||||
if len(form.Text) == 0 {
|
||||
_, _ = ctx.Write([]byte(""))
|
||||
return
|
||||
}
|
||||
|
||||
switch form.Mode {
|
||||
case "comment":
|
||||
fallthrough
|
||||
case "gfm":
|
||||
urlPrefix := form.Context
|
||||
meta := map[string]string{}
|
||||
if !strings.HasPrefix(setting.AppSubURL+"/", urlPrefix) {
|
||||
// check if urlPrefix is already set to a URL
|
||||
linkRegex, _ := xurls.StrictMatchingScheme("https?://")
|
||||
m := linkRegex.FindStringIndex(urlPrefix)
|
||||
if m == nil {
|
||||
urlPrefix = util.URLJoin(setting.AppURL, form.Context)
|
||||
}
|
||||
}
|
||||
if ctx.Repo != nil && ctx.Repo.Repository != nil {
|
||||
// "gfm" = Github Flavored Markdown - set this to render as a document
|
||||
if form.Mode == "gfm" {
|
||||
meta = ctx.Repo.Repository.ComposeDocumentMetas()
|
||||
} else {
|
||||
meta = ctx.Repo.Repository.ComposeMetas()
|
||||
}
|
||||
}
|
||||
if form.Mode == "gfm" {
|
||||
meta["mode"] = "document"
|
||||
}
|
||||
|
||||
if err := markdown.Render(&markup.RenderContext{
|
||||
Ctx: ctx,
|
||||
URLPrefix: urlPrefix,
|
||||
Metas: meta,
|
||||
IsWiki: form.Wiki,
|
||||
}, strings.NewReader(form.Text), ctx.Resp); err != nil {
|
||||
ctx.Error(http.StatusInternalServerError, err.Error())
|
||||
return
|
||||
}
|
||||
default:
|
||||
if err := markdown.RenderRaw(&markup.RenderContext{
|
||||
Ctx: ctx,
|
||||
URLPrefix: form.Context,
|
||||
}, strings.NewReader(form.Text), ctx.Resp); err != nil {
|
||||
ctx.Error(http.StatusInternalServerError, err.Error())
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
// Copyright 2017 The Gitea Authors. All rights reserved.
|
||||
// Use of this source code is governed by a MIT-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package misc
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"code.gitea.io/gitea/modules/base"
|
||||
"code.gitea.io/gitea/modules/context"
|
||||
)
|
||||
|
||||
// tplSwagger swagger page template
|
||||
const tplSwagger base.TplName = "swagger/ui"
|
||||
|
||||
// Swagger render swagger-ui page with v1 json
|
||||
func Swagger(ctx *context.Context) {
|
||||
ctx.Data["APIJSONVersion"] = "v1"
|
||||
ctx.HTML(http.StatusOK, tplSwagger)
|
||||
}
|
||||
@@ -10,6 +10,7 @@ import (
|
||||
|
||||
"code.gitea.io/gitea/models"
|
||||
"code.gitea.io/gitea/models/db"
|
||||
"code.gitea.io/gitea/models/organization"
|
||||
repo_model "code.gitea.io/gitea/models/repo"
|
||||
"code.gitea.io/gitea/modules/base"
|
||||
"code.gitea.io/gitea/modules/context"
|
||||
@@ -39,7 +40,7 @@ func Home(ctx *context.Context) {
|
||||
|
||||
org := ctx.Org.Organization
|
||||
|
||||
if !models.HasOrgOrUserVisible(org.AsUser(), ctx.User) {
|
||||
if !organization.HasOrgOrUserVisible(ctx, org.AsUser(), ctx.Doer) {
|
||||
ctx.NotFound("HasOrgOrUserVisible", nil)
|
||||
return
|
||||
}
|
||||
@@ -113,7 +114,7 @@ func Home(ctx *context.Context) {
|
||||
OwnerID: org.ID,
|
||||
OrderBy: orderBy,
|
||||
Private: ctx.IsSigned,
|
||||
Actor: ctx.User,
|
||||
Actor: ctx.Doer,
|
||||
Language: language,
|
||||
IncludeDescription: setting.UI.SearchRepoDescription,
|
||||
})
|
||||
@@ -122,28 +123,28 @@ func Home(ctx *context.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
opts := &models.FindOrgMembersOpts{
|
||||
opts := &organization.FindOrgMembersOpts{
|
||||
OrgID: org.ID,
|
||||
PublicOnly: true,
|
||||
ListOptions: db.ListOptions{Page: 1, PageSize: 25},
|
||||
}
|
||||
|
||||
if ctx.User != nil {
|
||||
isMember, err := org.IsOrgMember(ctx.User.ID)
|
||||
if ctx.Doer != nil {
|
||||
isMember, err := org.IsOrgMember(ctx.Doer.ID)
|
||||
if err != nil {
|
||||
ctx.Error(http.StatusInternalServerError, "IsOrgMember")
|
||||
return
|
||||
}
|
||||
opts.PublicOnly = !isMember && !ctx.User.IsAdmin
|
||||
opts.PublicOnly = !isMember && !ctx.Doer.IsAdmin
|
||||
}
|
||||
|
||||
members, _, err := models.FindOrgMembers(opts)
|
||||
members, _, err := organization.FindOrgMembers(opts)
|
||||
if err != nil {
|
||||
ctx.ServerError("FindOrgMembers", err)
|
||||
return
|
||||
}
|
||||
|
||||
membersCount, err := models.CountOrgMembers(opts)
|
||||
membersCount, err := organization.CountOrgMembers(opts)
|
||||
if err != nil {
|
||||
ctx.ServerError("CountOrgMembers", err)
|
||||
return
|
||||
|
||||
+15
-14
@@ -9,6 +9,7 @@ import (
|
||||
"net/http"
|
||||
|
||||
"code.gitea.io/gitea/models"
|
||||
"code.gitea.io/gitea/models/organization"
|
||||
"code.gitea.io/gitea/modules/base"
|
||||
"code.gitea.io/gitea/modules/context"
|
||||
"code.gitea.io/gitea/modules/log"
|
||||
@@ -31,21 +32,21 @@ func Members(ctx *context.Context) {
|
||||
page = 1
|
||||
}
|
||||
|
||||
opts := &models.FindOrgMembersOpts{
|
||||
opts := &organization.FindOrgMembersOpts{
|
||||
OrgID: org.ID,
|
||||
PublicOnly: true,
|
||||
}
|
||||
|
||||
if ctx.User != nil {
|
||||
isMember, err := ctx.Org.Organization.IsOrgMember(ctx.User.ID)
|
||||
if ctx.Doer != nil {
|
||||
isMember, err := ctx.Org.Organization.IsOrgMember(ctx.Doer.ID)
|
||||
if err != nil {
|
||||
ctx.Error(http.StatusInternalServerError, "IsOrgMember")
|
||||
return
|
||||
}
|
||||
opts.PublicOnly = !isMember && !ctx.User.IsAdmin
|
||||
opts.PublicOnly = !isMember && !ctx.Doer.IsAdmin
|
||||
}
|
||||
|
||||
total, err := models.CountOrgMembers(opts)
|
||||
total, err := organization.CountOrgMembers(opts)
|
||||
if err != nil {
|
||||
ctx.Error(http.StatusInternalServerError, "CountOrgMembers")
|
||||
return
|
||||
@@ -54,7 +55,7 @@ func Members(ctx *context.Context) {
|
||||
pager := context.NewPagination(int(total), setting.UI.MembersPagingNum, page, 5)
|
||||
opts.ListOptions.Page = page
|
||||
opts.ListOptions.PageSize = setting.UI.MembersPagingNum
|
||||
members, membersIsPublic, err := models.FindOrgMembers(opts)
|
||||
members, membersIsPublic, err := organization.FindOrgMembers(opts)
|
||||
if err != nil {
|
||||
ctx.ServerError("GetMembers", err)
|
||||
return
|
||||
@@ -80,24 +81,24 @@ func MembersAction(ctx *context.Context) {
|
||||
var err error
|
||||
switch ctx.Params(":action") {
|
||||
case "private":
|
||||
if ctx.User.ID != uid && !ctx.Org.IsOwner {
|
||||
if ctx.Doer.ID != uid && !ctx.Org.IsOwner {
|
||||
ctx.Error(http.StatusNotFound)
|
||||
return
|
||||
}
|
||||
err = models.ChangeOrgUserStatus(org.ID, uid, false)
|
||||
err = organization.ChangeOrgUserStatus(org.ID, uid, false)
|
||||
case "public":
|
||||
if ctx.User.ID != uid && !ctx.Org.IsOwner {
|
||||
if ctx.Doer.ID != uid && !ctx.Org.IsOwner {
|
||||
ctx.Error(http.StatusNotFound)
|
||||
return
|
||||
}
|
||||
err = models.ChangeOrgUserStatus(org.ID, uid, true)
|
||||
err = organization.ChangeOrgUserStatus(org.ID, uid, true)
|
||||
case "remove":
|
||||
if !ctx.Org.IsOwner {
|
||||
ctx.Error(http.StatusNotFound)
|
||||
return
|
||||
}
|
||||
err = org.RemoveMember(uid)
|
||||
if models.IsErrLastOrgOwner(err) {
|
||||
err = models.RemoveOrgUser(org.ID, uid)
|
||||
if organization.IsErrLastOrgOwner(err) {
|
||||
ctx.Flash.Error(ctx.Tr("form.last_org_owner"))
|
||||
ctx.JSON(http.StatusOK, map[string]interface{}{
|
||||
"redirect": ctx.Org.OrgLink + "/members",
|
||||
@@ -105,8 +106,8 @@ func MembersAction(ctx *context.Context) {
|
||||
return
|
||||
}
|
||||
case "leave":
|
||||
err = org.RemoveMember(ctx.User.ID)
|
||||
if models.IsErrLastOrgOwner(err) {
|
||||
err = models.RemoveOrgUser(org.ID, ctx.Doer.ID)
|
||||
if organization.IsErrLastOrgOwner(err) {
|
||||
ctx.Flash.Error(ctx.Tr("form.last_org_owner"))
|
||||
ctx.JSON(http.StatusOK, map[string]interface{}{
|
||||
"redirect": ctx.Org.OrgLink + "/members",
|
||||
|
||||
@@ -9,8 +9,8 @@ import (
|
||||
"errors"
|
||||
"net/http"
|
||||
|
||||
"code.gitea.io/gitea/models"
|
||||
"code.gitea.io/gitea/models/db"
|
||||
"code.gitea.io/gitea/models/organization"
|
||||
user_model "code.gitea.io/gitea/models/user"
|
||||
"code.gitea.io/gitea/modules/base"
|
||||
"code.gitea.io/gitea/modules/context"
|
||||
@@ -29,7 +29,7 @@ const (
|
||||
func Create(ctx *context.Context) {
|
||||
ctx.Data["Title"] = ctx.Tr("new_org")
|
||||
ctx.Data["DefaultOrgVisibilityMode"] = setting.Service.DefaultOrgVisibilityMode
|
||||
if !ctx.User.CanCreateOrganization() {
|
||||
if !ctx.Doer.CanCreateOrganization() {
|
||||
ctx.ServerError("Not allowed", errors.New(ctx.Tr("org.form.create_org_not_allowed")))
|
||||
return
|
||||
}
|
||||
@@ -41,7 +41,7 @@ func CreatePost(ctx *context.Context) {
|
||||
form := *web.GetForm(ctx).(*forms.CreateOrgForm)
|
||||
ctx.Data["Title"] = ctx.Tr("new_org")
|
||||
|
||||
if !ctx.User.CanCreateOrganization() {
|
||||
if !ctx.Doer.CanCreateOrganization() {
|
||||
ctx.ServerError("Not allowed", errors.New(ctx.Tr("org.form.create_org_not_allowed")))
|
||||
return
|
||||
}
|
||||
@@ -51,7 +51,7 @@ func CreatePost(ctx *context.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
org := &models.Organization{
|
||||
org := &organization.Organization{
|
||||
Name: form.OrgName,
|
||||
IsActive: true,
|
||||
Type: user_model.UserTypeOrganization,
|
||||
@@ -59,7 +59,7 @@ func CreatePost(ctx *context.Context) {
|
||||
RepoAdminChangeTeamAccess: form.RepoAdminChangeTeamAccess,
|
||||
}
|
||||
|
||||
if err := models.CreateOrganization(org, ctx.User); err != nil {
|
||||
if err := organization.CreateOrganization(org, ctx.Doer); err != nil {
|
||||
ctx.Data["Err_OrgName"] = true
|
||||
switch {
|
||||
case user_model.IsErrUserAlreadyExist(err):
|
||||
@@ -68,7 +68,7 @@ func CreatePost(ctx *context.Context) {
|
||||
ctx.RenderWithErr(ctx.Tr("org.form.name_reserved", err.(db.ErrNameReserved).Name), tplCreateOrg, &form)
|
||||
case db.IsErrNamePatternNotAllowed(err):
|
||||
ctx.RenderWithErr(ctx.Tr("org.form.name_pattern_not_allowed", err.(db.ErrNamePatternNotAllowed).Pattern), tplCreateOrg, &form)
|
||||
case models.IsErrUserNotAllowedCreateOrg(err):
|
||||
case organization.IsErrUserNotAllowedCreateOrg(err):
|
||||
ctx.RenderWithErr(ctx.Tr("org.form.create_org_not_allowed"), tplCreateOrg, &form)
|
||||
default:
|
||||
ctx.ServerError("CreateOrganization", err)
|
||||
|
||||
@@ -10,6 +10,7 @@ import (
|
||||
"code.gitea.io/gitea/models"
|
||||
"code.gitea.io/gitea/models/db"
|
||||
"code.gitea.io/gitea/modules/context"
|
||||
repo_module "code.gitea.io/gitea/modules/repository"
|
||||
"code.gitea.io/gitea/modules/web"
|
||||
"code.gitea.io/gitea/services/forms"
|
||||
)
|
||||
@@ -48,7 +49,7 @@ func NewLabel(ctx *context.Context) {
|
||||
Description: form.Description,
|
||||
Color: form.Color,
|
||||
}
|
||||
if err := models.NewLabel(l); err != nil {
|
||||
if err := models.NewLabel(ctx, l); err != nil {
|
||||
ctx.ServerError("NewLabel", err)
|
||||
return
|
||||
}
|
||||
@@ -100,9 +101,9 @@ func InitializeLabels(ctx *context.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
if err := models.InitializeLabels(db.DefaultContext, ctx.Org.Organization.ID, form.TemplateName, true); err != nil {
|
||||
if models.IsErrIssueLabelTemplateLoad(err) {
|
||||
originalErr := err.(models.ErrIssueLabelTemplateLoad).OriginalError
|
||||
if err := repo_module.InitializeLabels(ctx, ctx.Org.Organization.ID, form.TemplateName, true); err != nil {
|
||||
if repo_module.IsErrIssueLabelTemplateLoad(err) {
|
||||
originalErr := err.(repo_module.ErrIssueLabelTemplateLoad).OriginalError
|
||||
ctx.Flash.Error(ctx.Tr("repo.issues.label_templates.fail_to_load_file", form.TemplateName, originalErr))
|
||||
ctx.Redirect(ctx.Org.OrgLink + "/settings/labels")
|
||||
return
|
||||
|
||||
@@ -18,6 +18,7 @@ import (
|
||||
"code.gitea.io/gitea/modules/base"
|
||||
"code.gitea.io/gitea/modules/context"
|
||||
"code.gitea.io/gitea/modules/log"
|
||||
repo_module "code.gitea.io/gitea/modules/repository"
|
||||
"code.gitea.io/gitea/modules/setting"
|
||||
"code.gitea.io/gitea/modules/web"
|
||||
user_setting "code.gitea.io/gitea/routers/web/user/setting"
|
||||
@@ -96,7 +97,7 @@ func SettingsPost(ctx *context.Context) {
|
||||
org.Name = form.Name
|
||||
org.LowerName = strings.ToLower(form.Name)
|
||||
|
||||
if ctx.User.IsAdmin {
|
||||
if ctx.Doer.IsAdmin {
|
||||
org.MaxRepoCreation = form.MaxRepoCreation
|
||||
}
|
||||
|
||||
@@ -181,6 +182,9 @@ func SettingsDelete(ctx *context.Context) {
|
||||
if models.IsErrUserOwnRepos(err) {
|
||||
ctx.Flash.Error(ctx.Tr("form.org_still_own_repo"))
|
||||
ctx.Redirect(ctx.Org.OrgLink + "/settings/delete")
|
||||
} else if models.IsErrUserOwnPackages(err) {
|
||||
ctx.Flash.Error(ctx.Tr("form.org_still_own_packages"))
|
||||
ctx.Redirect(ctx.Org.OrgLink + "/settings/delete")
|
||||
} else {
|
||||
ctx.ServerError("DeleteOrganization", err)
|
||||
}
|
||||
@@ -232,6 +236,6 @@ func Labels(ctx *context.Context) {
|
||||
ctx.Data["PageIsOrgSettings"] = true
|
||||
ctx.Data["PageIsOrgSettingsLabels"] = true
|
||||
ctx.Data["RequireTribute"] = true
|
||||
ctx.Data["LabelTemplates"] = models.LabelTemplates
|
||||
ctx.Data["LabelTemplates"] = repo_module.LabelTemplates
|
||||
ctx.HTML(http.StatusOK, tplSettingsLabels)
|
||||
}
|
||||
|
||||
+73
-24
@@ -13,13 +13,17 @@ import (
|
||||
"strings"
|
||||
|
||||
"code.gitea.io/gitea/models"
|
||||
"code.gitea.io/gitea/models/db"
|
||||
"code.gitea.io/gitea/models/organization"
|
||||
"code.gitea.io/gitea/models/perm"
|
||||
repo_model "code.gitea.io/gitea/models/repo"
|
||||
unit_model "code.gitea.io/gitea/models/unit"
|
||||
user_model "code.gitea.io/gitea/models/user"
|
||||
"code.gitea.io/gitea/modules/base"
|
||||
"code.gitea.io/gitea/modules/context"
|
||||
"code.gitea.io/gitea/modules/convert"
|
||||
"code.gitea.io/gitea/modules/log"
|
||||
api "code.gitea.io/gitea/modules/structs"
|
||||
"code.gitea.io/gitea/modules/web"
|
||||
"code.gitea.io/gitea/routers/utils"
|
||||
"code.gitea.io/gitea/services/forms"
|
||||
@@ -43,7 +47,7 @@ func Teams(ctx *context.Context) {
|
||||
ctx.Data["PageIsOrgTeams"] = true
|
||||
|
||||
for _, t := range ctx.Org.Teams {
|
||||
if err := t.GetMembers(&models.SearchMembersOptions{}); err != nil {
|
||||
if err := t.GetMembersCtx(ctx); err != nil {
|
||||
ctx.ServerError("GetMembers", err)
|
||||
return
|
||||
}
|
||||
@@ -69,11 +73,11 @@ func TeamsAction(ctx *context.Context) {
|
||||
ctx.Error(http.StatusNotFound)
|
||||
return
|
||||
}
|
||||
err = ctx.Org.Team.AddMember(ctx.User.ID)
|
||||
err = models.AddTeamMember(ctx.Org.Team, ctx.Doer.ID)
|
||||
case "leave":
|
||||
err = ctx.Org.Team.RemoveMember(ctx.User.ID)
|
||||
err = models.RemoveTeamMember(ctx.Org.Team, ctx.Doer.ID)
|
||||
if err != nil {
|
||||
if models.IsErrLastOrgOwner(err) {
|
||||
if organization.IsErrLastOrgOwner(err) {
|
||||
ctx.Flash.Error(ctx.Tr("form.last_org_owner"))
|
||||
} else {
|
||||
log.Error("Action(%s): %v", ctx.Params(":action"), err)
|
||||
@@ -94,9 +98,9 @@ func TeamsAction(ctx *context.Context) {
|
||||
ctx.Error(http.StatusNotFound)
|
||||
return
|
||||
}
|
||||
err = ctx.Org.Team.RemoveMember(uid)
|
||||
err = models.RemoveTeamMember(ctx.Org.Team, uid)
|
||||
if err != nil {
|
||||
if models.IsErrLastOrgOwner(err) {
|
||||
if organization.IsErrLastOrgOwner(err) {
|
||||
ctx.Flash.Error(ctx.Tr("form.last_org_owner"))
|
||||
} else {
|
||||
log.Error("Action(%s): %v", ctx.Params(":action"), err)
|
||||
@@ -139,14 +143,14 @@ func TeamsAction(ctx *context.Context) {
|
||||
if ctx.Org.Team.IsMember(u.ID) {
|
||||
ctx.Flash.Error(ctx.Tr("org.teams.add_duplicate_users"))
|
||||
} else {
|
||||
err = ctx.Org.Team.AddMember(u.ID)
|
||||
err = models.AddTeamMember(ctx.Org.Team, u.ID)
|
||||
}
|
||||
|
||||
page = "team"
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
if models.IsErrLastOrgOwner(err) {
|
||||
if organization.IsErrLastOrgOwner(err) {
|
||||
ctx.Flash.Error(ctx.Tr("form.last_org_owner"))
|
||||
} else {
|
||||
log.Error("Action(%s): %v", ctx.Params(":action"), err)
|
||||
@@ -191,13 +195,13 @@ func TeamsRepoAction(ctx *context.Context) {
|
||||
ctx.ServerError("GetRepositoryByName", err)
|
||||
return
|
||||
}
|
||||
err = ctx.Org.Team.AddRepository(repo)
|
||||
err = models.AddRepository(ctx.Org.Team, repo)
|
||||
case "remove":
|
||||
err = ctx.Org.Team.RemoveRepository(ctx.FormInt64("repoid"))
|
||||
err = models.RemoveRepository(ctx.Org.Team, ctx.FormInt64("repoid"))
|
||||
case "addall":
|
||||
err = ctx.Org.Team.AddAllRepositories()
|
||||
err = models.AddAllRepositories(ctx.Org.Team)
|
||||
case "removeall":
|
||||
err = ctx.Org.Team.RemoveAllRepositories()
|
||||
err = models.RemoveAllRepositories(ctx.Org.Team)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
@@ -220,7 +224,7 @@ func NewTeam(ctx *context.Context) {
|
||||
ctx.Data["Title"] = ctx.Org.Organization.FullName
|
||||
ctx.Data["PageIsOrgTeams"] = true
|
||||
ctx.Data["PageIsOrgTeamsNew"] = true
|
||||
ctx.Data["Team"] = &models.Team{}
|
||||
ctx.Data["Team"] = &organization.Team{}
|
||||
ctx.Data["Units"] = unit_model.Units
|
||||
ctx.HTML(http.StatusOK, tplTeamNew)
|
||||
}
|
||||
@@ -251,7 +255,7 @@ func NewTeamPost(ctx *context.Context) {
|
||||
p = unit_model.MinUnitAccessMode(unitPerms)
|
||||
}
|
||||
|
||||
t := &models.Team{
|
||||
t := &organization.Team{
|
||||
OrgID: ctx.Org.Organization.ID,
|
||||
Name: form.TeamName,
|
||||
Description: form.Description,
|
||||
@@ -261,9 +265,9 @@ func NewTeamPost(ctx *context.Context) {
|
||||
}
|
||||
|
||||
if t.AccessMode < perm.AccessModeAdmin {
|
||||
units := make([]*models.TeamUnit, 0, len(unitPerms))
|
||||
units := make([]*organization.TeamUnit, 0, len(unitPerms))
|
||||
for tp, perm := range unitPerms {
|
||||
units = append(units, &models.TeamUnit{
|
||||
units = append(units, &organization.TeamUnit{
|
||||
OrgID: ctx.Org.Organization.ID,
|
||||
Type: tp,
|
||||
AccessMode: perm,
|
||||
@@ -291,7 +295,7 @@ func NewTeamPost(ctx *context.Context) {
|
||||
if err := models.NewTeam(t); err != nil {
|
||||
ctx.Data["Err_TeamName"] = true
|
||||
switch {
|
||||
case models.IsErrTeamAlreadyExist(err):
|
||||
case organization.IsErrTeamAlreadyExist(err):
|
||||
ctx.RenderWithErr(ctx.Tr("form.team_name_been_taken"), tplTeamNew, &form)
|
||||
default:
|
||||
ctx.ServerError("NewTeam", err)
|
||||
@@ -307,7 +311,7 @@ func TeamMembers(ctx *context.Context) {
|
||||
ctx.Data["Title"] = ctx.Org.Team.Name
|
||||
ctx.Data["PageIsOrgTeams"] = true
|
||||
ctx.Data["PageIsOrgTeamMembers"] = true
|
||||
if err := ctx.Org.Team.GetMembers(&models.SearchMembersOptions{}); err != nil {
|
||||
if err := ctx.Org.Team.GetMembersCtx(ctx); err != nil {
|
||||
ctx.ServerError("GetMembers", err)
|
||||
return
|
||||
}
|
||||
@@ -320,7 +324,7 @@ func TeamRepositories(ctx *context.Context) {
|
||||
ctx.Data["Title"] = ctx.Org.Team.Name
|
||||
ctx.Data["PageIsOrgTeams"] = true
|
||||
ctx.Data["PageIsOrgTeamRepos"] = true
|
||||
if err := ctx.Org.Team.GetRepositories(&models.SearchOrgTeamOptions{}); err != nil {
|
||||
if err := ctx.Org.Team.GetRepositoriesCtx(ctx); err != nil {
|
||||
ctx.ServerError("GetRepositories", err)
|
||||
return
|
||||
}
|
||||
@@ -328,6 +332,51 @@ func TeamRepositories(ctx *context.Context) {
|
||||
ctx.HTML(http.StatusOK, tplTeamRepositories)
|
||||
}
|
||||
|
||||
// SearchTeam api for searching teams
|
||||
func SearchTeam(ctx *context.Context) {
|
||||
listOptions := db.ListOptions{
|
||||
Page: ctx.FormInt("page"),
|
||||
PageSize: convert.ToCorrectPageSize(ctx.FormInt("limit")),
|
||||
}
|
||||
|
||||
opts := &organization.SearchTeamOptions{
|
||||
UserID: ctx.Doer.ID,
|
||||
Keyword: ctx.FormTrim("q"),
|
||||
OrgID: ctx.Org.Organization.ID,
|
||||
IncludeDesc: ctx.FormString("include_desc") == "" || ctx.FormBool("include_desc"),
|
||||
ListOptions: listOptions,
|
||||
}
|
||||
|
||||
teams, maxResults, err := organization.SearchTeam(opts)
|
||||
if err != nil {
|
||||
log.Error("SearchTeam failed: %v", err)
|
||||
ctx.JSON(http.StatusInternalServerError, map[string]interface{}{
|
||||
"ok": false,
|
||||
"error": "SearchTeam internal failure",
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
apiTeams := make([]*api.Team, len(teams))
|
||||
for i := range teams {
|
||||
if err := teams[i].GetUnits(); err != nil {
|
||||
log.Error("Team GetUnits failed: %v", err)
|
||||
ctx.JSON(http.StatusInternalServerError, map[string]interface{}{
|
||||
"ok": false,
|
||||
"error": "SearchTeam failed to get units",
|
||||
})
|
||||
return
|
||||
}
|
||||
apiTeams[i] = convert.ToTeam(teams[i])
|
||||
}
|
||||
|
||||
ctx.SetTotalCountHeader(maxResults)
|
||||
ctx.JSON(http.StatusOK, map[string]interface{}{
|
||||
"ok": true,
|
||||
"data": apiTeams,
|
||||
})
|
||||
}
|
||||
|
||||
// EditTeam render team edit page
|
||||
func EditTeam(ctx *context.Context) {
|
||||
ctx.Data["Title"] = ctx.Org.Organization.FullName
|
||||
@@ -374,17 +423,17 @@ func EditTeamPost(ctx *context.Context) {
|
||||
}
|
||||
t.Description = form.Description
|
||||
if t.AccessMode < perm.AccessModeAdmin {
|
||||
units := make([]models.TeamUnit, 0, len(unitPerms))
|
||||
units := make([]organization.TeamUnit, 0, len(unitPerms))
|
||||
for tp, perm := range unitPerms {
|
||||
units = append(units, models.TeamUnit{
|
||||
units = append(units, organization.TeamUnit{
|
||||
OrgID: t.OrgID,
|
||||
TeamID: t.ID,
|
||||
Type: tp,
|
||||
AccessMode: perm,
|
||||
})
|
||||
}
|
||||
if err := models.UpdateTeamUnits(t, units); err != nil {
|
||||
ctx.Error(http.StatusInternalServerError, "LoadIssue", err.Error())
|
||||
if err := organization.UpdateTeamUnits(t, units); err != nil {
|
||||
ctx.Error(http.StatusInternalServerError, "UpdateTeamUnits", err.Error())
|
||||
return
|
||||
}
|
||||
}
|
||||
@@ -403,7 +452,7 @@ func EditTeamPost(ctx *context.Context) {
|
||||
if err := models.UpdateTeam(t, isAuthChanged, isIncludeAllChanged); err != nil {
|
||||
ctx.Data["Err_TeamName"] = true
|
||||
switch {
|
||||
case models.IsErrTeamAlreadyExist(err):
|
||||
case organization.IsErrTeamAlreadyExist(err):
|
||||
ctx.RenderWithErr(ctx.Tr("form.team_name_been_taken"), tplTeamNew, &form)
|
||||
default:
|
||||
ctx.ServerError("UpdateTeam", err)
|
||||
|
||||
@@ -44,7 +44,7 @@ func uploadAttachment(ctx *context.Context, repoID int64, allowedTypes string) {
|
||||
}
|
||||
defer file.Close()
|
||||
|
||||
attach, err := attachment.UploadAttachment(file, ctx.User.ID, repoID, 0, header.Filename, allowedTypes)
|
||||
attach, err := attachment.UploadAttachment(file, ctx.Doer.ID, repoID, 0, header.Filename, allowedTypes)
|
||||
if err != nil {
|
||||
if upload.IsErrFileTypeForbidden(err) {
|
||||
ctx.Error(http.StatusBadRequest, err.Error())
|
||||
@@ -68,7 +68,7 @@ func DeleteAttachment(ctx *context.Context) {
|
||||
ctx.Error(http.StatusBadRequest, err.Error())
|
||||
return
|
||||
}
|
||||
if !ctx.IsSigned || (ctx.User.ID != attach.UploaderID) {
|
||||
if !ctx.IsSigned || (ctx.Doer.ID != attach.UploaderID) {
|
||||
ctx.Error(http.StatusForbidden)
|
||||
return
|
||||
}
|
||||
@@ -101,12 +101,12 @@ func GetAttachment(ctx *context.Context) {
|
||||
}
|
||||
|
||||
if repository == nil { // If not linked
|
||||
if !(ctx.IsSigned && attach.UploaderID == ctx.User.ID) { // We block if not the uploader
|
||||
if !(ctx.IsSigned && attach.UploaderID == ctx.Doer.ID) { // We block if not the uploader
|
||||
ctx.Error(http.StatusNotFound)
|
||||
return
|
||||
}
|
||||
} else { // If we have the repository we check access
|
||||
perm, err := models.GetUserRepoPermission(repository, ctx.User)
|
||||
perm, err := models.GetUserRepoPermission(ctx, repository, ctx.Doer)
|
||||
if err != nil {
|
||||
ctx.Error(http.StatusInternalServerError, "GetUserRepoPermission", err.Error())
|
||||
return
|
||||
|
||||
+10
-10
@@ -56,7 +56,7 @@ func Branches(ctx *context.Context) {
|
||||
ctx.Data["IsWriter"] = ctx.Repo.CanWrite(unit.TypeCode)
|
||||
ctx.Data["IsMirror"] = ctx.Repo.Repository.IsMirror
|
||||
ctx.Data["CanPull"] = ctx.Repo.CanWrite(unit.TypeCode) ||
|
||||
(ctx.IsSigned && repo_model.HasForkedRepo(ctx.User.ID, ctx.Repo.Repository.ID))
|
||||
(ctx.IsSigned && repo_model.HasForkedRepo(ctx.Doer.ID, ctx.Repo.Repository.ID))
|
||||
ctx.Data["PageIsViewCode"] = true
|
||||
ctx.Data["PageIsBranches"] = true
|
||||
|
||||
@@ -90,7 +90,7 @@ func DeleteBranchPost(ctx *context.Context) {
|
||||
defer redirect(ctx)
|
||||
branchName := ctx.FormString("name")
|
||||
|
||||
if err := repo_service.DeleteBranch(ctx.User, ctx.Repo.Repository, ctx.Repo.GitRepo, branchName); err != nil {
|
||||
if err := repo_service.DeleteBranch(ctx.Doer, ctx.Repo.Repository, ctx.Repo.GitRepo, branchName); err != nil {
|
||||
switch {
|
||||
case git.IsErrBranchNotExist(err):
|
||||
log.Debug("DeleteBranch: Can't delete non existing branch '%s'", branchName)
|
||||
@@ -129,7 +129,7 @@ func RestoreBranchPost(ctx *context.Context) {
|
||||
if err := git.Push(ctx, ctx.Repo.Repository.RepoPath(), git.PushOptions{
|
||||
Remote: ctx.Repo.Repository.RepoPath(),
|
||||
Branch: fmt.Sprintf("%s:%s%s", deletedBranch.Commit, git.BranchPrefix, deletedBranch.Name),
|
||||
Env: models.PushingEnvironment(ctx.User, ctx.Repo.Repository),
|
||||
Env: repo_module.PushingEnvironment(ctx.Doer, ctx.Repo.Repository),
|
||||
}); err != nil {
|
||||
if strings.Contains(err.Error(), "already exists") {
|
||||
log.Debug("RestoreBranch: Can't restore branch '%s', since one with same name already exist", deletedBranch.Name)
|
||||
@@ -147,8 +147,8 @@ func RestoreBranchPost(ctx *context.Context) {
|
||||
RefFullName: git.BranchPrefix + deletedBranch.Name,
|
||||
OldCommitID: git.EmptySHA,
|
||||
NewCommitID: deletedBranch.Commit,
|
||||
PusherID: ctx.User.ID,
|
||||
PusherName: ctx.User.Name,
|
||||
PusherID: ctx.Doer.ID,
|
||||
PusherName: ctx.Doer.Name,
|
||||
RepoUserName: ctx.Repo.Owner.Name,
|
||||
RepoName: ctx.Repo.Repository.Name,
|
||||
}); err != nil {
|
||||
@@ -279,7 +279,7 @@ func loadOneBranch(ctx *context.Context, rawBranch, defaultBranch *git.Branch, p
|
||||
}
|
||||
if repo, ok := repoIDToRepo[pr.BaseRepoID]; ok {
|
||||
pr.BaseRepo = repo
|
||||
} else if err := pr.LoadBaseRepo(); err != nil {
|
||||
} else if err := pr.LoadBaseRepoCtx(ctx); err != nil {
|
||||
ctx.ServerError("pr.LoadBaseRepo", err)
|
||||
return nil
|
||||
} else {
|
||||
@@ -290,7 +290,7 @@ func loadOneBranch(ctx *context.Context, rawBranch, defaultBranch *git.Branch, p
|
||||
if pr.HasMerged {
|
||||
baseGitRepo, ok := repoIDToGitRepo[pr.BaseRepoID]
|
||||
if !ok {
|
||||
baseGitRepo, err = git.OpenRepositoryCtx(ctx, pr.BaseRepo.RepoPath())
|
||||
baseGitRepo, err = git.OpenRepository(ctx, pr.BaseRepo.RepoPath())
|
||||
if err != nil {
|
||||
ctx.ServerError("OpenRepository", err)
|
||||
return nil
|
||||
@@ -364,11 +364,11 @@ func CreateBranch(ctx *context.Context) {
|
||||
if ctx.Repo.IsViewBranch {
|
||||
target = ctx.Repo.BranchName
|
||||
}
|
||||
err = release_service.CreateNewTag(ctx, ctx.User, ctx.Repo.Repository, target, form.NewBranchName, "")
|
||||
err = release_service.CreateNewTag(ctx, ctx.Doer, ctx.Repo.Repository, target, form.NewBranchName, "")
|
||||
} else if ctx.Repo.IsViewBranch {
|
||||
err = repo_service.CreateNewBranch(ctx, ctx.User, ctx.Repo.Repository, ctx.Repo.BranchName, form.NewBranchName)
|
||||
err = repo_service.CreateNewBranch(ctx, ctx.Doer, ctx.Repo.Repository, ctx.Repo.BranchName, form.NewBranchName)
|
||||
} else {
|
||||
err = repo_service.CreateNewBranchFromCommit(ctx, ctx.User, ctx.Repo.Repository, ctx.Repo.CommitID, form.NewBranchName)
|
||||
err = repo_service.CreateNewBranchFromCommit(ctx, ctx.Doer, ctx.Repo.Repository, ctx.Repo.CommitID, form.NewBranchName)
|
||||
}
|
||||
if err != nil {
|
||||
if models.IsErrTagAlreadyExists(err) {
|
||||
|
||||
@@ -47,8 +47,6 @@ func CherryPick(ctx *context.Context) {
|
||||
ctx.Data["commit_message"] = splits[1]
|
||||
}
|
||||
|
||||
ctx.Data["RequireHighlightJS"] = true
|
||||
|
||||
canCommit := renderCommitRights(ctx)
|
||||
ctx.Data["TreePath"] = ""
|
||||
|
||||
@@ -77,7 +75,6 @@ func CherryPickPost(ctx *context.Context) {
|
||||
ctx.Data["CherryPickType"] = "cherry-pick"
|
||||
}
|
||||
|
||||
ctx.Data["RequireHighlightJS"] = true
|
||||
canCommit := renderCommitRights(ctx)
|
||||
branchName := ctx.Repo.BranchName
|
||||
if form.CommitChoice == frmCommitChoiceNewBranch {
|
||||
@@ -127,7 +124,7 @@ func CherryPickPost(ctx *context.Context) {
|
||||
|
||||
// First lets try the simple plain read-tree -m approach
|
||||
opts.Content = sha
|
||||
if _, err := files.CherryPick(ctx, ctx.Repo.Repository, ctx.User, form.Revert, opts); err != nil {
|
||||
if _, err := files.CherryPick(ctx, ctx.Repo.Repository, ctx.Doer, form.Revert, opts); err != nil {
|
||||
if models.IsErrBranchAlreadyExists(err) {
|
||||
// User has specified a branch that already exists
|
||||
branchErr := err.(models.ErrBranchAlreadyExists)
|
||||
@@ -151,7 +148,7 @@ func CherryPickPost(ctx *context.Context) {
|
||||
return
|
||||
}
|
||||
} else {
|
||||
if err := git.GetRawDiff(ctx, ctx.Repo.Repository.RepoPath(), sha, git.RawDiffType("patch"), buf); err != nil {
|
||||
if err := git.GetRawDiff(ctx.Repo.GitRepo, sha, git.RawDiffType("patch"), buf); err != nil {
|
||||
if git.IsErrNotExist(err) {
|
||||
ctx.NotFound("GetRawDiff", errors.New("commit "+ctx.Params(":sha")+" does not exist."))
|
||||
return
|
||||
@@ -164,7 +161,7 @@ func CherryPickPost(ctx *context.Context) {
|
||||
opts.Content = buf.String()
|
||||
ctx.Data["FileContent"] = opts.Content
|
||||
|
||||
if _, err := files.ApplyDiffPatch(ctx, ctx.Repo.Repository, ctx.User, opts); err != nil {
|
||||
if _, err := files.ApplyDiffPatch(ctx, ctx.Repo.Repository, ctx.Doer, opts); err != nil {
|
||||
if models.IsErrBranchAlreadyExists(err) {
|
||||
// User has specified a branch that already exists
|
||||
branchErr := err.(models.ErrBranchAlreadyExists)
|
||||
|
||||
@@ -7,13 +7,13 @@ package repo
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
"code.gitea.io/gitea/models"
|
||||
asymkey_model "code.gitea.io/gitea/models/asymkey"
|
||||
"code.gitea.io/gitea/models/db"
|
||||
repo_model "code.gitea.io/gitea/models/repo"
|
||||
user_model "code.gitea.io/gitea/models/user"
|
||||
"code.gitea.io/gitea/modules/base"
|
||||
"code.gitea.io/gitea/modules/charset"
|
||||
@@ -253,7 +253,6 @@ func FileHistory(ctx *context.Context) {
|
||||
// Diff show different from current commit to previous commit
|
||||
func Diff(ctx *context.Context) {
|
||||
ctx.Data["PageIsDiff"] = true
|
||||
ctx.Data["RequireHighlightJS"] = true
|
||||
ctx.Data["RequireTribute"] = true
|
||||
|
||||
userName := ctx.Repo.Owner.Name
|
||||
@@ -265,7 +264,7 @@ func Diff(ctx *context.Context) {
|
||||
)
|
||||
|
||||
if ctx.Data["PageIsWiki"] != nil {
|
||||
gitRepo, err = git.OpenRepositoryCtx(ctx, ctx.Repo.Repository.WikiPath())
|
||||
gitRepo, err = git.OpenRepository(ctx, ctx.Repo.Repository.WikiPath())
|
||||
if err != nil {
|
||||
ctx.ServerError("Repo.GitRepo.GetCommit", err)
|
||||
return
|
||||
@@ -381,15 +380,24 @@ func Diff(ctx *context.Context) {
|
||||
|
||||
// RawDiff dumps diff results of repository in given commit ID to io.Writer
|
||||
func RawDiff(ctx *context.Context) {
|
||||
var repoPath string
|
||||
var gitRepo *git.Repository
|
||||
if ctx.Data["PageIsWiki"] != nil {
|
||||
repoPath = ctx.Repo.Repository.WikiPath()
|
||||
wikiRepo, err := git.OpenRepository(ctx, ctx.Repo.Repository.WikiPath())
|
||||
if err != nil {
|
||||
ctx.ServerError("OpenRepository", err)
|
||||
return
|
||||
}
|
||||
defer wikiRepo.Close()
|
||||
gitRepo = wikiRepo
|
||||
} else {
|
||||
repoPath = repo_model.RepoPath(ctx.Repo.Owner.Name, ctx.Repo.Repository.Name)
|
||||
gitRepo = ctx.Repo.GitRepo
|
||||
if gitRepo == nil {
|
||||
ctx.ServerError("GitRepo not open", fmt.Errorf("no open git repo for '%s'", ctx.Repo.Repository.FullName()))
|
||||
return
|
||||
}
|
||||
}
|
||||
if err := git.GetRawDiff(
|
||||
ctx,
|
||||
repoPath,
|
||||
gitRepo,
|
||||
ctx.Params(":sha"),
|
||||
git.RawDiffType(ctx.Params(":ext")),
|
||||
ctx.Resp,
|
||||
|
||||
+37
-20
@@ -18,7 +18,6 @@ import (
|
||||
"strings"
|
||||
|
||||
"code.gitea.io/gitea/models"
|
||||
"code.gitea.io/gitea/models/db"
|
||||
repo_model "code.gitea.io/gitea/models/repo"
|
||||
"code.gitea.io/gitea/models/unit"
|
||||
user_model "code.gitea.io/gitea/models/user"
|
||||
@@ -144,6 +143,11 @@ func setCsvCompareContext(ctx *context.Context) {
|
||||
if err == errTooLarge {
|
||||
return CsvDiffResult{nil, err.Error()}
|
||||
}
|
||||
if err != nil {
|
||||
log.Error("CreateCsvDiff error whilst creating baseReader from file %s in commit %s in %s: %v", diffFile.Name, baseCommit.ID.String(), ctx.Repo.Repository.Name, err)
|
||||
return CsvDiffResult{nil, "unable to load file from base commit"}
|
||||
}
|
||||
|
||||
headReader, headBlobCloser, err := csvReaderFromCommit(&markup.RenderContext{Ctx: ctx, Filename: diffFile.Name}, headCommit)
|
||||
if headBlobCloser != nil {
|
||||
defer headBlobCloser.Close()
|
||||
@@ -151,13 +155,17 @@ func setCsvCompareContext(ctx *context.Context) {
|
||||
if err == errTooLarge {
|
||||
return CsvDiffResult{nil, err.Error()}
|
||||
}
|
||||
if err != nil {
|
||||
log.Error("CreateCsvDiff error whilst creating headReader from file %s in commit %s in %s: %v", diffFile.Name, headCommit.ID.String(), ctx.Repo.Repository.Name, err)
|
||||
return CsvDiffResult{nil, "unable to load file from head commit"}
|
||||
}
|
||||
|
||||
sections, err := gitdiff.CreateCsvDiff(diffFile, baseReader, headReader)
|
||||
if err != nil {
|
||||
errMessage, err := csv_module.FormatError(err, ctx.Locale)
|
||||
if err != nil {
|
||||
log.Error("RenderCsvDiff failed: %v", err)
|
||||
return CsvDiffResult{nil, ""}
|
||||
log.Error("CreateCsvDiff FormatError failed: %v", err)
|
||||
return CsvDiffResult{nil, "unknown csv diff error"}
|
||||
}
|
||||
return CsvDiffResult{nil, errMessage}
|
||||
}
|
||||
@@ -269,7 +277,7 @@ func ParseCompareInfo(ctx *context.Context) *CompareInfo {
|
||||
}
|
||||
return nil
|
||||
}
|
||||
if err := ci.HeadRepo.GetOwner(db.DefaultContext); err != nil {
|
||||
if err := ci.HeadRepo.GetOwner(ctx); err != nil {
|
||||
if user_model.IsErrUserNotExist(err) {
|
||||
ctx.NotFound("GetUserByName", nil)
|
||||
} else {
|
||||
@@ -299,6 +307,13 @@ func ParseCompareInfo(ctx *context.Context) *CompareInfo {
|
||||
ci.BaseBranch = baseCommit.ID.String()
|
||||
ctx.Data["BaseBranch"] = ci.BaseBranch
|
||||
baseIsCommit = true
|
||||
} else if ci.BaseBranch == git.EmptySHA {
|
||||
if isSameRepo {
|
||||
ctx.Redirect(ctx.Repo.RepoLink + "/compare/" + util.PathEscapeSegments(ci.HeadBranch))
|
||||
} else {
|
||||
ctx.Redirect(ctx.Repo.RepoLink + "/compare/" + util.PathEscapeSegments(ci.HeadRepo.FullName()) + ":" + util.PathEscapeSegments(ci.HeadBranch))
|
||||
}
|
||||
return nil
|
||||
} else {
|
||||
ctx.NotFound("IsRefExist", nil)
|
||||
return nil
|
||||
@@ -338,8 +353,8 @@ func ParseCompareInfo(ctx *context.Context) *CompareInfo {
|
||||
// check if they have a fork of the base repo and offer that as
|
||||
// "OwnForkRepo"
|
||||
var ownForkRepo *repo_model.Repository
|
||||
if ctx.User != nil && baseRepo.OwnerID != ctx.User.ID {
|
||||
repo := repo_model.GetForkedRepo(ctx.User.ID, baseRepo.ID)
|
||||
if ctx.Doer != nil && baseRepo.OwnerID != ctx.Doer.ID {
|
||||
repo := repo_model.GetForkedRepo(ctx.Doer.ID, baseRepo.ID)
|
||||
if repo != nil {
|
||||
ownForkRepo = repo
|
||||
ctx.Data["OwnForkRepo"] = ownForkRepo
|
||||
@@ -354,7 +369,7 @@ func ParseCompareInfo(ctx *context.Context) *CompareInfo {
|
||||
has = true
|
||||
}
|
||||
|
||||
// 4. If the ctx.User has their own fork of the baseRepo and the headUser is the ctx.User
|
||||
// 4. If the ctx.Doer has their own fork of the baseRepo and the headUser is the ctx.Doer
|
||||
// set the headRepo to the ownFork
|
||||
if !has && ownForkRepo != nil && ownForkRepo.OwnerID == ci.HeadUser.ID {
|
||||
ci.HeadRepo = ownForkRepo
|
||||
@@ -383,7 +398,7 @@ func ParseCompareInfo(ctx *context.Context) *CompareInfo {
|
||||
ci.HeadRepo = ctx.Repo.Repository
|
||||
ci.HeadGitRepo = ctx.Repo.GitRepo
|
||||
} else if has {
|
||||
ci.HeadGitRepo, err = git.OpenRepositoryCtx(ctx, ci.HeadRepo.RepoPath())
|
||||
ci.HeadGitRepo, err = git.OpenRepository(ctx, ci.HeadRepo.RepoPath())
|
||||
if err != nil {
|
||||
ctx.ServerError("OpenRepository", err)
|
||||
return nil
|
||||
@@ -392,11 +407,12 @@ func ParseCompareInfo(ctx *context.Context) *CompareInfo {
|
||||
}
|
||||
|
||||
ctx.Data["HeadRepo"] = ci.HeadRepo
|
||||
ctx.Data["BaseCompareRepo"] = ctx.Repo.Repository
|
||||
|
||||
// Now we need to assert that the ctx.User has permission to read
|
||||
// Now we need to assert that the ctx.Doer has permission to read
|
||||
// the baseRepo's code and pulls
|
||||
// (NOT headRepo's)
|
||||
permBase, err := models.GetUserRepoPermission(baseRepo, ctx.User)
|
||||
permBase, err := models.GetUserRepoPermission(ctx, baseRepo, ctx.Doer)
|
||||
if err != nil {
|
||||
ctx.ServerError("GetUserRepoPermission", err)
|
||||
return nil
|
||||
@@ -404,7 +420,7 @@ func ParseCompareInfo(ctx *context.Context) *CompareInfo {
|
||||
if !permBase.CanRead(unit.TypeCode) {
|
||||
if log.IsTrace() {
|
||||
log.Trace("Permission Denied: User: %-v cannot read code in Repo: %-v\nUser in baseRepo has Permissions: %-+v",
|
||||
ctx.User,
|
||||
ctx.Doer,
|
||||
baseRepo,
|
||||
permBase)
|
||||
}
|
||||
@@ -414,8 +430,8 @@ func ParseCompareInfo(ctx *context.Context) *CompareInfo {
|
||||
|
||||
// If we're not merging from the same repo:
|
||||
if !isSameRepo {
|
||||
// Assert ctx.User has permission to read headRepo's codes
|
||||
permHead, err := models.GetUserRepoPermission(ci.HeadRepo, ctx.User)
|
||||
// Assert ctx.Doer has permission to read headRepo's codes
|
||||
permHead, err := models.GetUserRepoPermission(ctx, ci.HeadRepo, ctx.Doer)
|
||||
if err != nil {
|
||||
ctx.ServerError("GetUserRepoPermission", err)
|
||||
return nil
|
||||
@@ -423,13 +439,14 @@ func ParseCompareInfo(ctx *context.Context) *CompareInfo {
|
||||
if !permHead.CanRead(unit.TypeCode) {
|
||||
if log.IsTrace() {
|
||||
log.Trace("Permission Denied: User: %-v cannot read code in Repo: %-v\nUser in headRepo has Permissions: %-+v",
|
||||
ctx.User,
|
||||
ctx.Doer,
|
||||
ci.HeadRepo,
|
||||
permHead)
|
||||
}
|
||||
ctx.NotFound("ParseCompareInfo", nil)
|
||||
return nil
|
||||
}
|
||||
ctx.Data["CanWriteToHeadRepo"] = permHead.CanWrite(unit.TypeCode)
|
||||
}
|
||||
|
||||
// If we have a rootRepo and it's different from:
|
||||
@@ -439,7 +456,7 @@ func ParseCompareInfo(ctx *context.Context) *CompareInfo {
|
||||
if rootRepo != nil &&
|
||||
rootRepo.ID != ci.HeadRepo.ID &&
|
||||
rootRepo.ID != baseRepo.ID {
|
||||
canRead := models.CheckRepoUnitUser(rootRepo, ctx.User, unit.TypeCode)
|
||||
canRead := models.CheckRepoUnitUser(rootRepo, ctx.Doer, unit.TypeCode)
|
||||
if canRead {
|
||||
ctx.Data["RootRepo"] = rootRepo
|
||||
if !fileOnly {
|
||||
@@ -464,7 +481,7 @@ func ParseCompareInfo(ctx *context.Context) *CompareInfo {
|
||||
ownForkRepo.ID != ci.HeadRepo.ID &&
|
||||
ownForkRepo.ID != baseRepo.ID &&
|
||||
(rootRepo == nil || ownForkRepo.ID != rootRepo.ID) {
|
||||
canRead := models.CheckRepoUnitUser(ownForkRepo, ctx.User, unit.TypeCode)
|
||||
canRead := models.CheckRepoUnitUser(ownForkRepo, ctx.Doer, unit.TypeCode)
|
||||
if canRead {
|
||||
ctx.Data["OwnForkRepo"] = ownForkRepo
|
||||
if !fileOnly {
|
||||
@@ -506,7 +523,7 @@ func ParseCompareInfo(ctx *context.Context) *CompareInfo {
|
||||
if ctx.Data["PageIsComparePull"] == true && !permBase.CanReadIssuesOrPulls(true) {
|
||||
if log.IsTrace() {
|
||||
log.Trace("Permission Denied: User: %-v cannot create/read pull requests in Repo: %-v\nUser in baseRepo has Permissions: %-+v",
|
||||
ctx.User,
|
||||
ctx.Doer,
|
||||
baseRepo,
|
||||
permBase)
|
||||
}
|
||||
@@ -655,7 +672,7 @@ func PrepareCompareDiff(
|
||||
}
|
||||
|
||||
func getBranchesAndTagsForRepo(ctx gocontext.Context, repo *repo_model.Repository) (branches, tags []string, err error) {
|
||||
gitRepo, err := git.OpenRepositoryCtx(ctx, repo.RepoPath())
|
||||
gitRepo, err := git.OpenRepository(ctx, repo.RepoPath())
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
@@ -789,7 +806,7 @@ func ExcerptBlob(ctx *context.Context) {
|
||||
gitRepo := ctx.Repo.GitRepo
|
||||
if ctx.FormBool("wiki") {
|
||||
var err error
|
||||
gitRepo, err = git.OpenRepositoryCtx(ctx, ctx.Repo.Repository.WikiPath())
|
||||
gitRepo, err = git.OpenRepository(ctx, ctx.Repo.Repository.WikiPath())
|
||||
if err != nil {
|
||||
ctx.ServerError("OpenRepository", err)
|
||||
return
|
||||
@@ -857,7 +874,7 @@ func ExcerptBlob(ctx *context.Context) {
|
||||
}
|
||||
}
|
||||
ctx.Data["section"] = section
|
||||
ctx.Data["fileName"] = filePath
|
||||
ctx.Data["FileNameHash"] = base.EncodeSha1(filePath)
|
||||
ctx.Data["AfterCommitID"] = commitID
|
||||
ctx.Data["Anchor"] = anchor
|
||||
ctx.HTML(http.StatusOK, tplBlobExcerpt)
|
||||
|
||||
@@ -6,7 +6,11 @@
|
||||
package repo
|
||||
|
||||
import (
|
||||
"path"
|
||||
"time"
|
||||
|
||||
"code.gitea.io/gitea/models"
|
||||
"code.gitea.io/gitea/modules/cache"
|
||||
"code.gitea.io/gitea/modules/context"
|
||||
"code.gitea.io/gitea/modules/git"
|
||||
"code.gitea.io/gitea/modules/httpcache"
|
||||
@@ -18,8 +22,8 @@ import (
|
||||
)
|
||||
|
||||
// ServeBlobOrLFS download a git.Blob redirecting to LFS if necessary
|
||||
func ServeBlobOrLFS(ctx *context.Context, blob *git.Blob) error {
|
||||
if httpcache.HandleGenericETagCache(ctx.Req, ctx.Resp, `"`+blob.ID.String()+`"`) {
|
||||
func ServeBlobOrLFS(ctx *context.Context, blob *git.Blob, lastModified time.Time) error {
|
||||
if httpcache.HandleGenericETagTimeCache(ctx.Req, ctx.Resp, `"`+blob.ID.String()+`"`, lastModified) {
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -45,7 +49,7 @@ func ServeBlobOrLFS(ctx *context.Context, blob *git.Blob) error {
|
||||
log.Error("ServeBlobOrLFS: Close: %v", err)
|
||||
}
|
||||
closed = true
|
||||
return common.ServeBlob(ctx, blob)
|
||||
return common.ServeBlob(ctx, blob, lastModified)
|
||||
}
|
||||
if httpcache.HandleGenericETagCache(ctx.Req, ctx.Resp, `"`+pointer.Oid+`"`) {
|
||||
return nil
|
||||
@@ -76,37 +80,65 @@ func ServeBlobOrLFS(ctx *context.Context, blob *git.Blob) error {
|
||||
}
|
||||
closed = true
|
||||
|
||||
return common.ServeBlob(ctx, blob)
|
||||
return common.ServeBlob(ctx, blob, lastModified)
|
||||
}
|
||||
|
||||
func getBlobForEntry(ctx *context.Context) (blob *git.Blob, lastModified time.Time) {
|
||||
entry, err := ctx.Repo.Commit.GetTreeEntryByPath(ctx.Repo.TreePath)
|
||||
if err != nil {
|
||||
if git.IsErrNotExist(err) {
|
||||
ctx.NotFound("GetTreeEntryByPath", err)
|
||||
} else {
|
||||
ctx.ServerError("GetTreeEntryByPath", err)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
if entry.IsDir() || entry.IsSubModule() {
|
||||
ctx.NotFound("getBlobForEntry", nil)
|
||||
return
|
||||
}
|
||||
|
||||
var c *git.LastCommitCache
|
||||
if setting.CacheService.LastCommit.Enabled && ctx.Repo.CommitsCount >= setting.CacheService.LastCommit.CommitsCount {
|
||||
c = git.NewLastCommitCache(ctx.Repo.Repository.FullName(), ctx.Repo.GitRepo, setting.LastCommitCacheTTLSeconds, cache.GetCache())
|
||||
}
|
||||
|
||||
info, _, err := git.Entries([]*git.TreeEntry{entry}).GetCommitsInfo(ctx, ctx.Repo.Commit, path.Dir("/" + ctx.Repo.TreePath)[1:], c)
|
||||
if err != nil {
|
||||
ctx.ServerError("GetCommitsInfo", err)
|
||||
return
|
||||
}
|
||||
|
||||
if len(info) == 1 {
|
||||
// Not Modified
|
||||
lastModified = info[0].Commit.Committer.When
|
||||
}
|
||||
blob = entry.Blob()
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// SingleDownload download a file by repos path
|
||||
func SingleDownload(ctx *context.Context) {
|
||||
blob, err := ctx.Repo.Commit.GetBlobByPath(ctx.Repo.TreePath)
|
||||
if err != nil {
|
||||
if git.IsErrNotExist(err) {
|
||||
ctx.NotFound("GetBlobByPath", nil)
|
||||
} else {
|
||||
ctx.ServerError("GetBlobByPath", err)
|
||||
}
|
||||
blob, lastModified := getBlobForEntry(ctx)
|
||||
if blob == nil {
|
||||
return
|
||||
}
|
||||
if err = common.ServeBlob(ctx, blob); err != nil {
|
||||
|
||||
if err := common.ServeBlob(ctx, blob, lastModified); err != nil {
|
||||
ctx.ServerError("ServeBlob", err)
|
||||
}
|
||||
}
|
||||
|
||||
// SingleDownloadOrLFS download a file by repos path redirecting to LFS if necessary
|
||||
func SingleDownloadOrLFS(ctx *context.Context) {
|
||||
blob, err := ctx.Repo.Commit.GetBlobByPath(ctx.Repo.TreePath)
|
||||
if err != nil {
|
||||
if git.IsErrNotExist(err) {
|
||||
ctx.NotFound("GetBlobByPath", nil)
|
||||
} else {
|
||||
ctx.ServerError("GetBlobByPath", err)
|
||||
}
|
||||
blob, lastModified := getBlobForEntry(ctx)
|
||||
if blob == nil {
|
||||
return
|
||||
}
|
||||
if err = ServeBlobOrLFS(ctx, blob); err != nil {
|
||||
|
||||
if err := ServeBlobOrLFS(ctx, blob, lastModified); err != nil {
|
||||
ctx.ServerError("ServeBlobOrLFS", err)
|
||||
}
|
||||
}
|
||||
@@ -122,7 +154,7 @@ func DownloadByID(ctx *context.Context) {
|
||||
}
|
||||
return
|
||||
}
|
||||
if err = common.ServeBlob(ctx, blob); err != nil {
|
||||
if err = common.ServeBlob(ctx, blob, time.Time{}); err != nil {
|
||||
ctx.ServerError("ServeBlob", err)
|
||||
}
|
||||
}
|
||||
@@ -138,7 +170,7 @@ func DownloadByIDOrLFS(ctx *context.Context) {
|
||||
}
|
||||
return
|
||||
}
|
||||
if err = ServeBlobOrLFS(ctx, blob); err != nil {
|
||||
if err = ServeBlobOrLFS(ctx, blob, time.Time{}); err != nil {
|
||||
ctx.ServerError("ServeBlob", err)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -40,7 +40,7 @@ const (
|
||||
)
|
||||
|
||||
func renderCommitRights(ctx *context.Context) bool {
|
||||
canCommitToBranch, err := ctx.Repo.CanCommitToBranch(ctx, ctx.User)
|
||||
canCommitToBranch, err := ctx.Repo.CanCommitToBranch(ctx, ctx.Doer)
|
||||
if err != nil {
|
||||
log.Error("CanCommitToBranch: %v", err)
|
||||
}
|
||||
@@ -67,7 +67,6 @@ func getParentTreeFields(treePath string) (treeNames, treePaths []string) {
|
||||
func editFile(ctx *context.Context, isNewFile bool) {
|
||||
ctx.Data["PageIsEdit"] = true
|
||||
ctx.Data["IsNewFile"] = isNewFile
|
||||
ctx.Data["RequireHighlightJS"] = true
|
||||
canCommit := renderCommitRights(ctx)
|
||||
|
||||
treePath := cleanUploadFileName(ctx.Repo.TreePath)
|
||||
@@ -197,7 +196,6 @@ func editFilePost(ctx *context.Context, form forms.EditRepoFileForm, isNewFile b
|
||||
ctx.Data["PageIsEdit"] = true
|
||||
ctx.Data["PageHasPosted"] = true
|
||||
ctx.Data["IsNewFile"] = isNewFile
|
||||
ctx.Data["RequireHighlightJS"] = true
|
||||
ctx.Data["TreePath"] = form.TreePath
|
||||
ctx.Data["TreeNames"] = treeNames
|
||||
ctx.Data["TreePaths"] = treePaths
|
||||
@@ -241,7 +239,7 @@ func editFilePost(ctx *context.Context, form forms.EditRepoFileForm, isNewFile b
|
||||
message += "\n\n" + form.CommitMessage
|
||||
}
|
||||
|
||||
if _, err := files_service.CreateOrUpdateRepoFile(ctx, ctx.Repo.Repository, ctx.User, &files_service.UpdateRepoFileOptions{
|
||||
if _, err := files_service.CreateOrUpdateRepoFile(ctx, ctx.Repo.Repository, ctx.Doer, &files_service.UpdateRepoFileOptions{
|
||||
LastCommitID: form.LastCommit,
|
||||
OldBranch: ctx.Repo.BranchName,
|
||||
NewBranch: branchName,
|
||||
@@ -447,7 +445,7 @@ func DeleteFilePost(ctx *context.Context) {
|
||||
message += "\n\n" + form.CommitMessage
|
||||
}
|
||||
|
||||
if _, err := files_service.DeleteRepoFile(ctx, ctx.Repo.Repository, ctx.User, &files_service.DeleteRepoFileOptions{
|
||||
if _, err := files_service.DeleteRepoFile(ctx, ctx.Repo.Repository, ctx.Doer, &files_service.DeleteRepoFileOptions{
|
||||
LastCommitID: form.LastCommit,
|
||||
OldBranch: ctx.Repo.BranchName,
|
||||
NewBranch: branchName,
|
||||
@@ -653,7 +651,7 @@ func UploadFilePost(ctx *context.Context) {
|
||||
message += "\n\n" + form.CommitMessage
|
||||
}
|
||||
|
||||
if err := files_service.UploadRepoFiles(ctx, ctx.Repo.Repository, ctx.User, &files_service.UploadRepoFileOptions{
|
||||
if err := files_service.UploadRepoFiles(ctx, ctx.Repo.Repository, ctx.Doer, &files_service.UploadRepoFileOptions{
|
||||
LastCommitID: ctx.Repo.CommitID,
|
||||
OldBranch: oldBranchName,
|
||||
NewBranch: branchName,
|
||||
@@ -780,7 +778,7 @@ func UploadFileToServer(ctx *context.Context) {
|
||||
func RemoveUploadFileFromServer(ctx *context.Context) {
|
||||
form := web.GetForm(ctx).(*forms.RemoveUploadFileForm)
|
||||
if len(form.File) == 0 {
|
||||
ctx.Status(204)
|
||||
ctx.Status(http.StatusNoContent)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -790,7 +788,7 @@ func RemoveUploadFileFromServer(ctx *context.Context) {
|
||||
}
|
||||
|
||||
log.Trace("Upload file removed: %s", form.File)
|
||||
ctx.Status(204)
|
||||
ctx.Status(http.StatusNoContent)
|
||||
}
|
||||
|
||||
// GetUniquePatchBranchName Gets a unique branch name for a new patch branch
|
||||
@@ -798,7 +796,7 @@ func RemoveUploadFileFromServer(ctx *context.Context) {
|
||||
// that doesn't already exist. If we exceed 1000 tries or an error is thrown, we just return "" so the user has to
|
||||
// type in the branch name themselves (will be an empty field)
|
||||
func GetUniquePatchBranchName(ctx *context.Context) string {
|
||||
prefix := ctx.User.LowerName + "-patch-"
|
||||
prefix := ctx.Doer.LowerName + "-patch-"
|
||||
for i := 1; i <= 1000; i++ {
|
||||
branchName := fmt.Sprintf("%s%d", prefix, i)
|
||||
if _, err := ctx.Repo.GitRepo.GetBranch(branchName); err != nil {
|
||||
|
||||
@@ -67,7 +67,7 @@ func TestGetClosestParentWithFiles(t *testing.T) {
|
||||
|
||||
repo := ctx.Repo.Repository
|
||||
branch := repo.DefaultBranch
|
||||
gitRepo, _ := git.OpenRepository(repo.RepoPath())
|
||||
gitRepo, _ := git.OpenRepository(git.DefaultContext, repo.RepoPath())
|
||||
defer gitRepo.Close()
|
||||
commit, _ := gitRepo.GetBranchCommit(branch)
|
||||
expectedTreePath := ""
|
||||
|
||||
+27
-42
@@ -21,14 +21,13 @@ import (
|
||||
|
||||
"code.gitea.io/gitea/models"
|
||||
"code.gitea.io/gitea/models/auth"
|
||||
"code.gitea.io/gitea/models/db"
|
||||
"code.gitea.io/gitea/models/perm"
|
||||
repo_model "code.gitea.io/gitea/models/repo"
|
||||
"code.gitea.io/gitea/models/unit"
|
||||
user_model "code.gitea.io/gitea/models/user"
|
||||
"code.gitea.io/gitea/modules/context"
|
||||
"code.gitea.io/gitea/modules/git"
|
||||
"code.gitea.io/gitea/modules/log"
|
||||
repo_module "code.gitea.io/gitea/modules/repository"
|
||||
"code.gitea.io/gitea/modules/setting"
|
||||
"code.gitea.io/gitea/modules/structs"
|
||||
"code.gitea.io/gitea/modules/util"
|
||||
@@ -111,19 +110,7 @@ func httpBase(ctx *context.Context) (h *serviceHandler) {
|
||||
reponame = reponame[:len(reponame)-5]
|
||||
}
|
||||
|
||||
owner, err := user_model.GetUserByName(username)
|
||||
if err != nil {
|
||||
if user_model.IsErrUserNotExist(err) {
|
||||
if redirectUserID, err := user_model.LookupUserRedirect(username); err == nil {
|
||||
context.RedirectToUser(ctx, username, redirectUserID)
|
||||
} else {
|
||||
ctx.NotFound(fmt.Sprintf("User %s does not exist", username), nil)
|
||||
}
|
||||
} else {
|
||||
ctx.ServerError("GetUserByName", err)
|
||||
}
|
||||
return
|
||||
}
|
||||
owner := ctx.ContextUser
|
||||
if !owner.IsOrganization() && !owner.IsActive {
|
||||
ctx.PlainText(http.StatusForbidden, "Repository cannot be accessed. You cannot push or open issues/pull-requests.")
|
||||
return
|
||||
@@ -159,7 +146,7 @@ func httpBase(ctx *context.Context) (h *serviceHandler) {
|
||||
|
||||
// don't allow anonymous pulls if organization is not public
|
||||
if isPublicPull {
|
||||
if err := repo.GetOwner(db.DefaultContext); err != nil {
|
||||
if err := repo.GetOwner(ctx); err != nil {
|
||||
ctx.ServerError("GetOwner", err)
|
||||
return
|
||||
}
|
||||
@@ -178,7 +165,7 @@ func httpBase(ctx *context.Context) (h *serviceHandler) {
|
||||
}
|
||||
|
||||
if ctx.IsBasicAuth && ctx.Data["IsApiToken"] != true {
|
||||
_, err = auth.GetTwoFactorByUID(ctx.User.ID)
|
||||
_, err = auth.GetTwoFactorByUID(ctx.Doer.ID)
|
||||
if err == nil {
|
||||
// TODO: This response should be changed to "invalid credentials" for security reasons once the expectation behind it (creating an app token to authenticate) is properly documented
|
||||
ctx.PlainText(http.StatusUnauthorized, "Users with two-factor authentication enabled cannot perform HTTP/HTTPS operations via plain username and password. Please create and use a personal access token on the user settings page")
|
||||
@@ -189,13 +176,13 @@ func httpBase(ctx *context.Context) (h *serviceHandler) {
|
||||
}
|
||||
}
|
||||
|
||||
if !ctx.User.IsActive || ctx.User.ProhibitLogin {
|
||||
if !ctx.Doer.IsActive || ctx.Doer.ProhibitLogin {
|
||||
ctx.PlainText(http.StatusForbidden, "Your account is disabled.")
|
||||
return
|
||||
}
|
||||
|
||||
if repoExist {
|
||||
p, err := models.GetUserRepoPermission(repo, ctx.User)
|
||||
p, err := models.GetUserRepoPermission(ctx, repo, ctx.Doer)
|
||||
if err != nil {
|
||||
ctx.ServerError("GetUserRepoPermission", err)
|
||||
return
|
||||
@@ -218,22 +205,21 @@ func httpBase(ctx *context.Context) (h *serviceHandler) {
|
||||
}
|
||||
|
||||
environ = []string{
|
||||
models.EnvRepoUsername + "=" + username,
|
||||
models.EnvRepoName + "=" + reponame,
|
||||
models.EnvPusherName + "=" + ctx.User.Name,
|
||||
models.EnvPusherID + fmt.Sprintf("=%d", ctx.User.ID),
|
||||
models.EnvIsDeployKey + "=false",
|
||||
models.EnvAppURL + "=" + setting.AppURL,
|
||||
repo_module.EnvRepoUsername + "=" + username,
|
||||
repo_module.EnvRepoName + "=" + reponame,
|
||||
repo_module.EnvPusherName + "=" + ctx.Doer.Name,
|
||||
repo_module.EnvPusherID + fmt.Sprintf("=%d", ctx.Doer.ID),
|
||||
repo_module.EnvAppURL + "=" + setting.AppURL,
|
||||
}
|
||||
|
||||
if !ctx.User.KeepEmailPrivate {
|
||||
environ = append(environ, models.EnvPusherEmail+"="+ctx.User.Email)
|
||||
if !ctx.Doer.KeepEmailPrivate {
|
||||
environ = append(environ, repo_module.EnvPusherEmail+"="+ctx.Doer.Email)
|
||||
}
|
||||
|
||||
if isWiki {
|
||||
environ = append(environ, models.EnvRepoIsWiki+"=true")
|
||||
environ = append(environ, repo_module.EnvRepoIsWiki+"=true")
|
||||
} else {
|
||||
environ = append(environ, models.EnvRepoIsWiki+"=false")
|
||||
environ = append(environ, repo_module.EnvRepoIsWiki+"=false")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -263,7 +249,7 @@ func httpBase(ctx *context.Context) (h *serviceHandler) {
|
||||
return
|
||||
}
|
||||
|
||||
repo, err = repo_service.PushCreateRepo(ctx.User, owner, reponame)
|
||||
repo, err = repo_service.PushCreateRepo(ctx.Doer, owner, reponame)
|
||||
if err != nil {
|
||||
log.Error("pushCreateRepo: %v", err)
|
||||
ctx.Status(http.StatusNotFound)
|
||||
@@ -284,7 +270,7 @@ func httpBase(ctx *context.Context) (h *serviceHandler) {
|
||||
}
|
||||
}
|
||||
|
||||
environ = append(environ, models.EnvRepoID+fmt.Sprintf("=%d", repo.ID))
|
||||
environ = append(environ, repo_module.EnvRepoID+fmt.Sprintf("=%d", repo.ID))
|
||||
|
||||
w := ctx.Resp
|
||||
r := ctx.Req
|
||||
@@ -328,7 +314,7 @@ func dummyInfoRefs(ctx *context.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
refs, err := git.NewCommand(ctx, "receive-pack", "--stateless-rpc", "--advertise-refs", ".").RunInDirBytes(tmpDir)
|
||||
refs, _, err := git.NewCommand(ctx, "receive-pack", "--stateless-rpc", "--advertise-refs", ".").RunStdBytes(&git.RunOpts{Dir: tmpDir})
|
||||
if err != nil {
|
||||
log.Error(fmt.Sprintf("%v - %s", err, string(refs)))
|
||||
}
|
||||
@@ -412,7 +398,7 @@ func (h *serviceHandler) sendFile(contentType, file string) {
|
||||
var safeGitProtocolHeader = regexp.MustCompile(`^[0-9a-zA-Z]+=[0-9a-zA-Z]+(:[0-9a-zA-Z]+=[0-9a-zA-Z]+)*$`)
|
||||
|
||||
func getGitConfig(ctx gocontext.Context, option, dir string) string {
|
||||
out, err := git.NewCommand(ctx, "config", option).RunInDir(dir)
|
||||
out, _, err := git.NewCommand(ctx, "config", option).RunStdString(&git.RunOpts{Dir: dir})
|
||||
if err != nil {
|
||||
log.Error("%v - %s", err, out)
|
||||
}
|
||||
@@ -487,13 +473,12 @@ func serviceRPC(ctx gocontext.Context, h serviceHandler, service string) {
|
||||
var stderr bytes.Buffer
|
||||
cmd := git.NewCommand(h.r.Context(), service, "--stateless-rpc", h.dir)
|
||||
cmd.SetDescription(fmt.Sprintf("%s %s %s [repo_path: %s]", git.GitExecutable, service, "--stateless-rpc", h.dir))
|
||||
if err := cmd.RunWithContext(&git.RunContext{
|
||||
Timeout: -1,
|
||||
Dir: h.dir,
|
||||
Env: append(os.Environ(), h.environ...),
|
||||
Stdout: h.w,
|
||||
Stdin: reqBody,
|
||||
Stderr: &stderr,
|
||||
if err := cmd.Run(&git.RunOpts{
|
||||
Dir: h.dir,
|
||||
Env: append(os.Environ(), h.environ...),
|
||||
Stdout: h.w,
|
||||
Stdin: reqBody,
|
||||
Stderr: &stderr,
|
||||
}); err != nil {
|
||||
if err.Error() != "signal: killed" {
|
||||
log.Error("Fail to serve RPC(%s) in %s: %v - %s", service, h.dir, err, stderr.String())
|
||||
@@ -527,7 +512,7 @@ func getServiceType(r *http.Request) string {
|
||||
}
|
||||
|
||||
func updateServerInfo(ctx gocontext.Context, dir string) []byte {
|
||||
out, err := git.NewCommand(ctx, "update-server-info").RunInDirBytes(dir)
|
||||
out, _, err := git.NewCommand(ctx, "update-server-info").RunStdBytes(&git.RunOpts{Dir: dir})
|
||||
if err != nil {
|
||||
log.Error(fmt.Sprintf("%v - %s", err, string(out)))
|
||||
}
|
||||
@@ -557,7 +542,7 @@ func GetInfoRefs(ctx *context.Context) {
|
||||
}
|
||||
h.environ = append(os.Environ(), h.environ...)
|
||||
|
||||
refs, err := git.NewCommand(ctx, service, "--stateless-rpc", "--advertise-refs", ".").RunInDirTimeoutEnv(h.environ, -1, h.dir)
|
||||
refs, _, err := git.NewCommand(ctx, service, "--stateless-rpc", "--advertise-refs", ".").RunStdBytes(&git.RunOpts{Env: h.environ, Dir: h.dir})
|
||||
if err != nil {
|
||||
log.Error(fmt.Sprintf("%v - %s", err, string(refs)))
|
||||
}
|
||||
|
||||
+579
-158
File diff suppressed because it is too large
Load Diff
@@ -12,16 +12,15 @@ import (
|
||||
"strings"
|
||||
|
||||
"code.gitea.io/gitea/models"
|
||||
"code.gitea.io/gitea/models/db"
|
||||
issuesModel "code.gitea.io/gitea/models/issues"
|
||||
"code.gitea.io/gitea/models/unit"
|
||||
"code.gitea.io/gitea/modules/context"
|
||||
"code.gitea.io/gitea/modules/log"
|
||||
"code.gitea.io/gitea/modules/setting"
|
||||
"code.gitea.io/gitea/modules/timeutil"
|
||||
"code.gitea.io/gitea/modules/translation/i18n"
|
||||
|
||||
"github.com/sergi/go-diff/diffmatchpatch"
|
||||
"github.com/unknwon/i18n"
|
||||
)
|
||||
|
||||
// GetContentHistoryOverview get overview
|
||||
@@ -32,7 +31,7 @@ func GetContentHistoryOverview(ctx *context.Context) {
|
||||
}
|
||||
|
||||
lang := ctx.Locale.Language()
|
||||
editedHistoryCountMap, _ := issuesModel.QueryIssueContentHistoryEditedCountMap(db.DefaultContext, issue.ID)
|
||||
editedHistoryCountMap, _ := issuesModel.QueryIssueContentHistoryEditedCountMap(ctx, issue.ID)
|
||||
ctx.JSON(http.StatusOK, map[string]interface{}{
|
||||
"i18n": map[string]interface{}{
|
||||
"textEdited": i18n.Tr(lang, "repo.issues.content_history.edited"),
|
||||
@@ -52,7 +51,7 @@ func GetContentHistoryList(ctx *context.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
items, _ := issuesModel.FetchIssueContentHistoryList(db.DefaultContext, issue.ID, commentID)
|
||||
items, _ := issuesModel.FetchIssueContentHistoryList(ctx, issue.ID, commentID)
|
||||
|
||||
// render history list to HTML for frontend dropdown items: (name, value)
|
||||
// name is HTML of "avatar + userName + userAction + timeSince"
|
||||
@@ -99,11 +98,11 @@ func canSoftDeleteContentHistory(ctx *context.Context, issue *models.Issue, comm
|
||||
} else if ctx.Repo.CanWrite(unit.TypeIssues) {
|
||||
if comment == nil {
|
||||
// the issue poster or the history poster can soft-delete
|
||||
canSoftDelete = ctx.User.ID == issue.PosterID || ctx.User.ID == history.PosterID
|
||||
canSoftDelete = ctx.Doer.ID == issue.PosterID || ctx.Doer.ID == history.PosterID
|
||||
canSoftDelete = canSoftDelete && (history.IssueID == issue.ID)
|
||||
} else {
|
||||
// the comment poster or the history poster can soft-delete
|
||||
canSoftDelete = ctx.User.ID == comment.PosterID || ctx.User.ID == history.PosterID
|
||||
canSoftDelete = ctx.Doer.ID == comment.PosterID || ctx.Doer.ID == history.PosterID
|
||||
canSoftDelete = canSoftDelete && (history.IssueID == issue.ID)
|
||||
canSoftDelete = canSoftDelete && (history.CommentID == comment.ID)
|
||||
}
|
||||
@@ -119,7 +118,7 @@ func GetContentHistoryDetail(ctx *context.Context) {
|
||||
}
|
||||
|
||||
historyID := ctx.FormInt64("history_id")
|
||||
history, prevHistory, err := issuesModel.GetIssueContentHistoryAndPrev(db.DefaultContext, historyID)
|
||||
history, prevHistory, err := issuesModel.GetIssueContentHistoryAndPrev(ctx, historyID)
|
||||
if err != nil {
|
||||
ctx.JSON(http.StatusNotFound, map[string]interface{}{
|
||||
"message": "Can not find the content history",
|
||||
@@ -196,7 +195,7 @@ func SoftDeleteContentHistory(ctx *context.Context) {
|
||||
return
|
||||
}
|
||||
}
|
||||
if history, err = issuesModel.GetIssueContentHistoryByID(db.DefaultContext, historyID); err != nil {
|
||||
if history, err = issuesModel.GetIssueContentHistoryByID(ctx, historyID); err != nil {
|
||||
log.Error("can not get issue content history %v. err=%v", historyID, err)
|
||||
return
|
||||
}
|
||||
@@ -209,7 +208,7 @@ func SoftDeleteContentHistory(ctx *context.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
err = issuesModel.SoftDeleteIssueContentHistory(db.DefaultContext, historyID)
|
||||
err = issuesModel.SoftDeleteIssueContentHistory(ctx, historyID)
|
||||
log.Debug("soft delete issue content history. issue=%d, comment=%d, history=%d", issue.ID, commentID, historyID)
|
||||
ctx.JSON(http.StatusOK, map[string]interface{}{
|
||||
"ok": err == nil,
|
||||
|
||||
@@ -22,20 +22,20 @@ func AddDependency(ctx *context.Context) {
|
||||
}
|
||||
|
||||
// Check if the Repo is allowed to have dependencies
|
||||
if !ctx.Repo.CanCreateIssueDependencies(ctx.User, issue.IsPull) {
|
||||
if !ctx.Repo.CanCreateIssueDependencies(ctx.Doer, issue.IsPull) {
|
||||
ctx.Error(http.StatusForbidden, "CanCreateIssueDependencies")
|
||||
return
|
||||
}
|
||||
|
||||
depID := ctx.FormInt64("newDependency")
|
||||
|
||||
if err = issue.LoadRepo(); err != nil {
|
||||
if err = issue.LoadRepo(ctx); err != nil {
|
||||
ctx.ServerError("LoadRepo", err)
|
||||
return
|
||||
}
|
||||
|
||||
// Redirect
|
||||
defer ctx.Redirect(issue.HTMLURL(), http.StatusSeeOther)
|
||||
defer ctx.Redirect(issue.HTMLURL())
|
||||
|
||||
// Dependency
|
||||
dep, err := models.GetIssueByID(depID)
|
||||
@@ -56,7 +56,7 @@ func AddDependency(ctx *context.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
err = models.CreateIssueDependency(ctx.User, issue, dep)
|
||||
err = models.CreateIssueDependency(ctx.Doer, issue, dep)
|
||||
if err != nil {
|
||||
if models.IsErrDependencyExists(err) {
|
||||
ctx.Flash.Error(ctx.Tr("repo.issues.dependency.add_error_dep_exists"))
|
||||
@@ -81,14 +81,14 @@ func RemoveDependency(ctx *context.Context) {
|
||||
}
|
||||
|
||||
// Check if the Repo is allowed to have dependencies
|
||||
if !ctx.Repo.CanCreateIssueDependencies(ctx.User, issue.IsPull) {
|
||||
if !ctx.Repo.CanCreateIssueDependencies(ctx.Doer, issue.IsPull) {
|
||||
ctx.Error(http.StatusForbidden, "CanCreateIssueDependencies")
|
||||
return
|
||||
}
|
||||
|
||||
depID := ctx.FormInt64("removeDependencyID")
|
||||
|
||||
if err = issue.LoadRepo(); err != nil {
|
||||
if err = issue.LoadRepo(ctx); err != nil {
|
||||
ctx.ServerError("LoadRepo", err)
|
||||
return
|
||||
}
|
||||
@@ -115,7 +115,7 @@ func RemoveDependency(ctx *context.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
if err = models.RemoveIssueDependency(ctx.User, issue, dep, depType); err != nil {
|
||||
if err = models.RemoveIssueDependency(ctx.Doer, issue, dep, depType); err != nil {
|
||||
if models.IsErrDependencyNotExists(err) {
|
||||
ctx.Flash.Error(ctx.Tr("repo.issues.dependency.add_error_dep_not_exist"))
|
||||
return
|
||||
@@ -125,5 +125,5 @@ func RemoveDependency(ctx *context.Context) {
|
||||
}
|
||||
|
||||
// Redirect
|
||||
ctx.Redirect(issue.HTMLURL(), http.StatusSeeOther)
|
||||
ctx.Redirect(issue.HTMLURL())
|
||||
}
|
||||
|
||||
@@ -9,9 +9,11 @@ import (
|
||||
|
||||
"code.gitea.io/gitea/models"
|
||||
"code.gitea.io/gitea/models/db"
|
||||
"code.gitea.io/gitea/models/organization"
|
||||
"code.gitea.io/gitea/modules/base"
|
||||
"code.gitea.io/gitea/modules/context"
|
||||
"code.gitea.io/gitea/modules/log"
|
||||
repo_module "code.gitea.io/gitea/modules/repository"
|
||||
"code.gitea.io/gitea/modules/web"
|
||||
"code.gitea.io/gitea/services/forms"
|
||||
issue_service "code.gitea.io/gitea/services/issue"
|
||||
@@ -27,7 +29,7 @@ func Labels(ctx *context.Context) {
|
||||
ctx.Data["PageIsIssueList"] = true
|
||||
ctx.Data["PageIsLabels"] = true
|
||||
ctx.Data["RequireTribute"] = true
|
||||
ctx.Data["LabelTemplates"] = models.LabelTemplates
|
||||
ctx.Data["LabelTemplates"] = repo_module.LabelTemplates
|
||||
ctx.HTML(http.StatusOK, tplLabels)
|
||||
}
|
||||
|
||||
@@ -39,9 +41,9 @@ func InitializeLabels(ctx *context.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
if err := models.InitializeLabels(db.DefaultContext, ctx.Repo.Repository.ID, form.TemplateName, false); err != nil {
|
||||
if models.IsErrIssueLabelTemplateLoad(err) {
|
||||
originalErr := err.(models.ErrIssueLabelTemplateLoad).OriginalError
|
||||
if err := repo_module.InitializeLabels(ctx, ctx.Repo.Repository.ID, form.TemplateName, false); err != nil {
|
||||
if repo_module.IsErrIssueLabelTemplateLoad(err) {
|
||||
originalErr := err.(repo_module.ErrIssueLabelTemplateLoad).OriginalError
|
||||
ctx.Flash.Error(ctx.Tr("repo.issues.label_templates.fail_to_load_file", form.TemplateName, originalErr))
|
||||
ctx.Redirect(ctx.Repo.RepoLink + "/labels")
|
||||
return
|
||||
@@ -77,13 +79,13 @@ func RetrieveLabels(ctx *context.Context) {
|
||||
}
|
||||
ctx.Data["OrgLabels"] = orgLabels
|
||||
|
||||
org, err := models.GetOrgByName(ctx.Repo.Owner.LowerName)
|
||||
org, err := organization.GetOrgByName(ctx.Repo.Owner.LowerName)
|
||||
if err != nil {
|
||||
ctx.ServerError("GetOrgByName", err)
|
||||
return
|
||||
}
|
||||
if ctx.User != nil {
|
||||
ctx.Org.IsOwner, err = org.IsOwnedBy(ctx.User.ID)
|
||||
if ctx.Doer != nil {
|
||||
ctx.Org.IsOwner, err = org.IsOwnedBy(ctx.Doer.ID)
|
||||
if err != nil {
|
||||
ctx.ServerError("org.IsOwnedBy", err)
|
||||
return
|
||||
@@ -115,7 +117,7 @@ func NewLabel(ctx *context.Context) {
|
||||
Description: form.Description,
|
||||
Color: form.Color,
|
||||
}
|
||||
if err := models.NewLabel(l); err != nil {
|
||||
if err := models.NewLabel(ctx, l); err != nil {
|
||||
ctx.ServerError("NewLabel", err)
|
||||
return
|
||||
}
|
||||
@@ -169,7 +171,7 @@ func UpdateIssueLabel(ctx *context.Context) {
|
||||
switch action := ctx.FormString("action"); action {
|
||||
case "clear":
|
||||
for _, issue := range issues {
|
||||
if err := issue_service.ClearLabels(issue, ctx.User); err != nil {
|
||||
if err := issue_service.ClearLabels(issue, ctx.Doer); err != nil {
|
||||
ctx.ServerError("ClearLabels", err)
|
||||
return
|
||||
}
|
||||
@@ -189,7 +191,7 @@ func UpdateIssueLabel(ctx *context.Context) {
|
||||
// detach if any issues already have label, otherwise attach
|
||||
action = "attach"
|
||||
for _, issue := range issues {
|
||||
if issue.HasLabel(label.ID) {
|
||||
if models.HasIssueLabel(issue.ID, label.ID) {
|
||||
action = "detach"
|
||||
break
|
||||
}
|
||||
@@ -198,14 +200,14 @@ func UpdateIssueLabel(ctx *context.Context) {
|
||||
|
||||
if action == "attach" {
|
||||
for _, issue := range issues {
|
||||
if err = issue_service.AddLabel(issue, ctx.User, label); err != nil {
|
||||
if err = issue_service.AddLabel(issue, ctx.Doer, label); err != nil {
|
||||
ctx.ServerError("AddLabel", err)
|
||||
return
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for _, issue := range issues {
|
||||
if err = issue_service.RemoveLabel(issue, ctx.User, label); err != nil {
|
||||
if err = issue_service.RemoveLabel(issue, ctx.Doer, label); err != nil {
|
||||
ctx.ServerError("RemoveLabel", err)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -36,7 +36,7 @@ func TestInitializeLabels(t *testing.T) {
|
||||
test.LoadRepo(t, ctx, 2)
|
||||
web.SetForm(ctx, &forms.InitializeLabelsForm{TemplateName: "Default"})
|
||||
InitializeLabels(ctx)
|
||||
assert.EqualValues(t, http.StatusFound, ctx.Resp.Status())
|
||||
assert.EqualValues(t, http.StatusSeeOther, ctx.Resp.Status())
|
||||
unittest.AssertExistsAndLoadBean(t, &models.Label{
|
||||
RepoID: 2,
|
||||
Name: "enhancement",
|
||||
@@ -82,7 +82,7 @@ func TestNewLabel(t *testing.T) {
|
||||
Color: "#abcdef",
|
||||
})
|
||||
NewLabel(ctx)
|
||||
assert.EqualValues(t, http.StatusFound, ctx.Resp.Status())
|
||||
assert.EqualValues(t, http.StatusSeeOther, ctx.Resp.Status())
|
||||
unittest.AssertExistsAndLoadBean(t, &models.Label{
|
||||
Name: "newlabel",
|
||||
Color: "#abcdef",
|
||||
@@ -101,7 +101,7 @@ func TestUpdateLabel(t *testing.T) {
|
||||
Color: "#abcdef",
|
||||
})
|
||||
UpdateLabel(ctx)
|
||||
assert.EqualValues(t, http.StatusFound, ctx.Resp.Status())
|
||||
assert.EqualValues(t, http.StatusSeeOther, ctx.Resp.Status())
|
||||
unittest.AssertExistsAndLoadBean(t, &models.Label{
|
||||
ID: 2,
|
||||
Name: "newnameforlabel",
|
||||
|
||||
@@ -5,8 +5,6 @@
|
||||
package repo
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"code.gitea.io/gitea/models"
|
||||
"code.gitea.io/gitea/modules/context"
|
||||
"code.gitea.io/gitea/modules/web"
|
||||
@@ -35,7 +33,7 @@ func LockIssue(ctx *context.Context) {
|
||||
}
|
||||
|
||||
if err := models.LockIssue(&models.IssueLockOptions{
|
||||
Doer: ctx.User,
|
||||
Doer: ctx.Doer,
|
||||
Issue: issue,
|
||||
Reason: form.Reason,
|
||||
}); err != nil {
|
||||
@@ -43,7 +41,7 @@ func LockIssue(ctx *context.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
ctx.Redirect(issue.HTMLURL(), http.StatusSeeOther)
|
||||
ctx.Redirect(issue.HTMLURL())
|
||||
}
|
||||
|
||||
// UnlockIssue unlocks a previously locked issue.
|
||||
@@ -60,12 +58,12 @@ func UnlockIssue(ctx *context.Context) {
|
||||
}
|
||||
|
||||
if err := models.UnlockIssue(&models.IssueLockOptions{
|
||||
Doer: ctx.User,
|
||||
Doer: ctx.Doer,
|
||||
Issue: issue,
|
||||
}); err != nil {
|
||||
ctx.ServerError("UnlockIssue", err)
|
||||
return
|
||||
}
|
||||
|
||||
ctx.Redirect(issue.HTMLURL(), http.StatusSeeOther)
|
||||
ctx.Redirect(issue.HTMLURL())
|
||||
}
|
||||
|
||||
@@ -9,7 +9,9 @@ import (
|
||||
"strings"
|
||||
|
||||
"code.gitea.io/gitea/models"
|
||||
"code.gitea.io/gitea/models/db"
|
||||
"code.gitea.io/gitea/modules/context"
|
||||
"code.gitea.io/gitea/modules/eventsource"
|
||||
)
|
||||
|
||||
// IssueStopwatch creates or stops a stopwatch for the given issue.
|
||||
@@ -21,16 +23,16 @@ func IssueStopwatch(c *context.Context) {
|
||||
|
||||
var showSuccessMessage bool
|
||||
|
||||
if !models.StopwatchExists(c.User.ID, issue.ID) {
|
||||
if !models.StopwatchExists(c.Doer.ID, issue.ID) {
|
||||
showSuccessMessage = true
|
||||
}
|
||||
|
||||
if !c.Repo.CanUseTimetracker(issue, c.User) {
|
||||
if !c.Repo.CanUseTimetracker(issue, c.Doer) {
|
||||
c.NotFound("CanUseTimetracker", nil)
|
||||
return
|
||||
}
|
||||
|
||||
if err := models.CreateOrStopIssueStopwatch(c.User, issue); err != nil {
|
||||
if err := models.CreateOrStopIssueStopwatch(c.Doer, issue); err != nil {
|
||||
c.ServerError("CreateOrStopIssueStopwatch", err)
|
||||
return
|
||||
}
|
||||
@@ -49,33 +51,45 @@ func CancelStopwatch(c *context.Context) {
|
||||
if c.Written() {
|
||||
return
|
||||
}
|
||||
if !c.Repo.CanUseTimetracker(issue, c.User) {
|
||||
if !c.Repo.CanUseTimetracker(issue, c.Doer) {
|
||||
c.NotFound("CanUseTimetracker", nil)
|
||||
return
|
||||
}
|
||||
|
||||
if err := models.CancelStopwatch(c.User, issue); err != nil {
|
||||
if err := models.CancelStopwatch(c.Doer, issue); err != nil {
|
||||
c.ServerError("CancelStopwatch", err)
|
||||
return
|
||||
}
|
||||
|
||||
stopwatches, err := models.GetUserStopwatches(c.Doer.ID, db.ListOptions{})
|
||||
if err != nil {
|
||||
c.ServerError("GetUserStopwatches", err)
|
||||
return
|
||||
}
|
||||
if len(stopwatches) == 0 {
|
||||
eventsource.GetManager().SendMessage(c.Doer.ID, &eventsource.Event{
|
||||
Name: "stopwatches",
|
||||
Data: "{}",
|
||||
})
|
||||
}
|
||||
|
||||
url := issue.HTMLURL()
|
||||
c.Redirect(url, http.StatusSeeOther)
|
||||
}
|
||||
|
||||
// GetActiveStopwatch is the middleware that sets .ActiveStopwatch on context
|
||||
func GetActiveStopwatch(c *context.Context) {
|
||||
if strings.HasPrefix(c.Req.URL.Path, "/api") {
|
||||
func GetActiveStopwatch(ctx *context.Context) {
|
||||
if strings.HasPrefix(ctx.Req.URL.Path, "/api") {
|
||||
return
|
||||
}
|
||||
|
||||
if !c.IsSigned {
|
||||
if !ctx.IsSigned {
|
||||
return
|
||||
}
|
||||
|
||||
_, sw, err := models.HasUserStopwatch(c.User.ID)
|
||||
_, sw, err := models.HasUserStopwatch(ctx.Doer.ID)
|
||||
if err != nil {
|
||||
c.ServerError("HasUserStopwatch", err)
|
||||
ctx.ServerError("HasUserStopwatch", err)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -85,15 +99,15 @@ func GetActiveStopwatch(c *context.Context) {
|
||||
|
||||
issue, err := models.GetIssueByID(sw.IssueID)
|
||||
if err != nil || issue == nil {
|
||||
c.ServerError("GetIssueByID", err)
|
||||
ctx.ServerError("GetIssueByID", err)
|
||||
return
|
||||
}
|
||||
if err = issue.LoadRepo(); err != nil {
|
||||
c.ServerError("LoadRepo", err)
|
||||
if err = issue.LoadRepo(ctx); err != nil {
|
||||
ctx.ServerError("LoadRepo", err)
|
||||
return
|
||||
}
|
||||
|
||||
c.Data["ActiveStopwatch"] = StopwatchTmplInfo{
|
||||
ctx.Data["ActiveStopwatch"] = StopwatchTmplInfo{
|
||||
issue.Link(),
|
||||
issue.Repo.FullName(),
|
||||
issue.Index,
|
||||
|
||||
@@ -9,6 +9,7 @@ import (
|
||||
"time"
|
||||
|
||||
"code.gitea.io/gitea/models"
|
||||
"code.gitea.io/gitea/models/db"
|
||||
"code.gitea.io/gitea/modules/context"
|
||||
"code.gitea.io/gitea/modules/util"
|
||||
"code.gitea.io/gitea/modules/web"
|
||||
@@ -22,7 +23,7 @@ func AddTimeManually(c *context.Context) {
|
||||
if c.Written() {
|
||||
return
|
||||
}
|
||||
if !c.Repo.CanUseTimetracker(issue, c.User) {
|
||||
if !c.Repo.CanUseTimetracker(issue, c.Doer) {
|
||||
c.NotFound("CanUseTimetracker", nil)
|
||||
return
|
||||
}
|
||||
@@ -42,7 +43,7 @@ func AddTimeManually(c *context.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
if _, err := models.AddTime(c.User, issue, int64(total.Seconds()), time.Now()); err != nil {
|
||||
if _, err := models.AddTime(c.Doer, issue, int64(total.Seconds()), time.Now()); err != nil {
|
||||
c.ServerError("AddTime", err)
|
||||
return
|
||||
}
|
||||
@@ -56,14 +57,14 @@ func DeleteTime(c *context.Context) {
|
||||
if c.Written() {
|
||||
return
|
||||
}
|
||||
if !c.Repo.CanUseTimetracker(issue, c.User) {
|
||||
if !c.Repo.CanUseTimetracker(issue, c.Doer) {
|
||||
c.NotFound("CanUseTimetracker", nil)
|
||||
return
|
||||
}
|
||||
|
||||
t, err := models.GetTrackedTimeByID(c.ParamsInt64(":timeid"))
|
||||
if err != nil {
|
||||
if models.IsErrNotExist(err) {
|
||||
if db.IsErrNotExist(err) {
|
||||
c.NotFound("time not found", err)
|
||||
return
|
||||
}
|
||||
@@ -72,7 +73,7 @@ func DeleteTime(c *context.Context) {
|
||||
}
|
||||
|
||||
// only OP or admin may delete
|
||||
if !c.IsSigned || (!c.IsUserSiteAdmin() && c.User.ID != t.UserID) {
|
||||
if !c.IsSigned || (!c.IsUserSiteAdmin() && c.Doer.ID != t.UserID) {
|
||||
c.Error(http.StatusForbidden, "not allowed")
|
||||
return
|
||||
}
|
||||
|
||||
@@ -20,7 +20,7 @@ func IssueWatch(ctx *context.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
if !ctx.IsSigned || (ctx.User.ID != issue.PosterID && !ctx.Repo.CanReadIssuesOrPulls(issue.IsPull)) {
|
||||
if !ctx.IsSigned || (ctx.Doer.ID != issue.PosterID && !ctx.Repo.CanReadIssuesOrPulls(issue.IsPull)) {
|
||||
if log.IsTrace() {
|
||||
if ctx.IsSigned {
|
||||
issueType := "issues"
|
||||
@@ -29,7 +29,7 @@ func IssueWatch(ctx *context.Context) {
|
||||
}
|
||||
log.Trace("Permission Denied: User %-v not the Poster (ID: %d) and cannot read %s in Repo %-v.\n"+
|
||||
"User in Repo has Permissions: %-+v",
|
||||
ctx.User,
|
||||
ctx.Doer,
|
||||
log.NewColoredIDValue(issue.PosterID),
|
||||
issueType,
|
||||
ctx.Repo.Repository,
|
||||
@@ -48,10 +48,10 @@ func IssueWatch(ctx *context.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
if err := models.CreateOrUpdateIssueWatch(ctx.User.ID, issue.ID, watch); err != nil {
|
||||
if err := models.CreateOrUpdateIssueWatch(ctx.Doer.ID, issue.ID, watch); err != nil {
|
||||
ctx.ServerError("CreateOrUpdateIssueWatch", err)
|
||||
return
|
||||
}
|
||||
|
||||
ctx.Redirect(issue.HTMLURL(), http.StatusSeeOther)
|
||||
ctx.Redirect(issue.HTMLURL())
|
||||
}
|
||||
|
||||
+21
-7
@@ -23,6 +23,7 @@ import (
|
||||
"code.gitea.io/gitea/modules/git/pipeline"
|
||||
"code.gitea.io/gitea/modules/lfs"
|
||||
"code.gitea.io/gitea/modules/log"
|
||||
repo_module "code.gitea.io/gitea/modules/repository"
|
||||
"code.gitea.io/gitea/modules/setting"
|
||||
"code.gitea.io/gitea/modules/storage"
|
||||
"code.gitea.io/gitea/modules/typesniffer"
|
||||
@@ -103,14 +104,14 @@ func LFSLocks(ctx *context.Context) {
|
||||
}
|
||||
|
||||
// Clone base repo.
|
||||
tmpBasePath, err := models.CreateTemporaryPath("locks")
|
||||
tmpBasePath, err := repo_module.CreateTemporaryPath("locks")
|
||||
if err != nil {
|
||||
log.Error("Failed to create temporary path: %v", err)
|
||||
ctx.ServerError("LFSLocks", err)
|
||||
return
|
||||
}
|
||||
defer func() {
|
||||
if err := models.RemoveTemporaryPath(tmpBasePath); err != nil {
|
||||
if err := repo_module.RemoveTemporaryPath(tmpBasePath); err != nil {
|
||||
log.Error("LFSLocks: RemoveTemporaryPath: %v", err)
|
||||
}
|
||||
}()
|
||||
@@ -124,7 +125,7 @@ func LFSLocks(ctx *context.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
gitRepo, err := git.OpenRepositoryCtx(ctx, tmpBasePath)
|
||||
gitRepo, err := git.OpenRepository(ctx, tmpBasePath)
|
||||
if err != nil {
|
||||
log.Error("Unable to open temporary repository: %s (%v)", tmpBasePath, err)
|
||||
ctx.ServerError("LFSLocks", fmt.Errorf("failed to open new temporary repository in: %s %v", tmpBasePath, err))
|
||||
@@ -217,7 +218,7 @@ func LFSLockFile(ctx *context.Context) {
|
||||
|
||||
_, err := models.CreateLFSLock(ctx.Repo.Repository, &models.LFSLock{
|
||||
Path: lockPath,
|
||||
OwnerID: ctx.User.ID,
|
||||
OwnerID: ctx.Doer.ID,
|
||||
})
|
||||
if err != nil {
|
||||
if models.IsErrLFSLockAlreadyExist(err) {
|
||||
@@ -237,7 +238,7 @@ func LFSUnlock(ctx *context.Context) {
|
||||
ctx.NotFound("LFSUnlock", nil)
|
||||
return
|
||||
}
|
||||
_, err := models.DeleteLFSLockByID(ctx.ParamsInt64("lid"), ctx.Repo.Repository, ctx.User, true)
|
||||
_, err := models.DeleteLFSLockByID(ctx.ParamsInt64("lid"), ctx.Repo.Repository, ctx.Doer, true)
|
||||
if err != nil {
|
||||
ctx.ServerError("LFSUnlock", err)
|
||||
return
|
||||
@@ -253,6 +254,13 @@ func LFSFileGet(ctx *context.Context) {
|
||||
}
|
||||
ctx.Data["LFSFilesLink"] = ctx.Repo.RepoLink + "/settings/lfs"
|
||||
oid := ctx.Params("oid")
|
||||
|
||||
p := lfs.Pointer{Oid: oid}
|
||||
if !p.IsValid() {
|
||||
ctx.NotFound("LFSFileGet", nil)
|
||||
return
|
||||
}
|
||||
|
||||
ctx.Data["Title"] = oid
|
||||
ctx.Data["PageIsSettingsLFS"] = true
|
||||
meta, err := models.GetLFSMetaObjectByOid(ctx.Repo.Repository.ID, oid)
|
||||
@@ -343,6 +351,12 @@ func LFSDelete(ctx *context.Context) {
|
||||
return
|
||||
}
|
||||
oid := ctx.Params("oid")
|
||||
p := lfs.Pointer{Oid: oid}
|
||||
if !p.IsValid() {
|
||||
ctx.NotFound("LFSDelete", nil)
|
||||
return
|
||||
}
|
||||
|
||||
count, err := models.RemoveLFSMetaObjectByOid(ctx.Repo.Repository.ID, oid)
|
||||
if err != nil {
|
||||
ctx.ServerError("LFSDelete", err)
|
||||
@@ -463,7 +477,7 @@ func LFSPointerFiles(ctx *context.Context) {
|
||||
// Can we fix?
|
||||
// OK well that's "simple"
|
||||
// - we need to check whether current user has access to a repo that has access to the file
|
||||
result.Associatable, err = models.LFSObjectAccessible(ctx.User, pointerBlob.Oid)
|
||||
result.Associatable, err = models.LFSObjectAccessible(ctx.Doer, pointerBlob.Oid)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -538,7 +552,7 @@ func LFSAutoAssociate(ctx *context.Context) {
|
||||
metas[i].Oid = oid[:idx]
|
||||
// metas[i].RepositoryID = ctx.Repo.Repository.ID
|
||||
}
|
||||
if err := models.LFSAutoAssociate(metas, ctx.User, ctx.Repo.Repository.ID); err != nil {
|
||||
if err := models.LFSAutoAssociate(metas, ctx.Doer, ctx.Repo.Repository.ID); err != nil {
|
||||
ctx.ServerError("LFSAutoAssociate", err)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -12,5 +12,7 @@ import (
|
||||
)
|
||||
|
||||
func TestMain(m *testing.M) {
|
||||
unittest.MainTest(m, filepath.Join("..", "..", ".."))
|
||||
unittest.MainTest(m, &unittest.TestOptions{
|
||||
GiteaRootPath: filepath.Join("..", "..", ".."),
|
||||
})
|
||||
}
|
||||
|
||||
@@ -43,7 +43,7 @@ func SetDiffViewStyle(ctx *context.Context) {
|
||||
}
|
||||
|
||||
var (
|
||||
userStyle = ctx.User.DiffViewStyle
|
||||
userStyle = ctx.Doer.DiffViewStyle
|
||||
style string
|
||||
)
|
||||
|
||||
@@ -56,7 +56,7 @@ func SetDiffViewStyle(ctx *context.Context) {
|
||||
}
|
||||
|
||||
ctx.Data["IsSplitStyle"] = style == "split"
|
||||
if err := user_model.UpdateUserDiffViewStyle(ctx.User, style); err != nil {
|
||||
if err := user_model.UpdateUserDiffViewStyle(ctx.Doer, style); err != nil {
|
||||
ctx.ServerError("ErrUpdateDiffViewStyle", err)
|
||||
}
|
||||
}
|
||||
@@ -72,12 +72,12 @@ func SetWhitespaceBehavior(ctx *context.Context) {
|
||||
whitespaceBehavior = defaultWhitespaceBehavior
|
||||
}
|
||||
if ctx.IsSigned {
|
||||
userWhitespaceBehavior, err := user_model.GetUserSetting(ctx.User.ID, user_model.SettingsKeyDiffWhitespaceBehavior, defaultWhitespaceBehavior)
|
||||
userWhitespaceBehavior, err := user_model.GetUserSetting(ctx.Doer.ID, user_model.SettingsKeyDiffWhitespaceBehavior, defaultWhitespaceBehavior)
|
||||
if err == nil {
|
||||
if whitespaceBehavior == "" {
|
||||
whitespaceBehavior = userWhitespaceBehavior
|
||||
} else if whitespaceBehavior != userWhitespaceBehavior {
|
||||
_ = user_model.SetUserSetting(ctx.User.ID, user_model.SettingsKeyDiffWhitespaceBehavior, whitespaceBehavior)
|
||||
_ = user_model.SetUserSetting(ctx.Doer.ID, user_model.SettingsKeyDiffWhitespaceBehavior, whitespaceBehavior)
|
||||
}
|
||||
} // else: we can ignore the error safely
|
||||
}
|
||||
|
||||
@@ -106,8 +106,7 @@ func handleMigrateError(ctx *context.Context, owner *user_model.User, err error,
|
||||
ctx.Data["Err_RepoName"] = true
|
||||
ctx.RenderWithErr(ctx.Tr("repo.form.name_pattern_not_allowed", err.(db.ErrNamePatternNotAllowed).Pattern), tpl, form)
|
||||
default:
|
||||
remoteAddr, _ := forms.ParseRemoteAddr(form.CloneAddr, form.AuthUsername, form.AuthPassword)
|
||||
err = util.NewStringURLSanitizedError(err, remoteAddr, true)
|
||||
err = util.SanitizeErrorCredentialURLs(err)
|
||||
if strings.Contains(err.Error(), "Authentication failed") ||
|
||||
strings.Contains(err.Error(), "Bad credentials") ||
|
||||
strings.Contains(err.Error(), "could not read Username") {
|
||||
@@ -178,7 +177,7 @@ func MigratePost(ctx *context.Context) {
|
||||
|
||||
remoteAddr, err := forms.ParseRemoteAddr(form.CloneAddr, form.AuthUsername, form.AuthPassword)
|
||||
if err == nil {
|
||||
err = migrations.IsMigrateURLAllowed(remoteAddr, ctx.User)
|
||||
err = migrations.IsMigrateURLAllowed(remoteAddr, ctx.Doer)
|
||||
}
|
||||
if err != nil {
|
||||
ctx.Data["Err_CloneAddr"] = true
|
||||
@@ -195,7 +194,7 @@ func MigratePost(ctx *context.Context) {
|
||||
ctx.RenderWithErr(ctx.Tr("repo.migrate.invalid_lfs_endpoint"), tpl, &form)
|
||||
return
|
||||
}
|
||||
err = migrations.IsMigrateURLAllowed(ep.String(), ctx.User)
|
||||
err = migrations.IsMigrateURLAllowed(ep.String(), ctx.Doer)
|
||||
if err != nil {
|
||||
ctx.Data["Err_LFSEndpoint"] = true
|
||||
handleMigrateRemoteAddrError(ctx, err, tpl, form)
|
||||
@@ -233,13 +232,13 @@ func MigratePost(ctx *context.Context) {
|
||||
opts.Releases = false
|
||||
}
|
||||
|
||||
err = repo_model.CheckCreateRepository(ctx.User, ctxUser, opts.RepoName, false)
|
||||
err = repo_model.CheckCreateRepository(ctx.Doer, ctxUser, opts.RepoName, false)
|
||||
if err != nil {
|
||||
handleMigrateError(ctx, ctxUser, err, "MigratePost", tpl, form)
|
||||
return
|
||||
}
|
||||
|
||||
err = task.MigrateRepository(ctx.User, ctxUser, opts)
|
||||
err = task.MigrateRepository(ctx.Doer, ctxUser, opts)
|
||||
if err == nil {
|
||||
ctx.Redirect(ctxUser.HomeLink() + "/" + url.PathEscape(opts.RepoName))
|
||||
return
|
||||
|
||||
@@ -9,8 +9,8 @@ import (
|
||||
"net/url"
|
||||
"time"
|
||||
|
||||
"code.gitea.io/gitea/models"
|
||||
"code.gitea.io/gitea/models/db"
|
||||
issues_model "code.gitea.io/gitea/models/issues"
|
||||
"code.gitea.io/gitea/modules/base"
|
||||
"code.gitea.io/gitea/modules/context"
|
||||
"code.gitea.io/gitea/modules/markup"
|
||||
@@ -38,7 +38,7 @@ func Milestones(ctx *context.Context) {
|
||||
ctx.Data["PageIsMilestones"] = true
|
||||
|
||||
isShowClosed := ctx.FormString("state") == "closed"
|
||||
stats, err := models.GetMilestonesStatsByRepoCond(builder.And(builder.Eq{"id": ctx.Repo.Repository.ID}))
|
||||
stats, err := issues_model.GetMilestonesStatsByRepoCond(builder.And(builder.Eq{"id": ctx.Repo.Repository.ID}))
|
||||
if err != nil {
|
||||
ctx.ServerError("MilestoneStats", err)
|
||||
return
|
||||
@@ -60,7 +60,7 @@ func Milestones(ctx *context.Context) {
|
||||
state = structs.StateClosed
|
||||
}
|
||||
|
||||
miles, total, err := models.GetMilestones(models.GetMilestonesOption{
|
||||
miles, total, err := issues_model.GetMilestones(issues_model.GetMilestonesOption{
|
||||
ListOptions: db.ListOptions{
|
||||
Page: page,
|
||||
PageSize: setting.UI.IssuePagingNum,
|
||||
@@ -143,7 +143,7 @@ func NewMilestonePost(ctx *context.Context) {
|
||||
}
|
||||
|
||||
deadline = time.Date(deadline.Year(), deadline.Month(), deadline.Day(), 23, 59, 59, 0, deadline.Location())
|
||||
if err = models.NewMilestone(&models.Milestone{
|
||||
if err = issues_model.NewMilestone(&issues_model.Milestone{
|
||||
RepoID: ctx.Repo.Repository.ID,
|
||||
Name: form.Title,
|
||||
Content: form.Content,
|
||||
@@ -163,9 +163,9 @@ func EditMilestone(ctx *context.Context) {
|
||||
ctx.Data["PageIsMilestones"] = true
|
||||
ctx.Data["PageIsEditMilestone"] = true
|
||||
|
||||
m, err := models.GetMilestoneByRepoID(ctx.Repo.Repository.ID, ctx.ParamsInt64(":id"))
|
||||
m, err := issues_model.GetMilestoneByRepoID(ctx, ctx.Repo.Repository.ID, ctx.ParamsInt64(":id"))
|
||||
if err != nil {
|
||||
if models.IsErrMilestoneNotExist(err) {
|
||||
if issues_model.IsErrMilestoneNotExist(err) {
|
||||
ctx.NotFound("", nil)
|
||||
} else {
|
||||
ctx.ServerError("GetMilestoneByRepoID", err)
|
||||
@@ -203,9 +203,9 @@ func EditMilestonePost(ctx *context.Context) {
|
||||
}
|
||||
|
||||
deadline = time.Date(deadline.Year(), deadline.Month(), deadline.Day(), 23, 59, 59, 0, deadline.Location())
|
||||
m, err := models.GetMilestoneByRepoID(ctx.Repo.Repository.ID, ctx.ParamsInt64(":id"))
|
||||
m, err := issues_model.GetMilestoneByRepoID(ctx, ctx.Repo.Repository.ID, ctx.ParamsInt64(":id"))
|
||||
if err != nil {
|
||||
if models.IsErrMilestoneNotExist(err) {
|
||||
if issues_model.IsErrMilestoneNotExist(err) {
|
||||
ctx.NotFound("", nil)
|
||||
} else {
|
||||
ctx.ServerError("GetMilestoneByRepoID", err)
|
||||
@@ -215,7 +215,7 @@ func EditMilestonePost(ctx *context.Context) {
|
||||
m.Name = form.Title
|
||||
m.Content = form.Content
|
||||
m.DeadlineUnix = timeutil.TimeStamp(deadline.Unix())
|
||||
if err = models.UpdateMilestone(m, m.IsClosed); err != nil {
|
||||
if err = issues_model.UpdateMilestone(m, m.IsClosed); err != nil {
|
||||
ctx.ServerError("UpdateMilestone", err)
|
||||
return
|
||||
}
|
||||
@@ -237,8 +237,8 @@ func ChangeMilestoneStatus(ctx *context.Context) {
|
||||
}
|
||||
id := ctx.ParamsInt64(":id")
|
||||
|
||||
if err := models.ChangeMilestoneStatusByRepoIDAndID(ctx.Repo.Repository.ID, id, toClose); err != nil {
|
||||
if models.IsErrMilestoneNotExist(err) {
|
||||
if err := issues_model.ChangeMilestoneStatusByRepoIDAndID(ctx.Repo.Repository.ID, id, toClose); err != nil {
|
||||
if issues_model.IsErrMilestoneNotExist(err) {
|
||||
ctx.NotFound("", err)
|
||||
} else {
|
||||
ctx.ServerError("ChangeMilestoneStatusByIDAndRepoID", err)
|
||||
@@ -250,7 +250,7 @@ func ChangeMilestoneStatus(ctx *context.Context) {
|
||||
|
||||
// DeleteMilestone delete a milestone
|
||||
func DeleteMilestone(ctx *context.Context) {
|
||||
if err := models.DeleteMilestoneByRepoID(ctx.Repo.Repository.ID, ctx.FormInt64("id")); err != nil {
|
||||
if err := issues_model.DeleteMilestoneByRepoID(ctx.Repo.Repository.ID, ctx.FormInt64("id")); err != nil {
|
||||
ctx.Flash.Error("DeleteMilestoneByRepoID: " + err.Error())
|
||||
} else {
|
||||
ctx.Flash.Success(ctx.Tr("repo.milestones.deletion_success"))
|
||||
@@ -264,9 +264,9 @@ func DeleteMilestone(ctx *context.Context) {
|
||||
// MilestoneIssuesAndPulls lists all the issues and pull requests of the milestone
|
||||
func MilestoneIssuesAndPulls(ctx *context.Context) {
|
||||
milestoneID := ctx.ParamsInt64(":id")
|
||||
milestone, err := models.GetMilestoneByRepoID(ctx.Repo.Repository.ID, milestoneID)
|
||||
milestone, err := issues_model.GetMilestoneByRepoID(ctx, ctx.Repo.Repository.ID, milestoneID)
|
||||
if err != nil {
|
||||
if models.IsErrMilestoneNotExist(err) {
|
||||
if issues_model.IsErrMilestoneNotExist(err) {
|
||||
ctx.NotFound("GetMilestoneByID", err)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -0,0 +1,73 @@
|
||||
// Copyright 2021 The Gitea Authors. All rights reserved.
|
||||
// Use of this source code is governed by a MIT-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package repo
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"code.gitea.io/gitea/models/db"
|
||||
"code.gitea.io/gitea/models/packages"
|
||||
"code.gitea.io/gitea/modules/base"
|
||||
"code.gitea.io/gitea/modules/context"
|
||||
"code.gitea.io/gitea/modules/setting"
|
||||
)
|
||||
|
||||
const (
|
||||
tplPackagesList base.TplName = "repo/packages"
|
||||
)
|
||||
|
||||
// Packages displays a list of all packages in the repository
|
||||
func Packages(ctx *context.Context) {
|
||||
page := ctx.FormInt("page")
|
||||
if page <= 1 {
|
||||
page = 1
|
||||
}
|
||||
query := ctx.FormTrim("q")
|
||||
packageType := ctx.FormTrim("type")
|
||||
|
||||
pvs, total, err := packages.SearchLatestVersions(ctx, &packages.PackageSearchOptions{
|
||||
Paginator: &db.ListOptions{
|
||||
PageSize: setting.UI.PackagesPagingNum,
|
||||
Page: page,
|
||||
},
|
||||
OwnerID: ctx.ContextUser.ID,
|
||||
RepoID: ctx.Repo.Repository.ID,
|
||||
Type: packages.Type(packageType),
|
||||
Name: packages.SearchValue{Value: query},
|
||||
})
|
||||
if err != nil {
|
||||
ctx.ServerError("SearchLatestVersions", err)
|
||||
return
|
||||
}
|
||||
|
||||
pds, err := packages.GetPackageDescriptors(ctx, pvs)
|
||||
if err != nil {
|
||||
ctx.ServerError("GetPackageDescriptors", err)
|
||||
return
|
||||
}
|
||||
|
||||
hasPackages, err := packages.HasRepositoryPackages(ctx, ctx.Repo.Repository.ID)
|
||||
if err != nil {
|
||||
ctx.ServerError("HasRepositoryPackages", err)
|
||||
return
|
||||
}
|
||||
|
||||
ctx.Data["Title"] = ctx.Tr("packages.title")
|
||||
ctx.Data["IsPackagesPage"] = true
|
||||
ctx.Data["ContextUser"] = ctx.ContextUser
|
||||
ctx.Data["Query"] = query
|
||||
ctx.Data["PackageType"] = packageType
|
||||
ctx.Data["HasPackages"] = hasPackages
|
||||
ctx.Data["PackageDescriptors"] = pds
|
||||
ctx.Data["Total"] = total
|
||||
ctx.Data["RepositoryAccessMap"] = map[int64]bool{ctx.Repo.Repository.ID: true} // There is only the current repository
|
||||
|
||||
pager := context.NewPagination(int(total), setting.UI.PackagesPagingNum, page, 5)
|
||||
pager.AddParam(ctx, "q", "Query")
|
||||
pager.AddParam(ctx, "type", "PackageType")
|
||||
ctx.Data["Page"] = pager
|
||||
|
||||
ctx.HTML(http.StatusOK, tplPackagesList)
|
||||
}
|
||||
@@ -24,8 +24,6 @@ const (
|
||||
|
||||
// NewDiffPatch render create patch page
|
||||
func NewDiffPatch(ctx *context.Context) {
|
||||
ctx.Data["RequireHighlightJS"] = true
|
||||
|
||||
canCommit := renderCommitRights(ctx)
|
||||
|
||||
ctx.Data["TreePath"] = ""
|
||||
@@ -54,7 +52,6 @@ func NewDiffPatchPost(ctx *context.Context) {
|
||||
if form.CommitChoice == frmCommitChoiceNewBranch {
|
||||
branchName = form.NewBranchName
|
||||
}
|
||||
ctx.Data["RequireHighlightJS"] = true
|
||||
ctx.Data["TreePath"] = ""
|
||||
ctx.Data["BranchLink"] = ctx.Repo.RepoLink + "/src/" + ctx.Repo.BranchNameSubURL()
|
||||
ctx.Data["FileContent"] = form.Content
|
||||
@@ -90,7 +87,7 @@ func NewDiffPatchPost(ctx *context.Context) {
|
||||
message += "\n\n" + form.CommitMessage
|
||||
}
|
||||
|
||||
if _, err := files.ApplyDiffPatch(ctx, ctx.Repo.Repository, ctx.User, &files.ApplyDiffPatchOptions{
|
||||
if _, err := files.ApplyDiffPatch(ctx, ctx.Repo.Repository, ctx.Doer, &files.ApplyDiffPatchOptions{
|
||||
LastCommitID: form.LastCommit,
|
||||
OldBranch: ctx.Repo.BranchName,
|
||||
NewBranch: branchName,
|
||||
|
||||
@@ -12,6 +12,7 @@ import (
|
||||
|
||||
"code.gitea.io/gitea/models"
|
||||
"code.gitea.io/gitea/models/perm"
|
||||
project_model "code.gitea.io/gitea/models/project"
|
||||
"code.gitea.io/gitea/models/unit"
|
||||
"code.gitea.io/gitea/modules/base"
|
||||
"code.gitea.io/gitea/modules/context"
|
||||
@@ -69,12 +70,12 @@ func Projects(ctx *context.Context) {
|
||||
total = repo.NumClosedProjects
|
||||
}
|
||||
|
||||
projects, count, err := models.GetProjects(models.ProjectSearchOptions{
|
||||
projects, count, err := project_model.GetProjects(project_model.SearchOptions{
|
||||
RepoID: repo.ID,
|
||||
Page: page,
|
||||
IsClosed: util.OptionalBoolOf(isShowClosed),
|
||||
SortType: sortType,
|
||||
Type: models.ProjectTypeRepository,
|
||||
Type: project_model.TypeRepository,
|
||||
})
|
||||
if err != nil {
|
||||
ctx.ServerError("GetProjects", err)
|
||||
@@ -122,7 +123,7 @@ 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"] = models.GetProjectsConfig()
|
||||
ctx.Data["ProjectTypes"] = project_model.GetProjectsConfig()
|
||||
ctx.Data["CanWriteProjects"] = ctx.Repo.Permission.CanWrite(unit.TypeProjects)
|
||||
ctx.HTML(http.StatusOK, tplProjectsNew)
|
||||
}
|
||||
@@ -134,18 +135,18 @@ func NewProjectPost(ctx *context.Context) {
|
||||
|
||||
if ctx.HasError() {
|
||||
ctx.Data["CanWriteProjects"] = ctx.Repo.Permission.CanWrite(unit.TypeProjects)
|
||||
ctx.Data["ProjectTypes"] = models.GetProjectsConfig()
|
||||
ctx.Data["ProjectTypes"] = project_model.GetProjectsConfig()
|
||||
ctx.HTML(http.StatusOK, tplProjectsNew)
|
||||
return
|
||||
}
|
||||
|
||||
if err := models.NewProject(&models.Project{
|
||||
if err := project_model.NewProject(&project_model.Project{
|
||||
RepoID: ctx.Repo.Repository.ID,
|
||||
Title: form.Title,
|
||||
Description: form.Content,
|
||||
CreatorID: ctx.User.ID,
|
||||
CreatorID: ctx.Doer.ID,
|
||||
BoardType: form.BoardType,
|
||||
Type: models.ProjectTypeRepository,
|
||||
Type: project_model.TypeRepository,
|
||||
}); err != nil {
|
||||
ctx.ServerError("NewProject", err)
|
||||
return
|
||||
@@ -168,8 +169,8 @@ func ChangeProjectStatus(ctx *context.Context) {
|
||||
}
|
||||
id := ctx.ParamsInt64(":id")
|
||||
|
||||
if err := models.ChangeProjectStatusByRepoIDAndID(ctx.Repo.Repository.ID, id, toClose); err != nil {
|
||||
if models.IsErrProjectNotExist(err) {
|
||||
if err := project_model.ChangeProjectStatusByRepoIDAndID(ctx.Repo.Repository.ID, id, toClose); err != nil {
|
||||
if project_model.IsErrProjectNotExist(err) {
|
||||
ctx.NotFound("", err)
|
||||
} else {
|
||||
ctx.ServerError("ChangeProjectStatusByIDAndRepoID", err)
|
||||
@@ -181,9 +182,9 @@ func ChangeProjectStatus(ctx *context.Context) {
|
||||
|
||||
// DeleteProject delete a project
|
||||
func DeleteProject(ctx *context.Context) {
|
||||
p, err := models.GetProjectByID(ctx.ParamsInt64(":id"))
|
||||
p, err := project_model.GetProjectByID(ctx.ParamsInt64(":id"))
|
||||
if err != nil {
|
||||
if models.IsErrProjectNotExist(err) {
|
||||
if project_model.IsErrProjectNotExist(err) {
|
||||
ctx.NotFound("", nil)
|
||||
} else {
|
||||
ctx.ServerError("GetProjectByID", err)
|
||||
@@ -195,7 +196,7 @@ func DeleteProject(ctx *context.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
if err := models.DeleteProjectByID(p.ID); err != nil {
|
||||
if err := project_model.DeleteProjectByID(p.ID); err != nil {
|
||||
ctx.Flash.Error("DeleteProjectByID: " + err.Error())
|
||||
} else {
|
||||
ctx.Flash.Success(ctx.Tr("repo.projects.deletion_success"))
|
||||
@@ -212,9 +213,9 @@ func EditProject(ctx *context.Context) {
|
||||
ctx.Data["PageIsEditProjects"] = true
|
||||
ctx.Data["CanWriteProjects"] = ctx.Repo.Permission.CanWrite(unit.TypeProjects)
|
||||
|
||||
p, err := models.GetProjectByID(ctx.ParamsInt64(":id"))
|
||||
p, err := project_model.GetProjectByID(ctx.ParamsInt64(":id"))
|
||||
if err != nil {
|
||||
if models.IsErrProjectNotExist(err) {
|
||||
if project_model.IsErrProjectNotExist(err) {
|
||||
ctx.NotFound("", nil)
|
||||
} else {
|
||||
ctx.ServerError("GetProjectByID", err)
|
||||
@@ -244,9 +245,9 @@ func EditProjectPost(ctx *context.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
p, err := models.GetProjectByID(ctx.ParamsInt64(":id"))
|
||||
p, err := project_model.GetProjectByID(ctx.ParamsInt64(":id"))
|
||||
if err != nil {
|
||||
if models.IsErrProjectNotExist(err) {
|
||||
if project_model.IsErrProjectNotExist(err) {
|
||||
ctx.NotFound("", nil)
|
||||
} else {
|
||||
ctx.ServerError("GetProjectByID", err)
|
||||
@@ -260,7 +261,7 @@ func EditProjectPost(ctx *context.Context) {
|
||||
|
||||
p.Title = form.Title
|
||||
p.Description = form.Content
|
||||
if err = models.UpdateProject(p); err != nil {
|
||||
if err = project_model.UpdateProject(p); err != nil {
|
||||
ctx.ServerError("UpdateProjects", err)
|
||||
return
|
||||
}
|
||||
@@ -271,9 +272,9 @@ func EditProjectPost(ctx *context.Context) {
|
||||
|
||||
// ViewProject renders the project board for a project
|
||||
func ViewProject(ctx *context.Context) {
|
||||
project, err := models.GetProjectByID(ctx.ParamsInt64(":id"))
|
||||
project, err := project_model.GetProjectByID(ctx.ParamsInt64(":id"))
|
||||
if err != nil {
|
||||
if models.IsErrProjectNotExist(err) {
|
||||
if project_model.IsErrProjectNotExist(err) {
|
||||
ctx.NotFound("", nil)
|
||||
} else {
|
||||
ctx.ServerError("GetProjectByID", err)
|
||||
@@ -285,7 +286,7 @@ func ViewProject(ctx *context.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
boards, err := models.GetProjectBoards(project.ID)
|
||||
boards, err := project_model.GetBoards(project.ID)
|
||||
if err != nil {
|
||||
ctx.ServerError("GetProjectBoards", err)
|
||||
return
|
||||
@@ -295,27 +296,29 @@ func ViewProject(ctx *context.Context) {
|
||||
boards[0].Title = ctx.Tr("repo.projects.type.uncategorized")
|
||||
}
|
||||
|
||||
issueList, err := boards.LoadIssues()
|
||||
issuesMap, err := models.LoadIssuesFromBoardList(boards)
|
||||
if err != nil {
|
||||
ctx.ServerError("LoadIssuesOfBoards", err)
|
||||
return
|
||||
}
|
||||
|
||||
linkedPrsMap := make(map[int64][]*models.Issue)
|
||||
for _, issue := range issueList {
|
||||
var referencedIds []int64
|
||||
for _, comment := range issue.Comments {
|
||||
if comment.RefIssueID != 0 && comment.RefIsPull {
|
||||
referencedIds = append(referencedIds, comment.RefIssueID)
|
||||
for _, issuesList := range issuesMap {
|
||||
for _, issue := range issuesList {
|
||||
var referencedIds []int64
|
||||
for _, comment := range issue.Comments {
|
||||
if comment.RefIssueID != 0 && comment.RefIsPull {
|
||||
referencedIds = append(referencedIds, comment.RefIssueID)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if len(referencedIds) > 0 {
|
||||
if linkedPrs, err := models.Issues(&models.IssuesOptions{
|
||||
IssueIDs: referencedIds,
|
||||
IsPull: util.OptionalBoolTrue,
|
||||
}); err == nil {
|
||||
linkedPrsMap[issue.ID] = linkedPrs
|
||||
if len(referencedIds) > 0 {
|
||||
if linkedPrs, err := models.Issues(&models.IssuesOptions{
|
||||
IssueIDs: referencedIds,
|
||||
IsPull: util.OptionalBoolTrue,
|
||||
}); err == nil {
|
||||
linkedPrsMap[issue.ID] = linkedPrs
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -335,6 +338,7 @@ func ViewProject(ctx *context.Context) {
|
||||
ctx.Data["IsProjectsPage"] = true
|
||||
ctx.Data["CanWriteProjects"] = ctx.Repo.Permission.CanWrite(unit.TypeProjects)
|
||||
ctx.Data["Project"] = project
|
||||
ctx.Data["IssuesMap"] = issuesMap
|
||||
ctx.Data["Boards"] = boards
|
||||
|
||||
ctx.HTML(http.StatusOK, tplProjectsView)
|
||||
@@ -354,7 +358,7 @@ func UpdateIssueProject(ctx *context.Context) {
|
||||
continue
|
||||
}
|
||||
|
||||
if err := models.ChangeProjectAssign(issue, ctx.User, projectID); err != nil {
|
||||
if err := models.ChangeProjectAssign(issue, ctx.Doer, projectID); err != nil {
|
||||
ctx.ServerError("ChangeProjectAssign", err)
|
||||
return
|
||||
}
|
||||
@@ -367,7 +371,7 @@ func UpdateIssueProject(ctx *context.Context) {
|
||||
|
||||
// DeleteProjectBoard allows for the deletion of a project board
|
||||
func DeleteProjectBoard(ctx *context.Context) {
|
||||
if ctx.User == nil {
|
||||
if ctx.Doer == nil {
|
||||
ctx.JSON(http.StatusForbidden, map[string]string{
|
||||
"message": "Only signed in users are allowed to perform this action.",
|
||||
})
|
||||
@@ -381,9 +385,9 @@ func DeleteProjectBoard(ctx *context.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
project, err := models.GetProjectByID(ctx.ParamsInt64(":id"))
|
||||
project, err := project_model.GetProjectByID(ctx.ParamsInt64(":id"))
|
||||
if err != nil {
|
||||
if models.IsErrProjectNotExist(err) {
|
||||
if project_model.IsErrProjectNotExist(err) {
|
||||
ctx.NotFound("", nil)
|
||||
} else {
|
||||
ctx.ServerError("GetProjectByID", err)
|
||||
@@ -391,7 +395,7 @@ func DeleteProjectBoard(ctx *context.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
pb, err := models.GetProjectBoard(ctx.ParamsInt64(":boardID"))
|
||||
pb, err := project_model.GetBoard(ctx.ParamsInt64(":boardID"))
|
||||
if err != nil {
|
||||
ctx.ServerError("GetProjectBoard", err)
|
||||
return
|
||||
@@ -410,7 +414,7 @@ func DeleteProjectBoard(ctx *context.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
if err := models.DeleteProjectBoardByID(ctx.ParamsInt64(":boardID")); err != nil {
|
||||
if err := project_model.DeleteBoardByID(ctx.ParamsInt64(":boardID")); err != nil {
|
||||
ctx.ServerError("DeleteProjectBoardByID", err)
|
||||
return
|
||||
}
|
||||
@@ -430,9 +434,9 @@ func AddBoardToProjectPost(ctx *context.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
project, err := models.GetProjectByID(ctx.ParamsInt64(":id"))
|
||||
project, err := project_model.GetProjectByID(ctx.ParamsInt64(":id"))
|
||||
if err != nil {
|
||||
if models.IsErrProjectNotExist(err) {
|
||||
if project_model.IsErrProjectNotExist(err) {
|
||||
ctx.NotFound("", nil)
|
||||
} else {
|
||||
ctx.ServerError("GetProjectByID", err)
|
||||
@@ -440,11 +444,11 @@ func AddBoardToProjectPost(ctx *context.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
if err := models.NewProjectBoard(&models.ProjectBoard{
|
||||
if err := project_model.NewBoard(&project_model.Board{
|
||||
ProjectID: project.ID,
|
||||
Title: form.Title,
|
||||
Color: form.Color,
|
||||
CreatorID: ctx.User.ID,
|
||||
CreatorID: ctx.Doer.ID,
|
||||
}); err != nil {
|
||||
ctx.ServerError("NewProjectBoard", err)
|
||||
return
|
||||
@@ -455,8 +459,8 @@ func AddBoardToProjectPost(ctx *context.Context) {
|
||||
})
|
||||
}
|
||||
|
||||
func checkProjectBoardChangePermissions(ctx *context.Context) (*models.Project, *models.ProjectBoard) {
|
||||
if ctx.User == nil {
|
||||
func checkProjectBoardChangePermissions(ctx *context.Context) (*project_model.Project, *project_model.Board) {
|
||||
if ctx.Doer == nil {
|
||||
ctx.JSON(http.StatusForbidden, map[string]string{
|
||||
"message": "Only signed in users are allowed to perform this action.",
|
||||
})
|
||||
@@ -470,9 +474,9 @@ func checkProjectBoardChangePermissions(ctx *context.Context) (*models.Project,
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
project, err := models.GetProjectByID(ctx.ParamsInt64(":id"))
|
||||
project, err := project_model.GetProjectByID(ctx.ParamsInt64(":id"))
|
||||
if err != nil {
|
||||
if models.IsErrProjectNotExist(err) {
|
||||
if project_model.IsErrProjectNotExist(err) {
|
||||
ctx.NotFound("", nil)
|
||||
} else {
|
||||
ctx.ServerError("GetProjectByID", err)
|
||||
@@ -480,7 +484,7 @@ func checkProjectBoardChangePermissions(ctx *context.Context) (*models.Project,
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
board, err := models.GetProjectBoard(ctx.ParamsInt64(":boardID"))
|
||||
board, err := project_model.GetBoard(ctx.ParamsInt64(":boardID"))
|
||||
if err != nil {
|
||||
ctx.ServerError("GetProjectBoard", err)
|
||||
return nil, nil
|
||||
@@ -519,7 +523,7 @@ func EditProjectBoard(ctx *context.Context) {
|
||||
board.Sorting = form.Sorting
|
||||
}
|
||||
|
||||
if err := models.UpdateProjectBoard(board); err != nil {
|
||||
if err := project_model.UpdateBoard(board); err != nil {
|
||||
ctx.ServerError("UpdateProjectBoard", err)
|
||||
return
|
||||
}
|
||||
@@ -536,7 +540,7 @@ func SetDefaultProjectBoard(ctx *context.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
if err := models.SetDefaultBoard(project.ID, board.ID); err != nil {
|
||||
if err := project_model.SetDefaultBoard(project.ID, board.ID); err != nil {
|
||||
ctx.ServerError("SetDefaultBoard", err)
|
||||
return
|
||||
}
|
||||
@@ -548,7 +552,7 @@ func SetDefaultProjectBoard(ctx *context.Context) {
|
||||
|
||||
// MoveIssues moves or keeps issues in a column and sorts them inside that column
|
||||
func MoveIssues(ctx *context.Context) {
|
||||
if ctx.User == nil {
|
||||
if ctx.Doer == nil {
|
||||
ctx.JSON(http.StatusForbidden, map[string]string{
|
||||
"message": "Only signed in users are allowed to perform this action.",
|
||||
})
|
||||
@@ -562,9 +566,9 @@ func MoveIssues(ctx *context.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
project, err := models.GetProjectByID(ctx.ParamsInt64(":id"))
|
||||
project, err := project_model.GetProjectByID(ctx.ParamsInt64(":id"))
|
||||
if err != nil {
|
||||
if models.IsErrProjectNotExist(err) {
|
||||
if project_model.IsErrProjectNotExist(err) {
|
||||
ctx.NotFound("ProjectNotExist", nil)
|
||||
} else {
|
||||
ctx.ServerError("GetProjectByID", err)
|
||||
@@ -576,19 +580,18 @@ func MoveIssues(ctx *context.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
var board *models.ProjectBoard
|
||||
var board *project_model.Board
|
||||
|
||||
if ctx.ParamsInt64(":boardID") == 0 {
|
||||
board = &models.ProjectBoard{
|
||||
board = &project_model.Board{
|
||||
ID: 0,
|
||||
ProjectID: project.ID,
|
||||
Title: ctx.Tr("repo.projects.type.uncategorized"),
|
||||
}
|
||||
} else {
|
||||
// column
|
||||
board, err = models.GetProjectBoard(ctx.ParamsInt64(":boardID"))
|
||||
board, err = project_model.GetBoard(ctx.ParamsInt64(":boardID"))
|
||||
if err != nil {
|
||||
if models.IsErrProjectBoardNotExist(err) {
|
||||
if project_model.IsErrProjectBoardNotExist(err) {
|
||||
ctx.NotFound("ProjectBoardNotExist", nil)
|
||||
} else {
|
||||
ctx.ServerError("GetProjectBoard", err)
|
||||
@@ -634,7 +637,7 @@ func MoveIssues(ctx *context.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
if err = models.MoveIssuesOnProjectBoard(board, sortedIssueIDs); err != nil {
|
||||
if err = project_model.MoveIssuesOnProjectBoard(board, sortedIssueIDs); err != nil {
|
||||
ctx.ServerError("MoveIssuesOnProjectBoard", err)
|
||||
return
|
||||
}
|
||||
@@ -647,8 +650,43 @@ func MoveIssues(ctx *context.Context) {
|
||||
// CreateProject renders the generic project creation page
|
||||
func CreateProject(ctx *context.Context) {
|
||||
ctx.Data["Title"] = ctx.Tr("repo.projects.new")
|
||||
ctx.Data["ProjectTypes"] = models.GetProjectsConfig()
|
||||
ctx.Data["ProjectTypes"] = project_model.GetProjectsConfig()
|
||||
ctx.Data["CanWriteProjects"] = ctx.Repo.Permission.CanWrite(unit.TypeProjects)
|
||||
|
||||
ctx.HTML(http.StatusOK, tplGenericProjectsNew)
|
||||
}
|
||||
|
||||
// CreateProjectPost creates an individual and/or organization project
|
||||
func CreateProjectPost(ctx *context.Context, form forms.UserCreateProjectForm) {
|
||||
user := checkContextUser(ctx, form.UID)
|
||||
if ctx.Written() {
|
||||
return
|
||||
}
|
||||
|
||||
ctx.Data["ContextUser"] = user
|
||||
|
||||
if ctx.HasError() {
|
||||
ctx.Data["CanWriteProjects"] = ctx.Repo.Permission.CanWrite(unit.TypeProjects)
|
||||
ctx.HTML(http.StatusOK, tplGenericProjectsNew)
|
||||
return
|
||||
}
|
||||
|
||||
projectType := project_model.TypeIndividual
|
||||
if user.IsOrganization() {
|
||||
projectType = project_model.TypeOrganization
|
||||
}
|
||||
|
||||
if err := project_model.NewProject(&project_model.Project{
|
||||
Title: form.Title,
|
||||
Description: form.Content,
|
||||
CreatorID: user.ID,
|
||||
BoardType: form.BoardType,
|
||||
Type: projectType,
|
||||
}); err != nil {
|
||||
ctx.ServerError("NewProject", err)
|
||||
return
|
||||
}
|
||||
|
||||
ctx.Flash.Success(ctx.Tr("repo.projects.create_success", form.Title))
|
||||
ctx.Redirect(setting.AppSubURL + "/")
|
||||
}
|
||||
|
||||
+175
-160
@@ -18,6 +18,7 @@ import (
|
||||
|
||||
"code.gitea.io/gitea/models"
|
||||
"code.gitea.io/gitea/models/db"
|
||||
"code.gitea.io/gitea/models/organization"
|
||||
repo_model "code.gitea.io/gitea/models/repo"
|
||||
"code.gitea.io/gitea/models/unit"
|
||||
user_model "code.gitea.io/gitea/models/user"
|
||||
@@ -33,6 +34,7 @@ import (
|
||||
"code.gitea.io/gitea/modules/web"
|
||||
"code.gitea.io/gitea/modules/web/middleware"
|
||||
"code.gitea.io/gitea/routers/utils"
|
||||
asymkey_service "code.gitea.io/gitea/services/asymkey"
|
||||
"code.gitea.io/gitea/services/forms"
|
||||
"code.gitea.io/gitea/services/gitdiff"
|
||||
pull_service "code.gitea.io/gitea/services/pull"
|
||||
@@ -68,7 +70,7 @@ func getRepository(ctx *context.Context, repoID int64) *repo_model.Repository {
|
||||
return nil
|
||||
}
|
||||
|
||||
perm, err := models.GetUserRepoPermission(repo, ctx.User)
|
||||
perm, err := models.GetUserRepoPermission(ctx, repo, ctx.Doer)
|
||||
if err != nil {
|
||||
ctx.ServerError("GetUserRepoPermission", err)
|
||||
return nil
|
||||
@@ -77,7 +79,7 @@ func getRepository(ctx *context.Context, repoID int64) *repo_model.Repository {
|
||||
if !perm.CanRead(unit.TypeCode) {
|
||||
log.Trace("Permission Denied: User %-v cannot read %-v of repo %-v\n"+
|
||||
"User in repo has Permissions: %-+v",
|
||||
ctx.User,
|
||||
ctx.Doer,
|
||||
unit.TypeCode,
|
||||
ctx.Repo,
|
||||
perm)
|
||||
@@ -99,7 +101,7 @@ func getForkRepository(ctx *context.Context) *repo_model.Repository {
|
||||
return nil
|
||||
}
|
||||
|
||||
if err := forkRepo.GetOwner(db.DefaultContext); err != nil {
|
||||
if err := forkRepo.GetOwner(ctx); err != nil {
|
||||
ctx.ServerError("GetOwner", err)
|
||||
return nil
|
||||
}
|
||||
@@ -107,16 +109,16 @@ func getForkRepository(ctx *context.Context) *repo_model.Repository {
|
||||
ctx.Data["repo_name"] = forkRepo.Name
|
||||
ctx.Data["description"] = forkRepo.Description
|
||||
ctx.Data["IsPrivate"] = forkRepo.IsPrivate || forkRepo.Owner.Visibility == structs.VisibleTypePrivate
|
||||
canForkToUser := forkRepo.OwnerID != ctx.User.ID && !repo_model.HasForkedRepo(ctx.User.ID, forkRepo.ID)
|
||||
canForkToUser := forkRepo.OwnerID != ctx.Doer.ID && !repo_model.HasForkedRepo(ctx.Doer.ID, forkRepo.ID)
|
||||
|
||||
ctx.Data["ForkRepo"] = forkRepo
|
||||
|
||||
ownedOrgs, err := models.GetOrgsCanCreateRepoByUserID(ctx.User.ID)
|
||||
ownedOrgs, err := organization.GetOrgsCanCreateRepoByUserID(ctx.Doer.ID)
|
||||
if err != nil {
|
||||
ctx.ServerError("GetOrgsCanCreateRepoByUserID", err)
|
||||
return nil
|
||||
}
|
||||
var orgs []*models.Organization
|
||||
var orgs []*organization.Organization
|
||||
for _, org := range ownedOrgs {
|
||||
if forkRepo.OwnerID != org.ID && !repo_model.HasForkedRepo(org.ID, forkRepo.ID) {
|
||||
orgs = append(orgs, org)
|
||||
@@ -125,7 +127,7 @@ func getForkRepository(ctx *context.Context) *repo_model.Repository {
|
||||
|
||||
traverseParentRepo := forkRepo
|
||||
for {
|
||||
if ctx.User.ID == traverseParentRepo.OwnerID {
|
||||
if ctx.Doer.ID == traverseParentRepo.OwnerID {
|
||||
canForkToUser = false
|
||||
} else {
|
||||
for i, org := range orgs {
|
||||
@@ -150,7 +152,7 @@ func getForkRepository(ctx *context.Context) *repo_model.Repository {
|
||||
ctx.Data["Orgs"] = orgs
|
||||
|
||||
if canForkToUser {
|
||||
ctx.Data["ContextUser"] = ctx.User
|
||||
ctx.Data["ContextUser"] = ctx.Doer
|
||||
} else if len(orgs) > 0 {
|
||||
ctx.Data["ContextUser"] = orgs[0]
|
||||
}
|
||||
@@ -216,7 +218,7 @@ func ForkPost(ctx *context.Context) {
|
||||
|
||||
// Check if user is allowed to create repo's on the organization.
|
||||
if ctxUser.IsOrganization() {
|
||||
isAllowedToFork, err := models.OrgFromUser(ctxUser).CanCreateOrgRepo(ctx.User.ID)
|
||||
isAllowedToFork, err := organization.OrgFromUser(ctxUser).CanCreateOrgRepo(ctx.Doer.ID)
|
||||
if err != nil {
|
||||
ctx.ServerError("CanCreateOrgRepo", err)
|
||||
return
|
||||
@@ -226,7 +228,7 @@ func ForkPost(ctx *context.Context) {
|
||||
}
|
||||
}
|
||||
|
||||
repo, err := repo_service.ForkRepository(ctx.User, ctxUser, repo_service.ForkRepoOptions{
|
||||
repo, err := repo_service.ForkRepository(ctx, ctx.Doer, ctxUser, repo_service.ForkRepoOptions{
|
||||
BaseRepo: forkRepo,
|
||||
Name: form.RepoName,
|
||||
Description: form.Description,
|
||||
@@ -264,7 +266,7 @@ func checkPullInfo(ctx *context.Context) *models.Issue {
|
||||
ctx.ServerError("LoadPoster", err)
|
||||
return nil
|
||||
}
|
||||
if err := issue.LoadRepo(); err != nil {
|
||||
if err := issue.LoadRepo(ctx); err != nil {
|
||||
ctx.ServerError("LoadRepo", err)
|
||||
return nil
|
||||
}
|
||||
@@ -281,14 +283,14 @@ func checkPullInfo(ctx *context.Context) *models.Issue {
|
||||
return nil
|
||||
}
|
||||
|
||||
if err = issue.PullRequest.LoadHeadRepo(); err != nil {
|
||||
if err = issue.PullRequest.LoadHeadRepoCtx(ctx); err != nil {
|
||||
ctx.ServerError("LoadHeadRepo", err)
|
||||
return nil
|
||||
}
|
||||
|
||||
if ctx.IsSigned {
|
||||
// Update issue-user.
|
||||
if err = issue.ReadBy(ctx.User.ID); err != nil {
|
||||
if err = issue.ReadBy(ctx, ctx.Doer.ID); err != nil {
|
||||
ctx.ServerError("ReadBy", err)
|
||||
return nil
|
||||
}
|
||||
@@ -338,7 +340,7 @@ func PrepareMergedViewPullInfo(ctx *context.Context, issue *models.Issue) *git.C
|
||||
}
|
||||
if commitSHA != "" {
|
||||
// Get immediate parent of the first commit in the patch, grab history back
|
||||
parentCommit, err = git.NewCommand(ctx, "rev-list", "-1", "--skip=1", commitSHA).RunInDir(ctx.Repo.GitRepo.Path)
|
||||
parentCommit, _, err = git.NewCommand(ctx, "rev-list", "-1", "--skip=1", commitSHA).RunStdString(&git.RunOpts{Dir: ctx.Repo.GitRepo.Path})
|
||||
if err == nil {
|
||||
parentCommit = strings.TrimSpace(parentCommit)
|
||||
}
|
||||
@@ -395,12 +397,12 @@ func PrepareViewPullInfo(ctx *context.Context, issue *models.Issue) *git.Compare
|
||||
repo := ctx.Repo.Repository
|
||||
pull := issue.PullRequest
|
||||
|
||||
if err := pull.LoadHeadRepo(); err != nil {
|
||||
if err := pull.LoadHeadRepoCtx(ctx); err != nil {
|
||||
ctx.ServerError("LoadHeadRepo", err)
|
||||
return nil
|
||||
}
|
||||
|
||||
if err := pull.LoadBaseRepo(); err != nil {
|
||||
if err := pull.LoadBaseRepoCtx(ctx); err != nil {
|
||||
ctx.ServerError("LoadBaseRepo", err)
|
||||
return nil
|
||||
}
|
||||
@@ -417,7 +419,7 @@ func PrepareViewPullInfo(ctx *context.Context, issue *models.Issue) *git.Compare
|
||||
if pull.BaseRepoID == ctx.Repo.Repository.ID && ctx.Repo.GitRepo != nil {
|
||||
baseGitRepo = ctx.Repo.GitRepo
|
||||
} else {
|
||||
baseGitRepo, err := git.OpenRepositoryCtx(ctx, pull.BaseRepo.RepoPath())
|
||||
baseGitRepo, err := git.OpenRepository(ctx, pull.BaseRepo.RepoPath())
|
||||
if err != nil {
|
||||
ctx.ServerError("OpenRepository", err)
|
||||
return nil
|
||||
@@ -469,7 +471,7 @@ func PrepareViewPullInfo(ctx *context.Context, issue *models.Issue) *git.Compare
|
||||
var headBranchSha string
|
||||
// HeadRepo may be missing
|
||||
if pull.HeadRepo != nil {
|
||||
headGitRepo, err := git.OpenRepositoryCtx(ctx, pull.HeadRepo.RepoPath())
|
||||
headGitRepo, err := git.OpenRepository(ctx, pull.HeadRepo.RepoPath())
|
||||
if err != nil {
|
||||
ctx.ServerError("OpenRepository", err)
|
||||
return nil
|
||||
@@ -497,7 +499,7 @@ func PrepareViewPullInfo(ctx *context.Context, issue *models.Issue) *git.Compare
|
||||
|
||||
if headBranchExist {
|
||||
var err error
|
||||
ctx.Data["UpdateAllowed"], ctx.Data["UpdateByRebaseAllowed"], err = pull_service.IsUserAllowedToUpdate(pull, ctx.User)
|
||||
ctx.Data["UpdateAllowed"], ctx.Data["UpdateByRebaseAllowed"], err = pull_service.IsUserAllowedToUpdate(ctx, pull, ctx.Doer)
|
||||
if err != nil {
|
||||
ctx.ServerError("IsUserAllowedToUpdate", err)
|
||||
return nil
|
||||
@@ -683,23 +685,36 @@ func ViewPullFiles(ctx *context.Context) {
|
||||
if fileOnly && (len(files) == 2 || len(files) == 1) {
|
||||
maxLines, maxFiles = -1, -1
|
||||
}
|
||||
diffOptions := &gitdiff.DiffOptions{
|
||||
BeforeCommitID: startCommitID,
|
||||
AfterCommitID: endCommitID,
|
||||
SkipTo: ctx.FormString("skip-to"),
|
||||
MaxLines: maxLines,
|
||||
MaxLineCharacters: setting.Git.MaxGitDiffLineCharacters,
|
||||
MaxFiles: maxFiles,
|
||||
WhitespaceBehavior: gitdiff.GetWhitespaceFlag(ctx.Data["WhitespaceBehavior"].(string)),
|
||||
}
|
||||
|
||||
diff, err := gitdiff.GetDiff(gitRepo,
|
||||
&gitdiff.DiffOptions{
|
||||
BeforeCommitID: startCommitID,
|
||||
AfterCommitID: endCommitID,
|
||||
SkipTo: ctx.FormString("skip-to"),
|
||||
MaxLines: maxLines,
|
||||
MaxLineCharacters: setting.Git.MaxGitDiffLineCharacters,
|
||||
MaxFiles: maxFiles,
|
||||
WhitespaceBehavior: gitdiff.GetWhitespaceFlag(ctx.Data["WhitespaceBehavior"].(string)),
|
||||
}, ctx.FormStrings("files")...)
|
||||
var methodWithError string
|
||||
var diff *gitdiff.Diff
|
||||
if !ctx.IsSigned {
|
||||
diff, err = gitdiff.GetDiff(gitRepo, diffOptions, files...)
|
||||
methodWithError = "GetDiff"
|
||||
} else {
|
||||
diff, err = gitdiff.SyncAndGetUserSpecificDiff(ctx, ctx.Doer.ID, pull, gitRepo, diffOptions, files...)
|
||||
methodWithError = "SyncAndGetUserSpecificDiff"
|
||||
}
|
||||
if err != nil {
|
||||
ctx.ServerError("GetDiffRangeWithWhitespaceBehavior", err)
|
||||
ctx.ServerError(methodWithError, err)
|
||||
return
|
||||
}
|
||||
|
||||
if err = diff.LoadComments(ctx, issue, ctx.User); err != nil {
|
||||
ctx.PageData["prReview"] = map[string]interface{}{
|
||||
"numberOfFiles": diff.NumFiles,
|
||||
"numberOfViewedFiles": diff.NumViewedFiles,
|
||||
}
|
||||
|
||||
if err = diff.LoadComments(ctx, issue, ctx.Doer); err != nil {
|
||||
ctx.ServerError("LoadComments", err)
|
||||
return
|
||||
}
|
||||
@@ -732,8 +747,8 @@ func ViewPullFiles(ctx *context.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
if ctx.IsSigned && ctx.User != nil {
|
||||
if ctx.Data["CanMarkConversation"], err = models.CanMarkConversation(issue, ctx.User); err != nil {
|
||||
if ctx.IsSigned && ctx.Doer != nil {
|
||||
if ctx.Data["CanMarkConversation"], err = models.CanMarkConversation(issue, ctx.Doer); err != nil {
|
||||
ctx.ServerError("CanMarkConversation", err)
|
||||
return
|
||||
}
|
||||
@@ -741,7 +756,6 @@ func ViewPullFiles(ctx *context.Context) {
|
||||
|
||||
setCompareContext(ctx, baseCommit, commit, ctx.Repo.Owner.Name, ctx.Repo.Repository.Name)
|
||||
|
||||
ctx.Data["RequireHighlightJS"] = true
|
||||
ctx.Data["RequireTribute"] = true
|
||||
if ctx.Data["Assignees"], err = models.GetRepoAssignees(ctx.Repo.Repository); err != nil {
|
||||
ctx.ServerError("GetAssignees", err)
|
||||
@@ -751,13 +765,29 @@ func ViewPullFiles(ctx *context.Context) {
|
||||
if ctx.Written() {
|
||||
return
|
||||
}
|
||||
ctx.Data["CurrentReview"], err = models.GetCurrentReview(ctx.User, issue)
|
||||
|
||||
currentReview, err := models.GetCurrentReview(ctx.Doer, issue)
|
||||
if err != nil && !models.IsErrReviewNotExist(err) {
|
||||
ctx.ServerError("GetCurrentReview", err)
|
||||
return
|
||||
}
|
||||
numPendingCodeComments := int64(0)
|
||||
if currentReview != nil {
|
||||
numPendingCodeComments, err = models.CountComments(&models.FindCommentsOptions{
|
||||
Type: models.CommentTypeCode,
|
||||
ReviewID: currentReview.ID,
|
||||
IssueID: issue.ID,
|
||||
})
|
||||
if err != nil {
|
||||
ctx.ServerError("CountComments", err)
|
||||
return
|
||||
}
|
||||
}
|
||||
ctx.Data["CurrentReview"] = currentReview
|
||||
ctx.Data["PendingCodeCommentNumber"] = numPendingCodeComments
|
||||
|
||||
getBranchData(ctx, issue)
|
||||
ctx.Data["IsIssuePoster"] = ctx.IsSigned && issue.IsPoster(ctx.User.ID)
|
||||
ctx.Data["IsIssuePoster"] = ctx.IsSigned && issue.IsPoster(ctx.Doer.ID)
|
||||
ctx.Data["HasIssuesOrPullsWritePermission"] = ctx.Repo.CanWriteIssuesOrPulls(issue.IsPull)
|
||||
|
||||
ctx.Data["IsAttachmentEnabled"] = setting.Attachment.Enabled
|
||||
@@ -783,16 +813,16 @@ func UpdatePullRequest(ctx *context.Context) {
|
||||
|
||||
rebase := ctx.FormString("style") == "rebase"
|
||||
|
||||
if err := issue.PullRequest.LoadBaseRepo(); err != nil {
|
||||
if err := issue.PullRequest.LoadBaseRepoCtx(ctx); err != nil {
|
||||
ctx.ServerError("LoadBaseRepo", err)
|
||||
return
|
||||
}
|
||||
if err := issue.PullRequest.LoadHeadRepo(); err != nil {
|
||||
if err := issue.PullRequest.LoadHeadRepoCtx(ctx); err != nil {
|
||||
ctx.ServerError("LoadHeadRepo", err)
|
||||
return
|
||||
}
|
||||
|
||||
allowedUpdateByMerge, allowedUpdateByRebase, err := pull_service.IsUserAllowedToUpdate(issue.PullRequest, ctx.User)
|
||||
allowedUpdateByMerge, allowedUpdateByRebase, err := pull_service.IsUserAllowedToUpdate(ctx, issue.PullRequest, ctx.Doer)
|
||||
if err != nil {
|
||||
ctx.ServerError("IsUserAllowedToMerge", err)
|
||||
return
|
||||
@@ -808,7 +838,7 @@ func UpdatePullRequest(ctx *context.Context) {
|
||||
// default merge commit message
|
||||
message := fmt.Sprintf("Merge branch '%s' into %s", issue.PullRequest.BaseBranch, issue.PullRequest.HeadBranch)
|
||||
|
||||
if err = pull_service.Update(ctx, issue.PullRequest, ctx.User, message, rebase); err != nil {
|
||||
if err = pull_service.Update(ctx, issue.PullRequest, ctx.Doer, message, rebase); err != nil {
|
||||
if models.IsErrMergeConflicts(err) {
|
||||
conflictError := err.(models.ErrMergeConflicts)
|
||||
flashError, err := ctx.RenderToString(tplAlertDetails, map[string]interface{}{
|
||||
@@ -857,50 +887,62 @@ func MergePullRequest(ctx *context.Context) {
|
||||
if ctx.Written() {
|
||||
return
|
||||
}
|
||||
if issue.IsClosed {
|
||||
if issue.IsPull {
|
||||
ctx.Flash.Error(ctx.Tr("repo.pulls.is_closed"))
|
||||
ctx.Redirect(issue.Link())
|
||||
return
|
||||
}
|
||||
ctx.Flash.Error(ctx.Tr("repo.issues.closed_title"))
|
||||
ctx.Redirect(issue.Link())
|
||||
return
|
||||
}
|
||||
|
||||
pr := issue.PullRequest
|
||||
pr.Issue = issue
|
||||
pr.Issue.Repo = ctx.Repo.Repository
|
||||
manuallMerge := repo_model.MergeStyle(form.Do) == repo_model.MergeStyleManuallyMerged
|
||||
forceMerge := form.ForceMerge != nil && *form.ForceMerge
|
||||
|
||||
allowedMerge, err := pull_service.IsUserAllowedToMerge(pr, ctx.Repo.Permission, ctx.User)
|
||||
if err != nil {
|
||||
ctx.ServerError("IsUserAllowedToMerge", err)
|
||||
return
|
||||
}
|
||||
if !allowedMerge {
|
||||
ctx.Flash.Error(ctx.Tr("repo.pulls.update_not_allowed"))
|
||||
ctx.Redirect(issue.Link())
|
||||
return
|
||||
}
|
||||
|
||||
if pr.HasMerged {
|
||||
ctx.Flash.Error(ctx.Tr("repo.pulls.has_merged"))
|
||||
ctx.Redirect(issue.Link())
|
||||
// start with merging by checking
|
||||
if err := pull_service.CheckPullMergable(ctx, ctx.Doer, &ctx.Repo.Permission, pr, manuallMerge, forceMerge); err != nil {
|
||||
if errors.Is(err, pull_service.ErrIsClosed) {
|
||||
if issue.IsPull {
|
||||
ctx.Flash.Error(ctx.Tr("repo.pulls.is_closed"))
|
||||
ctx.Redirect(issue.Link())
|
||||
} else {
|
||||
ctx.Flash.Error(ctx.Tr("repo.issues.closed_title"))
|
||||
ctx.Redirect(issue.Link())
|
||||
}
|
||||
} else if errors.Is(err, pull_service.ErrUserNotAllowedToMerge) {
|
||||
ctx.Flash.Error(ctx.Tr("repo.pulls.update_not_allowed"))
|
||||
ctx.Redirect(issue.Link())
|
||||
} else if errors.Is(err, pull_service.ErrHasMerged) {
|
||||
ctx.Flash.Error(ctx.Tr("repo.pulls.has_merged"))
|
||||
ctx.Redirect(issue.Link())
|
||||
} else if errors.Is(err, pull_service.ErrIsWorkInProgress) {
|
||||
ctx.Flash.Error(ctx.Tr("repo.pulls.no_merge_wip"))
|
||||
ctx.Redirect(issue.Link())
|
||||
} else if errors.Is(err, pull_service.ErrNotMergableState) {
|
||||
ctx.Flash.Error(ctx.Tr("repo.pulls.no_merge_not_ready"))
|
||||
ctx.Redirect(issue.Link())
|
||||
} else if models.IsErrDisallowedToMerge(err) {
|
||||
ctx.Flash.Error(ctx.Tr("repo.pulls.no_merge_not_ready"))
|
||||
ctx.Redirect(issue.Link())
|
||||
} else if asymkey_service.IsErrWontSign(err) {
|
||||
ctx.Flash.Error(err.Error()) // has not translation ...
|
||||
ctx.Redirect(issue.Link())
|
||||
} else if errors.Is(err, pull_service.ErrDependenciesLeft) {
|
||||
ctx.Flash.Error(ctx.Tr("repo.issues.dependency.pr_close_blocked"))
|
||||
ctx.Redirect(issue.Link())
|
||||
} else {
|
||||
ctx.ServerError("WebCheck", err)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// handle manually-merged mark
|
||||
if repo_model.MergeStyle(form.Do) == repo_model.MergeStyleManuallyMerged {
|
||||
if err = pull_service.MergedManually(pr, ctx.User, ctx.Repo.GitRepo, form.MergeCommitID); err != nil {
|
||||
if manuallMerge {
|
||||
if err := pull_service.MergedManually(pr, ctx.Doer, ctx.Repo.GitRepo, form.MergeCommitID); err != nil {
|
||||
if models.IsErrInvalidMergeStyle(err) {
|
||||
ctx.Flash.Error(ctx.Tr("repo.pulls.invalid_merge_option"))
|
||||
ctx.Redirect(issue.Link())
|
||||
return
|
||||
} else if strings.Contains(err.Error(), "Wrong commit ID") {
|
||||
ctx.Flash.Error(ctx.Tr("repo.pulls.wrong_commit_id"))
|
||||
ctx.Redirect(issue.Link())
|
||||
return
|
||||
} else {
|
||||
ctx.ServerError("MergedManually", err)
|
||||
}
|
||||
|
||||
ctx.ServerError("MergedManually", err)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -908,49 +950,13 @@ func MergePullRequest(ctx *context.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
if !pr.CanAutoMerge() {
|
||||
ctx.Flash.Error(ctx.Tr("repo.pulls.no_merge_not_ready"))
|
||||
ctx.Redirect(issue.Link())
|
||||
return
|
||||
}
|
||||
|
||||
if pr.IsWorkInProgress() {
|
||||
ctx.Flash.Error(ctx.Tr("repo.pulls.no_merge_wip"))
|
||||
ctx.Redirect(issue.Link())
|
||||
return
|
||||
}
|
||||
|
||||
if err := pull_service.CheckPRReadyToMerge(ctx, pr, false); err != nil {
|
||||
if !models.IsErrNotAllowedToMerge(err) {
|
||||
ctx.ServerError("Merge PR status", err)
|
||||
return
|
||||
}
|
||||
if isRepoAdmin, err := models.IsUserRepoAdmin(pr.BaseRepo, ctx.User); err != nil {
|
||||
ctx.ServerError("IsUserRepoAdmin", err)
|
||||
return
|
||||
} else if !isRepoAdmin {
|
||||
ctx.Flash.Error(ctx.Tr("repo.pulls.no_merge_not_ready"))
|
||||
ctx.Redirect(issue.Link())
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
if ctx.HasError() {
|
||||
ctx.Flash.Error(ctx.Data["ErrorMsg"].(string))
|
||||
ctx.Redirect(issue.Link())
|
||||
return
|
||||
}
|
||||
|
||||
message := strings.TrimSpace(form.MergeTitleField)
|
||||
if len(message) == 0 {
|
||||
if repo_model.MergeStyle(form.Do) == repo_model.MergeStyleMerge {
|
||||
message = pr.GetDefaultMergeMessage()
|
||||
}
|
||||
if repo_model.MergeStyle(form.Do) == repo_model.MergeStyleRebaseMerge {
|
||||
message = pr.GetDefaultMergeMessage()
|
||||
}
|
||||
if repo_model.MergeStyle(form.Do) == repo_model.MergeStyleSquash {
|
||||
message = pr.GetDefaultSquashMessage()
|
||||
var err error
|
||||
message, err = pull_service.GetDefaultMergeMessage(ctx.Repo.GitRepo, pr, repo_model.MergeStyle(form.Do))
|
||||
if err != nil {
|
||||
ctx.ServerError("GetDefaultMergeMessage", err)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
@@ -959,25 +965,10 @@ func MergePullRequest(ctx *context.Context) {
|
||||
message += "\n\n" + form.MergeMessageField
|
||||
}
|
||||
|
||||
pr.Issue = issue
|
||||
pr.Issue.Repo = ctx.Repo.Repository
|
||||
|
||||
noDeps, err := models.IssueNoDependenciesLeft(issue)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
if !noDeps {
|
||||
ctx.Flash.Error(ctx.Tr("repo.issues.dependency.pr_close_blocked"))
|
||||
ctx.Redirect(issue.Link())
|
||||
return
|
||||
}
|
||||
|
||||
if err = pull_service.Merge(ctx, pr, ctx.User, ctx.Repo.GitRepo, repo_model.MergeStyle(form.Do), form.HeadCommitID, message); err != nil {
|
||||
if err := pull_service.Merge(ctx, pr, ctx.Doer, ctx.Repo.GitRepo, repo_model.MergeStyle(form.Do), form.HeadCommitID, message); err != nil {
|
||||
if models.IsErrInvalidMergeStyle(err) {
|
||||
ctx.Flash.Error(ctx.Tr("repo.pulls.invalid_merge_option"))
|
||||
ctx.Redirect(issue.Link())
|
||||
return
|
||||
} else if models.IsErrMergeConflicts(err) {
|
||||
conflictError := err.(models.ErrMergeConflicts)
|
||||
flashError, err := ctx.RenderToString(tplAlertDetails, map[string]interface{}{
|
||||
@@ -991,7 +982,6 @@ func MergePullRequest(ctx *context.Context) {
|
||||
}
|
||||
ctx.Flash.Error(flashError)
|
||||
ctx.Redirect(issue.Link())
|
||||
return
|
||||
} else if models.IsErrRebaseConflicts(err) {
|
||||
conflictError := err.(models.ErrRebaseConflicts)
|
||||
flashError, err := ctx.RenderToString(tplAlertDetails, map[string]interface{}{
|
||||
@@ -1005,22 +995,18 @@ func MergePullRequest(ctx *context.Context) {
|
||||
}
|
||||
ctx.Flash.Error(flashError)
|
||||
ctx.Redirect(issue.Link())
|
||||
return
|
||||
} else if models.IsErrMergeUnrelatedHistories(err) {
|
||||
log.Debug("MergeUnrelatedHistories error: %v", err)
|
||||
ctx.Flash.Error(ctx.Tr("repo.pulls.unrelated_histories"))
|
||||
ctx.Redirect(issue.Link())
|
||||
return
|
||||
} else if git.IsErrPushOutOfDate(err) {
|
||||
log.Debug("MergePushOutOfDate error: %v", err)
|
||||
ctx.Flash.Error(ctx.Tr("repo.pulls.merge_out_of_date"))
|
||||
ctx.Redirect(issue.Link())
|
||||
return
|
||||
} else if models.IsErrSHADoesNotMatch(err) {
|
||||
log.Debug("MergeHeadOutOfDate error: %v", err)
|
||||
ctx.Flash.Error(ctx.Tr("repo.pulls.head_out_of_date"))
|
||||
ctx.Redirect(issue.Link())
|
||||
return
|
||||
} else if git.IsErrPushRejected(err) {
|
||||
log.Debug("MergePushRejected error: %v", err)
|
||||
pushrejErr := err.(*git.ErrPushRejected)
|
||||
@@ -1040,13 +1026,14 @@ func MergePullRequest(ctx *context.Context) {
|
||||
ctx.Flash.Error(flashError)
|
||||
}
|
||||
ctx.Redirect(issue.Link())
|
||||
return
|
||||
} else {
|
||||
ctx.ServerError("Merge", err)
|
||||
}
|
||||
ctx.ServerError("Merge", err)
|
||||
return
|
||||
}
|
||||
log.Trace("Pull request merged: %d", pr.ID)
|
||||
|
||||
if err := stopTimerIfAvailable(ctx.User, issue); err != nil {
|
||||
if err := stopTimerIfAvailable(ctx.Doer, issue); err != nil {
|
||||
ctx.ServerError("CreateOrStopIssueStopwatch", err)
|
||||
return
|
||||
}
|
||||
@@ -1055,7 +1042,7 @@ func MergePullRequest(ctx *context.Context) {
|
||||
|
||||
if form.DeleteBranchAfterMerge {
|
||||
// Don't cleanup when other pr use this branch as head branch
|
||||
exist, err := models.HasUnmergedPullRequestsByHeadInfo(pr.HeadRepoID, pr.HeadBranch)
|
||||
exist, err := models.HasUnmergedPullRequestsByHeadInfo(ctx, pr.HeadRepoID, pr.HeadBranch)
|
||||
if err != nil {
|
||||
ctx.ServerError("HasUnmergedPullRequestsByHeadInfo", err)
|
||||
return
|
||||
@@ -1069,7 +1056,7 @@ func MergePullRequest(ctx *context.Context) {
|
||||
if ctx.Repo != nil && ctx.Repo.Repository != nil && pr.HeadRepoID == ctx.Repo.Repository.ID && ctx.Repo.GitRepo != nil {
|
||||
headRepo = ctx.Repo.GitRepo
|
||||
} else {
|
||||
headRepo, err = git.OpenRepositoryCtx(ctx, pr.HeadRepo.RepoPath())
|
||||
headRepo, err = git.OpenRepository(ctx, pr.HeadRepo.RepoPath())
|
||||
if err != nil {
|
||||
ctx.ServerError(fmt.Sprintf("OpenRepository[%s]", pr.HeadRepo.RepoPath()), err)
|
||||
return
|
||||
@@ -1100,7 +1087,6 @@ func CompareAndPullRequestPost(ctx *context.Context) {
|
||||
ctx.Data["IsDiffCompare"] = true
|
||||
ctx.Data["IsRepoToolbarCommits"] = true
|
||||
ctx.Data["RequireTribute"] = true
|
||||
ctx.Data["RequireHighlightJS"] = true
|
||||
ctx.Data["PullRequestWorkInProgressPrefixes"] = setting.Repository.PullRequest.WorkInProgressPrefixes
|
||||
ctx.Data["IsAttachmentEnabled"] = setting.Attachment.Enabled
|
||||
upload.AddUploadContext(ctx, "comment")
|
||||
@@ -1168,21 +1154,22 @@ func CompareAndPullRequestPost(ctx *context.Context) {
|
||||
RepoID: repo.ID,
|
||||
Repo: repo,
|
||||
Title: form.Title,
|
||||
PosterID: ctx.User.ID,
|
||||
Poster: ctx.User,
|
||||
PosterID: ctx.Doer.ID,
|
||||
Poster: ctx.Doer,
|
||||
MilestoneID: milestoneID,
|
||||
IsPull: true,
|
||||
Content: form.Content,
|
||||
}
|
||||
pullRequest := &models.PullRequest{
|
||||
HeadRepoID: ci.HeadRepo.ID,
|
||||
BaseRepoID: repo.ID,
|
||||
HeadBranch: ci.HeadBranch,
|
||||
BaseBranch: ci.BaseBranch,
|
||||
HeadRepo: ci.HeadRepo,
|
||||
BaseRepo: repo,
|
||||
MergeBase: ci.CompareInfo.MergeBase,
|
||||
Type: models.PullRequestGitea,
|
||||
HeadRepoID: ci.HeadRepo.ID,
|
||||
BaseRepoID: repo.ID,
|
||||
HeadBranch: ci.HeadBranch,
|
||||
BaseBranch: ci.BaseBranch,
|
||||
HeadRepo: ci.HeadRepo,
|
||||
BaseRepo: repo,
|
||||
MergeBase: ci.CompareInfo.MergeBase,
|
||||
Type: models.PullRequestGitea,
|
||||
AllowMaintainerEdit: form.AllowMaintainerEdit,
|
||||
}
|
||||
// FIXME: check error in the case two people send pull request at almost same time, give nice error prompt
|
||||
// instead of 500.
|
||||
@@ -1235,7 +1222,7 @@ func CleanUpPullRequest(ctx *context.Context) {
|
||||
}
|
||||
|
||||
// Don't cleanup when there are other PR's that use this branch as head branch.
|
||||
exist, err := models.HasUnmergedPullRequestsByHeadInfo(pr.HeadRepoID, pr.HeadBranch)
|
||||
exist, err := models.HasUnmergedPullRequestsByHeadInfo(ctx, pr.HeadRepoID, pr.HeadBranch)
|
||||
if err != nil {
|
||||
ctx.ServerError("HasUnmergedPullRequestsByHeadInfo", err)
|
||||
return
|
||||
@@ -1245,22 +1232,22 @@ func CleanUpPullRequest(ctx *context.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
if err := pr.LoadHeadRepo(); err != nil {
|
||||
if err := pr.LoadHeadRepoCtx(ctx); err != nil {
|
||||
ctx.ServerError("LoadHeadRepo", err)
|
||||
return
|
||||
} else if pr.HeadRepo == nil {
|
||||
// Forked repository has already been deleted
|
||||
ctx.NotFound("CleanUpPullRequest", nil)
|
||||
return
|
||||
} else if err = pr.LoadBaseRepo(); err != nil {
|
||||
} else if err = pr.LoadBaseRepoCtx(ctx); err != nil {
|
||||
ctx.ServerError("LoadBaseRepo", err)
|
||||
return
|
||||
} else if err = pr.HeadRepo.GetOwner(db.DefaultContext); err != nil {
|
||||
} else if err = pr.HeadRepo.GetOwner(ctx); err != nil {
|
||||
ctx.ServerError("HeadRepo.GetOwner", err)
|
||||
return
|
||||
}
|
||||
|
||||
perm, err := models.GetUserRepoPermission(pr.HeadRepo, ctx.User)
|
||||
perm, err := models.GetUserRepoPermission(ctx, pr.HeadRepo, ctx.Doer)
|
||||
if err != nil {
|
||||
ctx.ServerError("GetUserRepoPermission", err)
|
||||
return
|
||||
@@ -1279,7 +1266,7 @@ func CleanUpPullRequest(ctx *context.Context) {
|
||||
gitBaseRepo = ctx.Repo.GitRepo
|
||||
} else {
|
||||
// If not just open it
|
||||
gitBaseRepo, err = git.OpenRepositoryCtx(ctx, pr.BaseRepo.RepoPath())
|
||||
gitBaseRepo, err = git.OpenRepository(ctx, pr.BaseRepo.RepoPath())
|
||||
if err != nil {
|
||||
ctx.ServerError(fmt.Sprintf("OpenRepository[%s]", pr.BaseRepo.RepoPath()), err)
|
||||
return
|
||||
@@ -1294,7 +1281,7 @@ func CleanUpPullRequest(ctx *context.Context) {
|
||||
gitRepo = ctx.Repo.GitRepo
|
||||
} else if pr.BaseRepoID != pr.HeadRepoID {
|
||||
// Otherwise just load it up
|
||||
gitRepo, err = git.OpenRepositoryCtx(ctx, pr.HeadRepo.RepoPath())
|
||||
gitRepo, err = git.OpenRepository(ctx, pr.HeadRepo.RepoPath())
|
||||
if err != nil {
|
||||
ctx.ServerError(fmt.Sprintf("OpenRepository[%s]", pr.HeadRepo.RepoPath()), err)
|
||||
return
|
||||
@@ -1331,7 +1318,7 @@ func CleanUpPullRequest(ctx *context.Context) {
|
||||
|
||||
func deleteBranch(ctx *context.Context, pr *models.PullRequest, gitRepo *git.Repository) {
|
||||
fullBranchName := pr.HeadRepo.Owner.Name + "/" + pr.HeadBranch
|
||||
if err := repo_service.DeleteBranch(ctx.User, pr.HeadRepo, gitRepo, pr.HeadBranch); err != nil {
|
||||
if err := repo_service.DeleteBranch(ctx.Doer, pr.HeadRepo, gitRepo, pr.HeadBranch); err != nil {
|
||||
switch {
|
||||
case git.IsErrBranchNotExist(err):
|
||||
ctx.Flash.Error(ctx.Tr("repo.branch.deletion_failed", fullBranchName))
|
||||
@@ -1346,7 +1333,7 @@ func deleteBranch(ctx *context.Context, pr *models.PullRequest, gitRepo *git.Rep
|
||||
return
|
||||
}
|
||||
|
||||
if err := models.AddDeletePRBranchComment(ctx.User, pr.BaseRepo, pr.IssueID, pr.HeadBranch); err != nil {
|
||||
if err := models.AddDeletePRBranchComment(ctx, ctx.Doer, pr.BaseRepo, pr.IssueID, pr.HeadBranch); err != nil {
|
||||
// Do not fail here as branch has already been deleted
|
||||
log.Error("DeleteBranch: %v", err)
|
||||
}
|
||||
@@ -1396,7 +1383,7 @@ func UpdatePullRequestTarget(ctx *context.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
if !ctx.IsSigned || (!issue.IsPoster(ctx.User.ID) && !ctx.Repo.CanWriteIssuesOrPulls(issue.IsPull)) {
|
||||
if !ctx.IsSigned || (!issue.IsPoster(ctx.Doer.ID) && !ctx.Repo.CanWriteIssuesOrPulls(issue.IsPull)) {
|
||||
ctx.Error(http.StatusForbidden)
|
||||
return
|
||||
}
|
||||
@@ -1407,7 +1394,7 @@ func UpdatePullRequestTarget(ctx *context.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
if err := pull_service.ChangeTargetBranch(ctx, pr, ctx.User, targetBranch); err != nil {
|
||||
if err := pull_service.ChangeTargetBranch(ctx, pr, ctx.Doer, targetBranch); err != nil {
|
||||
if models.IsErrPullRequestAlreadyExists(err) {
|
||||
err := err.(models.ErrPullRequestAlreadyExists)
|
||||
|
||||
@@ -1448,9 +1435,37 @@ func UpdatePullRequestTarget(ctx *context.Context) {
|
||||
}
|
||||
return
|
||||
}
|
||||
notification.NotifyPullRequestChangeTargetBranch(ctx.User, pr, targetBranch)
|
||||
notification.NotifyPullRequestChangeTargetBranch(ctx.Doer, pr, targetBranch)
|
||||
|
||||
ctx.JSON(http.StatusOK, map[string]interface{}{
|
||||
"base_branch": pr.BaseBranch,
|
||||
})
|
||||
}
|
||||
|
||||
// SetAllowEdits allow edits from maintainers to PRs
|
||||
func SetAllowEdits(ctx *context.Context) {
|
||||
form := web.GetForm(ctx).(*forms.UpdateAllowEditsForm)
|
||||
|
||||
pr, err := models.GetPullRequestByIndex(ctx.Repo.Repository.ID, ctx.ParamsInt64(":index"))
|
||||
if err != nil {
|
||||
if models.IsErrPullRequestNotExist(err) {
|
||||
ctx.NotFound("GetPullRequestByIndex", err)
|
||||
} else {
|
||||
ctx.ServerError("GetPullRequestByIndex", err)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
if err := pull_service.SetAllowEdits(ctx, ctx.Doer, pr, form.AllowMaintainerEdit); err != nil {
|
||||
if errors.Is(pull_service.ErrUserHasNoPermissionForAction, err) {
|
||||
ctx.Error(http.StatusForbidden)
|
||||
return
|
||||
}
|
||||
ctx.ServerError("SetAllowEdits", err)
|
||||
return
|
||||
}
|
||||
|
||||
ctx.JSON(http.StatusOK, map[string]interface{}{
|
||||
"allow_maintainer_edit": pr.AllowMaintainerEdit,
|
||||
})
|
||||
}
|
||||
|
||||
@@ -9,8 +9,10 @@ import (
|
||||
"net/http"
|
||||
|
||||
"code.gitea.io/gitea/models"
|
||||
pull_model "code.gitea.io/gitea/models/pull"
|
||||
"code.gitea.io/gitea/modules/base"
|
||||
"code.gitea.io/gitea/modules/context"
|
||||
"code.gitea.io/gitea/modules/json"
|
||||
"code.gitea.io/gitea/modules/log"
|
||||
"code.gitea.io/gitea/modules/setting"
|
||||
"code.gitea.io/gitea/modules/web"
|
||||
@@ -29,7 +31,7 @@ func RenderNewCodeCommentForm(ctx *context.Context) {
|
||||
if !issue.IsPull {
|
||||
return
|
||||
}
|
||||
currentReview, err := models.GetCurrentReview(ctx.User, issue)
|
||||
currentReview, err := models.GetCurrentReview(ctx.Doer, issue)
|
||||
if err != nil && !models.IsErrReviewNotExist(err) {
|
||||
ctx.ServerError("GetCurrentReview", err)
|
||||
return
|
||||
@@ -69,7 +71,7 @@ func CreateCodeComment(ctx *context.Context) {
|
||||
}
|
||||
|
||||
comment, err := pull_service.CreateCodeComment(ctx,
|
||||
ctx.User,
|
||||
ctx.Doer,
|
||||
ctx.Repo.GitRepo,
|
||||
issue,
|
||||
signedLine,
|
||||
@@ -117,7 +119,7 @@ func UpdateResolveConversation(ctx *context.Context) {
|
||||
}
|
||||
|
||||
var permResult bool
|
||||
if permResult, err = models.CanMarkConversation(comment.Issue, ctx.User); err != nil {
|
||||
if permResult, err = models.CanMarkConversation(comment.Issue, ctx.Doer); err != nil {
|
||||
ctx.ServerError("CanMarkConversation", err)
|
||||
return
|
||||
}
|
||||
@@ -132,7 +134,7 @@ func UpdateResolveConversation(ctx *context.Context) {
|
||||
}
|
||||
|
||||
if action == "Resolve" || action == "UnResolve" {
|
||||
err = models.MarkConversation(comment, ctx.User, action == "Resolve")
|
||||
err = models.MarkConversation(comment, ctx.Doer, action == "Resolve")
|
||||
if err != nil {
|
||||
ctx.ServerError("MarkConversation", err)
|
||||
return
|
||||
@@ -152,7 +154,7 @@ func UpdateResolveConversation(ctx *context.Context) {
|
||||
}
|
||||
|
||||
func renderConversation(ctx *context.Context, comment *models.Comment) {
|
||||
comments, err := models.FetchCodeCommentsByLine(ctx, comment.Issue, ctx.User, comment.TreePath, comment.Line)
|
||||
comments, err := models.FetchCodeCommentsByLine(ctx, comment.Issue, ctx.Doer, comment.TreePath, comment.Line)
|
||||
if err != nil {
|
||||
ctx.ServerError("FetchCodeCommentsByLine", err)
|
||||
return
|
||||
@@ -198,7 +200,7 @@ func SubmitReview(ctx *context.Context) {
|
||||
|
||||
// can not approve/reject your own PR
|
||||
case models.ReviewTypeApprove, models.ReviewTypeReject:
|
||||
if issue.IsPoster(ctx.User.ID) {
|
||||
if issue.IsPoster(ctx.Doer.ID) {
|
||||
var translated string
|
||||
if reviewType == models.ReviewTypeApprove {
|
||||
translated = ctx.Tr("repo.issues.review.self.approval")
|
||||
@@ -217,7 +219,7 @@ func SubmitReview(ctx *context.Context) {
|
||||
attachments = form.Files
|
||||
}
|
||||
|
||||
_, comm, err := pull_service.SubmitReview(ctx, ctx.User, ctx.Repo.GitRepo, issue, reviewType, form.Content, form.CommitID, attachments)
|
||||
_, comm, err := pull_service.SubmitReview(ctx, ctx.Doer, ctx.Repo.GitRepo, issue, reviewType, form.Content, form.CommitID, attachments)
|
||||
if err != nil {
|
||||
if models.IsContentEmptyErr(err) {
|
||||
ctx.Flash.Error(ctx.Tr("repo.issues.review.content.empty"))
|
||||
@@ -234,7 +236,7 @@ func SubmitReview(ctx *context.Context) {
|
||||
// DismissReview dismissing stale review by repo admin
|
||||
func DismissReview(ctx *context.Context) {
|
||||
form := web.GetForm(ctx).(*forms.DismissReviewForm)
|
||||
comm, err := pull_service.DismissReview(ctx, form.ReviewID, form.Message, ctx.User, true)
|
||||
comm, err := pull_service.DismissReview(ctx, form.ReviewID, form.Message, ctx.Doer, true)
|
||||
if err != nil {
|
||||
ctx.ServerError("pull_service.DismissReview", err)
|
||||
return
|
||||
@@ -242,3 +244,47 @@ func DismissReview(ctx *context.Context) {
|
||||
|
||||
ctx.Redirect(fmt.Sprintf("%s/pulls/%d#%s", ctx.Repo.RepoLink, comm.Issue.Index, comm.HashTag()))
|
||||
}
|
||||
|
||||
// viewedFilesUpdate Struct to parse the body of a request to update the reviewed files of a PR
|
||||
// If you want to implement an API to update the review, simply move this struct into modules.
|
||||
type viewedFilesUpdate struct {
|
||||
Files map[string]bool `json:"files"`
|
||||
HeadCommitSHA string `json:"headCommitSHA"`
|
||||
}
|
||||
|
||||
func UpdateViewedFiles(ctx *context.Context) {
|
||||
// Find corresponding PR
|
||||
issue := checkPullInfo(ctx)
|
||||
if ctx.Written() {
|
||||
return
|
||||
}
|
||||
pull := issue.PullRequest
|
||||
|
||||
var data *viewedFilesUpdate
|
||||
err := json.NewDecoder(ctx.Req.Body).Decode(&data)
|
||||
if err != nil {
|
||||
log.Warn("Attempted to update a review but could not parse request body: %v", err)
|
||||
ctx.Resp.WriteHeader(http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
// Expect the review to have been now if no head commit was supplied
|
||||
if data.HeadCommitSHA == "" {
|
||||
data.HeadCommitSHA = pull.HeadCommitID
|
||||
}
|
||||
|
||||
updatedFiles := make(map[string]pull_model.ViewedState, len(data.Files))
|
||||
for file, viewed := range data.Files {
|
||||
|
||||
// Only unviewed and viewed are possible, has-changed can not be set from the outside
|
||||
state := pull_model.Unviewed
|
||||
if viewed {
|
||||
state = pull_model.Viewed
|
||||
}
|
||||
updatedFiles[file] = state
|
||||
}
|
||||
|
||||
if err := pull_model.UpdateReviewState(ctx, ctx.Doer.ID, pull.ID, data.HeadCommitSHA, updatedFiles); err != nil {
|
||||
ctx.ServerError("UpdateReview", err)
|
||||
}
|
||||
}
|
||||
|
||||
+10
-10
@@ -134,8 +134,8 @@ func releasesOrTags(ctx *context.Context, isTagList bool) {
|
||||
// Temporary cache commits count of used branches to speed up.
|
||||
countCache := make(map[string]int64)
|
||||
cacheUsers := make(map[int64]*user_model.User)
|
||||
if ctx.User != nil {
|
||||
cacheUsers[ctx.User.ID] = ctx.User
|
||||
if ctx.Doer != nil {
|
||||
cacheUsers[ctx.Doer.ID] = ctx.Doer
|
||||
}
|
||||
var ok bool
|
||||
|
||||
@@ -325,7 +325,7 @@ func NewReleasePost(ctx *context.Context) {
|
||||
}
|
||||
|
||||
if len(form.TagOnly) > 0 {
|
||||
if err = releaseservice.CreateNewTag(ctx, ctx.User, ctx.Repo.Repository, form.Target, form.TagName, msg); err != nil {
|
||||
if err = releaseservice.CreateNewTag(ctx, ctx.Doer, ctx.Repo.Repository, form.Target, form.TagName, msg); err != nil {
|
||||
if models.IsErrTagAlreadyExists(err) {
|
||||
e := err.(models.ErrTagAlreadyExists)
|
||||
ctx.Flash.Error(ctx.Tr("repo.branch.tag_collision", e.TagName))
|
||||
@@ -357,8 +357,8 @@ func NewReleasePost(ctx *context.Context) {
|
||||
rel = &models.Release{
|
||||
RepoID: ctx.Repo.Repository.ID,
|
||||
Repo: ctx.Repo.Repository,
|
||||
PublisherID: ctx.User.ID,
|
||||
Publisher: ctx.User,
|
||||
PublisherID: ctx.Doer.ID,
|
||||
Publisher: ctx.Doer,
|
||||
Title: form.Title,
|
||||
TagName: form.TagName,
|
||||
Target: form.Target,
|
||||
@@ -394,16 +394,16 @@ func NewReleasePost(ctx *context.Context) {
|
||||
rel.Target = form.Target
|
||||
rel.IsDraft = len(form.Draft) > 0
|
||||
rel.IsPrerelease = form.Prerelease
|
||||
rel.PublisherID = ctx.User.ID
|
||||
rel.PublisherID = ctx.Doer.ID
|
||||
rel.IsTag = false
|
||||
|
||||
if err = releaseservice.UpdateRelease(ctx.User, ctx.Repo.GitRepo, rel, attachmentUUIDs, nil, nil); err != nil {
|
||||
if err = releaseservice.UpdateRelease(ctx.Doer, ctx.Repo.GitRepo, rel, attachmentUUIDs, nil, nil); err != nil {
|
||||
ctx.Data["Err_TagName"] = true
|
||||
ctx.ServerError("UpdateRelease", err)
|
||||
return
|
||||
}
|
||||
}
|
||||
log.Trace("Release created: %s/%s:%s", ctx.User.LowerName, ctx.Repo.Repository.Name, form.TagName)
|
||||
log.Trace("Release created: %s/%s:%s", ctx.Doer.LowerName, ctx.Repo.Repository.Name, form.TagName)
|
||||
|
||||
ctx.Redirect(ctx.Repo.RepoLink + "/releases")
|
||||
}
|
||||
@@ -497,7 +497,7 @@ func EditReleasePost(ctx *context.Context) {
|
||||
rel.Note = form.Content
|
||||
rel.IsDraft = len(form.Draft) > 0
|
||||
rel.IsPrerelease = form.Prerelease
|
||||
if err = releaseservice.UpdateRelease(ctx.User, ctx.Repo.GitRepo,
|
||||
if err = releaseservice.UpdateRelease(ctx.Doer, ctx.Repo.GitRepo,
|
||||
rel, addAttachmentUUIDs, delAttachmentUUIDs, editAttachments); err != nil {
|
||||
ctx.ServerError("UpdateRelease", err)
|
||||
return
|
||||
@@ -516,7 +516,7 @@ func DeleteTag(ctx *context.Context) {
|
||||
}
|
||||
|
||||
func deleteReleaseOrTag(ctx *context.Context, isDelTag bool) {
|
||||
if err := releaseservice.DeleteReleaseByID(ctx, ctx.FormInt64("id"), ctx.User, isDelTag); err != nil {
|
||||
if err := releaseservice.DeleteReleaseByID(ctx, ctx.FormInt64("id"), ctx.Doer, isDelTag); err != nil {
|
||||
ctx.Flash.Error("DeleteReleaseByID: " + err.Error())
|
||||
} else {
|
||||
if isDelTag {
|
||||
|
||||
+149
-33
@@ -14,15 +14,20 @@ import (
|
||||
|
||||
"code.gitea.io/gitea/models"
|
||||
"code.gitea.io/gitea/models/db"
|
||||
"code.gitea.io/gitea/models/organization"
|
||||
repo_model "code.gitea.io/gitea/models/repo"
|
||||
"code.gitea.io/gitea/models/unit"
|
||||
user_model "code.gitea.io/gitea/models/user"
|
||||
"code.gitea.io/gitea/modules/base"
|
||||
"code.gitea.io/gitea/modules/context"
|
||||
"code.gitea.io/gitea/modules/convert"
|
||||
"code.gitea.io/gitea/modules/graceful"
|
||||
"code.gitea.io/gitea/modules/log"
|
||||
repo_module "code.gitea.io/gitea/modules/repository"
|
||||
"code.gitea.io/gitea/modules/setting"
|
||||
"code.gitea.io/gitea/modules/storage"
|
||||
api "code.gitea.io/gitea/modules/structs"
|
||||
"code.gitea.io/gitea/modules/util"
|
||||
"code.gitea.io/gitea/modules/web"
|
||||
"code.gitea.io/gitea/services/forms"
|
||||
repo_service "code.gitea.io/gitea/services/repository"
|
||||
@@ -57,14 +62,14 @@ func MustBeAbleToUpload(ctx *context.Context) {
|
||||
}
|
||||
|
||||
func checkContextUser(ctx *context.Context, uid int64) *user_model.User {
|
||||
orgs, err := models.GetOrgsCanCreateRepoByUserID(ctx.User.ID)
|
||||
orgs, err := organization.GetOrgsCanCreateRepoByUserID(ctx.Doer.ID)
|
||||
if err != nil {
|
||||
ctx.ServerError("GetOrgsCanCreateRepoByUserID", err)
|
||||
return nil
|
||||
}
|
||||
|
||||
if !ctx.User.IsAdmin {
|
||||
orgsAvailable := []*models.Organization{}
|
||||
if !ctx.Doer.IsAdmin {
|
||||
orgsAvailable := []*organization.Organization{}
|
||||
for i := 0; i < len(orgs); i++ {
|
||||
if orgs[i].CanCreateRepo() {
|
||||
orgsAvailable = append(orgsAvailable, orgs[i])
|
||||
@@ -76,13 +81,13 @@ func checkContextUser(ctx *context.Context, uid int64) *user_model.User {
|
||||
}
|
||||
|
||||
// Not equal means current user is an organization.
|
||||
if uid == ctx.User.ID || uid == 0 {
|
||||
return ctx.User
|
||||
if uid == ctx.Doer.ID || uid == 0 {
|
||||
return ctx.Doer
|
||||
}
|
||||
|
||||
org, err := user_model.GetUserByID(uid)
|
||||
if user_model.IsErrUserNotExist(err) {
|
||||
return ctx.User
|
||||
return ctx.Doer
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
@@ -95,8 +100,8 @@ func checkContextUser(ctx *context.Context, uid int64) *user_model.User {
|
||||
ctx.Error(http.StatusForbidden)
|
||||
return nil
|
||||
}
|
||||
if !ctx.User.IsAdmin {
|
||||
canCreate, err := models.OrgFromUser(org).CanCreateOrgRepo(ctx.User.ID)
|
||||
if !ctx.Doer.IsAdmin {
|
||||
canCreate, err := organization.OrgFromUser(org).CanCreateOrgRepo(ctx.Doer.ID)
|
||||
if err != nil {
|
||||
ctx.ServerError("CanCreateOrgRepo", err)
|
||||
return nil
|
||||
@@ -113,13 +118,13 @@ func checkContextUser(ctx *context.Context, uid int64) *user_model.User {
|
||||
func getRepoPrivate(ctx *context.Context) bool {
|
||||
switch strings.ToLower(setting.Repository.DefaultPrivate) {
|
||||
case setting.RepoCreatingLastUserVisibility:
|
||||
return ctx.User.LastRepoVisibility
|
||||
return ctx.Doer.LastRepoVisibility
|
||||
case setting.RepoCreatingPrivate:
|
||||
return true
|
||||
case setting.RepoCreatingPublic:
|
||||
return false
|
||||
default:
|
||||
return ctx.User.LastRepoVisibility
|
||||
return ctx.Doer.LastRepoVisibility
|
||||
}
|
||||
}
|
||||
|
||||
@@ -128,10 +133,10 @@ func Create(ctx *context.Context) {
|
||||
ctx.Data["Title"] = ctx.Tr("new_repo")
|
||||
|
||||
// Give default value for template to render.
|
||||
ctx.Data["Gitignores"] = models.Gitignores
|
||||
ctx.Data["LabelTemplates"] = models.LabelTemplates
|
||||
ctx.Data["Licenses"] = models.Licenses
|
||||
ctx.Data["Readmes"] = models.Readmes
|
||||
ctx.Data["Gitignores"] = repo_module.Gitignores
|
||||
ctx.Data["LabelTemplates"] = repo_module.LabelTemplates
|
||||
ctx.Data["Licenses"] = repo_module.Licenses
|
||||
ctx.Data["Readmes"] = repo_module.Readmes
|
||||
ctx.Data["readme"] = "Default"
|
||||
ctx.Data["private"] = getRepoPrivate(ctx)
|
||||
ctx.Data["IsForcedPrivate"] = setting.Repository.ForcePrivate
|
||||
@@ -153,8 +158,8 @@ func Create(ctx *context.Context) {
|
||||
}
|
||||
}
|
||||
|
||||
ctx.Data["CanCreateRepo"] = ctx.User.CanCreateRepo()
|
||||
ctx.Data["MaxCreationLimit"] = ctx.User.MaxCreationLimit()
|
||||
ctx.Data["CanCreateRepo"] = ctx.Doer.CanCreateRepo()
|
||||
ctx.Data["MaxCreationLimit"] = ctx.Doer.MaxCreationLimit()
|
||||
|
||||
ctx.HTML(http.StatusOK, tplCreate)
|
||||
}
|
||||
@@ -196,13 +201,13 @@ func CreatePost(ctx *context.Context) {
|
||||
form := web.GetForm(ctx).(*forms.CreateRepoForm)
|
||||
ctx.Data["Title"] = ctx.Tr("new_repo")
|
||||
|
||||
ctx.Data["Gitignores"] = models.Gitignores
|
||||
ctx.Data["LabelTemplates"] = models.LabelTemplates
|
||||
ctx.Data["Licenses"] = models.Licenses
|
||||
ctx.Data["Readmes"] = models.Readmes
|
||||
ctx.Data["Gitignores"] = repo_module.Gitignores
|
||||
ctx.Data["LabelTemplates"] = repo_module.LabelTemplates
|
||||
ctx.Data["Licenses"] = repo_module.Licenses
|
||||
ctx.Data["Readmes"] = repo_module.Readmes
|
||||
|
||||
ctx.Data["CanCreateRepo"] = ctx.User.CanCreateRepo()
|
||||
ctx.Data["MaxCreationLimit"] = ctx.User.MaxCreationLimit()
|
||||
ctx.Data["CanCreateRepo"] = ctx.Doer.CanCreateRepo()
|
||||
ctx.Data["MaxCreationLimit"] = ctx.Doer.MaxCreationLimit()
|
||||
|
||||
ctxUser := checkContextUser(ctx, form.UID)
|
||||
if ctx.Written() {
|
||||
@@ -245,14 +250,14 @@ func CreatePost(ctx *context.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
repo, err = repo_service.GenerateRepository(ctx.User, ctxUser, templateRepo, opts)
|
||||
repo, err = repo_service.GenerateRepository(ctx.Doer, ctxUser, templateRepo, opts)
|
||||
if err == nil {
|
||||
log.Trace("Repository generated [%d]: %s/%s", repo.ID, ctxUser.Name, repo.Name)
|
||||
ctx.Redirect(repo.Link())
|
||||
return
|
||||
}
|
||||
} else {
|
||||
repo, err = repo_service.CreateRepository(ctx.User, ctxUser, models.CreateRepoOptions{
|
||||
repo, err = repo_service.CreateRepository(ctx.Doer, ctxUser, models.CreateRepoOptions{
|
||||
Name: form.RepoName,
|
||||
Description: form.Description,
|
||||
Gitignores: form.Gitignores,
|
||||
@@ -280,13 +285,13 @@ func Action(ctx *context.Context) {
|
||||
var err error
|
||||
switch ctx.Params(":action") {
|
||||
case "watch":
|
||||
err = repo_model.WatchRepo(ctx.User.ID, ctx.Repo.Repository.ID, true)
|
||||
err = repo_model.WatchRepo(ctx.Doer.ID, ctx.Repo.Repository.ID, true)
|
||||
case "unwatch":
|
||||
err = repo_model.WatchRepo(ctx.User.ID, ctx.Repo.Repository.ID, false)
|
||||
err = repo_model.WatchRepo(ctx.Doer.ID, ctx.Repo.Repository.ID, false)
|
||||
case "star":
|
||||
err = repo_model.StarRepo(ctx.User.ID, ctx.Repo.Repository.ID, true)
|
||||
err = repo_model.StarRepo(ctx.Doer.ID, ctx.Repo.Repository.ID, true)
|
||||
case "unstar":
|
||||
err = repo_model.StarRepo(ctx.User.ID, ctx.Repo.Repository.ID, false)
|
||||
err = repo_model.StarRepo(ctx.Doer.ID, ctx.Repo.Repository.ID, false)
|
||||
case "accept_transfer":
|
||||
err = acceptOrRejectRepoTransfer(ctx, true)
|
||||
case "reject_transfer":
|
||||
@@ -320,7 +325,7 @@ func acceptOrRejectRepoTransfer(ctx *context.Context, accept bool) error {
|
||||
return err
|
||||
}
|
||||
|
||||
if !repoTransfer.CanUserAcceptTransfer(ctx.User) {
|
||||
if !repoTransfer.CanUserAcceptTransfer(ctx.Doer) {
|
||||
return errors.New("user does not have enough permissions")
|
||||
}
|
||||
|
||||
@@ -353,7 +358,7 @@ func RedirectDownload(ctx *context.Context) {
|
||||
)
|
||||
tagNames := []string{vTag}
|
||||
curRepo := ctx.Repo.Repository
|
||||
releases, err := models.GetReleasesByRepoIDAndNames(db.DefaultContext, curRepo.ID, tagNames)
|
||||
releases, err := models.GetReleasesByRepoIDAndNames(ctx, curRepo.ID, tagNames)
|
||||
if err != nil {
|
||||
if repo_model.IsErrAttachmentNotExist(err) {
|
||||
ctx.Error(http.StatusNotFound)
|
||||
@@ -394,7 +399,7 @@ func Download(ctx *context.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
archiver, err := repo_model.GetRepoArchiver(db.DefaultContext, aReq.RepoID, aReq.Type, aReq.CommitID)
|
||||
archiver, err := repo_model.GetRepoArchiver(ctx, aReq.RepoID, aReq.Type, aReq.CommitID)
|
||||
if err != nil {
|
||||
ctx.ServerError("models.GetRepoArchiver", err)
|
||||
return
|
||||
@@ -424,7 +429,7 @@ func Download(ctx *context.Context) {
|
||||
return
|
||||
}
|
||||
times++
|
||||
archiver, err = repo_model.GetRepoArchiver(db.DefaultContext, aReq.RepoID, aReq.Type, aReq.CommitID)
|
||||
archiver, err = repo_model.GetRepoArchiver(ctx, aReq.RepoID, aReq.Type, aReq.CommitID)
|
||||
if err != nil {
|
||||
ctx.ServerError("archiver_service.StartArchive", err)
|
||||
return
|
||||
@@ -480,7 +485,7 @@ func InitiateDownload(ctx *context.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
archiver, err := repo_model.GetRepoArchiver(db.DefaultContext, aReq.RepoID, aReq.Type, aReq.CommitID)
|
||||
archiver, err := repo_model.GetRepoArchiver(ctx, aReq.RepoID, aReq.Type, aReq.CommitID)
|
||||
if err != nil {
|
||||
ctx.ServerError("archiver_service.StartArchive", err)
|
||||
return
|
||||
@@ -501,3 +506,114 @@ func InitiateDownload(ctx *context.Context) {
|
||||
"complete": completed,
|
||||
})
|
||||
}
|
||||
|
||||
// SearchRepo repositories via options
|
||||
func SearchRepo(ctx *context.Context) {
|
||||
opts := &models.SearchRepoOptions{
|
||||
ListOptions: db.ListOptions{
|
||||
Page: ctx.FormInt("page"),
|
||||
PageSize: convert.ToCorrectPageSize(ctx.FormInt("limit")),
|
||||
},
|
||||
Actor: ctx.Doer,
|
||||
Keyword: ctx.FormTrim("q"),
|
||||
OwnerID: ctx.FormInt64("uid"),
|
||||
PriorityOwnerID: ctx.FormInt64("priority_owner_id"),
|
||||
TeamID: ctx.FormInt64("team_id"),
|
||||
TopicOnly: ctx.FormBool("topic"),
|
||||
Collaborate: util.OptionalBoolNone,
|
||||
Private: ctx.IsSigned && (ctx.FormString("private") == "" || ctx.FormBool("private")),
|
||||
Template: util.OptionalBoolNone,
|
||||
StarredByID: ctx.FormInt64("starredBy"),
|
||||
IncludeDescription: ctx.FormBool("includeDesc"),
|
||||
}
|
||||
|
||||
if ctx.FormString("template") != "" {
|
||||
opts.Template = util.OptionalBoolOf(ctx.FormBool("template"))
|
||||
}
|
||||
|
||||
if ctx.FormBool("exclusive") {
|
||||
opts.Collaborate = util.OptionalBoolFalse
|
||||
}
|
||||
|
||||
mode := ctx.FormString("mode")
|
||||
switch mode {
|
||||
case "source":
|
||||
opts.Fork = util.OptionalBoolFalse
|
||||
opts.Mirror = util.OptionalBoolFalse
|
||||
case "fork":
|
||||
opts.Fork = util.OptionalBoolTrue
|
||||
case "mirror":
|
||||
opts.Mirror = util.OptionalBoolTrue
|
||||
case "collaborative":
|
||||
opts.Mirror = util.OptionalBoolFalse
|
||||
opts.Collaborate = util.OptionalBoolTrue
|
||||
case "":
|
||||
default:
|
||||
ctx.Error(http.StatusUnprocessableEntity, fmt.Sprintf("Invalid search mode: \"%s\"", mode))
|
||||
return
|
||||
}
|
||||
|
||||
if ctx.FormString("archived") != "" {
|
||||
opts.Archived = util.OptionalBoolOf(ctx.FormBool("archived"))
|
||||
}
|
||||
|
||||
if ctx.FormString("is_private") != "" {
|
||||
opts.IsPrivate = util.OptionalBoolOf(ctx.FormBool("is_private"))
|
||||
}
|
||||
|
||||
sortMode := ctx.FormString("sort")
|
||||
if len(sortMode) > 0 {
|
||||
sortOrder := ctx.FormString("order")
|
||||
if len(sortOrder) == 0 {
|
||||
sortOrder = "asc"
|
||||
}
|
||||
if searchModeMap, ok := context.SearchOrderByMap[sortOrder]; ok {
|
||||
if orderBy, ok := searchModeMap[sortMode]; ok {
|
||||
opts.OrderBy = orderBy
|
||||
} else {
|
||||
ctx.Error(http.StatusUnprocessableEntity, fmt.Sprintf("Invalid sort mode: \"%s\"", sortMode))
|
||||
return
|
||||
}
|
||||
} else {
|
||||
ctx.Error(http.StatusUnprocessableEntity, fmt.Sprintf("Invalid sort order: \"%s\"", sortOrder))
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
var err error
|
||||
repos, count, err := models.SearchRepository(opts)
|
||||
if err != nil {
|
||||
ctx.JSON(http.StatusInternalServerError, api.SearchError{
|
||||
OK: false,
|
||||
Error: err.Error(),
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
ctx.SetTotalCountHeader(count)
|
||||
|
||||
// To improve performance when only the count is requested
|
||||
if ctx.FormBool("count_only") {
|
||||
return
|
||||
}
|
||||
|
||||
results := make([]*api.Repository, len(repos))
|
||||
for i, repo := range repos {
|
||||
results[i] = &api.Repository{
|
||||
ID: repo.ID,
|
||||
FullName: repo.FullName(),
|
||||
Fork: repo.IsFork,
|
||||
Private: repo.IsPrivate,
|
||||
Template: repo.IsTemplate,
|
||||
Mirror: repo.IsMirror,
|
||||
Stars: repo.NumStars,
|
||||
HTMLURL: repo.HTMLURL(),
|
||||
Internal: !repo.IsPrivate && repo.Owner.Visibility == api.VisibleTypePrivate,
|
||||
}
|
||||
}
|
||||
|
||||
ctx.JSON(http.StatusOK, api.SearchResults{
|
||||
OK: true,
|
||||
Data: results,
|
||||
})
|
||||
}
|
||||
|
||||
@@ -18,7 +18,7 @@ const tplSearch base.TplName = "repo/search"
|
||||
// Search render repository search page
|
||||
func Search(ctx *context.Context) {
|
||||
if !setting.Indexer.RepoIndexerEnabled {
|
||||
ctx.Redirect(ctx.Repo.RepoLink, 302)
|
||||
ctx.Redirect(ctx.Repo.RepoLink)
|
||||
return
|
||||
}
|
||||
language := ctx.FormTrim("l")
|
||||
@@ -47,7 +47,6 @@ func Search(ctx *context.Context) {
|
||||
ctx.Data["SourcePath"] = ctx.Repo.Repository.HTMLURL()
|
||||
ctx.Data["SearchResults"] = searchResults
|
||||
ctx.Data["SearchResultLanguages"] = searchResultLanguages
|
||||
ctx.Data["RequireHighlightJS"] = true
|
||||
ctx.Data["PageIsViewCode"] = true
|
||||
|
||||
pager := context.NewPagination(total, setting.UI.RepoSearchPagingNum, page, 5)
|
||||
|
||||
+35
-29
@@ -17,6 +17,7 @@ import (
|
||||
"code.gitea.io/gitea/models"
|
||||
asymkey_model "code.gitea.io/gitea/models/asymkey"
|
||||
"code.gitea.io/gitea/models/db"
|
||||
"code.gitea.io/gitea/models/organization"
|
||||
"code.gitea.io/gitea/models/perm"
|
||||
repo_model "code.gitea.io/gitea/models/repo"
|
||||
unit_model "code.gitea.io/gitea/models/unit"
|
||||
@@ -31,7 +32,6 @@ import (
|
||||
"code.gitea.io/gitea/modules/repository"
|
||||
"code.gitea.io/gitea/modules/setting"
|
||||
"code.gitea.io/gitea/modules/structs"
|
||||
"code.gitea.io/gitea/modules/timeutil"
|
||||
"code.gitea.io/gitea/modules/typesniffer"
|
||||
"code.gitea.io/gitea/modules/util"
|
||||
"code.gitea.io/gitea/modules/validation"
|
||||
@@ -70,7 +70,7 @@ func Settings(ctx *context.Context) {
|
||||
ctx.Data["SigningKeyAvailable"] = len(signing) > 0
|
||||
ctx.Data["SigningSettings"] = setting.Repository.Signing
|
||||
ctx.Data["CodeIndexerEnabled"] = setting.Indexer.RepoIndexerEnabled
|
||||
if ctx.User.IsAdmin {
|
||||
if ctx.Doer.IsAdmin {
|
||||
if setting.Indexer.RepoIndexerEnabled {
|
||||
status, err := repo_model.GetIndexerStatus(ctx.Repo.Repository, repo_model.RepoIndexerTypeCode)
|
||||
if err != nil {
|
||||
@@ -119,7 +119,7 @@ func SettingsPost(ctx *context.Context) {
|
||||
ctx.Repo.GitRepo.Close()
|
||||
ctx.Repo.GitRepo = nil
|
||||
}
|
||||
if err := repo_service.ChangeRepositoryName(ctx.User, repo, newRepoName); err != nil {
|
||||
if err := repo_service.ChangeRepositoryName(ctx.Doer, repo, newRepoName); err != nil {
|
||||
ctx.Data["Err_RepoName"] = true
|
||||
switch {
|
||||
case repo_model.IsErrRepoAlreadyExist(err):
|
||||
@@ -162,7 +162,7 @@ func SettingsPost(ctx *context.Context) {
|
||||
|
||||
visibilityChanged := repo.IsPrivate != form.Private
|
||||
// when ForcePrivate enabled, you could change public repo to private, but only admin users can change private to public
|
||||
if visibilityChanged && setting.Repository.ForcePrivate && !form.Private && !ctx.User.IsAdmin {
|
||||
if visibilityChanged && setting.Repository.ForcePrivate && !form.Private && !ctx.Doer.IsAdmin {
|
||||
ctx.RenderWithErr(ctx.Tr("form.repository_force_private"), tplSettingsOptions, form)
|
||||
return
|
||||
}
|
||||
@@ -194,11 +194,7 @@ func SettingsPost(ctx *context.Context) {
|
||||
} else {
|
||||
ctx.Repo.Mirror.EnablePrune = form.EnablePrune
|
||||
ctx.Repo.Mirror.Interval = interval
|
||||
if interval != 0 {
|
||||
ctx.Repo.Mirror.NextUpdateUnix = timeutil.TimeStampNow().AddDuration(interval)
|
||||
} else {
|
||||
ctx.Repo.Mirror.NextUpdateUnix = 0
|
||||
}
|
||||
ctx.Repo.Mirror.ScheduleNextUpdate()
|
||||
if err := repo_model.UpdateMirror(ctx.Repo.Mirror); err != nil {
|
||||
ctx.Data["Err_Interval"] = true
|
||||
ctx.RenderWithErr(ctx.Tr("repo.mirror_interval_invalid"), tplSettingsOptions, &form)
|
||||
@@ -213,7 +209,7 @@ func SettingsPost(ctx *context.Context) {
|
||||
|
||||
address, err := forms.ParseRemoteAddr(form.MirrorAddress, form.MirrorUsername, form.MirrorPassword)
|
||||
if err == nil {
|
||||
err = migrations.IsMigrateURLAllowed(address, ctx.User)
|
||||
err = migrations.IsMigrateURLAllowed(address, ctx.Doer)
|
||||
}
|
||||
if err != nil {
|
||||
ctx.Data["Err_MirrorAddress"] = true
|
||||
@@ -235,7 +231,7 @@ func SettingsPost(ctx *context.Context) {
|
||||
ctx.RenderWithErr(ctx.Tr("repo.migrate.invalid_lfs_endpoint"), tplSettingsOptions, &form)
|
||||
return
|
||||
}
|
||||
err = migrations.IsMigrateURLAllowed(ep.String(), ctx.User)
|
||||
err = migrations.IsMigrateURLAllowed(ep.String(), ctx.Doer)
|
||||
if err != nil {
|
||||
ctx.Data["Err_LFSEndpoint"] = true
|
||||
handleSettingRemoteAddrError(ctx, err, form)
|
||||
@@ -329,7 +325,7 @@ func SettingsPost(ctx *context.Context) {
|
||||
|
||||
address, err := forms.ParseRemoteAddr(form.PushMirrorAddress, form.PushMirrorUsername, form.PushMirrorPassword)
|
||||
if err == nil {
|
||||
err = migrations.IsMigrateURLAllowed(address, ctx.User)
|
||||
err = migrations.IsMigrateURLAllowed(address, ctx.Doer)
|
||||
}
|
||||
if err != nil {
|
||||
ctx.Data["Err_PushMirrorAddress"] = true
|
||||
@@ -460,6 +456,15 @@ func SettingsPost(ctx *context.Context) {
|
||||
deleteUnitTypes = append(deleteUnitTypes, unit_model.TypeProjects)
|
||||
}
|
||||
|
||||
if form.EnablePackages && !unit_model.TypeProjects.UnitGlobalDisabled() {
|
||||
units = append(units, repo_model.RepoUnit{
|
||||
RepoID: repo.ID,
|
||||
Type: unit_model.TypePackages,
|
||||
})
|
||||
} else if !unit_model.TypePackages.UnitGlobalDisabled() {
|
||||
deleteUnitTypes = append(deleteUnitTypes, unit_model.TypePackages)
|
||||
}
|
||||
|
||||
if form.EnablePulls && !unit_model.TypePullRequests.UnitGlobalDisabled() {
|
||||
units = append(units, repo_model.RepoUnit{
|
||||
RepoID: repo.ID,
|
||||
@@ -516,7 +521,7 @@ func SettingsPost(ctx *context.Context) {
|
||||
ctx.Redirect(ctx.Repo.RepoLink + "/settings")
|
||||
|
||||
case "admin":
|
||||
if !ctx.User.IsAdmin {
|
||||
if !ctx.Doer.IsAdmin {
|
||||
ctx.Error(http.StatusForbidden)
|
||||
return
|
||||
}
|
||||
@@ -536,7 +541,7 @@ func SettingsPost(ctx *context.Context) {
|
||||
ctx.Redirect(ctx.Repo.RepoLink + "/settings")
|
||||
|
||||
case "admin_index":
|
||||
if !ctx.User.IsAdmin {
|
||||
if !ctx.Doer.IsAdmin {
|
||||
ctx.Error(http.StatusForbidden)
|
||||
return
|
||||
}
|
||||
@@ -595,7 +600,7 @@ func SettingsPost(ctx *context.Context) {
|
||||
ctx.Error(http.StatusNotFound)
|
||||
return
|
||||
}
|
||||
if err := repo.GetOwner(db.DefaultContext); err != nil {
|
||||
if err := repo.GetOwner(ctx); err != nil {
|
||||
ctx.ServerError("Convert Fork", err)
|
||||
return
|
||||
}
|
||||
@@ -648,7 +653,7 @@ func SettingsPost(ctx *context.Context) {
|
||||
}
|
||||
|
||||
if newOwner.Type == user_model.UserTypeOrganization {
|
||||
if !ctx.User.IsAdmin && newOwner.Visibility == structs.VisibleTypePrivate && !models.OrgFromUser(newOwner).HasMemberWithUserID(ctx.User.ID) {
|
||||
if !ctx.Doer.IsAdmin && newOwner.Visibility == structs.VisibleTypePrivate && !organization.OrgFromUser(newOwner).HasMemberWithUserID(ctx.Doer.ID) {
|
||||
// The user shouldn't know about this organization
|
||||
ctx.RenderWithErr(ctx.Tr("form.enterred_invalid_owner_name"), tplSettingsOptions, nil)
|
||||
return
|
||||
@@ -661,7 +666,7 @@ func SettingsPost(ctx *context.Context) {
|
||||
ctx.Repo.GitRepo = nil
|
||||
}
|
||||
|
||||
if err := repo_service.StartRepositoryTransfer(ctx.User, newOwner, repo, nil); err != nil {
|
||||
if err := repo_service.StartRepositoryTransfer(ctx.Doer, newOwner, repo, nil); err != nil {
|
||||
if repo_model.IsErrRepoAlreadyExist(err) {
|
||||
ctx.RenderWithErr(ctx.Tr("repo.settings.new_owner_has_same_repo"), tplSettingsOptions, nil)
|
||||
} else if models.IsErrRepoTransferInProgress(err) {
|
||||
@@ -724,7 +729,7 @@ func SettingsPost(ctx *context.Context) {
|
||||
ctx.Repo.GitRepo.Close()
|
||||
}
|
||||
|
||||
if err := repo_service.DeleteRepository(ctx, ctx.User, ctx.Repo.Repository, true); err != nil {
|
||||
if err := repo_service.DeleteRepository(ctx, ctx.Doer, ctx.Repo.Repository, true); err != nil {
|
||||
ctx.ServerError("DeleteRepository", err)
|
||||
return
|
||||
}
|
||||
@@ -835,7 +840,7 @@ func Collaboration(ctx *context.Context) {
|
||||
}
|
||||
ctx.Data["Collaborators"] = users
|
||||
|
||||
teams, err := models.GetRepoTeams(ctx.Repo.Repository)
|
||||
teams, err := organization.GetRepoTeams(ctx.Repo.Repository)
|
||||
if err != nil {
|
||||
ctx.ServerError("GetRepoTeams", err)
|
||||
return
|
||||
@@ -894,7 +899,7 @@ func CollaborationPost(ctx *context.Context) {
|
||||
}
|
||||
|
||||
if setting.Service.EnableNotifyMail {
|
||||
mailer.SendCollaboratorMail(u, ctx.User, ctx.Repo.Repository)
|
||||
mailer.SendCollaboratorMail(u, ctx.Doer, ctx.Repo.Repository)
|
||||
}
|
||||
|
||||
ctx.Flash.Success(ctx.Tr("repo.settings.add_collaborator_success"))
|
||||
@@ -938,9 +943,9 @@ func AddTeamPost(ctx *context.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
team, err := models.OrgFromUser(ctx.Repo.Owner).GetTeam(name)
|
||||
team, err := organization.OrgFromUser(ctx.Repo.Owner).GetTeam(name)
|
||||
if err != nil {
|
||||
if models.IsErrTeamNotExist(err) {
|
||||
if organization.IsErrTeamNotExist(err) {
|
||||
ctx.Flash.Error(ctx.Tr("form.team_not_exist"))
|
||||
ctx.Redirect(ctx.Repo.RepoLink + "/settings/collaboration")
|
||||
} else {
|
||||
@@ -955,13 +960,13 @@ func AddTeamPost(ctx *context.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
if models.HasTeamRepo(ctx.Repo.Repository.OwnerID, team.ID, ctx.Repo.Repository.ID) {
|
||||
if organization.HasTeamRepo(ctx, ctx.Repo.Repository.OwnerID, team.ID, ctx.Repo.Repository.ID) {
|
||||
ctx.Flash.Error(ctx.Tr("repo.settings.add_team_duplicate"))
|
||||
ctx.Redirect(ctx.Repo.RepoLink + "/settings/collaboration")
|
||||
return
|
||||
}
|
||||
|
||||
if err = team.AddRepository(ctx.Repo.Repository); err != nil {
|
||||
if err = models.AddRepository(team, ctx.Repo.Repository); err != nil {
|
||||
ctx.ServerError("team.AddRepository", err)
|
||||
return
|
||||
}
|
||||
@@ -978,13 +983,13 @@ func DeleteTeam(ctx *context.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
team, err := models.GetTeamByID(ctx.FormInt64("id"))
|
||||
team, err := organization.GetTeamByID(ctx.FormInt64("id"))
|
||||
if err != nil {
|
||||
ctx.ServerError("GetTeamByID", err)
|
||||
return
|
||||
}
|
||||
|
||||
if err = team.RemoveRepository(ctx.Repo.Repository.ID); err != nil {
|
||||
if err = models.RemoveRepository(team, ctx.Repo.Repository.ID); err != nil {
|
||||
ctx.ServerError("team.RemoveRepositorys", err)
|
||||
return
|
||||
}
|
||||
@@ -1055,7 +1060,7 @@ func DeployKeys(ctx *context.Context) {
|
||||
ctx.Data["PageIsSettingsKeys"] = true
|
||||
ctx.Data["DisableSSH"] = setting.SSH.Disabled
|
||||
|
||||
keys, err := asymkey_model.ListDeployKeys(db.DefaultContext, &asymkey_model.ListDeployKeysOptions{RepoID: ctx.Repo.Repository.ID})
|
||||
keys, err := asymkey_model.ListDeployKeys(ctx, &asymkey_model.ListDeployKeysOptions{RepoID: ctx.Repo.Repository.ID})
|
||||
if err != nil {
|
||||
ctx.ServerError("ListDeployKeys", err)
|
||||
return
|
||||
@@ -1070,8 +1075,9 @@ func DeployKeysPost(ctx *context.Context) {
|
||||
form := web.GetForm(ctx).(*forms.AddKeyForm)
|
||||
ctx.Data["Title"] = ctx.Tr("repo.settings.deploy_keys")
|
||||
ctx.Data["PageIsSettingsKeys"] = true
|
||||
ctx.Data["DisableSSH"] = setting.SSH.Disabled
|
||||
|
||||
keys, err := asymkey_model.ListDeployKeys(db.DefaultContext, &asymkey_model.ListDeployKeysOptions{RepoID: ctx.Repo.Repository.ID})
|
||||
keys, err := asymkey_model.ListDeployKeys(ctx, &asymkey_model.ListDeployKeysOptions{RepoID: ctx.Repo.Repository.ID})
|
||||
if err != nil {
|
||||
ctx.ServerError("ListDeployKeys", err)
|
||||
return
|
||||
@@ -1127,7 +1133,7 @@ func DeployKeysPost(ctx *context.Context) {
|
||||
|
||||
// DeleteDeployKey response for deleting a deploy key
|
||||
func DeleteDeployKey(ctx *context.Context) {
|
||||
if err := asymkey_service.DeleteDeployKey(ctx.User, ctx.FormInt64("id")); err != nil {
|
||||
if err := asymkey_service.DeleteDeployKey(ctx.Doer, ctx.FormInt64("id")); err != nil {
|
||||
ctx.Flash.Error("DeleteDeployKey: " + err.Error())
|
||||
} else {
|
||||
ctx.Flash.Success(ctx.Tr("repo.settings.deploy_key_deletion_success"))
|
||||
|
||||
@@ -11,6 +11,7 @@ import (
|
||||
"time"
|
||||
|
||||
"code.gitea.io/gitea/models"
|
||||
"code.gitea.io/gitea/models/organization"
|
||||
"code.gitea.io/gitea/models/perm"
|
||||
repo_model "code.gitea.io/gitea/models/repo"
|
||||
"code.gitea.io/gitea/modules/base"
|
||||
@@ -73,7 +74,7 @@ func ProtectedBranchPost(ctx *context.Context) {
|
||||
|
||||
branch := ctx.FormString("branch")
|
||||
if !ctx.Repo.GitRepo.IsBranchExist(branch) {
|
||||
ctx.Status(404)
|
||||
ctx.Status(http.StatusNotFound)
|
||||
return
|
||||
} else if repo.DefaultBranch != branch {
|
||||
repo.DefaultBranch = branch
|
||||
@@ -158,7 +159,7 @@ func SettingsProtectedBranch(c *context.Context) {
|
||||
}
|
||||
|
||||
if c.Repo.Owner.IsOrganization() {
|
||||
teams, err := models.OrgFromUser(c.Repo.Owner).TeamsWithAccessToRepo(c.Repo.Repository.ID, perm.AccessModeRead)
|
||||
teams, err := organization.OrgFromUser(c.Repo.Owner).TeamsWithAccessToRepo(c.Repo.Repository.ID, perm.AccessModeRead)
|
||||
if err != nil {
|
||||
c.ServerError("Repo.Owner.TeamsWithAccessToRepo", err)
|
||||
return
|
||||
@@ -260,7 +261,7 @@ func SettingsProtectedBranchPost(ctx *context.Context) {
|
||||
protectBranch.UnprotectedFilePatterns = f.UnprotectedFilePatterns
|
||||
protectBranch.BlockOnOutdatedBranch = f.BlockOnOutdatedBranch
|
||||
|
||||
err = models.UpdateProtectBranch(ctx.Repo.Repository, protectBranch, models.WhitelistOptions{
|
||||
err = models.UpdateProtectBranch(ctx, ctx.Repo.Repository, protectBranch, models.WhitelistOptions{
|
||||
UserIDs: whitelistUsers,
|
||||
TeamIDs: whitelistTeams,
|
||||
MergeUserIDs: mergeWhitelistUsers,
|
||||
@@ -305,7 +306,7 @@ func RenameBranchPost(ctx *context.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
msg, err := repository.RenameBranch(ctx.Repo.Repository, ctx.User, ctx.Repo.GitRepo, form.From, form.To)
|
||||
msg, err := repository.RenameBranch(ctx.Repo.Repository, ctx.Doer, ctx.Repo.GitRepo, form.From, form.To)
|
||||
if err != nil {
|
||||
ctx.ServerError("RenameBranch", err)
|
||||
return
|
||||
|
||||
@@ -11,6 +11,7 @@ import (
|
||||
|
||||
"code.gitea.io/gitea/models"
|
||||
asymkey_model "code.gitea.io/gitea/models/asymkey"
|
||||
"code.gitea.io/gitea/models/organization"
|
||||
"code.gitea.io/gitea/models/perm"
|
||||
repo_model "code.gitea.io/gitea/models/repo"
|
||||
"code.gitea.io/gitea/models/unittest"
|
||||
@@ -60,7 +61,7 @@ func TestAddReadOnlyDeployKey(t *testing.T) {
|
||||
}
|
||||
web.SetForm(ctx, &addKeyForm)
|
||||
DeployKeysPost(ctx)
|
||||
assert.EqualValues(t, http.StatusFound, ctx.Resp.Status())
|
||||
assert.EqualValues(t, http.StatusSeeOther, ctx.Resp.Status())
|
||||
|
||||
unittest.AssertExistsAndLoadBean(t, &asymkey_model.DeployKey{
|
||||
Name: addKeyForm.Title,
|
||||
@@ -90,7 +91,7 @@ func TestAddReadWriteOnlyDeployKey(t *testing.T) {
|
||||
}
|
||||
web.SetForm(ctx, &addKeyForm)
|
||||
DeployKeysPost(ctx)
|
||||
assert.EqualValues(t, http.StatusFound, ctx.Resp.Status())
|
||||
assert.EqualValues(t, http.StatusSeeOther, ctx.Resp.Status())
|
||||
|
||||
unittest.AssertExistsAndLoadBean(t, &asymkey_model.DeployKey{
|
||||
Name: addKeyForm.Title,
|
||||
@@ -127,7 +128,7 @@ func TestCollaborationPost(t *testing.T) {
|
||||
|
||||
CollaborationPost(ctx)
|
||||
|
||||
assert.EqualValues(t, http.StatusFound, ctx.Resp.Status())
|
||||
assert.EqualValues(t, http.StatusSeeOther, ctx.Resp.Status())
|
||||
|
||||
exists, err := models.IsCollaborator(re.ID, 4)
|
||||
assert.NoError(t, err)
|
||||
@@ -153,7 +154,7 @@ func TestCollaborationPost_InactiveUser(t *testing.T) {
|
||||
|
||||
CollaborationPost(ctx)
|
||||
|
||||
assert.EqualValues(t, http.StatusFound, ctx.Resp.Status())
|
||||
assert.EqualValues(t, http.StatusSeeOther, ctx.Resp.Status())
|
||||
assert.NotEmpty(t, ctx.Flash.ErrorMsg)
|
||||
}
|
||||
|
||||
@@ -185,7 +186,7 @@ func TestCollaborationPost_AddCollaboratorTwice(t *testing.T) {
|
||||
|
||||
CollaborationPost(ctx)
|
||||
|
||||
assert.EqualValues(t, http.StatusFound, ctx.Resp.Status())
|
||||
assert.EqualValues(t, http.StatusSeeOther, ctx.Resp.Status())
|
||||
|
||||
exists, err := models.IsCollaborator(re.ID, 4)
|
||||
assert.NoError(t, err)
|
||||
@@ -194,7 +195,7 @@ func TestCollaborationPost_AddCollaboratorTwice(t *testing.T) {
|
||||
// Try adding the same collaborator again
|
||||
CollaborationPost(ctx)
|
||||
|
||||
assert.EqualValues(t, http.StatusFound, ctx.Resp.Status())
|
||||
assert.EqualValues(t, http.StatusSeeOther, ctx.Resp.Status())
|
||||
assert.NotEmpty(t, ctx.Flash.ErrorMsg)
|
||||
}
|
||||
|
||||
@@ -216,7 +217,7 @@ func TestCollaborationPost_NonExistentUser(t *testing.T) {
|
||||
|
||||
CollaborationPost(ctx)
|
||||
|
||||
assert.EqualValues(t, http.StatusFound, ctx.Resp.Status())
|
||||
assert.EqualValues(t, http.StatusSeeOther, ctx.Resp.Status())
|
||||
assert.NotEmpty(t, ctx.Flash.ErrorMsg)
|
||||
}
|
||||
|
||||
@@ -231,7 +232,7 @@ func TestAddTeamPost(t *testing.T) {
|
||||
Type: user_model.UserTypeOrganization,
|
||||
}
|
||||
|
||||
team := &models.Team{
|
||||
team := &organization.Team{
|
||||
ID: 11,
|
||||
OrgID: 26,
|
||||
}
|
||||
@@ -255,8 +256,8 @@ func TestAddTeamPost(t *testing.T) {
|
||||
|
||||
AddTeamPost(ctx)
|
||||
|
||||
assert.True(t, team.HasRepository(re.ID))
|
||||
assert.EqualValues(t, http.StatusFound, ctx.Resp.Status())
|
||||
assert.True(t, models.HasRepository(team, re.ID))
|
||||
assert.EqualValues(t, http.StatusSeeOther, ctx.Resp.Status())
|
||||
assert.Empty(t, ctx.Flash.ErrorMsg)
|
||||
}
|
||||
|
||||
@@ -271,7 +272,7 @@ func TestAddTeamPost_NotAllowed(t *testing.T) {
|
||||
Type: user_model.UserTypeOrganization,
|
||||
}
|
||||
|
||||
team := &models.Team{
|
||||
team := &organization.Team{
|
||||
ID: 11,
|
||||
OrgID: 26,
|
||||
}
|
||||
@@ -295,8 +296,8 @@ func TestAddTeamPost_NotAllowed(t *testing.T) {
|
||||
|
||||
AddTeamPost(ctx)
|
||||
|
||||
assert.False(t, team.HasRepository(re.ID))
|
||||
assert.EqualValues(t, http.StatusFound, ctx.Resp.Status())
|
||||
assert.False(t, models.HasRepository(team, re.ID))
|
||||
assert.EqualValues(t, http.StatusSeeOther, ctx.Resp.Status())
|
||||
assert.NotEmpty(t, ctx.Flash.ErrorMsg)
|
||||
}
|
||||
|
||||
@@ -311,7 +312,7 @@ func TestAddTeamPost_AddTeamTwice(t *testing.T) {
|
||||
Type: user_model.UserTypeOrganization,
|
||||
}
|
||||
|
||||
team := &models.Team{
|
||||
team := &organization.Team{
|
||||
ID: 11,
|
||||
OrgID: 26,
|
||||
}
|
||||
@@ -336,8 +337,8 @@ func TestAddTeamPost_AddTeamTwice(t *testing.T) {
|
||||
AddTeamPost(ctx)
|
||||
|
||||
AddTeamPost(ctx)
|
||||
assert.True(t, team.HasRepository(re.ID))
|
||||
assert.EqualValues(t, http.StatusFound, ctx.Resp.Status())
|
||||
assert.True(t, models.HasRepository(team, re.ID))
|
||||
assert.EqualValues(t, http.StatusSeeOther, ctx.Resp.Status())
|
||||
assert.NotEmpty(t, ctx.Flash.ErrorMsg)
|
||||
}
|
||||
|
||||
@@ -370,7 +371,7 @@ func TestAddTeamPost_NonExistentTeam(t *testing.T) {
|
||||
ctx.Repo = repo
|
||||
|
||||
AddTeamPost(ctx)
|
||||
assert.EqualValues(t, http.StatusFound, ctx.Resp.Status())
|
||||
assert.EqualValues(t, http.StatusSeeOther, ctx.Resp.Status())
|
||||
assert.NotEmpty(t, ctx.Flash.ErrorMsg)
|
||||
}
|
||||
|
||||
@@ -385,7 +386,7 @@ func TestDeleteTeam(t *testing.T) {
|
||||
Type: user_model.UserTypeOrganization,
|
||||
}
|
||||
|
||||
team := &models.Team{
|
||||
team := &organization.Team{
|
||||
ID: 2,
|
||||
OrgID: 3,
|
||||
}
|
||||
@@ -409,5 +410,5 @@ func TestDeleteTeam(t *testing.T) {
|
||||
|
||||
DeleteTeam(ctx)
|
||||
|
||||
assert.False(t, team.HasRepository(re.ID))
|
||||
assert.False(t, models.HasRepository(team, re.ID))
|
||||
}
|
||||
|
||||
@@ -10,6 +10,7 @@ import (
|
||||
"strings"
|
||||
|
||||
"code.gitea.io/gitea/models"
|
||||
"code.gitea.io/gitea/models/organization"
|
||||
"code.gitea.io/gitea/models/perm"
|
||||
"code.gitea.io/gitea/modules/base"
|
||||
"code.gitea.io/gitea/modules/context"
|
||||
@@ -150,7 +151,7 @@ func setTagsContext(ctx *context.Context) error {
|
||||
ctx.Data["Users"] = users
|
||||
|
||||
if ctx.Repo.Owner.IsOrganization() {
|
||||
teams, err := models.OrgFromUser(ctx.Repo.Owner).TeamsWithAccessToRepo(ctx.Repo.Repository.ID, perm.AccessModeRead)
|
||||
teams, err := organization.OrgFromUser(ctx.Repo.Owner).TeamsWithAccessToRepo(ctx.Repo.Repository.ID, perm.AccessModeRead)
|
||||
if err != nil {
|
||||
ctx.ServerError("Repo.Owner.TeamsWithAccessToRepo", err)
|
||||
return err
|
||||
|
||||
@@ -15,7 +15,7 @@ import (
|
||||
|
||||
// TopicsPost response for creating repository
|
||||
func TopicsPost(ctx *context.Context) {
|
||||
if ctx.User == nil {
|
||||
if ctx.Doer == nil {
|
||||
ctx.JSON(http.StatusForbidden, map[string]interface{}{
|
||||
"message": "Only owners could change the topics.",
|
||||
})
|
||||
|
||||
+151
-121
@@ -38,6 +38,7 @@ import (
|
||||
"code.gitea.io/gitea/modules/structs"
|
||||
"code.gitea.io/gitea/modules/typesniffer"
|
||||
"code.gitea.io/gitea/modules/util"
|
||||
"code.gitea.io/gitea/routers/web/feed"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -145,6 +146,21 @@ func renderDirectory(ctx *context.Context, treeLink string) {
|
||||
ctx.Data["Title"] = ctx.Tr("repo.file.title", ctx.Repo.Repository.Name+"/"+path.Base(ctx.Repo.TreePath), ctx.Repo.RefName)
|
||||
}
|
||||
|
||||
// Check permission to add or upload new file.
|
||||
if ctx.Repo.CanWrite(unit_model.TypeCode) && ctx.Repo.IsViewBranch {
|
||||
ctx.Data["CanAddFile"] = !ctx.Repo.Repository.IsArchived
|
||||
ctx.Data["CanUploadFile"] = setting.Repository.Upload.Enabled && !ctx.Repo.Repository.IsArchived
|
||||
}
|
||||
|
||||
readmeFile, readmeTreelink := findReadmeFile(ctx, entries, treeLink)
|
||||
if ctx.Written() || readmeFile == nil {
|
||||
return
|
||||
}
|
||||
|
||||
renderReadmeFile(ctx, readmeFile, readmeTreelink)
|
||||
}
|
||||
|
||||
func findReadmeFile(ctx *context.Context, entries git.Entries, treeLink string) (*namedBlob, string) {
|
||||
// 3 for the extensions in exts[] in order
|
||||
// the last one is for a readme that doesn't
|
||||
// strictly match an extension
|
||||
@@ -182,7 +198,7 @@ func renderDirectory(ctx *context.Context, treeLink string) {
|
||||
target, err = entry.FollowLinks()
|
||||
if err != nil && !git.IsErrBadLink(err) {
|
||||
ctx.ServerError("FollowLinks", err)
|
||||
return
|
||||
return nil, ""
|
||||
}
|
||||
}
|
||||
log.Debug("%t", target == nil)
|
||||
@@ -204,7 +220,7 @@ func renderDirectory(ctx *context.Context, treeLink string) {
|
||||
entry, err = entry.FollowLinks()
|
||||
if err != nil && !git.IsErrBadLink(err) {
|
||||
ctx.ServerError("FollowLinks", err)
|
||||
return
|
||||
return nil, ""
|
||||
}
|
||||
}
|
||||
if entry != nil && (entry.IsExecutable() || entry.IsRegular()) {
|
||||
@@ -235,7 +251,7 @@ func renderDirectory(ctx *context.Context, treeLink string) {
|
||||
readmeFile, err = getReadmeFileFromPath(ctx.Repo.Commit, entry.GetSubJumpablePathName())
|
||||
if err != nil {
|
||||
ctx.ServerError("getReadmeFileFromPath", err)
|
||||
return
|
||||
return nil, ""
|
||||
}
|
||||
if readmeFile != nil {
|
||||
readmeFile.name = entry.Name() + "/" + readmeFile.name
|
||||
@@ -244,129 +260,127 @@ func renderDirectory(ctx *context.Context, treeLink string) {
|
||||
}
|
||||
}
|
||||
}
|
||||
return readmeFile, readmeTreelink
|
||||
}
|
||||
|
||||
if readmeFile != nil {
|
||||
ctx.Data["RawFileLink"] = ""
|
||||
ctx.Data["ReadmeInList"] = true
|
||||
ctx.Data["ReadmeExist"] = true
|
||||
ctx.Data["FileIsSymlink"] = readmeFile.isSymlink
|
||||
func renderReadmeFile(ctx *context.Context, readmeFile *namedBlob, readmeTreelink string) {
|
||||
ctx.Data["RawFileLink"] = ""
|
||||
ctx.Data["ReadmeInList"] = true
|
||||
ctx.Data["ReadmeExist"] = true
|
||||
ctx.Data["FileIsSymlink"] = readmeFile.isSymlink
|
||||
|
||||
dataRc, err := readmeFile.blob.DataAsync()
|
||||
if err != nil {
|
||||
ctx.ServerError("Data", err)
|
||||
return
|
||||
}
|
||||
defer dataRc.Close()
|
||||
dataRc, err := readmeFile.blob.DataAsync()
|
||||
if err != nil {
|
||||
ctx.ServerError("Data", err)
|
||||
return
|
||||
}
|
||||
defer dataRc.Close()
|
||||
|
||||
buf := make([]byte, 1024)
|
||||
n, _ := util.ReadAtMost(dataRc, buf)
|
||||
buf = buf[:n]
|
||||
buf := make([]byte, 1024)
|
||||
n, _ := util.ReadAtMost(dataRc, buf)
|
||||
buf = buf[:n]
|
||||
|
||||
st := typesniffer.DetectContentType(buf)
|
||||
isTextFile := st.IsText()
|
||||
st := typesniffer.DetectContentType(buf)
|
||||
isTextFile := st.IsText()
|
||||
|
||||
ctx.Data["FileIsText"] = isTextFile
|
||||
ctx.Data["FileName"] = readmeFile.name
|
||||
fileSize := int64(0)
|
||||
isLFSFile := false
|
||||
ctx.Data["IsLFSFile"] = false
|
||||
ctx.Data["FileIsText"] = isTextFile
|
||||
ctx.Data["FileName"] = readmeFile.name
|
||||
fileSize := int64(0)
|
||||
isLFSFile := false
|
||||
ctx.Data["IsLFSFile"] = false
|
||||
|
||||
// FIXME: what happens when README file is an image?
|
||||
if isTextFile && setting.LFS.StartServer {
|
||||
pointer, _ := lfs.ReadPointerFromBuffer(buf)
|
||||
if pointer.IsValid() {
|
||||
meta, err := models.GetLFSMetaObjectByOid(ctx.Repo.Repository.ID, pointer.Oid)
|
||||
if err != nil && err != models.ErrLFSObjectNotExist {
|
||||
ctx.ServerError("GetLFSMetaObject", err)
|
||||
// FIXME: what happens when README file is an image?
|
||||
if isTextFile && setting.LFS.StartServer {
|
||||
pointer, _ := lfs.ReadPointerFromBuffer(buf)
|
||||
if pointer.IsValid() {
|
||||
meta, err := models.GetLFSMetaObjectByOid(ctx.Repo.Repository.ID, pointer.Oid)
|
||||
if err != nil && err != models.ErrLFSObjectNotExist {
|
||||
ctx.ServerError("GetLFSMetaObject", err)
|
||||
return
|
||||
}
|
||||
if meta != nil {
|
||||
ctx.Data["IsLFSFile"] = true
|
||||
isLFSFile = true
|
||||
|
||||
// OK read the lfs object
|
||||
var err error
|
||||
dataRc, err = lfs.ReadMetaObject(pointer)
|
||||
if err != nil {
|
||||
ctx.ServerError("ReadMetaObject", err)
|
||||
return
|
||||
}
|
||||
if meta != nil {
|
||||
ctx.Data["IsLFSFile"] = true
|
||||
isLFSFile = true
|
||||
defer dataRc.Close()
|
||||
|
||||
// OK read the lfs object
|
||||
var err error
|
||||
dataRc, err = lfs.ReadMetaObject(pointer)
|
||||
if err != nil {
|
||||
ctx.ServerError("ReadMetaObject", err)
|
||||
return
|
||||
}
|
||||
defer dataRc.Close()
|
||||
|
||||
buf = make([]byte, 1024)
|
||||
n, err = util.ReadAtMost(dataRc, buf)
|
||||
if err != nil {
|
||||
ctx.ServerError("Data", err)
|
||||
return
|
||||
}
|
||||
buf = buf[:n]
|
||||
|
||||
st = typesniffer.DetectContentType(buf)
|
||||
isTextFile = st.IsText()
|
||||
ctx.Data["IsTextFile"] = isTextFile
|
||||
|
||||
fileSize = meta.Size
|
||||
ctx.Data["FileSize"] = meta.Size
|
||||
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(meta.Oid), url.PathEscape(filenameBase64))
|
||||
buf = make([]byte, 1024)
|
||||
n, err = util.ReadAtMost(dataRc, buf)
|
||||
if err != nil {
|
||||
ctx.ServerError("Data", err)
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
buf = buf[:n]
|
||||
|
||||
if !isLFSFile {
|
||||
fileSize = readmeFile.blob.Size()
|
||||
}
|
||||
st = typesniffer.DetectContentType(buf)
|
||||
isTextFile = st.IsText()
|
||||
ctx.Data["IsTextFile"] = isTextFile
|
||||
|
||||
if isTextFile {
|
||||
if fileSize >= setting.UI.MaxDisplayFileSize {
|
||||
// Pretend that this is a normal text file to display 'This file is too large to be shown'
|
||||
ctx.Data["IsFileTooLarge"] = true
|
||||
ctx.Data["IsTextFile"] = true
|
||||
ctx.Data["FileSize"] = fileSize
|
||||
} else {
|
||||
rd := charset.ToUTF8WithFallbackReader(io.MultiReader(bytes.NewReader(buf), dataRc))
|
||||
|
||||
if markupType := markup.Type(readmeFile.name); markupType != "" {
|
||||
ctx.Data["IsMarkup"] = true
|
||||
ctx.Data["MarkupType"] = string(markupType)
|
||||
var result strings.Builder
|
||||
err := markup.Render(&markup.RenderContext{
|
||||
Ctx: ctx,
|
||||
Filename: readmeFile.name,
|
||||
URLPrefix: readmeTreelink,
|
||||
Metas: ctx.Repo.Repository.ComposeDocumentMetas(),
|
||||
GitRepo: ctx.Repo.GitRepo,
|
||||
}, rd, &result)
|
||||
if err != nil {
|
||||
log.Error("Render failed: %v then fallback", err)
|
||||
buf := &bytes.Buffer{}
|
||||
ctx.Data["EscapeStatus"], _ = charset.EscapeControlReader(rd, buf)
|
||||
ctx.Data["FileContent"] = strings.ReplaceAll(
|
||||
gotemplate.HTMLEscapeString(buf.String()), "\n", `<br>`,
|
||||
)
|
||||
} else {
|
||||
ctx.Data["EscapeStatus"], ctx.Data["FileContent"] = charset.EscapeControlString(result.String())
|
||||
}
|
||||
} else {
|
||||
ctx.Data["IsRenderedHTML"] = true
|
||||
buf := &bytes.Buffer{}
|
||||
ctx.Data["EscapeStatus"], err = charset.EscapeControlReader(rd, buf)
|
||||
if err != nil {
|
||||
log.Error("Read failed: %v", err)
|
||||
}
|
||||
|
||||
ctx.Data["FileContent"] = strings.ReplaceAll(
|
||||
gotemplate.HTMLEscapeString(buf.String()), "\n", `<br>`,
|
||||
)
|
||||
}
|
||||
fileSize = meta.Size
|
||||
ctx.Data["FileSize"] = meta.Size
|
||||
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(meta.Oid), url.PathEscape(filenameBase64))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Check permission to add or upload new file.
|
||||
if ctx.Repo.CanWrite(unit_model.TypeCode) && ctx.Repo.IsViewBranch {
|
||||
ctx.Data["CanAddFile"] = !ctx.Repo.Repository.IsArchived
|
||||
ctx.Data["CanUploadFile"] = setting.Repository.Upload.Enabled && !ctx.Repo.Repository.IsArchived
|
||||
if !isTextFile {
|
||||
return
|
||||
}
|
||||
|
||||
if !isLFSFile {
|
||||
fileSize = readmeFile.blob.Size()
|
||||
}
|
||||
|
||||
if fileSize >= setting.UI.MaxDisplayFileSize {
|
||||
// Pretend that this is a normal text file to display 'This file is too large to be shown'
|
||||
ctx.Data["IsFileTooLarge"] = true
|
||||
ctx.Data["IsTextFile"] = true
|
||||
ctx.Data["FileSize"] = fileSize
|
||||
return
|
||||
}
|
||||
|
||||
rd := charset.ToUTF8WithFallbackReader(io.MultiReader(bytes.NewReader(buf), dataRc))
|
||||
|
||||
if markupType := markup.Type(readmeFile.name); markupType != "" {
|
||||
ctx.Data["IsMarkup"] = true
|
||||
ctx.Data["MarkupType"] = string(markupType)
|
||||
var result strings.Builder
|
||||
err := markup.Render(&markup.RenderContext{
|
||||
Ctx: ctx,
|
||||
Filename: readmeFile.name,
|
||||
URLPrefix: readmeTreelink,
|
||||
Metas: ctx.Repo.Repository.ComposeDocumentMetas(),
|
||||
GitRepo: ctx.Repo.GitRepo,
|
||||
}, rd, &result)
|
||||
if err != nil {
|
||||
log.Error("Render failed: %v then fallback", err)
|
||||
buf := &bytes.Buffer{}
|
||||
ctx.Data["EscapeStatus"], _ = charset.EscapeControlReader(rd, buf)
|
||||
ctx.Data["FileContent"] = strings.ReplaceAll(
|
||||
gotemplate.HTMLEscapeString(buf.String()), "\n", `<br>`,
|
||||
)
|
||||
} else {
|
||||
ctx.Data["EscapeStatus"], ctx.Data["FileContent"] = charset.EscapeControlString(result.String())
|
||||
}
|
||||
} else {
|
||||
ctx.Data["IsRenderedHTML"] = true
|
||||
buf := &bytes.Buffer{}
|
||||
ctx.Data["EscapeStatus"], err = charset.EscapeControlReader(rd, buf)
|
||||
if err != nil {
|
||||
log.Error("Read failed: %v", err)
|
||||
}
|
||||
|
||||
ctx.Data["FileContent"] = strings.ReplaceAll(
|
||||
gotemplate.HTMLEscapeString(buf.String()), "\n", `<br>`,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -488,9 +502,17 @@ 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())
|
||||
ctx.Data["ReadmeExist"] = readmeExist
|
||||
if markupType := markup.Type(blob.Name()); markupType != "" {
|
||||
|
||||
markupType := markup.Type(blob.Name())
|
||||
if markupType != "" {
|
||||
ctx.Data["HasSourceRenderedToggle"] = true
|
||||
}
|
||||
|
||||
if markupType != "" && !shouldRenderSource {
|
||||
ctx.Data["IsMarkup"] = true
|
||||
ctx.Data["MarkupType"] = markupType
|
||||
var result strings.Builder
|
||||
@@ -506,7 +528,7 @@ func renderFile(ctx *context.Context, entry *git.TreeEntry, treeLink, rawLink st
|
||||
return
|
||||
}
|
||||
ctx.Data["EscapeStatus"], ctx.Data["FileContent"] = charset.EscapeControlString(result.String())
|
||||
} else if readmeExist {
|
||||
} else if readmeExist && !shouldRenderSource {
|
||||
buf := &bytes.Buffer{}
|
||||
ctx.Data["IsRenderedHTML"] = true
|
||||
|
||||
@@ -557,8 +579,8 @@ func renderFile(ctx *context.Context, entry *git.TreeEntry, treeLink, rawLink st
|
||||
ctx.Data["LineEscapeStatus"] = statuses
|
||||
}
|
||||
if !isLFSFile {
|
||||
if ctx.Repo.CanEnableEditor() {
|
||||
if lfsLock != nil && lfsLock.OwnerID != ctx.User.ID {
|
||||
if ctx.Repo.CanEnableEditor(ctx.Doer) {
|
||||
if lfsLock != nil && lfsLock.OwnerID != ctx.Doer.ID {
|
||||
ctx.Data["CanEditFile"] = false
|
||||
ctx.Data["EditFileTooltip"] = ctx.Tr("repo.editor.this_file_locked")
|
||||
} else {
|
||||
@@ -567,7 +589,7 @@ func renderFile(ctx *context.Context, entry *git.TreeEntry, treeLink, rawLink st
|
||||
}
|
||||
} else if !ctx.Repo.IsViewBranch {
|
||||
ctx.Data["EditFileTooltip"] = ctx.Tr("repo.editor.must_be_on_a_branch")
|
||||
} else if !ctx.Repo.CanWrite(unit_model.TypeCode) {
|
||||
} else if !ctx.Repo.CanWriteToBranch(ctx.Doer, ctx.Repo.BranchName) {
|
||||
ctx.Data["EditFileTooltip"] = ctx.Tr("repo.editor.fork_before_edit")
|
||||
}
|
||||
}
|
||||
@@ -607,8 +629,8 @@ func renderFile(ctx *context.Context, entry *git.TreeEntry, treeLink, rawLink st
|
||||
}
|
||||
}
|
||||
|
||||
if ctx.Repo.CanEnableEditor() {
|
||||
if lfsLock != nil && lfsLock.OwnerID != ctx.User.ID {
|
||||
if ctx.Repo.CanEnableEditor(ctx.Doer) {
|
||||
if lfsLock != nil && lfsLock.OwnerID != ctx.Doer.ID {
|
||||
ctx.Data["CanDeleteFile"] = false
|
||||
ctx.Data["DeleteFileTooltip"] = ctx.Tr("repo.editor.this_file_locked")
|
||||
} else {
|
||||
@@ -617,7 +639,7 @@ func renderFile(ctx *context.Context, entry *git.TreeEntry, treeLink, rawLink st
|
||||
}
|
||||
} else if !ctx.Repo.IsViewBranch {
|
||||
ctx.Data["DeleteFileTooltip"] = ctx.Tr("repo.editor.must_be_on_a_branch")
|
||||
} else if !ctx.Repo.CanWrite(unit_model.TypeCode) {
|
||||
} else if !ctx.Repo.CanWriteToBranch(ctx.Doer, ctx.Repo.BranchName) {
|
||||
ctx.Data["DeleteFileTooltip"] = ctx.Tr("repo.editor.must_have_write_access")
|
||||
}
|
||||
}
|
||||
@@ -662,7 +684,7 @@ func checkHomeCodeViewable(ctx *context.Context) {
|
||||
|
||||
if ctx.IsSigned {
|
||||
// Set repo notification-status read if unread
|
||||
if err := models.SetRepoReadBy(ctx.Repo.Repository.ID, ctx.User.ID); err != nil {
|
||||
if err := models.SetRepoReadBy(ctx.Repo.Repository.ID, ctx.Doer.ID); err != nil {
|
||||
ctx.ServerError("ReadBy", err)
|
||||
return
|
||||
}
|
||||
@@ -691,6 +713,14 @@ func checkHomeCodeViewable(ctx *context.Context) {
|
||||
|
||||
// Home render repository home page
|
||||
func Home(ctx *context.Context) {
|
||||
isFeed, _, showFeedType := feed.GetFeedType(ctx.Params(":reponame"), ctx.Req)
|
||||
if isFeed {
|
||||
feed.ShowRepoFeed(ctx, ctx.Repo.Repository, showFeedType)
|
||||
return
|
||||
}
|
||||
|
||||
ctx.Data["FeedURL"] = ctx.Repo.Repository.HTMLURL()
|
||||
|
||||
checkHomeCodeViewable(ctx)
|
||||
if ctx.Written() {
|
||||
return
|
||||
@@ -875,7 +905,7 @@ func renderCode(ctx *context.Context) {
|
||||
ctx.ServerError("UpdateRepositoryCols", err)
|
||||
return
|
||||
}
|
||||
if err = models.UpdateRepoSize(db.DefaultContext, ctx.Repo.Repository); err != nil {
|
||||
if err = models.UpdateRepoSize(ctx, ctx.Repo.Repository); err != nil {
|
||||
ctx.ServerError("UpdateRepoSize", err)
|
||||
return
|
||||
}
|
||||
@@ -1008,7 +1038,7 @@ func Forks(ctx *context.Context) {
|
||||
}
|
||||
|
||||
for _, fork := range forks {
|
||||
if err = fork.GetOwner(db.DefaultContext); err != nil {
|
||||
if err = fork.GetOwner(ctx); err != nil {
|
||||
ctx.ServerError("GetOwner", err)
|
||||
return
|
||||
}
|
||||
|
||||
+17
-20
@@ -13,7 +13,6 @@ import (
|
||||
"path"
|
||||
"strings"
|
||||
|
||||
"code.gitea.io/gitea/models/db"
|
||||
"code.gitea.io/gitea/models/perm"
|
||||
user_model "code.gitea.io/gitea/models/user"
|
||||
"code.gitea.io/gitea/models/webhook"
|
||||
@@ -85,7 +84,7 @@ func getOrgRepoCtx(ctx *context.Context) (*orgRepoCtx, error) {
|
||||
}, nil
|
||||
}
|
||||
|
||||
if ctx.User.IsAdmin {
|
||||
if ctx.Doer.IsAdmin {
|
||||
// Are we looking at default webhooks?
|
||||
if ctx.Params(":configType") == "default-hooks" {
|
||||
return &orgRepoCtx{
|
||||
@@ -148,7 +147,6 @@ func WebhooksNew(ctx *context.Context) {
|
||||
if hookType == "discord" {
|
||||
ctx.Data["DiscordHook"] = map[string]interface{}{
|
||||
"Username": "Gitea",
|
||||
"IconURL": setting.AppURL + "img/favicon.png",
|
||||
}
|
||||
}
|
||||
ctx.Data["BaseLink"] = orCtx.LinkNew
|
||||
@@ -181,6 +179,7 @@ func ParseHookEvent(form forms.WebhookForm) *webhook.HookEvent {
|
||||
PullRequestReview: form.PullRequestReview,
|
||||
PullRequestSync: form.PullRequestSync,
|
||||
Repository: form.Repository,
|
||||
Package: form.Package,
|
||||
},
|
||||
BranchFilter: form.BranchFilter,
|
||||
}
|
||||
@@ -227,7 +226,7 @@ func GiteaHooksNewPost(ctx *context.Context) {
|
||||
if err := w.UpdateEvent(); err != nil {
|
||||
ctx.ServerError("UpdateEvent", err)
|
||||
return
|
||||
} else if err := webhook.CreateWebhook(db.DefaultContext, w); err != nil {
|
||||
} else if err := webhook.CreateWebhook(ctx, w); err != nil {
|
||||
ctx.ServerError("CreateWebhook", err)
|
||||
return
|
||||
}
|
||||
@@ -281,7 +280,7 @@ func newGogsWebhookPost(ctx *context.Context, form forms.NewGogshookForm, kind w
|
||||
if err := w.UpdateEvent(); err != nil {
|
||||
ctx.ServerError("UpdateEvent", err)
|
||||
return
|
||||
} else if err := webhook.CreateWebhook(db.DefaultContext, w); err != nil {
|
||||
} else if err := webhook.CreateWebhook(ctx, w); err != nil {
|
||||
ctx.ServerError("CreateWebhook", err)
|
||||
return
|
||||
}
|
||||
@@ -333,7 +332,7 @@ func DiscordHooksNewPost(ctx *context.Context) {
|
||||
if err := w.UpdateEvent(); err != nil {
|
||||
ctx.ServerError("UpdateEvent", err)
|
||||
return
|
||||
} else if err := webhook.CreateWebhook(db.DefaultContext, w); err != nil {
|
||||
} else if err := webhook.CreateWebhook(ctx, w); err != nil {
|
||||
ctx.ServerError("CreateWebhook", err)
|
||||
return
|
||||
}
|
||||
@@ -376,7 +375,7 @@ func DingtalkHooksNewPost(ctx *context.Context) {
|
||||
if err := w.UpdateEvent(); err != nil {
|
||||
ctx.ServerError("UpdateEvent", err)
|
||||
return
|
||||
} else if err := webhook.CreateWebhook(db.DefaultContext, w); err != nil {
|
||||
} else if err := webhook.CreateWebhook(ctx, w); err != nil {
|
||||
ctx.ServerError("CreateWebhook", err)
|
||||
return
|
||||
}
|
||||
@@ -428,7 +427,7 @@ func TelegramHooksNewPost(ctx *context.Context) {
|
||||
if err := w.UpdateEvent(); err != nil {
|
||||
ctx.ServerError("UpdateEvent", err)
|
||||
return
|
||||
} else if err := webhook.CreateWebhook(db.DefaultContext, w); err != nil {
|
||||
} else if err := webhook.CreateWebhook(ctx, w); err != nil {
|
||||
ctx.ServerError("CreateWebhook", err)
|
||||
return
|
||||
}
|
||||
@@ -483,7 +482,7 @@ func MatrixHooksNewPost(ctx *context.Context) {
|
||||
if err := w.UpdateEvent(); err != nil {
|
||||
ctx.ServerError("UpdateEvent", err)
|
||||
return
|
||||
} else if err := webhook.CreateWebhook(db.DefaultContext, w); err != nil {
|
||||
} else if err := webhook.CreateWebhook(ctx, w); err != nil {
|
||||
ctx.ServerError("CreateWebhook", err)
|
||||
return
|
||||
}
|
||||
@@ -526,7 +525,7 @@ func MSTeamsHooksNewPost(ctx *context.Context) {
|
||||
if err := w.UpdateEvent(); err != nil {
|
||||
ctx.ServerError("UpdateEvent", err)
|
||||
return
|
||||
} else if err := webhook.CreateWebhook(db.DefaultContext, w); err != nil {
|
||||
} else if err := webhook.CreateWebhook(ctx, w); err != nil {
|
||||
ctx.ServerError("CreateWebhook", err)
|
||||
return
|
||||
}
|
||||
@@ -586,7 +585,7 @@ func SlackHooksNewPost(ctx *context.Context) {
|
||||
if err := w.UpdateEvent(); err != nil {
|
||||
ctx.ServerError("UpdateEvent", err)
|
||||
return
|
||||
} else if err := webhook.CreateWebhook(db.DefaultContext, w); err != nil {
|
||||
} else if err := webhook.CreateWebhook(ctx, w); err != nil {
|
||||
ctx.ServerError("CreateWebhook", err)
|
||||
return
|
||||
}
|
||||
@@ -629,7 +628,7 @@ func FeishuHooksNewPost(ctx *context.Context) {
|
||||
if err := w.UpdateEvent(); err != nil {
|
||||
ctx.ServerError("UpdateEvent", err)
|
||||
return
|
||||
} else if err := webhook.CreateWebhook(db.DefaultContext, w); err != nil {
|
||||
} else if err := webhook.CreateWebhook(ctx, w); err != nil {
|
||||
ctx.ServerError("CreateWebhook", err)
|
||||
return
|
||||
}
|
||||
@@ -673,7 +672,7 @@ func WechatworkHooksNewPost(ctx *context.Context) {
|
||||
if err := w.UpdateEvent(); err != nil {
|
||||
ctx.ServerError("UpdateEvent", err)
|
||||
return
|
||||
} else if err := webhook.CreateWebhook(db.DefaultContext, w); err != nil {
|
||||
} else if err := webhook.CreateWebhook(ctx, w); err != nil {
|
||||
ctx.ServerError("CreateWebhook", err)
|
||||
return
|
||||
}
|
||||
@@ -726,7 +725,7 @@ func PackagistHooksNewPost(ctx *context.Context) {
|
||||
if err := w.UpdateEvent(); err != nil {
|
||||
ctx.ServerError("UpdateEvent", err)
|
||||
return
|
||||
} else if err := webhook.CreateWebhook(db.DefaultContext, w); err != nil {
|
||||
} else if err := webhook.CreateWebhook(ctx, w); err != nil {
|
||||
ctx.ServerError("CreateWebhook", err)
|
||||
return
|
||||
}
|
||||
@@ -736,8 +735,6 @@ func PackagistHooksNewPost(ctx *context.Context) {
|
||||
}
|
||||
|
||||
func checkWebhook(ctx *context.Context) (*orgRepoCtx, *webhook.Webhook) {
|
||||
ctx.Data["RequireHighlightJS"] = true
|
||||
|
||||
orCtx, err := getOrgRepoCtx(ctx)
|
||||
if err != nil {
|
||||
ctx.ServerError("getOrgRepoCtx", err)
|
||||
@@ -1242,7 +1239,7 @@ func TestWebhook(ctx *context.Context) {
|
||||
w, err := webhook.GetWebhookByRepoID(ctx.Repo.Repository.ID, hookID)
|
||||
if err != nil {
|
||||
ctx.Flash.Error("GetWebhookByID: " + err.Error())
|
||||
ctx.Status(500)
|
||||
ctx.Status(http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -1258,7 +1255,7 @@ func TestWebhook(ctx *context.Context) {
|
||||
}
|
||||
}
|
||||
|
||||
apiUser := convert.ToUserWithAccessMode(ctx.User, perm.AccessModeNone)
|
||||
apiUser := convert.ToUserWithAccessMode(ctx.Doer, perm.AccessModeNone)
|
||||
|
||||
apiCommit := &api.PayloadCommit{
|
||||
ID: commit.ID.String(),
|
||||
@@ -1286,10 +1283,10 @@ func TestWebhook(ctx *context.Context) {
|
||||
}
|
||||
if err := webhook_service.PrepareWebhook(w, ctx.Repo.Repository, webhook.HookEventPush, p); err != nil {
|
||||
ctx.Flash.Error("PrepareWebhook: " + err.Error())
|
||||
ctx.Status(500)
|
||||
ctx.Status(http.StatusInternalServerError)
|
||||
} else {
|
||||
ctx.Flash.Info(ctx.Tr("repo.settings.webhook.delivery.success"))
|
||||
ctx.Status(200)
|
||||
ctx.Status(http.StatusOK)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+54
-42
@@ -13,6 +13,7 @@ import (
|
||||
"net/url"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"code.gitea.io/gitea/models"
|
||||
"code.gitea.io/gitea/models/unit"
|
||||
@@ -47,7 +48,7 @@ func MustEnableWiki(ctx *context.Context) {
|
||||
if log.IsTrace() {
|
||||
log.Trace("Permission Denied: User %-v cannot read %-v or %-v of repo %-v\n"+
|
||||
"User in repo has Permissions: %-+v",
|
||||
ctx.User,
|
||||
ctx.Doer,
|
||||
unit.TypeWiki,
|
||||
unit.TypeExternalWiki,
|
||||
ctx.Repo.Repository,
|
||||
@@ -90,7 +91,7 @@ func findEntryForFile(commit *git.Commit, target string) (*git.TreeEntry, error)
|
||||
}
|
||||
|
||||
func findWikiRepoCommit(ctx *context.Context) (*git.Repository, *git.Commit, error) {
|
||||
wikiRepo, err := git.OpenRepositoryCtx(ctx, ctx.Repo.Repository.WikiPath())
|
||||
wikiRepo, err := git.OpenRepository(ctx, ctx.Repo.Repository.WikiPath())
|
||||
if err != nil {
|
||||
ctx.ServerError("OpenRepository", err)
|
||||
return nil, nil, err
|
||||
@@ -189,7 +190,9 @@ func renderViewPage(ctx *context.Context) (*git.Repository, *git.TreeEntry) {
|
||||
ctx.Data["old_title"] = pageName
|
||||
ctx.Data["Title"] = pageName
|
||||
ctx.Data["title"] = pageName
|
||||
ctx.Data["RequireHighlightJS"] = true
|
||||
|
||||
isSideBar := pageName == "_Sidebar"
|
||||
isFooter := pageName == "_Footer"
|
||||
|
||||
// lookup filename in wiki - get filecontent, gitTree entry , real filename
|
||||
data, entry, pageFilename, noEntry := wikiContentsByName(ctx, commit, pageName)
|
||||
@@ -203,20 +206,30 @@ func renderViewPage(ctx *context.Context) (*git.Repository, *git.TreeEntry) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
sidebarContent, _, _, _ := wikiContentsByName(ctx, commit, "_Sidebar")
|
||||
if ctx.Written() {
|
||||
if wikiRepo != nil {
|
||||
wikiRepo.Close()
|
||||
var sidebarContent []byte
|
||||
if !isSideBar {
|
||||
sidebarContent, _, _, _ = wikiContentsByName(ctx, commit, "_Sidebar")
|
||||
if ctx.Written() {
|
||||
if wikiRepo != nil {
|
||||
wikiRepo.Close()
|
||||
}
|
||||
return nil, nil
|
||||
}
|
||||
return nil, nil
|
||||
} else {
|
||||
sidebarContent = data
|
||||
}
|
||||
|
||||
footerContent, _, _, _ := wikiContentsByName(ctx, commit, "_Footer")
|
||||
if ctx.Written() {
|
||||
if wikiRepo != nil {
|
||||
wikiRepo.Close()
|
||||
var footerContent []byte
|
||||
if !isFooter {
|
||||
footerContent, _, _, _ = wikiContentsByName(ctx, commit, "_Footer")
|
||||
if ctx.Written() {
|
||||
if wikiRepo != nil {
|
||||
wikiRepo.Close()
|
||||
}
|
||||
return nil, nil
|
||||
}
|
||||
return nil, nil
|
||||
} else {
|
||||
footerContent = data
|
||||
}
|
||||
|
||||
rctx := &markup.RenderContext{
|
||||
@@ -237,27 +250,35 @@ func renderViewPage(ctx *context.Context) (*git.Repository, *git.TreeEntry) {
|
||||
|
||||
ctx.Data["EscapeStatus"], ctx.Data["content"] = charset.EscapeControlString(buf.String())
|
||||
|
||||
buf.Reset()
|
||||
if err := markdown.Render(rctx, bytes.NewReader(sidebarContent), &buf); err != nil {
|
||||
if wikiRepo != nil {
|
||||
wikiRepo.Close()
|
||||
if !isSideBar {
|
||||
buf.Reset()
|
||||
if err := markdown.Render(rctx, bytes.NewReader(sidebarContent), &buf); err != nil {
|
||||
if wikiRepo != nil {
|
||||
wikiRepo.Close()
|
||||
}
|
||||
ctx.ServerError("Render", err)
|
||||
return nil, nil
|
||||
}
|
||||
ctx.ServerError("Render", err)
|
||||
return nil, nil
|
||||
ctx.Data["sidebarPresent"] = sidebarContent != nil
|
||||
ctx.Data["sidebarEscapeStatus"], ctx.Data["sidebarContent"] = charset.EscapeControlString(buf.String())
|
||||
} else {
|
||||
ctx.Data["sidebarPresent"] = false
|
||||
}
|
||||
ctx.Data["sidebarPresent"] = sidebarContent != nil
|
||||
ctx.Data["sidebarEscapeStatus"], ctx.Data["sidebarContent"] = charset.EscapeControlString(buf.String())
|
||||
|
||||
buf.Reset()
|
||||
if err := markdown.Render(rctx, bytes.NewReader(footerContent), &buf); err != nil {
|
||||
if wikiRepo != nil {
|
||||
wikiRepo.Close()
|
||||
if !isFooter {
|
||||
buf.Reset()
|
||||
if err := markdown.Render(rctx, bytes.NewReader(footerContent), &buf); err != nil {
|
||||
if wikiRepo != nil {
|
||||
wikiRepo.Close()
|
||||
}
|
||||
ctx.ServerError("Render", err)
|
||||
return nil, nil
|
||||
}
|
||||
ctx.ServerError("Render", err)
|
||||
return nil, nil
|
||||
ctx.Data["footerPresent"] = footerContent != nil
|
||||
ctx.Data["footerEscapeStatus"], ctx.Data["footerContent"] = charset.EscapeControlString(buf.String())
|
||||
} else {
|
||||
ctx.Data["footerPresent"] = false
|
||||
}
|
||||
ctx.Data["footerPresent"] = footerContent != nil
|
||||
ctx.Data["footerEscapeStatus"], ctx.Data["footerContent"] = charset.EscapeControlString(buf.String())
|
||||
|
||||
// get commit count - wiki revisions
|
||||
commitsCount, _ := wikiRepo.FileCommitsCount("master", pageFilename)
|
||||
@@ -287,7 +308,6 @@ func renderRevisionPage(ctx *context.Context) (*git.Repository, *git.TreeEntry)
|
||||
ctx.Data["old_title"] = pageName
|
||||
ctx.Data["Title"] = pageName
|
||||
ctx.Data["title"] = pageName
|
||||
ctx.Data["RequireHighlightJS"] = true
|
||||
ctx.Data["Username"] = ctx.Repo.Owner.Name
|
||||
ctx.Data["Reponame"] = ctx.Repo.Repository.Name
|
||||
|
||||
@@ -363,7 +383,6 @@ func renderEditPage(ctx *context.Context) {
|
||||
ctx.Data["old_title"] = pageName
|
||||
ctx.Data["Title"] = pageName
|
||||
ctx.Data["title"] = pageName
|
||||
ctx.Data["RequireHighlightJS"] = true
|
||||
|
||||
// lookup filename in wiki - get filecontent, gitTree entry , real filename
|
||||
data, entry, _, noEntry := wikiContentsByName(ctx, commit, pageName)
|
||||
@@ -409,7 +428,6 @@ func WikiPost(ctx *context.Context) {
|
||||
|
||||
// Wiki renders single wiki page
|
||||
func Wiki(ctx *context.Context) {
|
||||
ctx.Data["PageIsWiki"] = true
|
||||
ctx.Data["CanWriteWiki"] = ctx.Repo.CanWrite(unit.TypeWiki) && !ctx.Repo.Repository.IsArchived
|
||||
|
||||
switch ctx.FormString("action") {
|
||||
@@ -474,7 +492,6 @@ func Wiki(ctx *context.Context) {
|
||||
|
||||
// WikiRevision renders file revision list of wiki page
|
||||
func WikiRevision(ctx *context.Context) {
|
||||
ctx.Data["PageIsWiki"] = true
|
||||
ctx.Data["CanWriteWiki"] = ctx.Repo.CanWrite(unit.TypeWiki) && !ctx.Repo.Repository.IsArchived
|
||||
|
||||
if !ctx.Repo.Repository.HasWiki() {
|
||||
@@ -519,7 +536,6 @@ func WikiPages(ctx *context.Context) {
|
||||
}
|
||||
|
||||
ctx.Data["Title"] = ctx.Tr("repo.wiki.pages")
|
||||
ctx.Data["PageIsWiki"] = true
|
||||
ctx.Data["CanWriteWiki"] = ctx.Repo.CanWrite(unit.TypeWiki) && !ctx.Repo.Repository.IsArchived
|
||||
|
||||
wikiRepo, commit, err := findWikiRepoCommit(ctx)
|
||||
@@ -612,7 +628,7 @@ func WikiRaw(ctx *context.Context) {
|
||||
}
|
||||
|
||||
if entry != nil {
|
||||
if err = common.ServeBlob(ctx, entry.Blob()); err != nil {
|
||||
if err = common.ServeBlob(ctx, entry.Blob(), time.Time{}); err != nil {
|
||||
ctx.ServerError("ServeBlob", err)
|
||||
}
|
||||
return
|
||||
@@ -624,7 +640,6 @@ func WikiRaw(ctx *context.Context) {
|
||||
// NewWiki render wiki create page
|
||||
func NewWiki(ctx *context.Context) {
|
||||
ctx.Data["Title"] = ctx.Tr("repo.wiki.new_page")
|
||||
ctx.Data["PageIsWiki"] = true
|
||||
|
||||
if !ctx.Repo.Repository.HasWiki() {
|
||||
ctx.Data["title"] = "Home"
|
||||
@@ -640,7 +655,6 @@ func NewWiki(ctx *context.Context) {
|
||||
func NewWikiPost(ctx *context.Context) {
|
||||
form := web.GetForm(ctx).(*forms.NewWikiForm)
|
||||
ctx.Data["Title"] = ctx.Tr("repo.wiki.new_page")
|
||||
ctx.Data["PageIsWiki"] = true
|
||||
|
||||
if ctx.HasError() {
|
||||
ctx.HTML(http.StatusOK, tplWikiNew)
|
||||
@@ -658,7 +672,7 @@ func NewWikiPost(ctx *context.Context) {
|
||||
form.Message = ctx.Tr("repo.editor.add", form.Title)
|
||||
}
|
||||
|
||||
if err := wiki_service.AddWikiPage(ctx, ctx.User, ctx.Repo.Repository, wikiName, form.Content, form.Message); err != nil {
|
||||
if err := wiki_service.AddWikiPage(ctx, ctx.Doer, ctx.Repo.Repository, wikiName, form.Content, form.Message); err != nil {
|
||||
if models.IsErrWikiReservedName(err) {
|
||||
ctx.Data["Err_Title"] = true
|
||||
ctx.RenderWithErr(ctx.Tr("repo.wiki.reserved_page", wikiName), tplWikiNew, &form)
|
||||
@@ -676,7 +690,6 @@ func NewWikiPost(ctx *context.Context) {
|
||||
|
||||
// EditWiki render wiki modify page
|
||||
func EditWiki(ctx *context.Context) {
|
||||
ctx.Data["PageIsWiki"] = true
|
||||
ctx.Data["PageIsWikiEdit"] = true
|
||||
|
||||
if !ctx.Repo.Repository.HasWiki() {
|
||||
@@ -696,7 +709,6 @@ func EditWiki(ctx *context.Context) {
|
||||
func EditWikiPost(ctx *context.Context) {
|
||||
form := web.GetForm(ctx).(*forms.NewWikiForm)
|
||||
ctx.Data["Title"] = ctx.Tr("repo.wiki.new_page")
|
||||
ctx.Data["PageIsWiki"] = true
|
||||
|
||||
if ctx.HasError() {
|
||||
ctx.HTML(http.StatusOK, tplWikiNew)
|
||||
@@ -710,7 +722,7 @@ func EditWikiPost(ctx *context.Context) {
|
||||
form.Message = ctx.Tr("repo.editor.update", form.Title)
|
||||
}
|
||||
|
||||
if err := wiki_service.EditWikiPage(ctx, ctx.User, ctx.Repo.Repository, oldWikiName, newWikiName, form.Content, form.Message); err != nil {
|
||||
if err := wiki_service.EditWikiPage(ctx, ctx.Doer, ctx.Repo.Repository, oldWikiName, newWikiName, form.Content, form.Message); err != nil {
|
||||
ctx.ServerError("EditWikiPage", err)
|
||||
return
|
||||
}
|
||||
@@ -725,7 +737,7 @@ func DeleteWikiPagePost(ctx *context.Context) {
|
||||
wikiName = "Home"
|
||||
}
|
||||
|
||||
if err := wiki_service.DeleteWikiPage(ctx, ctx.User, ctx.Repo.Repository, wikiName); err != nil {
|
||||
if err := wiki_service.DeleteWikiPage(ctx, ctx.Doer, ctx.Repo.Repository, wikiName); err != nil {
|
||||
ctx.ServerError("DeleteWikiPage", err)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -26,7 +26,7 @@ const (
|
||||
)
|
||||
|
||||
func wikiEntry(t *testing.T, repo *repo_model.Repository, wikiName string) *git.TreeEntry {
|
||||
wikiRepo, err := git.OpenRepository(repo.WikiPath())
|
||||
wikiRepo, err := git.OpenRepository(git.DefaultContext, repo.WikiPath())
|
||||
assert.NoError(t, err)
|
||||
defer wikiRepo.Close()
|
||||
commit, err := wikiRepo.GetBranchCommit("master")
|
||||
@@ -124,7 +124,7 @@ func TestNewWikiPost(t *testing.T) {
|
||||
Message: message,
|
||||
})
|
||||
NewWikiPost(ctx)
|
||||
assert.EqualValues(t, http.StatusFound, ctx.Resp.Status())
|
||||
assert.EqualValues(t, http.StatusSeeOther, ctx.Resp.Status())
|
||||
assertWikiExists(t, ctx.Repo.Repository, title)
|
||||
assert.Equal(t, wikiContent(t, ctx.Repo.Repository, title), content)
|
||||
}
|
||||
@@ -176,7 +176,7 @@ func TestEditWikiPost(t *testing.T) {
|
||||
Message: message,
|
||||
})
|
||||
EditWikiPost(ctx)
|
||||
assert.EqualValues(t, http.StatusFound, ctx.Resp.Status())
|
||||
assert.EqualValues(t, http.StatusSeeOther, ctx.Resp.Status())
|
||||
assertWikiExists(t, ctx.Repo.Repository, title)
|
||||
assert.Equal(t, wikiContent(t, ctx.Repo.Repository, title), content)
|
||||
if title != "Home" {
|
||||
|
||||
+78
-39
@@ -17,6 +17,8 @@ import (
|
||||
"code.gitea.io/gitea/models"
|
||||
asymkey_model "code.gitea.io/gitea/models/asymkey"
|
||||
"code.gitea.io/gitea/models/db"
|
||||
issues_model "code.gitea.io/gitea/models/issues"
|
||||
"code.gitea.io/gitea/models/organization"
|
||||
repo_model "code.gitea.io/gitea/models/repo"
|
||||
"code.gitea.io/gitea/models/unit"
|
||||
user_model "code.gitea.io/gitea/models/user"
|
||||
@@ -29,7 +31,6 @@ import (
|
||||
"code.gitea.io/gitea/modules/markup/markdown"
|
||||
"code.gitea.io/gitea/modules/setting"
|
||||
"code.gitea.io/gitea/modules/util"
|
||||
"code.gitea.io/gitea/routers/web/feed"
|
||||
issue_service "code.gitea.io/gitea/services/issue"
|
||||
pull_service "code.gitea.io/gitea/services/pull"
|
||||
|
||||
@@ -47,7 +48,7 @@ const (
|
||||
|
||||
// getDashboardContextUser finds out which context user dashboard is being viewed as .
|
||||
func getDashboardContextUser(ctx *context.Context) *user_model.User {
|
||||
ctxUser := ctx.User
|
||||
ctxUser := ctx.Doer
|
||||
orgName := ctx.Params(":org")
|
||||
if len(orgName) > 0 {
|
||||
ctxUser = ctx.Org.Organization.AsUser()
|
||||
@@ -55,7 +56,7 @@ func getDashboardContextUser(ctx *context.Context) *user_model.User {
|
||||
}
|
||||
ctx.Data["ContextUser"] = ctxUser
|
||||
|
||||
orgs, err := models.GetUserOrgsList(ctx.User)
|
||||
orgs, err := models.GetUserOrgsList(ctx.Doer)
|
||||
if err != nil {
|
||||
ctx.ServerError("GetUserOrgsList", err)
|
||||
return nil
|
||||
@@ -75,7 +76,7 @@ func Dashboard(ctx *context.Context) {
|
||||
ctx.Data["Title"] = ctxUser.DisplayName() + " - " + ctx.Tr("dashboard")
|
||||
ctx.Data["PageIsDashboard"] = true
|
||||
ctx.Data["PageIsNews"] = true
|
||||
cnt, _ := models.GetOrganizationCount(db.DefaultContext, ctxUser)
|
||||
cnt, _ := organization.GetOrganizationCount(ctx, ctxUser)
|
||||
ctx.Data["UserOrgsCount"] = cnt
|
||||
|
||||
var uid int64
|
||||
@@ -89,7 +90,7 @@ func Dashboard(ctx *context.Context) {
|
||||
}
|
||||
|
||||
if setting.Service.EnableUserHeatmap {
|
||||
data, err := models.GetUserHeatmapDataByUserTeam(ctxUser, ctx.Org.Team, ctx.User)
|
||||
data, err := models.GetUserHeatmapDataByUserTeam(ctxUser, ctx.Org.Team, ctx.Doer)
|
||||
if err != nil {
|
||||
ctx.ServerError("GetUserHeatmapDataByUserTeam", err)
|
||||
return
|
||||
@@ -100,11 +101,11 @@ func Dashboard(ctx *context.Context) {
|
||||
var err error
|
||||
var mirrors []*repo_model.Repository
|
||||
if ctxUser.IsOrganization() {
|
||||
var env models.AccessibleReposEnvironment
|
||||
var env organization.AccessibleReposEnvironment
|
||||
if ctx.Org.Team != nil {
|
||||
env = models.OrgFromUser(ctxUser).AccessibleTeamReposEnv(ctx.Org.Team)
|
||||
env = organization.OrgFromUser(ctxUser).AccessibleTeamReposEnv(ctx.Org.Team)
|
||||
} else {
|
||||
env, err = models.OrgFromUser(ctxUser).AccessibleReposEnv(ctx.User.ID)
|
||||
env, err = organization.AccessibleReposEnv(ctx, organization.OrgFromUser(ctxUser), ctx.Doer.ID)
|
||||
if err != nil {
|
||||
ctx.ServerError("AccessibleReposEnv", err)
|
||||
return
|
||||
@@ -131,17 +132,17 @@ func Dashboard(ctx *context.Context) {
|
||||
ctx.Data["MirrorCount"] = len(mirrors)
|
||||
ctx.Data["Mirrors"] = mirrors
|
||||
|
||||
ctx.Data["Feeds"] = feed.RetrieveFeeds(ctx, models.GetFeedsOptions{
|
||||
ctx.Data["Feeds"], err = models.GetFeeds(ctx, models.GetFeedsOptions{
|
||||
RequestedUser: ctxUser,
|
||||
RequestedTeam: ctx.Org.Team,
|
||||
Actor: ctx.User,
|
||||
Actor: ctx.Doer,
|
||||
IncludePrivate: true,
|
||||
OnlyPerformedBy: false,
|
||||
IncludeDeleted: false,
|
||||
Date: ctx.FormString("date"),
|
||||
})
|
||||
|
||||
if ctx.Written() {
|
||||
if err != nil {
|
||||
ctx.ServerError("GetFeeds", err)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -152,7 +153,7 @@ func Dashboard(ctx *context.Context) {
|
||||
func Milestones(ctx *context.Context) {
|
||||
if unit.TypeIssues.UnitGlobalDisabled() && unit.TypePullRequests.UnitGlobalDisabled() {
|
||||
log.Debug("Milestones overview page not available as both issues and pull requests are globally disabled")
|
||||
ctx.Status(404)
|
||||
ctx.Status(http.StatusNotFound)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -219,13 +220,13 @@ func Milestones(ctx *context.Context) {
|
||||
}
|
||||
}
|
||||
|
||||
counts, err := models.CountMilestonesByRepoCondAndKw(userRepoCond, keyword, isShowClosed)
|
||||
counts, err := issues_model.CountMilestonesByRepoCondAndKw(userRepoCond, keyword, isShowClosed)
|
||||
if err != nil {
|
||||
ctx.ServerError("CountMilestonesByRepoIDs", err)
|
||||
return
|
||||
}
|
||||
|
||||
milestones, err := models.SearchMilestones(repoCond, page, isShowClosed, sortType, keyword)
|
||||
milestones, err := issues_model.SearchMilestones(repoCond, page, isShowClosed, sortType, keyword)
|
||||
if err != nil {
|
||||
ctx.ServerError("SearchMilestones", err)
|
||||
return
|
||||
@@ -271,17 +272,17 @@ func Milestones(ctx *context.Context) {
|
||||
i++
|
||||
}
|
||||
|
||||
milestoneStats, err := models.GetMilestonesStatsByRepoCondAndKw(repoCond, keyword)
|
||||
milestoneStats, err := issues_model.GetMilestonesStatsByRepoCondAndKw(repoCond, keyword)
|
||||
if err != nil {
|
||||
ctx.ServerError("GetMilestoneStats", err)
|
||||
return
|
||||
}
|
||||
|
||||
var totalMilestoneStats *models.MilestonesStats
|
||||
var totalMilestoneStats *issues_model.MilestonesStats
|
||||
if len(repoIDs) == 0 {
|
||||
totalMilestoneStats = milestoneStats
|
||||
} else {
|
||||
totalMilestoneStats, err = models.GetMilestonesStatsByRepoCondAndKw(userRepoCond, keyword)
|
||||
totalMilestoneStats, err = issues_model.GetMilestonesStatsByRepoCondAndKw(userRepoCond, keyword)
|
||||
if err != nil {
|
||||
ctx.ServerError("GetMilestoneStats", err)
|
||||
return
|
||||
@@ -324,7 +325,7 @@ func Milestones(ctx *context.Context) {
|
||||
func Pulls(ctx *context.Context) {
|
||||
if unit.TypePullRequests.UnitGlobalDisabled() {
|
||||
log.Debug("Pull request overview page not available as it is globally disabled.")
|
||||
ctx.Status(404)
|
||||
ctx.Status(http.StatusNotFound)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -337,7 +338,7 @@ func Pulls(ctx *context.Context) {
|
||||
func Issues(ctx *context.Context) {
|
||||
if unit.TypeIssues.UnitGlobalDisabled() {
|
||||
log.Debug("Issues overview page not available as it is globally disabled.")
|
||||
ctx.Status(404)
|
||||
ctx.Status(http.StatusNotFound)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -363,7 +364,7 @@ func buildIssueOverview(ctx *context.Context, unitType unit.Type) {
|
||||
var (
|
||||
viewType string
|
||||
sortType = ctx.FormString("sort")
|
||||
filterMode = models.FilterModeAll
|
||||
filterMode int
|
||||
)
|
||||
|
||||
// --------------------------------------------------------------------------------
|
||||
@@ -389,8 +390,10 @@ func buildIssueOverview(ctx *context.Context, unitType unit.Type) {
|
||||
filterMode = models.FilterModeMention
|
||||
case "review_requested":
|
||||
filterMode = models.FilterModeReviewRequested
|
||||
case "your_repositories": // filterMode already set to All
|
||||
case "your_repositories":
|
||||
fallthrough
|
||||
default:
|
||||
filterMode = models.FilterModeYourRepositories
|
||||
viewType = "your_repositories"
|
||||
}
|
||||
|
||||
@@ -403,8 +406,8 @@ func buildIssueOverview(ctx *context.Context, unitType unit.Type) {
|
||||
// --------------------------------------------------------------------------
|
||||
|
||||
// Get repository IDs where User/Org/Team has access.
|
||||
var team *models.Team
|
||||
var org *models.Organization
|
||||
var team *organization.Team
|
||||
var org *organization.Organization
|
||||
if ctx.Org != nil {
|
||||
org = ctx.Org.Organization
|
||||
team = ctx.Org.Team
|
||||
@@ -417,19 +420,50 @@ func buildIssueOverview(ctx *context.Context, unitType unit.Type) {
|
||||
IsArchived: util.OptionalBoolFalse,
|
||||
Org: org,
|
||||
Team: team,
|
||||
User: ctx.User,
|
||||
User: ctx.Doer,
|
||||
}
|
||||
|
||||
// Search all repositories which
|
||||
//
|
||||
// As user:
|
||||
// - Owns the repository.
|
||||
// - Have collaborator permissions in repository.
|
||||
//
|
||||
// As org:
|
||||
// - Owns the repository.
|
||||
//
|
||||
// As team:
|
||||
// - Team org's owns the repository.
|
||||
// - Team has read permission to repository.
|
||||
repoOpts := &models.SearchRepoOptions{
|
||||
Actor: ctx.Doer,
|
||||
OwnerID: ctx.Doer.ID,
|
||||
Private: true,
|
||||
AllPublic: false,
|
||||
AllLimited: false,
|
||||
}
|
||||
|
||||
if ctxUser.IsOrganization() && ctx.Org.Team != nil {
|
||||
repoOpts.TeamID = ctx.Org.Team.ID
|
||||
}
|
||||
|
||||
switch filterMode {
|
||||
case models.FilterModeAll:
|
||||
case models.FilterModeAssign:
|
||||
opts.AssigneeID = ctx.User.ID
|
||||
opts.AssigneeID = ctx.Doer.ID
|
||||
case models.FilterModeCreate:
|
||||
opts.PosterID = ctx.User.ID
|
||||
opts.PosterID = ctx.Doer.ID
|
||||
case models.FilterModeMention:
|
||||
opts.MentionedID = ctx.User.ID
|
||||
opts.MentionedID = ctx.Doer.ID
|
||||
case models.FilterModeReviewRequested:
|
||||
opts.ReviewRequestedID = ctx.User.ID
|
||||
opts.ReviewRequestedID = ctx.Doer.ID
|
||||
case models.FilterModeYourRepositories:
|
||||
if ctxUser.IsOrganization() && ctx.Org.Team != nil {
|
||||
// Fixes a issue whereby the user's ID would be used
|
||||
// to check if it's in the team(which possible isn't the case).
|
||||
opts.User = nil
|
||||
}
|
||||
opts.RepoCond = models.SearchRepositoryCondition(repoOpts)
|
||||
}
|
||||
|
||||
// keyword holds the search term entered into the search field.
|
||||
@@ -493,7 +527,7 @@ func buildIssueOverview(ctx *context.Context, unitType unit.Type) {
|
||||
// Gets set when clicking filters on the issues overview page.
|
||||
repoIDs := getRepoIDs(ctx.FormString("repos"))
|
||||
if len(repoIDs) > 0 {
|
||||
opts.RepoIDs = repoIDs
|
||||
opts.RepoCond = builder.In("issue.repo_id", repoIDs)
|
||||
}
|
||||
|
||||
// ------------------------------
|
||||
@@ -539,7 +573,7 @@ func buildIssueOverview(ctx *context.Context, unitType unit.Type) {
|
||||
}
|
||||
}
|
||||
|
||||
commitStatus, err := pull_service.GetIssuesLastCommitStatus(ctx, issues)
|
||||
commitStatuses, lastStatus, err := pull_service.GetIssuesAllCommitStatus(ctx, issues)
|
||||
if err != nil {
|
||||
ctx.ServerError("GetIssuesLastCommitStatus", err)
|
||||
return
|
||||
@@ -551,7 +585,7 @@ func buildIssueOverview(ctx *context.Context, unitType unit.Type) {
|
||||
var issueStats *models.IssueStats
|
||||
if !forceEmpty {
|
||||
statsOpts := models.UserIssueStatsOptions{
|
||||
UserID: ctx.User.ID,
|
||||
UserID: ctx.Doer.ID,
|
||||
FilterMode: filterMode,
|
||||
IsPull: isPullList,
|
||||
IsClosed: isShowClosed,
|
||||
@@ -561,8 +595,12 @@ func buildIssueOverview(ctx *context.Context, unitType unit.Type) {
|
||||
Org: org,
|
||||
Team: team,
|
||||
}
|
||||
if len(repoIDs) > 0 {
|
||||
statsOpts.RepoIDs = repoIDs
|
||||
if filterMode == models.FilterModeYourRepositories {
|
||||
statsOpts.RepoCond = models.SearchRepositoryCondition(repoOpts)
|
||||
}
|
||||
// Detect when we only should search by team.
|
||||
if opts.User == nil {
|
||||
statsOpts.UserID = 0
|
||||
}
|
||||
issueStats, err = models.GetUserIssueStats(statsOpts)
|
||||
if err != nil {
|
||||
@@ -612,7 +650,8 @@ func buildIssueOverview(ctx *context.Context, unitType unit.Type) {
|
||||
}
|
||||
return 0
|
||||
}
|
||||
ctx.Data["CommitStatus"] = commitStatus
|
||||
ctx.Data["CommitLastStatus"] = lastStatus
|
||||
ctx.Data["CommitStatuses"] = commitStatuses
|
||||
ctx.Data["Repos"] = showRepos
|
||||
ctx.Data["Counts"] = issueCountByRepo
|
||||
ctx.Data["IssueStats"] = issueStats
|
||||
@@ -714,8 +753,8 @@ func loadRepoByIDs(ctxUser *user_model.User, issueCountByRepo map[int64]int64, u
|
||||
}
|
||||
|
||||
// ShowSSHKeys output all the ssh keys of user by uid
|
||||
func ShowSSHKeys(ctx *context.Context, uid int64) {
|
||||
keys, err := asymkey_model.ListPublicKeys(uid, db.ListOptions{})
|
||||
func ShowSSHKeys(ctx *context.Context) {
|
||||
keys, err := asymkey_model.ListPublicKeys(ctx.ContextUser.ID, db.ListOptions{})
|
||||
if err != nil {
|
||||
ctx.ServerError("ListPublicKeys", err)
|
||||
return
|
||||
@@ -730,8 +769,8 @@ func ShowSSHKeys(ctx *context.Context, uid int64) {
|
||||
}
|
||||
|
||||
// ShowGPGKeys output all the public GPG keys of user by uid
|
||||
func ShowGPGKeys(ctx *context.Context, uid int64) {
|
||||
keys, err := asymkey_model.ListGPGKeys(db.DefaultContext, uid, db.ListOptions{})
|
||||
func ShowGPGKeys(ctx *context.Context) {
|
||||
keys, err := asymkey_model.ListGPGKeys(ctx, ctx.ContextUser.ID, db.ListOptions{})
|
||||
if err != nil {
|
||||
ctx.ServerError("ListGPGKeys", err)
|
||||
return
|
||||
|
||||
@@ -26,7 +26,7 @@ func TestArchivedIssues(t *testing.T) {
|
||||
ctx.Req.Form.Set("state", "open")
|
||||
|
||||
// Assume: User 30 has access to two Repos with Issues, one of the Repos being archived.
|
||||
repos, _, _ := models.GetUserRepositories(&models.SearchRepoOptions{Actor: ctx.User})
|
||||
repos, _, _ := models.GetUserRepositories(&models.SearchRepoOptions{Actor: ctx.Doer})
|
||||
assert.Len(t, repos, 2)
|
||||
IsArchived := make(map[int64]bool)
|
||||
NumIssues := make(map[int64]int)
|
||||
|
||||
@@ -12,5 +12,7 @@ import (
|
||||
)
|
||||
|
||||
func TestMain(m *testing.M) {
|
||||
unittest.MainTest(m, filepath.Join("..", "..", ".."))
|
||||
unittest.MainTest(m, &unittest.TestOptions{
|
||||
GiteaRootPath: filepath.Join("..", "..", ".."),
|
||||
})
|
||||
}
|
||||
|
||||
@@ -15,6 +15,7 @@ import (
|
||||
"code.gitea.io/gitea/modules/base"
|
||||
"code.gitea.io/gitea/modules/context"
|
||||
"code.gitea.io/gitea/modules/setting"
|
||||
"code.gitea.io/gitea/modules/structs"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -33,7 +34,7 @@ func GetNotificationCount(c *context.Context) {
|
||||
}
|
||||
|
||||
c.Data["NotificationUnreadCount"] = func() int64 {
|
||||
count, err := models.GetNotificationCount(c.User, models.NotificationStatusUnread)
|
||||
count, err := models.GetNotificationCount(c.Doer, models.NotificationStatusUnread)
|
||||
if err != nil {
|
||||
c.ServerError("GetNotificationCount", err)
|
||||
return -1
|
||||
@@ -78,7 +79,7 @@ func getNotifications(c *context.Context) {
|
||||
status = models.NotificationStatusUnread
|
||||
}
|
||||
|
||||
total, err := models.GetNotificationCount(c.User, status)
|
||||
total, err := models.GetNotificationCount(c.Doer, status)
|
||||
if err != nil {
|
||||
c.ServerError("ErrGetNotificationCount", err)
|
||||
return
|
||||
@@ -92,7 +93,7 @@ func getNotifications(c *context.Context) {
|
||||
}
|
||||
|
||||
statuses := []models.NotificationStatus{status, models.NotificationStatusPinned}
|
||||
notifications, err := models.NotificationsForUser(c.User, statuses, page, perPage)
|
||||
notifications, err := models.NotificationsForUser(c.Doer, statuses, page, perPage)
|
||||
if err != nil {
|
||||
c.ServerError("ErrNotificationsForUser", err)
|
||||
return
|
||||
@@ -161,7 +162,7 @@ func NotificationStatusPost(c *context.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
if _, err := models.SetNotificationStatus(notificationID, c.User, status); err != nil {
|
||||
if _, err := models.SetNotificationStatus(notificationID, c.Doer, status); err != nil {
|
||||
c.ServerError("SetNotificationStatus", err)
|
||||
return
|
||||
}
|
||||
@@ -183,7 +184,7 @@ func NotificationStatusPost(c *context.Context) {
|
||||
|
||||
// NotificationPurgePost is a route for 'purging' the list of notifications - marking all unread as read
|
||||
func NotificationPurgePost(c *context.Context) {
|
||||
err := models.UpdateNotificationStatuses(c.User, models.NotificationStatusUnread, models.NotificationStatusRead)
|
||||
err := models.UpdateNotificationStatuses(c.Doer, models.NotificationStatusUnread, models.NotificationStatusRead)
|
||||
if err != nil {
|
||||
c.ServerError("ErrUpdateNotificationStatuses", err)
|
||||
return
|
||||
@@ -191,3 +192,8 @@ func NotificationPurgePost(c *context.Context) {
|
||||
|
||||
c.Redirect(setting.AppSubURL+"/notifications", http.StatusSeeOther)
|
||||
}
|
||||
|
||||
// NewAvailable returns the notification counts
|
||||
func NewAvailable(ctx *context.Context) {
|
||||
ctx.JSON(http.StatusOK, structs.NotificationCount{New: models.CountUnread(ctx.Doer)})
|
||||
}
|
||||
|
||||
@@ -0,0 +1,376 @@
|
||||
// Copyright 2021 The Gitea Authors. All rights reserved.
|
||||
// Use of this source code is governed by a MIT-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package user
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"code.gitea.io/gitea/models"
|
||||
"code.gitea.io/gitea/models/db"
|
||||
packages_model "code.gitea.io/gitea/models/packages"
|
||||
container_model "code.gitea.io/gitea/models/packages/container"
|
||||
"code.gitea.io/gitea/models/perm"
|
||||
repo_model "code.gitea.io/gitea/models/repo"
|
||||
"code.gitea.io/gitea/modules/base"
|
||||
"code.gitea.io/gitea/modules/context"
|
||||
"code.gitea.io/gitea/modules/log"
|
||||
"code.gitea.io/gitea/modules/setting"
|
||||
"code.gitea.io/gitea/modules/web"
|
||||
"code.gitea.io/gitea/services/forms"
|
||||
packages_service "code.gitea.io/gitea/services/packages"
|
||||
)
|
||||
|
||||
const (
|
||||
tplPackagesList base.TplName = "user/overview/packages"
|
||||
tplPackagesView base.TplName = "package/view"
|
||||
tplPackageVersionList base.TplName = "user/overview/package_versions"
|
||||
tplPackagesSettings base.TplName = "package/settings"
|
||||
)
|
||||
|
||||
// ListPackages displays a list of all packages of the context user
|
||||
func ListPackages(ctx *context.Context) {
|
||||
page := ctx.FormInt("page")
|
||||
if page <= 1 {
|
||||
page = 1
|
||||
}
|
||||
query := ctx.FormTrim("q")
|
||||
packageType := ctx.FormTrim("type")
|
||||
|
||||
pvs, total, err := packages_model.SearchLatestVersions(ctx, &packages_model.PackageSearchOptions{
|
||||
Paginator: &db.ListOptions{
|
||||
PageSize: setting.UI.PackagesPagingNum,
|
||||
Page: page,
|
||||
},
|
||||
OwnerID: ctx.ContextUser.ID,
|
||||
Type: packages_model.Type(packageType),
|
||||
Name: packages_model.SearchValue{Value: query},
|
||||
})
|
||||
if err != nil {
|
||||
ctx.ServerError("SearchLatestVersions", err)
|
||||
return
|
||||
}
|
||||
|
||||
pds, err := packages_model.GetPackageDescriptors(ctx, pvs)
|
||||
if err != nil {
|
||||
ctx.ServerError("GetPackageDescriptors", err)
|
||||
return
|
||||
}
|
||||
|
||||
repositoryAccessMap := make(map[int64]bool)
|
||||
for _, pd := range pds {
|
||||
if pd.Repository == nil {
|
||||
continue
|
||||
}
|
||||
if _, has := repositoryAccessMap[pd.Repository.ID]; has {
|
||||
continue
|
||||
}
|
||||
|
||||
permission, err := models.GetUserRepoPermission(ctx, pd.Repository, ctx.Doer)
|
||||
if err != nil {
|
||||
ctx.ServerError("GetUserRepoPermission", err)
|
||||
return
|
||||
}
|
||||
repositoryAccessMap[pd.Repository.ID] = permission.HasAccess()
|
||||
}
|
||||
|
||||
hasPackages, err := packages_model.HasOwnerPackages(ctx, ctx.ContextUser.ID)
|
||||
if err != nil {
|
||||
ctx.ServerError("HasOwnerPackages", err)
|
||||
return
|
||||
}
|
||||
|
||||
ctx.Data["Title"] = ctx.Tr("packages.title")
|
||||
ctx.Data["IsPackagesPage"] = true
|
||||
ctx.Data["ContextUser"] = ctx.ContextUser
|
||||
ctx.Data["Query"] = query
|
||||
ctx.Data["PackageType"] = packageType
|
||||
ctx.Data["HasPackages"] = hasPackages
|
||||
ctx.Data["PackageDescriptors"] = pds
|
||||
ctx.Data["Total"] = total
|
||||
ctx.Data["RepositoryAccessMap"] = repositoryAccessMap
|
||||
|
||||
pager := context.NewPagination(int(total), setting.UI.PackagesPagingNum, page, 5)
|
||||
pager.AddParam(ctx, "q", "Query")
|
||||
pager.AddParam(ctx, "type", "PackageType")
|
||||
ctx.Data["Page"] = pager
|
||||
|
||||
ctx.HTML(http.StatusOK, tplPackagesList)
|
||||
}
|
||||
|
||||
// RedirectToLastVersion redirects to the latest package version
|
||||
func RedirectToLastVersion(ctx *context.Context) {
|
||||
p, err := packages_model.GetPackageByName(ctx, ctx.Package.Owner.ID, packages_model.Type(ctx.Params("type")), ctx.Params("name"))
|
||||
if err != nil {
|
||||
if err == packages_model.ErrPackageNotExist {
|
||||
ctx.NotFound("GetPackageByName", err)
|
||||
} else {
|
||||
ctx.ServerError("GetPackageByName", err)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
pvs, _, err := packages_model.SearchLatestVersions(ctx, &packages_model.PackageSearchOptions{
|
||||
PackageID: p.ID,
|
||||
})
|
||||
if err != nil {
|
||||
ctx.ServerError("GetPackageByName", err)
|
||||
return
|
||||
}
|
||||
if len(pvs) == 0 {
|
||||
ctx.NotFound("", err)
|
||||
return
|
||||
}
|
||||
|
||||
pd, err := packages_model.GetPackageDescriptor(ctx, pvs[0])
|
||||
if err != nil {
|
||||
ctx.ServerError("GetPackageDescriptor", err)
|
||||
return
|
||||
}
|
||||
|
||||
ctx.Redirect(pd.FullWebLink())
|
||||
}
|
||||
|
||||
// ViewPackageVersion displays a single package version
|
||||
func ViewPackageVersion(ctx *context.Context) {
|
||||
pd := ctx.Package.Descriptor
|
||||
|
||||
ctx.Data["Title"] = pd.Package.Name
|
||||
ctx.Data["IsPackagesPage"] = true
|
||||
ctx.Data["ContextUser"] = ctx.ContextUser
|
||||
ctx.Data["PackageDescriptor"] = pd
|
||||
|
||||
var (
|
||||
total int64
|
||||
pvs []*packages_model.PackageVersion
|
||||
err error
|
||||
)
|
||||
switch pd.Package.Type {
|
||||
case packages_model.TypeContainer:
|
||||
ctx.Data["RegistryHost"] = setting.Packages.RegistryHost
|
||||
|
||||
pvs, total, err = container_model.SearchImageTags(ctx, &container_model.ImageTagsSearchOptions{
|
||||
Paginator: db.NewAbsoluteListOptions(0, 5),
|
||||
PackageID: pd.Package.ID,
|
||||
IsTagged: true,
|
||||
})
|
||||
default:
|
||||
pvs, total, err = packages_model.SearchVersions(ctx, &packages_model.PackageSearchOptions{
|
||||
Paginator: db.NewAbsoluteListOptions(0, 5),
|
||||
PackageID: pd.Package.ID,
|
||||
})
|
||||
if err != nil {
|
||||
ctx.ServerError("SearchVersions", err)
|
||||
return
|
||||
}
|
||||
}
|
||||
if err != nil {
|
||||
ctx.ServerError("", err)
|
||||
return
|
||||
}
|
||||
|
||||
ctx.Data["LatestVersions"] = pvs
|
||||
ctx.Data["TotalVersionCount"] = total
|
||||
|
||||
ctx.Data["CanWritePackages"] = ctx.Package.AccessMode >= perm.AccessModeWrite || ctx.IsUserSiteAdmin()
|
||||
|
||||
hasRepositoryAccess := false
|
||||
if pd.Repository != nil {
|
||||
permission, err := models.GetUserRepoPermission(ctx, pd.Repository, ctx.Doer)
|
||||
if err != nil {
|
||||
ctx.ServerError("GetUserRepoPermission", err)
|
||||
return
|
||||
}
|
||||
hasRepositoryAccess = permission.HasAccess()
|
||||
}
|
||||
ctx.Data["HasRepositoryAccess"] = hasRepositoryAccess
|
||||
|
||||
ctx.HTML(http.StatusOK, tplPackagesView)
|
||||
}
|
||||
|
||||
// ListPackageVersions lists all versions of a package
|
||||
func ListPackageVersions(ctx *context.Context) {
|
||||
p, err := packages_model.GetPackageByName(ctx, ctx.Package.Owner.ID, packages_model.Type(ctx.Params("type")), ctx.Params("name"))
|
||||
if err != nil {
|
||||
if err == packages_model.ErrPackageNotExist {
|
||||
ctx.NotFound("GetPackageByName", err)
|
||||
} else {
|
||||
ctx.ServerError("GetPackageByName", err)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
page := ctx.FormInt("page")
|
||||
if page <= 1 {
|
||||
page = 1
|
||||
}
|
||||
pagination := &db.ListOptions{
|
||||
PageSize: setting.UI.PackagesPagingNum,
|
||||
Page: page,
|
||||
}
|
||||
|
||||
query := ctx.FormTrim("q")
|
||||
|
||||
ctx.Data["Title"] = ctx.Tr("packages.title")
|
||||
ctx.Data["IsPackagesPage"] = true
|
||||
ctx.Data["ContextUser"] = ctx.ContextUser
|
||||
ctx.Data["PackageDescriptor"] = &packages_model.PackageDescriptor{
|
||||
Package: p,
|
||||
Owner: ctx.Package.Owner,
|
||||
}
|
||||
ctx.Data["Query"] = query
|
||||
|
||||
pagerParams := map[string]string{
|
||||
"q": query,
|
||||
}
|
||||
|
||||
var (
|
||||
total int64
|
||||
pvs []*packages_model.PackageVersion
|
||||
)
|
||||
switch p.Type {
|
||||
case packages_model.TypeContainer:
|
||||
tagged := ctx.FormTrim("tagged")
|
||||
|
||||
pagerParams["tagged"] = tagged
|
||||
ctx.Data["Tagged"] = tagged
|
||||
|
||||
pvs, total, err = container_model.SearchImageTags(ctx, &container_model.ImageTagsSearchOptions{
|
||||
Paginator: pagination,
|
||||
PackageID: p.ID,
|
||||
Query: query,
|
||||
IsTagged: tagged == "" || tagged == "tagged",
|
||||
})
|
||||
if err != nil {
|
||||
ctx.ServerError("SearchImageTags", err)
|
||||
return
|
||||
}
|
||||
default:
|
||||
pvs, total, err = packages_model.SearchVersions(ctx, &packages_model.PackageSearchOptions{
|
||||
Paginator: pagination,
|
||||
PackageID: p.ID,
|
||||
Version: packages_model.SearchValue{
|
||||
ExactMatch: false,
|
||||
Value: query,
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
ctx.ServerError("SearchVersions", err)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
ctx.Data["PackageDescriptors"], err = packages_model.GetPackageDescriptors(ctx, pvs)
|
||||
if err != nil {
|
||||
ctx.ServerError("GetPackageDescriptors", err)
|
||||
return
|
||||
}
|
||||
|
||||
ctx.Data["Total"] = total
|
||||
|
||||
pager := context.NewPagination(int(total), setting.UI.PackagesPagingNum, page, 5)
|
||||
for k, v := range pagerParams {
|
||||
pager.AddParamString(k, v)
|
||||
}
|
||||
ctx.Data["Page"] = pager
|
||||
|
||||
ctx.HTML(http.StatusOK, tplPackageVersionList)
|
||||
}
|
||||
|
||||
// PackageSettings displays the package settings page
|
||||
func PackageSettings(ctx *context.Context) {
|
||||
pd := ctx.Package.Descriptor
|
||||
|
||||
ctx.Data["Title"] = pd.Package.Name
|
||||
ctx.Data["IsPackagesPage"] = true
|
||||
ctx.Data["ContextUser"] = ctx.ContextUser
|
||||
ctx.Data["PackageDescriptor"] = pd
|
||||
|
||||
repos, _, _ := models.GetUserRepositories(&models.SearchRepoOptions{
|
||||
Actor: pd.Owner,
|
||||
Private: true,
|
||||
})
|
||||
ctx.Data["Repos"] = repos
|
||||
ctx.Data["CanWritePackages"] = ctx.Package.AccessMode >= perm.AccessModeWrite || ctx.IsUserSiteAdmin()
|
||||
|
||||
ctx.HTML(http.StatusOK, tplPackagesSettings)
|
||||
}
|
||||
|
||||
// PackageSettingsPost updates the package settings
|
||||
func PackageSettingsPost(ctx *context.Context) {
|
||||
pd := ctx.Package.Descriptor
|
||||
|
||||
form := web.GetForm(ctx).(*forms.PackageSettingForm)
|
||||
switch form.Action {
|
||||
case "link":
|
||||
success := func() bool {
|
||||
repoID := int64(0)
|
||||
if form.RepoID != 0 {
|
||||
repo, err := repo_model.GetRepositoryByID(form.RepoID)
|
||||
if err != nil {
|
||||
log.Error("Error getting repository: %v", err)
|
||||
return false
|
||||
}
|
||||
|
||||
if repo.OwnerID != pd.Owner.ID {
|
||||
return false
|
||||
}
|
||||
|
||||
repoID = repo.ID
|
||||
}
|
||||
|
||||
if err := packages_model.SetRepositoryLink(ctx, pd.Package.ID, repoID); err != nil {
|
||||
log.Error("Error updating package: %v", err)
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
}()
|
||||
|
||||
if success {
|
||||
ctx.Flash.Success(ctx.Tr("packages.settings.link.success"))
|
||||
} else {
|
||||
ctx.Flash.Error(ctx.Tr("packages.settings.link.error"))
|
||||
}
|
||||
|
||||
ctx.Redirect(ctx.Link)
|
||||
return
|
||||
case "delete":
|
||||
err := packages_service.RemovePackageVersion(ctx.Doer, ctx.Package.Descriptor.Version)
|
||||
if err != nil {
|
||||
log.Error("Error deleting package: %v", err)
|
||||
ctx.Flash.Error(ctx.Tr("packages.settings.delete.error"))
|
||||
} else {
|
||||
ctx.Flash.Success(ctx.Tr("packages.settings.delete.success"))
|
||||
}
|
||||
|
||||
ctx.Redirect(ctx.Package.Owner.HTMLURL() + "/-/packages")
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// DownloadPackageFile serves the content of a package file
|
||||
func DownloadPackageFile(ctx *context.Context) {
|
||||
pf, err := packages_model.GetFileForVersionByID(ctx, ctx.Package.Descriptor.Version.ID, ctx.ParamsInt64(":fileid"))
|
||||
if err != nil {
|
||||
if err == packages_model.ErrPackageFileNotExist {
|
||||
ctx.NotFound("", err)
|
||||
} else {
|
||||
ctx.ServerError("GetFileForVersionByID", err)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
s, _, err := packages_service.GetPackageFileStream(
|
||||
ctx,
|
||||
pf,
|
||||
)
|
||||
if err != nil {
|
||||
ctx.ServerError("GetPackageFileStream", err)
|
||||
return
|
||||
}
|
||||
defer s.Close()
|
||||
|
||||
ctx.ServeStream(s, pf.Name)
|
||||
}
|
||||
+47
-131
@@ -8,11 +8,12 @@ package user
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"path"
|
||||
"strings"
|
||||
|
||||
"code.gitea.io/gitea/models"
|
||||
"code.gitea.io/gitea/models/db"
|
||||
"code.gitea.io/gitea/models/organization"
|
||||
project_model "code.gitea.io/gitea/models/project"
|
||||
repo_model "code.gitea.io/gitea/models/repo"
|
||||
user_model "code.gitea.io/gitea/models/user"
|
||||
"code.gitea.io/gitea/modules/context"
|
||||
@@ -24,133 +25,51 @@ import (
|
||||
"code.gitea.io/gitea/routers/web/org"
|
||||
)
|
||||
|
||||
// GetUserByName get user by name
|
||||
func GetUserByName(ctx *context.Context, name string) *user_model.User {
|
||||
user, err := user_model.GetUserByName(name)
|
||||
if err != nil {
|
||||
if user_model.IsErrUserNotExist(err) {
|
||||
if redirectUserID, err := user_model.LookupUserRedirect(name); err == nil {
|
||||
context.RedirectToUser(ctx, name, redirectUserID)
|
||||
} else {
|
||||
ctx.NotFound("GetUserByName", err)
|
||||
}
|
||||
} else {
|
||||
ctx.ServerError("GetUserByName", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
return user
|
||||
}
|
||||
|
||||
// GetUserByParams returns user whose name is presented in URL paramenter.
|
||||
func GetUserByParams(ctx *context.Context) *user_model.User {
|
||||
return GetUserByName(ctx, ctx.Params(":username"))
|
||||
}
|
||||
|
||||
// Profile render user's profile page
|
||||
func Profile(ctx *context.Context) {
|
||||
uname := ctx.Params(":username")
|
||||
|
||||
// Special handle for FireFox requests favicon.ico.
|
||||
if uname == "favicon.ico" {
|
||||
ctx.ServeFile(path.Join(setting.StaticRootPath, "public/img/favicon.png"))
|
||||
if strings.Contains(ctx.Req.Header.Get("Accept"), "application/rss+xml") {
|
||||
feed.ShowUserFeedRSS(ctx)
|
||||
return
|
||||
}
|
||||
if strings.Contains(ctx.Req.Header.Get("Accept"), "application/atom+xml") {
|
||||
feed.ShowUserFeedAtom(ctx)
|
||||
return
|
||||
}
|
||||
|
||||
if strings.HasSuffix(uname, ".png") {
|
||||
ctx.Error(http.StatusNotFound)
|
||||
return
|
||||
}
|
||||
|
||||
isShowKeys := false
|
||||
if strings.HasSuffix(uname, ".keys") {
|
||||
isShowKeys = true
|
||||
uname = strings.TrimSuffix(uname, ".keys")
|
||||
}
|
||||
|
||||
isShowGPG := false
|
||||
if strings.HasSuffix(uname, ".gpg") {
|
||||
isShowGPG = true
|
||||
uname = strings.TrimSuffix(uname, ".gpg")
|
||||
}
|
||||
|
||||
showFeedType := ""
|
||||
if strings.HasSuffix(uname, ".rss") {
|
||||
showFeedType = "rss"
|
||||
uname = strings.TrimSuffix(uname, ".rss")
|
||||
} else if strings.Contains(ctx.Req.Header.Get("Accept"), "application/rss+xml") {
|
||||
showFeedType = "rss"
|
||||
}
|
||||
if strings.HasSuffix(uname, ".atom") {
|
||||
showFeedType = "atom"
|
||||
uname = strings.TrimSuffix(uname, ".atom")
|
||||
} else if strings.Contains(ctx.Req.Header.Get("Accept"), "application/atom+xml") {
|
||||
showFeedType = "atom"
|
||||
}
|
||||
|
||||
ctxUser := GetUserByName(ctx, uname)
|
||||
if ctx.Written() {
|
||||
return
|
||||
}
|
||||
|
||||
if ctxUser.IsOrganization() {
|
||||
/*
|
||||
// TODO: enable after rss.RetrieveFeeds() do handle org correctly
|
||||
// Show Org RSS feed
|
||||
if len(showFeedType) != 0 {
|
||||
rss.ShowUserFeed(ctx, ctxUser, showFeedType)
|
||||
return
|
||||
}
|
||||
*/
|
||||
|
||||
if ctx.ContextUser.IsOrganization() {
|
||||
org.Home(ctx)
|
||||
return
|
||||
}
|
||||
|
||||
// check view permissions
|
||||
if !models.IsUserVisibleToViewer(ctxUser, ctx.User) {
|
||||
ctx.NotFound("user", fmt.Errorf(uname))
|
||||
if !user_model.IsUserVisibleToViewer(ctx.ContextUser, ctx.Doer) {
|
||||
ctx.NotFound("user", fmt.Errorf(ctx.ContextUser.Name))
|
||||
return
|
||||
}
|
||||
|
||||
// Show SSH keys.
|
||||
if isShowKeys {
|
||||
ShowSSHKeys(ctx, ctxUser.ID)
|
||||
return
|
||||
}
|
||||
|
||||
// Show GPG keys.
|
||||
if isShowGPG {
|
||||
ShowGPGKeys(ctx, ctxUser.ID)
|
||||
return
|
||||
}
|
||||
|
||||
// Show User RSS feed
|
||||
if len(showFeedType) != 0 {
|
||||
feed.ShowUserFeed(ctx, ctxUser, showFeedType)
|
||||
return
|
||||
}
|
||||
// advertise feed via meta tag
|
||||
ctx.Data["FeedURL"] = ctx.ContextUser.HTMLURL()
|
||||
|
||||
// Show OpenID URIs
|
||||
openIDs, err := user_model.GetUserOpenIDs(ctxUser.ID)
|
||||
openIDs, err := user_model.GetUserOpenIDs(ctx.ContextUser.ID)
|
||||
if err != nil {
|
||||
ctx.ServerError("GetUserOpenIDs", err)
|
||||
return
|
||||
}
|
||||
|
||||
var isFollowing bool
|
||||
if ctx.User != nil && ctxUser != nil {
|
||||
isFollowing = user_model.IsFollowing(ctx.User.ID, ctxUser.ID)
|
||||
if ctx.Doer != nil {
|
||||
isFollowing = user_model.IsFollowing(ctx.Doer.ID, ctx.ContextUser.ID)
|
||||
}
|
||||
|
||||
ctx.Data["Title"] = ctxUser.DisplayName()
|
||||
ctx.Data["Title"] = ctx.ContextUser.DisplayName()
|
||||
ctx.Data["PageIsUserProfile"] = true
|
||||
ctx.Data["Owner"] = ctxUser
|
||||
ctx.Data["Owner"] = ctx.ContextUser
|
||||
ctx.Data["OpenIDs"] = openIDs
|
||||
ctx.Data["IsFollowing"] = isFollowing
|
||||
|
||||
if setting.Service.EnableUserHeatmap {
|
||||
data, err := models.GetUserHeatmapDataByUser(ctxUser, ctx.User)
|
||||
data, err := models.GetUserHeatmapDataByUser(ctx.ContextUser, ctx.Doer)
|
||||
if err != nil {
|
||||
ctx.ServerError("GetUserHeatmapDataByUser", err)
|
||||
return
|
||||
@@ -158,13 +77,13 @@ func Profile(ctx *context.Context) {
|
||||
ctx.Data["HeatmapData"] = data
|
||||
}
|
||||
|
||||
if len(ctxUser.Description) != 0 {
|
||||
if len(ctx.ContextUser.Description) != 0 {
|
||||
content, err := markdown.RenderString(&markup.RenderContext{
|
||||
URLPrefix: ctx.Repo.RepoLink,
|
||||
Metas: map[string]string{"mode": "document"},
|
||||
GitRepo: ctx.Repo.GitRepo,
|
||||
Ctx: ctx,
|
||||
}, ctxUser.Description)
|
||||
}, ctx.ContextUser.Description)
|
||||
if err != nil {
|
||||
ctx.ServerError("RenderString", err)
|
||||
return
|
||||
@@ -172,10 +91,10 @@ func Profile(ctx *context.Context) {
|
||||
ctx.Data["RenderedDescription"] = content
|
||||
}
|
||||
|
||||
showPrivate := ctx.IsSigned && (ctx.User.IsAdmin || ctx.User.ID == ctxUser.ID)
|
||||
showPrivate := ctx.IsSigned && (ctx.Doer.IsAdmin || ctx.Doer.ID == ctx.ContextUser.ID)
|
||||
|
||||
orgs, err := models.FindOrgs(models.FindOrgOptions{
|
||||
UserID: ctxUser.ID,
|
||||
orgs, err := organization.FindOrgs(organization.FindOrgOptions{
|
||||
UserID: ctx.ContextUser.ID,
|
||||
IncludePrivate: showPrivate,
|
||||
})
|
||||
if err != nil {
|
||||
@@ -184,7 +103,7 @@ func Profile(ctx *context.Context) {
|
||||
}
|
||||
|
||||
ctx.Data["Orgs"] = orgs
|
||||
ctx.Data["HasOrgsVisible"] = models.HasOrgsVisible(orgs, ctx.User)
|
||||
ctx.Data["HasOrgsVisible"] = organization.HasOrgsVisible(orgs, ctx.Doer)
|
||||
|
||||
tab := ctx.FormString("tab")
|
||||
ctx.Data["TabName"] = tab
|
||||
@@ -238,7 +157,7 @@ func Profile(ctx *context.Context) {
|
||||
|
||||
switch tab {
|
||||
case "followers":
|
||||
items, err := user_model.GetUserFollowers(ctxUser, db.ListOptions{
|
||||
items, err := user_model.GetUserFollowers(ctx.ContextUser, db.ListOptions{
|
||||
PageSize: setting.UI.User.RepoPagingNum,
|
||||
Page: page,
|
||||
})
|
||||
@@ -248,9 +167,9 @@ func Profile(ctx *context.Context) {
|
||||
}
|
||||
ctx.Data["Cards"] = items
|
||||
|
||||
total = ctxUser.NumFollowers
|
||||
total = ctx.ContextUser.NumFollowers
|
||||
case "following":
|
||||
items, err := user_model.GetUserFollowing(ctxUser, db.ListOptions{
|
||||
items, err := user_model.GetUserFollowing(ctx.ContextUser, db.ListOptions{
|
||||
PageSize: setting.UI.User.RepoPagingNum,
|
||||
Page: page,
|
||||
})
|
||||
@@ -260,17 +179,18 @@ func Profile(ctx *context.Context) {
|
||||
}
|
||||
ctx.Data["Cards"] = items
|
||||
|
||||
total = ctxUser.NumFollowing
|
||||
total = ctx.ContextUser.NumFollowing
|
||||
case "activity":
|
||||
ctx.Data["Feeds"] = feed.RetrieveFeeds(ctx, models.GetFeedsOptions{
|
||||
RequestedUser: ctxUser,
|
||||
Actor: ctx.User,
|
||||
ctx.Data["Feeds"], err = models.GetFeeds(ctx, models.GetFeedsOptions{
|
||||
RequestedUser: ctx.ContextUser,
|
||||
Actor: ctx.Doer,
|
||||
IncludePrivate: showPrivate,
|
||||
OnlyPerformedBy: true,
|
||||
IncludeDeleted: false,
|
||||
Date: ctx.FormString("date"),
|
||||
})
|
||||
if ctx.Written() {
|
||||
if err != nil {
|
||||
ctx.ServerError("GetFeeds", err)
|
||||
return
|
||||
}
|
||||
case "stars":
|
||||
@@ -280,11 +200,11 @@ func Profile(ctx *context.Context) {
|
||||
PageSize: setting.UI.User.RepoPagingNum,
|
||||
Page: page,
|
||||
},
|
||||
Actor: ctx.User,
|
||||
Actor: ctx.Doer,
|
||||
Keyword: keyword,
|
||||
OrderBy: orderBy,
|
||||
Private: ctx.IsSigned,
|
||||
StarredByID: ctxUser.ID,
|
||||
StarredByID: ctx.ContextUser.ID,
|
||||
Collaborate: util.OptionalBoolFalse,
|
||||
TopicOnly: topicOnly,
|
||||
Language: language,
|
||||
@@ -297,10 +217,10 @@ func Profile(ctx *context.Context) {
|
||||
|
||||
total = int(count)
|
||||
case "projects":
|
||||
ctx.Data["OpenProjects"], _, err = models.GetProjects(models.ProjectSearchOptions{
|
||||
ctx.Data["OpenProjects"], _, err = project_model.GetProjects(project_model.SearchOptions{
|
||||
Page: -1,
|
||||
IsClosed: util.OptionalBoolFalse,
|
||||
Type: models.ProjectTypeIndividual,
|
||||
Type: project_model.TypeIndividual,
|
||||
})
|
||||
if err != nil {
|
||||
ctx.ServerError("GetProjects", err)
|
||||
@@ -312,11 +232,11 @@ func Profile(ctx *context.Context) {
|
||||
PageSize: setting.UI.User.RepoPagingNum,
|
||||
Page: page,
|
||||
},
|
||||
Actor: ctx.User,
|
||||
Actor: ctx.Doer,
|
||||
Keyword: keyword,
|
||||
OrderBy: orderBy,
|
||||
Private: ctx.IsSigned,
|
||||
WatchedByID: ctxUser.ID,
|
||||
WatchedByID: ctx.ContextUser.ID,
|
||||
Collaborate: util.OptionalBoolFalse,
|
||||
TopicOnly: topicOnly,
|
||||
Language: language,
|
||||
@@ -334,9 +254,9 @@ func Profile(ctx *context.Context) {
|
||||
PageSize: setting.UI.User.RepoPagingNum,
|
||||
Page: page,
|
||||
},
|
||||
Actor: ctx.User,
|
||||
Actor: ctx.Doer,
|
||||
Keyword: keyword,
|
||||
OwnerID: ctxUser.ID,
|
||||
OwnerID: ctx.ContextUser.ID,
|
||||
OrderBy: orderBy,
|
||||
Private: ctx.IsSigned,
|
||||
Collaborate: util.OptionalBoolFalse,
|
||||
@@ -360,25 +280,21 @@ func Profile(ctx *context.Context) {
|
||||
pager.AddParam(ctx, "language", "Language")
|
||||
}
|
||||
ctx.Data["Page"] = pager
|
||||
ctx.Data["IsPackageEnabled"] = setting.Packages.Enabled
|
||||
|
||||
ctx.Data["ShowUserEmail"] = len(ctxUser.Email) > 0 && ctx.IsSigned && (!ctxUser.KeepEmailPrivate || ctxUser.ID == ctx.User.ID)
|
||||
ctx.Data["ShowUserEmail"] = len(ctx.ContextUser.Email) > 0 && ctx.IsSigned && (!ctx.ContextUser.KeepEmailPrivate || ctx.ContextUser.ID == ctx.Doer.ID)
|
||||
|
||||
ctx.HTML(http.StatusOK, tplProfile)
|
||||
}
|
||||
|
||||
// Action response for follow/unfollow user request
|
||||
func Action(ctx *context.Context) {
|
||||
u := GetUserByParams(ctx)
|
||||
if ctx.Written() {
|
||||
return
|
||||
}
|
||||
|
||||
var err error
|
||||
switch ctx.FormString("action") {
|
||||
case "follow":
|
||||
err = user_model.FollowUser(ctx.User.ID, u.ID)
|
||||
err = user_model.FollowUser(ctx.Doer.ID, ctx.ContextUser.ID)
|
||||
case "unfollow":
|
||||
err = user_model.UnfollowUser(ctx.User.ID, u.ID)
|
||||
err = user_model.UnfollowUser(ctx.Doer.ID, ctx.ContextUser.ID)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
@@ -386,5 +302,5 @@ func Action(ctx *context.Context) {
|
||||
return
|
||||
}
|
||||
// FIXME: We should check this URL and make sure that it's a valid Gitea URL
|
||||
ctx.RedirectToFirst(ctx.FormString("redirect_to"), u.HomeLink())
|
||||
ctx.RedirectToFirst(ctx.FormString("redirect_to"), ctx.ContextUser.HomeLink())
|
||||
}
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
// Copyright 2022 The Gitea Authors. All rights reserved.
|
||||
// Use of this source code is governed by a MIT-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package user
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"code.gitea.io/gitea/models/db"
|
||||
user_model "code.gitea.io/gitea/models/user"
|
||||
"code.gitea.io/gitea/modules/context"
|
||||
"code.gitea.io/gitea/modules/convert"
|
||||
)
|
||||
|
||||
// Search search users
|
||||
func Search(ctx *context.Context) {
|
||||
listOptions := db.ListOptions{
|
||||
Page: ctx.FormInt("page"),
|
||||
PageSize: convert.ToCorrectPageSize(ctx.FormInt("limit")),
|
||||
}
|
||||
|
||||
users, maxResults, err := user_model.SearchUsers(&user_model.SearchUserOptions{
|
||||
Actor: ctx.Doer,
|
||||
Keyword: ctx.FormTrim("q"),
|
||||
UID: ctx.FormInt64("uid"),
|
||||
Type: user_model.UserTypeIndividual,
|
||||
ListOptions: listOptions,
|
||||
})
|
||||
if err != nil {
|
||||
ctx.JSON(http.StatusInternalServerError, map[string]interface{}{
|
||||
"ok": false,
|
||||
"error": err.Error(),
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
ctx.SetTotalCountHeader(maxResults)
|
||||
|
||||
ctx.JSON(http.StatusOK, map[string]interface{}{
|
||||
"ok": true,
|
||||
"data": convert.ToUsers(ctx.Doer, users),
|
||||
})
|
||||
}
|
||||
@@ -11,7 +11,6 @@ import (
|
||||
"time"
|
||||
|
||||
"code.gitea.io/gitea/models"
|
||||
"code.gitea.io/gitea/models/db"
|
||||
user_model "code.gitea.io/gitea/models/user"
|
||||
"code.gitea.io/gitea/modules/base"
|
||||
"code.gitea.io/gitea/modules/context"
|
||||
@@ -34,7 +33,7 @@ const (
|
||||
func Account(ctx *context.Context) {
|
||||
ctx.Data["Title"] = ctx.Tr("settings")
|
||||
ctx.Data["PageIsSettingsAccount"] = true
|
||||
ctx.Data["Email"] = ctx.User.Email
|
||||
ctx.Data["Email"] = ctx.Doer.Email
|
||||
|
||||
loadAccountData(ctx)
|
||||
|
||||
@@ -56,7 +55,7 @@ func AccountPost(ctx *context.Context) {
|
||||
|
||||
if len(form.Password) < setting.MinPasswordLength {
|
||||
ctx.Flash.Error(ctx.Tr("auth.password_too_short", setting.MinPasswordLength))
|
||||
} else if ctx.User.IsPasswordSet() && !ctx.User.ValidatePassword(form.OldPassword) {
|
||||
} else if ctx.Doer.IsPasswordSet() && !ctx.Doer.ValidatePassword(form.OldPassword) {
|
||||
ctx.Flash.Error(ctx.Tr("settings.password_incorrect"))
|
||||
} else if form.Password != form.Retype {
|
||||
ctx.Flash.Error(ctx.Tr("form.password_not_match"))
|
||||
@@ -71,15 +70,15 @@ func AccountPost(ctx *context.Context) {
|
||||
ctx.Flash.Error(errMsg)
|
||||
} else {
|
||||
var err error
|
||||
if err = ctx.User.SetPassword(form.Password); err != nil {
|
||||
if err = ctx.Doer.SetPassword(form.Password); err != nil {
|
||||
ctx.ServerError("UpdateUser", err)
|
||||
return
|
||||
}
|
||||
if err := user_model.UpdateUserCols(db.DefaultContext, ctx.User, "salt", "passwd_hash_algo", "passwd"); err != nil {
|
||||
if err := user_model.UpdateUserCols(ctx, ctx.Doer, "salt", "passwd_hash_algo", "passwd"); err != nil {
|
||||
ctx.ServerError("UpdateUser", err)
|
||||
return
|
||||
}
|
||||
log.Trace("User password updated: %s", ctx.User.Name)
|
||||
log.Trace("User password updated: %s", ctx.Doer.Name)
|
||||
ctx.Flash.Success(ctx.Tr("settings.change_password_success"))
|
||||
}
|
||||
|
||||
@@ -99,50 +98,50 @@ func EmailPost(ctx *context.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
log.Trace("Email made primary: %s", ctx.User.Name)
|
||||
log.Trace("Email made primary: %s", ctx.Doer.Name)
|
||||
ctx.Redirect(setting.AppSubURL + "/user/settings/account")
|
||||
return
|
||||
}
|
||||
// Send activation Email
|
||||
if ctx.FormString("_method") == "SENDACTIVATION" {
|
||||
var address string
|
||||
if ctx.Cache.IsExist("MailResendLimit_" + ctx.User.LowerName) {
|
||||
if ctx.Cache.IsExist("MailResendLimit_" + ctx.Doer.LowerName) {
|
||||
log.Error("Send activation: activation still pending")
|
||||
ctx.Redirect(setting.AppSubURL + "/user/settings/account")
|
||||
return
|
||||
}
|
||||
|
||||
id := ctx.FormInt64("id")
|
||||
email, err := user_model.GetEmailAddressByID(ctx.User.ID, id)
|
||||
email, err := user_model.GetEmailAddressByID(ctx.Doer.ID, id)
|
||||
if err != nil {
|
||||
log.Error("GetEmailAddressByID(%d,%d) error: %v", ctx.User.ID, id, err)
|
||||
log.Error("GetEmailAddressByID(%d,%d) error: %v", ctx.Doer.ID, id, err)
|
||||
ctx.Redirect(setting.AppSubURL + "/user/settings/account")
|
||||
return
|
||||
}
|
||||
if email == nil {
|
||||
log.Warn("Send activation failed: EmailAddress[%d] not found for user: %-v", id, ctx.User)
|
||||
log.Warn("Send activation failed: EmailAddress[%d] not found for user: %-v", id, ctx.Doer)
|
||||
ctx.Redirect(setting.AppSubURL + "/user/settings/account")
|
||||
return
|
||||
}
|
||||
if email.IsActivated {
|
||||
log.Debug("Send activation failed: email %s is already activated for user: %-v", email.Email, ctx.User)
|
||||
log.Debug("Send activation failed: email %s is already activated for user: %-v", email.Email, ctx.Doer)
|
||||
ctx.Redirect(setting.AppSubURL + "/user/settings/account")
|
||||
return
|
||||
}
|
||||
if email.IsPrimary {
|
||||
if ctx.User.IsActive && !setting.Service.RegisterEmailConfirm {
|
||||
log.Debug("Send activation failed: email %s is already activated for user: %-v", email.Email, ctx.User)
|
||||
if ctx.Doer.IsActive && !setting.Service.RegisterEmailConfirm {
|
||||
log.Debug("Send activation failed: email %s is already activated for user: %-v", email.Email, ctx.Doer)
|
||||
ctx.Redirect(setting.AppSubURL + "/user/settings/account")
|
||||
return
|
||||
}
|
||||
// Only fired when the primary email is inactive (Wrong state)
|
||||
mailer.SendActivateAccountMail(ctx.Locale, ctx.User)
|
||||
mailer.SendActivateAccountMail(ctx.Locale, ctx.Doer)
|
||||
} else {
|
||||
mailer.SendActivateEmailMail(ctx.User, email)
|
||||
mailer.SendActivateEmailMail(ctx.Doer, email)
|
||||
}
|
||||
address = email.Email
|
||||
|
||||
if err := ctx.Cache.Put("MailResendLimit_"+ctx.User.LowerName, ctx.User.LowerName, 180); err != nil {
|
||||
if err := ctx.Cache.Put("MailResendLimit_"+ctx.Doer.LowerName, ctx.Doer.LowerName, 180); err != nil {
|
||||
log.Error("Set cache(MailResendLimit) fail: %v", err)
|
||||
}
|
||||
ctx.Flash.Info(ctx.Tr("settings.add_email_confirmation_sent", address, timeutil.MinutesToFriendly(setting.Service.ActiveCodeLives, ctx.Locale.Language())))
|
||||
@@ -155,16 +154,16 @@ func EmailPost(ctx *context.Context) {
|
||||
if !(preference == user_model.EmailNotificationsEnabled ||
|
||||
preference == user_model.EmailNotificationsOnMention ||
|
||||
preference == user_model.EmailNotificationsDisabled) {
|
||||
log.Error("Email notifications preference change returned unrecognized option %s: %s", preference, ctx.User.Name)
|
||||
log.Error("Email notifications preference change returned unrecognized option %s: %s", preference, ctx.Doer.Name)
|
||||
ctx.ServerError("SetEmailPreference", errors.New("option unrecognized"))
|
||||
return
|
||||
}
|
||||
if err := user_model.SetEmailNotifications(ctx.User, preference); err != nil {
|
||||
if err := user_model.SetEmailNotifications(ctx.Doer, preference); err != nil {
|
||||
log.Error("Set Email Notifications failed: %v", err)
|
||||
ctx.ServerError("SetEmailNotifications", err)
|
||||
return
|
||||
}
|
||||
log.Trace("Email notifications preference made %s: %s", preference, ctx.User.Name)
|
||||
log.Trace("Email notifications preference made %s: %s", preference, ctx.Doer.Name)
|
||||
ctx.Flash.Success(ctx.Tr("settings.email_preference_set_success"))
|
||||
ctx.Redirect(setting.AppSubURL + "/user/settings/account")
|
||||
return
|
||||
@@ -178,7 +177,7 @@ func EmailPost(ctx *context.Context) {
|
||||
}
|
||||
|
||||
email := &user_model.EmailAddress{
|
||||
UID: ctx.User.ID,
|
||||
UID: ctx.Doer.ID,
|
||||
Email: form.Email,
|
||||
IsActivated: !setting.Service.RegisterEmailConfirm,
|
||||
}
|
||||
@@ -188,7 +187,8 @@ func EmailPost(ctx *context.Context) {
|
||||
|
||||
ctx.RenderWithErr(ctx.Tr("form.email_been_used"), tplSettingsAccount, &form)
|
||||
return
|
||||
} else if user_model.IsErrEmailInvalid(err) {
|
||||
} else if user_model.IsErrEmailCharIsNotSupported(err) ||
|
||||
user_model.IsErrEmailInvalid(err) {
|
||||
loadAccountData(ctx)
|
||||
|
||||
ctx.RenderWithErr(ctx.Tr("form.email_invalid"), tplSettingsAccount, &form)
|
||||
@@ -200,8 +200,8 @@ func EmailPost(ctx *context.Context) {
|
||||
|
||||
// Send confirmation email
|
||||
if setting.Service.RegisterEmailConfirm {
|
||||
mailer.SendActivateEmailMail(ctx.User, email)
|
||||
if err := ctx.Cache.Put("MailResendLimit_"+ctx.User.LowerName, ctx.User.LowerName, 180); err != nil {
|
||||
mailer.SendActivateEmailMail(ctx.Doer, email)
|
||||
if err := ctx.Cache.Put("MailResendLimit_"+ctx.Doer.LowerName, ctx.Doer.LowerName, 180); err != nil {
|
||||
log.Error("Set cache(MailResendLimit) fail: %v", err)
|
||||
}
|
||||
ctx.Flash.Info(ctx.Tr("settings.add_email_confirmation_sent", email.Email, timeutil.MinutesToFriendly(setting.Service.ActiveCodeLives, ctx.Locale.Language())))
|
||||
@@ -215,11 +215,11 @@ func EmailPost(ctx *context.Context) {
|
||||
|
||||
// DeleteEmail response for delete user's email
|
||||
func DeleteEmail(ctx *context.Context) {
|
||||
if err := user_model.DeleteEmailAddress(&user_model.EmailAddress{ID: ctx.FormInt64("id"), UID: ctx.User.ID}); err != nil {
|
||||
if err := user_model.DeleteEmailAddress(&user_model.EmailAddress{ID: ctx.FormInt64("id"), UID: ctx.Doer.ID}); err != nil {
|
||||
ctx.ServerError("DeleteEmail", err)
|
||||
return
|
||||
}
|
||||
log.Trace("Email address deleted: %s", ctx.User.Name)
|
||||
log.Trace("Email address deleted: %s", ctx.Doer.Name)
|
||||
|
||||
ctx.Flash.Success(ctx.Tr("settings.email_deletion_success"))
|
||||
ctx.JSON(http.StatusOK, map[string]interface{}{
|
||||
@@ -232,7 +232,7 @@ func DeleteAccount(ctx *context.Context) {
|
||||
ctx.Data["Title"] = ctx.Tr("settings")
|
||||
ctx.Data["PageIsSettingsAccount"] = true
|
||||
|
||||
if _, _, err := auth.UserSignIn(ctx.User.Name, ctx.FormString("password")); err != nil {
|
||||
if _, _, err := auth.UserSignIn(ctx.Doer.Name, ctx.FormString("password")); err != nil {
|
||||
if user_model.IsErrUserNotExist(err) {
|
||||
loadAccountData(ctx)
|
||||
|
||||
@@ -243,7 +243,7 @@ func DeleteAccount(ctx *context.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
if err := user.DeleteUser(ctx.User); err != nil {
|
||||
if err := user.DeleteUser(ctx.Doer); err != nil {
|
||||
switch {
|
||||
case models.IsErrUserOwnRepos(err):
|
||||
ctx.Flash.Error(ctx.Tr("form.still_own_repo"))
|
||||
@@ -251,17 +251,20 @@ func DeleteAccount(ctx *context.Context) {
|
||||
case models.IsErrUserHasOrgs(err):
|
||||
ctx.Flash.Error(ctx.Tr("form.still_has_org"))
|
||||
ctx.Redirect(setting.AppSubURL + "/user/settings/account")
|
||||
case models.IsErrUserOwnPackages(err):
|
||||
ctx.Flash.Error(ctx.Tr("form.still_own_packages"))
|
||||
ctx.Redirect(setting.AppSubURL + "/user/settings/account")
|
||||
default:
|
||||
ctx.ServerError("DeleteUser", err)
|
||||
}
|
||||
} else {
|
||||
log.Trace("Account deleted: %s", ctx.User.Name)
|
||||
log.Trace("Account deleted: %s", ctx.Doer.Name)
|
||||
ctx.Redirect(setting.AppSubURL + "/")
|
||||
}
|
||||
}
|
||||
|
||||
func loadAccountData(ctx *context.Context) {
|
||||
emlist, err := user_model.GetEmailAddresses(ctx.User.ID)
|
||||
emlist, err := user_model.GetEmailAddresses(ctx.Doer.ID)
|
||||
if err != nil {
|
||||
ctx.ServerError("GetEmailAddresses", err)
|
||||
return
|
||||
@@ -270,7 +273,7 @@ func loadAccountData(ctx *context.Context) {
|
||||
user_model.EmailAddress
|
||||
CanBePrimary bool
|
||||
}
|
||||
pendingActivation := ctx.Cache.IsExist("MailResendLimit_" + ctx.User.LowerName)
|
||||
pendingActivation := ctx.Cache.IsExist("MailResendLimit_" + ctx.Doer.LowerName)
|
||||
emails := make([]*UserEmail, len(emlist))
|
||||
for i, em := range emlist {
|
||||
var email UserEmail
|
||||
@@ -279,12 +282,12 @@ func loadAccountData(ctx *context.Context) {
|
||||
emails[i] = &email
|
||||
}
|
||||
ctx.Data["Emails"] = emails
|
||||
ctx.Data["EmailNotificationsPreference"] = ctx.User.EmailNotifications()
|
||||
ctx.Data["EmailNotificationsPreference"] = ctx.Doer.EmailNotifications()
|
||||
ctx.Data["ActivationsPending"] = pendingActivation
|
||||
ctx.Data["CanAddEmails"] = !pendingActivation || !setting.Service.RegisterEmailConfirm
|
||||
|
||||
if setting.Service.UserDeleteWithCommentsMaxTime != 0 {
|
||||
ctx.Data["UserDeleteWithCommentsMaxTime"] = setting.Service.UserDeleteWithCommentsMaxTime.String()
|
||||
ctx.Data["UserDeleteWithComments"] = ctx.User.CreatedUnix.AsTime().Add(setting.Service.UserDeleteWithCommentsMaxTime).After(time.Now())
|
||||
ctx.Data["UserDeleteWithComments"] = ctx.Doer.CreatedUnix.AsTime().Add(setting.Service.UserDeleteWithCommentsMaxTime).After(time.Now())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -94,6 +94,6 @@ func TestChangePassword(t *testing.T) {
|
||||
AccountPost(ctx)
|
||||
|
||||
assert.Contains(t, ctx.Flash.ErrorMsg, req.Message)
|
||||
assert.EqualValues(t, http.StatusFound, ctx.Resp.Status())
|
||||
assert.EqualValues(t, http.StatusSeeOther, ctx.Resp.Status())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,7 +28,7 @@ func AdoptOrDeleteRepository(ctx *context.Context) {
|
||||
dir := ctx.FormString("id")
|
||||
action := ctx.FormString("action")
|
||||
|
||||
ctxUser := ctx.User
|
||||
ctxUser := ctx.Doer
|
||||
root := user_model.UserPath(ctxUser.LowerName)
|
||||
|
||||
// check not a repo
|
||||
|
||||
@@ -45,7 +45,7 @@ func ApplicationsPost(ctx *context.Context) {
|
||||
}
|
||||
|
||||
t := &models.AccessToken{
|
||||
UID: ctx.User.ID,
|
||||
UID: ctx.Doer.ID,
|
||||
Name: form.Name,
|
||||
}
|
||||
|
||||
@@ -73,7 +73,7 @@ func ApplicationsPost(ctx *context.Context) {
|
||||
|
||||
// DeleteApplication response for delete user access token
|
||||
func DeleteApplication(ctx *context.Context) {
|
||||
if err := models.DeleteAccessTokenByID(ctx.FormInt64("id"), ctx.User.ID); err != nil {
|
||||
if err := models.DeleteAccessTokenByID(ctx.FormInt64("id"), ctx.Doer.ID); err != nil {
|
||||
ctx.Flash.Error("DeleteAccessTokenByID: " + err.Error())
|
||||
} else {
|
||||
ctx.Flash.Success(ctx.Tr("settings.delete_token_success"))
|
||||
@@ -85,7 +85,7 @@ func DeleteApplication(ctx *context.Context) {
|
||||
}
|
||||
|
||||
func loadApplicationsData(ctx *context.Context) {
|
||||
tokens, err := models.ListAccessTokens(models.ListAccessTokensOptions{UserID: ctx.User.ID})
|
||||
tokens, err := models.ListAccessTokens(models.ListAccessTokensOptions{UserID: ctx.Doer.ID})
|
||||
if err != nil {
|
||||
ctx.ServerError("ListAccessTokens", err)
|
||||
return
|
||||
@@ -93,12 +93,12 @@ func loadApplicationsData(ctx *context.Context) {
|
||||
ctx.Data["Tokens"] = tokens
|
||||
ctx.Data["EnableOAuth2"] = setting.OAuth2.Enable
|
||||
if setting.OAuth2.Enable {
|
||||
ctx.Data["Applications"], err = auth.GetOAuth2ApplicationsByUserID(ctx.User.ID)
|
||||
ctx.Data["Applications"], err = auth.GetOAuth2ApplicationsByUserID(ctx.Doer.ID)
|
||||
if err != nil {
|
||||
ctx.ServerError("GetOAuth2ApplicationsByUserID", err)
|
||||
return
|
||||
}
|
||||
ctx.Data["Grants"], err = auth.GetOAuth2GrantsByUserID(ctx.User.ID)
|
||||
ctx.Data["Grants"], err = auth.GetOAuth2GrantsByUserID(ctx.Doer.ID)
|
||||
if err != nil {
|
||||
ctx.ServerError("GetOAuth2GrantsByUserID", err)
|
||||
return
|
||||
|
||||
@@ -52,7 +52,7 @@ func KeysPost(ctx *context.Context) {
|
||||
}
|
||||
switch form.Type {
|
||||
case "principal":
|
||||
content, err := asymkey_model.CheckPrincipalKeyString(ctx.User, form.Content)
|
||||
content, err := asymkey_model.CheckPrincipalKeyString(ctx.Doer, form.Content)
|
||||
if err != nil {
|
||||
if db.IsErrSSHDisabled(err) {
|
||||
ctx.Flash.Info(ctx.Tr("settings.ssh_disabled"))
|
||||
@@ -62,7 +62,7 @@ func KeysPost(ctx *context.Context) {
|
||||
ctx.Redirect(setting.AppSubURL + "/user/settings/keys")
|
||||
return
|
||||
}
|
||||
if _, err = asymkey_model.AddPrincipalKey(ctx.User.ID, content, 0); err != nil {
|
||||
if _, err = asymkey_model.AddPrincipalKey(ctx.Doer.ID, content, 0); err != nil {
|
||||
ctx.Data["HasPrincipalError"] = true
|
||||
switch {
|
||||
case asymkey_model.IsErrKeyAlreadyExist(err), asymkey_model.IsErrKeyNameAlreadyUsed(err):
|
||||
@@ -78,12 +78,12 @@ func KeysPost(ctx *context.Context) {
|
||||
ctx.Flash.Success(ctx.Tr("settings.add_principal_success", form.Content))
|
||||
ctx.Redirect(setting.AppSubURL + "/user/settings/keys")
|
||||
case "gpg":
|
||||
token := asymkey_model.VerificationToken(ctx.User, 1)
|
||||
lastToken := asymkey_model.VerificationToken(ctx.User, 0)
|
||||
token := asymkey_model.VerificationToken(ctx.Doer, 1)
|
||||
lastToken := asymkey_model.VerificationToken(ctx.Doer, 0)
|
||||
|
||||
keys, err := asymkey_model.AddGPGKey(ctx.User.ID, form.Content, token, form.Signature)
|
||||
keys, err := asymkey_model.AddGPGKey(ctx.Doer.ID, form.Content, token, form.Signature)
|
||||
if err != nil && asymkey_model.IsErrGPGInvalidTokenSignature(err) {
|
||||
keys, err = asymkey_model.AddGPGKey(ctx.User.ID, form.Content, lastToken, form.Signature)
|
||||
keys, err = asymkey_model.AddGPGKey(ctx.Doer.ID, form.Content, lastToken, form.Signature)
|
||||
}
|
||||
if err != nil {
|
||||
ctx.Data["HasGPGError"] = true
|
||||
@@ -125,12 +125,12 @@ func KeysPost(ctx *context.Context) {
|
||||
ctx.Flash.Success(ctx.Tr("settings.add_gpg_key_success", keyIDs))
|
||||
ctx.Redirect(setting.AppSubURL + "/user/settings/keys")
|
||||
case "verify_gpg":
|
||||
token := asymkey_model.VerificationToken(ctx.User, 1)
|
||||
lastToken := asymkey_model.VerificationToken(ctx.User, 0)
|
||||
token := asymkey_model.VerificationToken(ctx.Doer, 1)
|
||||
lastToken := asymkey_model.VerificationToken(ctx.Doer, 0)
|
||||
|
||||
keyID, err := asymkey_model.VerifyGPGKey(ctx.User.ID, form.KeyID, token, form.Signature)
|
||||
keyID, err := asymkey_model.VerifyGPGKey(ctx.Doer.ID, form.KeyID, token, form.Signature)
|
||||
if err != nil && asymkey_model.IsErrGPGInvalidTokenSignature(err) {
|
||||
keyID, err = asymkey_model.VerifyGPGKey(ctx.User.ID, form.KeyID, lastToken, form.Signature)
|
||||
keyID, err = asymkey_model.VerifyGPGKey(ctx.Doer.ID, form.KeyID, lastToken, form.Signature)
|
||||
}
|
||||
if err != nil {
|
||||
ctx.Data["HasGPGVerifyError"] = true
|
||||
@@ -161,7 +161,7 @@ func KeysPost(ctx *context.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
if _, err = asymkey_model.AddPublicKey(ctx.User.ID, form.Title, content, 0); err != nil {
|
||||
if _, err = asymkey_model.AddPublicKey(ctx.Doer.ID, form.Title, content, 0); err != nil {
|
||||
ctx.Data["HasSSHError"] = true
|
||||
switch {
|
||||
case asymkey_model.IsErrKeyAlreadyExist(err):
|
||||
@@ -185,12 +185,12 @@ func KeysPost(ctx *context.Context) {
|
||||
ctx.Flash.Success(ctx.Tr("settings.add_key_success", form.Title))
|
||||
ctx.Redirect(setting.AppSubURL + "/user/settings/keys")
|
||||
case "verify_ssh":
|
||||
token := asymkey_model.VerificationToken(ctx.User, 1)
|
||||
lastToken := asymkey_model.VerificationToken(ctx.User, 0)
|
||||
token := asymkey_model.VerificationToken(ctx.Doer, 1)
|
||||
lastToken := asymkey_model.VerificationToken(ctx.Doer, 0)
|
||||
|
||||
fingerprint, err := asymkey_model.VerifySSHKey(ctx.User.ID, form.Fingerprint, token, form.Signature)
|
||||
fingerprint, err := asymkey_model.VerifySSHKey(ctx.Doer.ID, form.Fingerprint, token, form.Signature)
|
||||
if err != nil && asymkey_model.IsErrSSHInvalidTokenSignature(err) {
|
||||
fingerprint, err = asymkey_model.VerifySSHKey(ctx.User.ID, form.Fingerprint, lastToken, form.Signature)
|
||||
fingerprint, err = asymkey_model.VerifySSHKey(ctx.Doer.ID, form.Fingerprint, lastToken, form.Signature)
|
||||
}
|
||||
if err != nil {
|
||||
ctx.Data["HasSSHVerifyError"] = true
|
||||
@@ -217,7 +217,7 @@ func KeysPost(ctx *context.Context) {
|
||||
func DeleteKey(ctx *context.Context) {
|
||||
switch ctx.FormString("type") {
|
||||
case "gpg":
|
||||
if err := asymkey_model.DeleteGPGKey(ctx.User, ctx.FormInt64("id")); err != nil {
|
||||
if err := asymkey_model.DeleteGPGKey(ctx.Doer, ctx.FormInt64("id")); err != nil {
|
||||
ctx.Flash.Error("DeleteGPGKey: " + err.Error())
|
||||
} else {
|
||||
ctx.Flash.Success(ctx.Tr("settings.gpg_key_deletion_success"))
|
||||
@@ -234,13 +234,13 @@ func DeleteKey(ctx *context.Context) {
|
||||
ctx.Redirect(setting.AppSubURL + "/user/settings/keys")
|
||||
return
|
||||
}
|
||||
if err := asymkey_service.DeletePublicKey(ctx.User, keyID); err != nil {
|
||||
if err := asymkey_service.DeletePublicKey(ctx.Doer, keyID); err != nil {
|
||||
ctx.Flash.Error("DeletePublicKey: " + err.Error())
|
||||
} else {
|
||||
ctx.Flash.Success(ctx.Tr("settings.ssh_key_deletion_success"))
|
||||
}
|
||||
case "principal":
|
||||
if err := asymkey_service.DeletePublicKey(ctx.User, ctx.FormInt64("id")); err != nil {
|
||||
if err := asymkey_service.DeletePublicKey(ctx.Doer, ctx.FormInt64("id")); err != nil {
|
||||
ctx.Flash.Error("DeletePublicKey: " + err.Error())
|
||||
} else {
|
||||
ctx.Flash.Success(ctx.Tr("settings.ssh_principal_deletion_success"))
|
||||
@@ -255,7 +255,7 @@ func DeleteKey(ctx *context.Context) {
|
||||
}
|
||||
|
||||
func loadKeysData(ctx *context.Context) {
|
||||
keys, err := asymkey_model.ListPublicKeys(ctx.User.ID, db.ListOptions{})
|
||||
keys, err := asymkey_model.ListPublicKeys(ctx.Doer.ID, db.ListOptions{})
|
||||
if err != nil {
|
||||
ctx.ServerError("ListPublicKeys", err)
|
||||
return
|
||||
@@ -269,18 +269,18 @@ func loadKeysData(ctx *context.Context) {
|
||||
}
|
||||
ctx.Data["ExternalKeys"] = externalKeys
|
||||
|
||||
gpgkeys, err := asymkey_model.ListGPGKeys(db.DefaultContext, ctx.User.ID, db.ListOptions{})
|
||||
gpgkeys, err := asymkey_model.ListGPGKeys(ctx, ctx.Doer.ID, db.ListOptions{})
|
||||
if err != nil {
|
||||
ctx.ServerError("ListGPGKeys", err)
|
||||
return
|
||||
}
|
||||
ctx.Data["GPGKeys"] = gpgkeys
|
||||
tokenToSign := asymkey_model.VerificationToken(ctx.User, 1)
|
||||
tokenToSign := asymkey_model.VerificationToken(ctx.Doer, 1)
|
||||
|
||||
// generate a new aes cipher using the csrfToken
|
||||
ctx.Data["TokenToSign"] = tokenToSign
|
||||
|
||||
principals, err := asymkey_model.ListPrincipalKeys(ctx.User.ID, db.ListOptions{})
|
||||
principals, err := asymkey_model.ListPrincipalKeys(ctx.Doer.ID, db.ListOptions{})
|
||||
if err != nil {
|
||||
ctx.ServerError("ListPrincipalKeys", err)
|
||||
return
|
||||
|
||||
@@ -12,5 +12,7 @@ import (
|
||||
)
|
||||
|
||||
func TestMain(m *testing.M) {
|
||||
unittest.MainTest(m, filepath.Join("..", "..", "..", ".."))
|
||||
unittest.MainTest(m, &unittest.TestOptions{
|
||||
GiteaRootPath: filepath.Join("..", "..", "..", ".."),
|
||||
})
|
||||
}
|
||||
|
||||
@@ -37,7 +37,7 @@ func OAuthApplicationsPost(ctx *context.Context) {
|
||||
app, err := auth.CreateOAuth2Application(auth.CreateOAuth2ApplicationOptions{
|
||||
Name: form.Name,
|
||||
RedirectURIs: []string{form.RedirectURI},
|
||||
UserID: ctx.User.ID,
|
||||
UserID: ctx.Doer.ID,
|
||||
})
|
||||
if err != nil {
|
||||
ctx.ServerError("CreateOAuth2Application", err)
|
||||
@@ -71,7 +71,7 @@ func OAuthApplicationsEdit(ctx *context.Context) {
|
||||
ID: ctx.ParamsInt64("id"),
|
||||
Name: form.Name,
|
||||
RedirectURIs: []string{form.RedirectURI},
|
||||
UserID: ctx.User.ID,
|
||||
UserID: ctx.Doer.ID,
|
||||
}); err != nil {
|
||||
ctx.ServerError("UpdateOAuth2Application", err)
|
||||
return
|
||||
@@ -94,7 +94,7 @@ func OAuthApplicationsRegenerateSecret(ctx *context.Context) {
|
||||
ctx.ServerError("GetOAuth2ApplicationByID", err)
|
||||
return
|
||||
}
|
||||
if app.UID != ctx.User.ID {
|
||||
if app.UID != ctx.Doer.ID {
|
||||
ctx.NotFound("Application not found", nil)
|
||||
return
|
||||
}
|
||||
@@ -119,7 +119,7 @@ func OAuth2ApplicationShow(ctx *context.Context) {
|
||||
ctx.ServerError("GetOAuth2ApplicationByID", err)
|
||||
return
|
||||
}
|
||||
if app.UID != ctx.User.ID {
|
||||
if app.UID != ctx.Doer.ID {
|
||||
ctx.NotFound("Application not found", nil)
|
||||
return
|
||||
}
|
||||
@@ -129,11 +129,11 @@ func OAuth2ApplicationShow(ctx *context.Context) {
|
||||
|
||||
// DeleteOAuth2Application deletes the given oauth2 application
|
||||
func DeleteOAuth2Application(ctx *context.Context) {
|
||||
if err := auth.DeleteOAuth2Application(ctx.FormInt64("id"), ctx.User.ID); err != nil {
|
||||
if err := auth.DeleteOAuth2Application(ctx.FormInt64("id"), ctx.Doer.ID); err != nil {
|
||||
ctx.ServerError("DeleteOAuth2Application", err)
|
||||
return
|
||||
}
|
||||
log.Trace("OAuth2 Application deleted: %s", ctx.User.Name)
|
||||
log.Trace("OAuth2 Application deleted: %s", ctx.Doer.Name)
|
||||
|
||||
ctx.Flash.Success(ctx.Tr("settings.remove_oauth2_application_success"))
|
||||
ctx.JSON(http.StatusOK, map[string]interface{}{
|
||||
@@ -143,11 +143,11 @@ func DeleteOAuth2Application(ctx *context.Context) {
|
||||
|
||||
// RevokeOAuth2Grant revokes the grant with the given id
|
||||
func RevokeOAuth2Grant(ctx *context.Context) {
|
||||
if ctx.User.ID == 0 || ctx.FormInt64("id") == 0 {
|
||||
if ctx.Doer.ID == 0 || ctx.FormInt64("id") == 0 {
|
||||
ctx.ServerError("RevokeOAuth2Grant", fmt.Errorf("user id or grant id is zero"))
|
||||
return
|
||||
}
|
||||
if err := auth.RevokeOAuth2Grant(ctx.FormInt64("id"), ctx.User.ID); err != nil {
|
||||
if err := auth.RevokeOAuth2Grant(ctx.FormInt64("id"), ctx.Doer.ID); err != nil {
|
||||
ctx.ServerError("RevokeOAuth2Grant", err)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -17,12 +17,14 @@ import (
|
||||
|
||||
"code.gitea.io/gitea/models"
|
||||
"code.gitea.io/gitea/models/db"
|
||||
"code.gitea.io/gitea/models/organization"
|
||||
repo_model "code.gitea.io/gitea/models/repo"
|
||||
user_model "code.gitea.io/gitea/models/user"
|
||||
"code.gitea.io/gitea/modules/base"
|
||||
"code.gitea.io/gitea/modules/context"
|
||||
"code.gitea.io/gitea/modules/log"
|
||||
"code.gitea.io/gitea/modules/setting"
|
||||
"code.gitea.io/gitea/modules/translation/i18n"
|
||||
"code.gitea.io/gitea/modules/typesniffer"
|
||||
"code.gitea.io/gitea/modules/util"
|
||||
"code.gitea.io/gitea/modules/web"
|
||||
@@ -30,8 +32,6 @@ import (
|
||||
"code.gitea.io/gitea/services/agit"
|
||||
"code.gitea.io/gitea/services/forms"
|
||||
user_service "code.gitea.io/gitea/services/user"
|
||||
|
||||
"github.com/unknwon/i18n"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -106,24 +106,24 @@ func ProfilePost(ctx *context.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
if len(form.Name) != 0 && ctx.User.Name != form.Name {
|
||||
log.Debug("Changing name for %s to %s", ctx.User.Name, form.Name)
|
||||
if err := HandleUsernameChange(ctx, ctx.User, form.Name); err != nil {
|
||||
if len(form.Name) != 0 && ctx.Doer.Name != form.Name {
|
||||
log.Debug("Changing name for %s to %s", ctx.Doer.Name, form.Name)
|
||||
if err := HandleUsernameChange(ctx, ctx.Doer, form.Name); err != nil {
|
||||
ctx.Redirect(setting.AppSubURL + "/user/settings")
|
||||
return
|
||||
}
|
||||
ctx.User.Name = form.Name
|
||||
ctx.User.LowerName = strings.ToLower(form.Name)
|
||||
ctx.Doer.Name = form.Name
|
||||
ctx.Doer.LowerName = strings.ToLower(form.Name)
|
||||
}
|
||||
|
||||
ctx.User.FullName = form.FullName
|
||||
ctx.User.KeepEmailPrivate = form.KeepEmailPrivate
|
||||
ctx.User.Website = form.Website
|
||||
ctx.User.Location = form.Location
|
||||
ctx.User.Description = form.Description
|
||||
ctx.User.KeepActivityPrivate = form.KeepActivityPrivate
|
||||
ctx.User.Visibility = form.Visibility
|
||||
if err := user_model.UpdateUserSetting(ctx.User); err != nil {
|
||||
ctx.Doer.FullName = form.FullName
|
||||
ctx.Doer.KeepEmailPrivate = form.KeepEmailPrivate
|
||||
ctx.Doer.Website = form.Website
|
||||
ctx.Doer.Location = form.Location
|
||||
ctx.Doer.Description = form.Description
|
||||
ctx.Doer.KeepActivityPrivate = form.KeepActivityPrivate
|
||||
ctx.Doer.Visibility = form.Visibility
|
||||
if err := user_model.UpdateUserSetting(ctx.Doer); err != nil {
|
||||
if _, ok := err.(user_model.ErrEmailAlreadyUsed); ok {
|
||||
ctx.Flash.Error(ctx.Tr("form.email_been_used"))
|
||||
ctx.Redirect(setting.AppSubURL + "/user/settings")
|
||||
@@ -134,10 +134,10 @@ func ProfilePost(ctx *context.Context) {
|
||||
}
|
||||
|
||||
// Update the language to the one we just set
|
||||
middleware.SetLocaleCookie(ctx.Resp, ctx.User.Language, 0)
|
||||
middleware.SetLocaleCookie(ctx.Resp, ctx.Doer.Language, 0)
|
||||
|
||||
log.Trace("User settings updated: %s", ctx.User.Name)
|
||||
ctx.Flash.Success(i18n.Tr(ctx.User.Language, "settings.update_profile_success"))
|
||||
log.Trace("User settings updated: %s", ctx.Doer.Name)
|
||||
ctx.Flash.Success(i18n.Tr(ctx.Doer.Language, "settings.update_profile_success"))
|
||||
ctx.Redirect(setting.AppSubURL + "/user/settings")
|
||||
}
|
||||
|
||||
@@ -185,7 +185,7 @@ func UpdateAvatarSetting(ctx *context.Context, form *forms.AvatarForm, ctxUser *
|
||||
}
|
||||
}
|
||||
|
||||
if err := user_model.UpdateUserCols(db.DefaultContext, ctxUser, "avatar", "avatar_email", "use_custom_avatar"); err != nil {
|
||||
if err := user_model.UpdateUserCols(ctx, ctxUser, "avatar", "avatar_email", "use_custom_avatar"); err != nil {
|
||||
return fmt.Errorf("UpdateUser: %v", err)
|
||||
}
|
||||
|
||||
@@ -195,7 +195,7 @@ func UpdateAvatarSetting(ctx *context.Context, form *forms.AvatarForm, ctxUser *
|
||||
// AvatarPost response for change user's avatar request
|
||||
func AvatarPost(ctx *context.Context) {
|
||||
form := web.GetForm(ctx).(*forms.AvatarForm)
|
||||
if err := UpdateAvatarSetting(ctx, form, ctx.User); err != nil {
|
||||
if err := UpdateAvatarSetting(ctx, form, ctx.Doer); err != nil {
|
||||
ctx.Flash.Error(err.Error())
|
||||
} else {
|
||||
ctx.Flash.Success(ctx.Tr("settings.update_avatar_success"))
|
||||
@@ -206,7 +206,7 @@ func AvatarPost(ctx *context.Context) {
|
||||
|
||||
// DeleteAvatar render delete avatar page
|
||||
func DeleteAvatar(ctx *context.Context) {
|
||||
if err := user_service.DeleteAvatar(ctx.User); err != nil {
|
||||
if err := user_service.DeleteAvatar(ctx.Doer); err != nil {
|
||||
ctx.Flash.Error(err.Error())
|
||||
}
|
||||
|
||||
@@ -218,12 +218,12 @@ func Organization(ctx *context.Context) {
|
||||
ctx.Data["Title"] = ctx.Tr("settings")
|
||||
ctx.Data["PageIsSettingsOrganization"] = true
|
||||
|
||||
opts := models.FindOrgOptions{
|
||||
opts := organization.FindOrgOptions{
|
||||
ListOptions: db.ListOptions{
|
||||
PageSize: setting.UI.Admin.UserPagingNum,
|
||||
Page: ctx.FormInt("page"),
|
||||
},
|
||||
UserID: ctx.User.ID,
|
||||
UserID: ctx.Doer.ID,
|
||||
IncludePrivate: ctx.IsSigned,
|
||||
}
|
||||
|
||||
@@ -231,12 +231,12 @@ func Organization(ctx *context.Context) {
|
||||
opts.Page = 1
|
||||
}
|
||||
|
||||
orgs, err := models.FindOrgs(opts)
|
||||
orgs, err := organization.FindOrgs(opts)
|
||||
if err != nil {
|
||||
ctx.ServerError("FindOrgs", err)
|
||||
return
|
||||
}
|
||||
total, err := models.CountOrgs(opts)
|
||||
total, err := organization.CountOrgs(opts)
|
||||
if err != nil {
|
||||
ctx.ServerError("CountOrgs", err)
|
||||
return
|
||||
@@ -268,7 +268,7 @@ func Repos(ctx *context.Context) {
|
||||
|
||||
adoptOrDelete := ctx.IsUserSiteAdmin() || (setting.Repository.AllowAdoptionOfUnadoptedRepositories && setting.Repository.AllowDeleteOfUnadoptedRepositories)
|
||||
|
||||
ctxUser := ctx.User
|
||||
ctxUser := ctx.Doer
|
||||
count := 0
|
||||
|
||||
if adoptOrDelete {
|
||||
@@ -360,7 +360,7 @@ func Appearance(ctx *context.Context) {
|
||||
ctx.Data["PageIsSettingsAppearance"] = true
|
||||
|
||||
var hiddenCommentTypes *big.Int
|
||||
val, err := user_model.GetUserSetting(ctx.User.ID, user_model.SettingsKeyHiddenCommentTypes)
|
||||
val, err := user_model.GetUserSetting(ctx.Doer.ID, user_model.SettingsKeyHiddenCommentTypes)
|
||||
if err != nil {
|
||||
ctx.ServerError("GetUserSetting", err)
|
||||
return
|
||||
@@ -391,13 +391,13 @@ func UpdateUIThemePost(ctx *context.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
if err := user_model.UpdateUserTheme(ctx.User, form.Theme); err != nil {
|
||||
if err := user_model.UpdateUserTheme(ctx.Doer, form.Theme); err != nil {
|
||||
ctx.Flash.Error(ctx.Tr("settings.theme_update_error"))
|
||||
ctx.Redirect(setting.AppSubURL + "/user/settings/appearance")
|
||||
return
|
||||
}
|
||||
|
||||
log.Trace("Update user theme: %s", ctx.User.Name)
|
||||
log.Trace("Update user theme: %s", ctx.Doer.Name)
|
||||
ctx.Flash.Success(ctx.Tr("settings.theme_update_success"))
|
||||
ctx.Redirect(setting.AppSubURL + "/user/settings/appearance")
|
||||
}
|
||||
@@ -414,31 +414,31 @@ func UpdateUserLang(ctx *context.Context) {
|
||||
ctx.Redirect(setting.AppSubURL + "/user/settings/appearance")
|
||||
return
|
||||
}
|
||||
ctx.User.Language = form.Language
|
||||
ctx.Doer.Language = form.Language
|
||||
}
|
||||
|
||||
if err := user_model.UpdateUserSetting(ctx.User); err != nil {
|
||||
if err := user_model.UpdateUserSetting(ctx.Doer); err != nil {
|
||||
ctx.ServerError("UpdateUserSetting", err)
|
||||
return
|
||||
}
|
||||
|
||||
// Update the language to the one we just set
|
||||
middleware.SetLocaleCookie(ctx.Resp, ctx.User.Language, 0)
|
||||
middleware.SetLocaleCookie(ctx.Resp, ctx.Doer.Language, 0)
|
||||
|
||||
log.Trace("User settings updated: %s", ctx.User.Name)
|
||||
ctx.Flash.Success(i18n.Tr(ctx.User.Language, "settings.update_language_success"))
|
||||
log.Trace("User settings updated: %s", ctx.Doer.Name)
|
||||
ctx.Flash.Success(i18n.Tr(ctx.Doer.Language, "settings.update_language_success"))
|
||||
ctx.Redirect(setting.AppSubURL + "/user/settings/appearance")
|
||||
}
|
||||
|
||||
// UpdateUserHiddenComments update a user's shown comment types
|
||||
func UpdateUserHiddenComments(ctx *context.Context) {
|
||||
err := user_model.SetUserSetting(ctx.User.ID, user_model.SettingsKeyHiddenCommentTypes, forms.UserHiddenCommentTypesFromRequest(ctx).String())
|
||||
err := user_model.SetUserSetting(ctx.Doer.ID, user_model.SettingsKeyHiddenCommentTypes, forms.UserHiddenCommentTypesFromRequest(ctx).String())
|
||||
if err != nil {
|
||||
ctx.ServerError("SetUserSetting", err)
|
||||
return
|
||||
}
|
||||
|
||||
log.Trace("User settings updated: %s", ctx.User.Name)
|
||||
log.Trace("User settings updated: %s", ctx.Doer.Name)
|
||||
ctx.Flash.Success(ctx.Tr("settings.saved_successfully"))
|
||||
ctx.Redirect(setting.AppSubURL + "/user/settings/appearance")
|
||||
}
|
||||
|
||||
@@ -29,7 +29,7 @@ func RegenerateScratchTwoFactor(ctx *context.Context) {
|
||||
ctx.Data["Title"] = ctx.Tr("settings")
|
||||
ctx.Data["PageIsSettingsSecurity"] = true
|
||||
|
||||
t, err := auth.GetTwoFactorByUID(ctx.User.ID)
|
||||
t, err := auth.GetTwoFactorByUID(ctx.Doer.ID)
|
||||
if err != nil {
|
||||
if auth.IsErrTwoFactorNotEnrolled(err) {
|
||||
ctx.Flash.Error(ctx.Tr("settings.twofa_not_enrolled"))
|
||||
@@ -59,7 +59,7 @@ func DisableTwoFactor(ctx *context.Context) {
|
||||
ctx.Data["Title"] = ctx.Tr("settings")
|
||||
ctx.Data["PageIsSettingsSecurity"] = true
|
||||
|
||||
t, err := auth.GetTwoFactorByUID(ctx.User.ID)
|
||||
t, err := auth.GetTwoFactorByUID(ctx.Doer.ID)
|
||||
if err != nil {
|
||||
if auth.IsErrTwoFactorNotEnrolled(err) {
|
||||
ctx.Flash.Error(ctx.Tr("settings.twofa_not_enrolled"))
|
||||
@@ -69,7 +69,7 @@ func DisableTwoFactor(ctx *context.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
if err = auth.DeleteTwoFactorByID(t.ID, ctx.User.ID); err != nil {
|
||||
if err = auth.DeleteTwoFactorByID(t.ID, ctx.Doer.ID); err != nil {
|
||||
if auth.IsErrTwoFactorNotEnrolled(err) {
|
||||
// There is a potential DB race here - we must have been disabled by another request in the intervening period
|
||||
ctx.Flash.Success(ctx.Tr("settings.twofa_disabled"))
|
||||
@@ -100,7 +100,7 @@ func twofaGenerateSecretAndQr(ctx *context.Context) bool {
|
||||
otpKey, err = totp.Generate(totp.GenerateOpts{
|
||||
SecretSize: 40,
|
||||
Issuer: issuer,
|
||||
AccountName: ctx.User.Name,
|
||||
AccountName: ctx.Doer.Name,
|
||||
})
|
||||
if err != nil {
|
||||
ctx.ServerError("SettingsTwoFactor: totpGenerate Failed", err)
|
||||
@@ -146,10 +146,10 @@ func EnrollTwoFactor(ctx *context.Context) {
|
||||
ctx.Data["Title"] = ctx.Tr("settings")
|
||||
ctx.Data["PageIsSettingsSecurity"] = true
|
||||
|
||||
t, err := auth.GetTwoFactorByUID(ctx.User.ID)
|
||||
t, err := auth.GetTwoFactorByUID(ctx.Doer.ID)
|
||||
if t != nil {
|
||||
// already enrolled - we should redirect back!
|
||||
log.Warn("Trying to re-enroll %-v in twofa when already enrolled", ctx.User)
|
||||
log.Warn("Trying to re-enroll %-v in twofa when already enrolled", ctx.Doer)
|
||||
ctx.Flash.Error(ctx.Tr("settings.twofa_is_enrolled"))
|
||||
ctx.Redirect(setting.AppSubURL + "/user/settings/security")
|
||||
return
|
||||
@@ -172,7 +172,7 @@ func EnrollTwoFactorPost(ctx *context.Context) {
|
||||
ctx.Data["Title"] = ctx.Tr("settings")
|
||||
ctx.Data["PageIsSettingsSecurity"] = true
|
||||
|
||||
t, err := auth.GetTwoFactorByUID(ctx.User.ID)
|
||||
t, err := auth.GetTwoFactorByUID(ctx.Doer.ID)
|
||||
if t != nil {
|
||||
// already enrolled
|
||||
ctx.Flash.Error(ctx.Tr("settings.twofa_is_enrolled"))
|
||||
@@ -210,7 +210,7 @@ func EnrollTwoFactorPost(ctx *context.Context) {
|
||||
}
|
||||
|
||||
t = &auth.TwoFactor{
|
||||
UID: ctx.User.ID,
|
||||
UID: ctx.Doer.ID,
|
||||
}
|
||||
err = t.SetSecret(secret)
|
||||
if err != nil {
|
||||
|
||||
@@ -45,7 +45,7 @@ func OpenIDPost(ctx *context.Context) {
|
||||
form.Openid = id
|
||||
log.Trace("Normalized id: " + id)
|
||||
|
||||
oids, err := user_model.GetUserOpenIDs(ctx.User.ID)
|
||||
oids, err := user_model.GetUserOpenIDs(ctx.Doer.ID)
|
||||
if err != nil {
|
||||
ctx.ServerError("GetUserOpenIDs", err)
|
||||
return
|
||||
@@ -89,7 +89,7 @@ func settingsOpenIDVerify(ctx *context.Context) {
|
||||
|
||||
log.Trace("Verified ID: " + id)
|
||||
|
||||
oid := &user_model.UserOpenID{UID: ctx.User.ID, URI: id}
|
||||
oid := &user_model.UserOpenID{UID: ctx.Doer.ID, URI: id}
|
||||
if err = user_model.AddUserOpenID(oid); err != nil {
|
||||
if user_model.IsErrOpenIDAlreadyUsed(err) {
|
||||
ctx.RenderWithErr(ctx.Tr("form.openid_been_used", id), tplSettingsSecurity, &forms.AddOpenIDForm{Openid: id})
|
||||
@@ -98,7 +98,7 @@ func settingsOpenIDVerify(ctx *context.Context) {
|
||||
ctx.ServerError("AddUserOpenID", err)
|
||||
return
|
||||
}
|
||||
log.Trace("Associated OpenID %s to user %s", id, ctx.User.Name)
|
||||
log.Trace("Associated OpenID %s to user %s", id, ctx.Doer.Name)
|
||||
ctx.Flash.Success(ctx.Tr("settings.add_openid_success"))
|
||||
|
||||
ctx.Redirect(setting.AppSubURL + "/user/settings/security")
|
||||
@@ -106,11 +106,11 @@ func settingsOpenIDVerify(ctx *context.Context) {
|
||||
|
||||
// DeleteOpenID response for delete user's openid
|
||||
func DeleteOpenID(ctx *context.Context) {
|
||||
if err := user_model.DeleteUserOpenID(&user_model.UserOpenID{ID: ctx.FormInt64("id"), UID: ctx.User.ID}); err != nil {
|
||||
if err := user_model.DeleteUserOpenID(&user_model.UserOpenID{ID: ctx.FormInt64("id"), UID: ctx.Doer.ID}); err != nil {
|
||||
ctx.ServerError("DeleteUserOpenID", err)
|
||||
return
|
||||
}
|
||||
log.Trace("OpenID address deleted: %s", ctx.User.Name)
|
||||
log.Trace("OpenID address deleted: %s", ctx.Doer.Name)
|
||||
|
||||
ctx.Flash.Success(ctx.Tr("settings.openid_deletion_success"))
|
||||
ctx.JSON(http.StatusOK, map[string]interface{}{
|
||||
|
||||
@@ -43,7 +43,7 @@ func DeleteAccountLink(ctx *context.Context) {
|
||||
if id <= 0 {
|
||||
ctx.Flash.Error("Account link id is not given")
|
||||
} else {
|
||||
if _, err := user_model.RemoveAccountLink(ctx.User, id); err != nil {
|
||||
if _, err := user_model.RemoveAccountLink(ctx.Doer, id); err != nil {
|
||||
ctx.Flash.Error("RemoveAccountLink: " + err.Error())
|
||||
} else {
|
||||
ctx.Flash.Success(ctx.Tr("settings.remove_account_link_success"))
|
||||
@@ -56,28 +56,28 @@ func DeleteAccountLink(ctx *context.Context) {
|
||||
}
|
||||
|
||||
func loadSecurityData(ctx *context.Context) {
|
||||
enrolled, err := auth.HasTwoFactorByUID(ctx.User.ID)
|
||||
enrolled, err := auth.HasTwoFactorByUID(ctx.Doer.ID)
|
||||
if err != nil {
|
||||
ctx.ServerError("SettingsTwoFactor", err)
|
||||
return
|
||||
}
|
||||
ctx.Data["TOTPEnrolled"] = enrolled
|
||||
|
||||
credentials, err := auth.GetWebAuthnCredentialsByUID(ctx.User.ID)
|
||||
credentials, err := auth.GetWebAuthnCredentialsByUID(ctx.Doer.ID)
|
||||
if err != nil {
|
||||
ctx.ServerError("GetWebAuthnCredentialsByUID", err)
|
||||
return
|
||||
}
|
||||
ctx.Data["WebAuthnCredentials"] = credentials
|
||||
|
||||
tokens, err := models.ListAccessTokens(models.ListAccessTokensOptions{UserID: ctx.User.ID})
|
||||
tokens, err := models.ListAccessTokens(models.ListAccessTokensOptions{UserID: ctx.Doer.ID})
|
||||
if err != nil {
|
||||
ctx.ServerError("ListAccessTokens", err)
|
||||
return
|
||||
}
|
||||
ctx.Data["Tokens"] = tokens
|
||||
|
||||
accountLinks, err := user_model.ListAccountLinks(ctx.User)
|
||||
accountLinks, err := user_model.ListAccountLinks(ctx.Doer)
|
||||
if err != nil {
|
||||
ctx.ServerError("ListAccountLinks", err)
|
||||
return
|
||||
@@ -109,7 +109,7 @@ func loadSecurityData(ctx *context.Context) {
|
||||
}
|
||||
ctx.Data["AccountLinks"] = sources
|
||||
|
||||
openid, err := user_model.GetUserOpenIDs(ctx.User.ID)
|
||||
openid, err := user_model.GetUserOpenIDs(ctx.Doer.ID)
|
||||
if err != nil {
|
||||
ctx.ServerError("GetUserOpenIDs", err)
|
||||
return
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user