aboutsummaryrefslogtreecommitdiff
path: root/routers
diff options
context:
space:
mode:
authorUnknwon <u@gogs.io>2017-06-11 00:34:14 -0400
committerUnknwon <u@gogs.io>2017-06-11 00:34:14 -0400
commit4400d2fdd933204044aeb18ce7d8613c53aa87c0 (patch)
tree841e91d5294c49b7335170fbc4b9ff79e882f91a /routers
parent6197a7639a88f7fb0fee8927e1d501504ae770ff (diff)
Refactoring: rename package routers -> routes
Diffstat (limited to 'routers')
-rw-r--r--routers/admin/admin.go258
-rw-r--r--routers/admin/auths.go265
-rw-r--r--routers/admin/notice.go72
-rw-r--r--routers/admin/orgs.go31
-rw-r--r--routers/admin/repos.go87
-rw-r--r--routers/admin/users.go262
-rw-r--r--routers/api/v1/admin/org.go44
-rw-r--r--routers/api/v1/admin/org_repo.go50
-rw-r--r--routers/api/v1/admin/org_team.go60
-rw-r--r--routers/api/v1/admin/repo.go23
-rw-r--r--routers/api/v1/admin/user.go160
-rw-r--r--routers/api/v1/api.go356
-rw-r--r--routers/api/v1/convert/convert.go127
-rw-r--r--routers/api/v1/convert/utils.go19
-rw-r--r--routers/api/v1/misc/markdown.go42
-rw-r--r--routers/api/v1/org/org.go66
-rw-r--r--routers/api/v1/org/team.go26
-rw-r--r--routers/api/v1/repo/branch.go55
-rw-r--r--routers/api/v1/repo/collaborators.go94
-rw-r--r--routers/api/v1/repo/file.go72
-rw-r--r--routers/api/v1/repo/hook.go186
-rw-r--r--routers/api/v1/repo/issue.go201
-rw-r--r--routers/api/v1/repo/issue_comment.go128
-rw-r--r--routers/api/v1/repo/issue_label.go169
-rw-r--r--routers/api/v1/repo/key.go114
-rw-r--r--routers/api/v1/repo/label.go110
-rw-r--r--routers/api/v1/repo/milestone.go103
-rw-r--r--routers/api/v1/repo/repo.go380
-rw-r--r--routers/api/v1/user/app.go40
-rw-r--r--routers/api/v1/user/email.go82
-rw-r--r--routers/api/v1/user/follower.go120
-rw-r--r--routers/api/v1/user/key.go120
-rw-r--r--routers/api/v1/user/user.go75
-rw-r--r--routers/dev/template.go24
-rw-r--r--routers/home.go163
-rw-r--r--routers/install.go392
-rw-r--r--routers/org/members.go123
-rw-r--r--routers/org/org.go56
-rw-r--r--routers/org/setting.go168
-rw-r--r--routers/org/teams.go271
-rw-r--r--routers/repo/branch.go142
-rw-r--r--routers/repo/commit.go239
-rw-r--r--routers/repo/download.go60
-rw-r--r--routers/repo/editor.go571
-rw-r--r--routers/repo/http.go447
-rw-r--r--routers/repo/issue.go1263
-rw-r--r--routers/repo/pull.go763
-rw-r--r--routers/repo/release.go332
-rw-r--r--routers/repo/repo.go335
-rw-r--r--routers/repo/setting.go631
-rw-r--r--routers/repo/view.go367
-rw-r--r--routers/repo/webhook.go558
-rw-r--r--routers/repo/wiki.go274
-rw-r--r--routers/user/auth.go534
-rw-r--r--routers/user/home.go424
-rw-r--r--routers/user/profile.go169
-rw-r--r--routers/user/setting.go664
57 files changed, 0 insertions, 12967 deletions
diff --git a/routers/admin/admin.go b/routers/admin/admin.go
deleted file mode 100644
index 0d5eb7a6..00000000
--- a/routers/admin/admin.go
+++ /dev/null
@@ -1,258 +0,0 @@
-// 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 (
- "encoding/json"
- "fmt"
- "runtime"
- "strings"
- "time"
-
- "github.com/Unknwon/com"
- "gopkg.in/macaron.v1"
-
- "github.com/gogits/gogs/models"
- "github.com/gogits/gogs/pkg/context"
- "github.com/gogits/gogs/pkg/cron"
- "github.com/gogits/gogs/pkg/mailer"
- "github.com/gogits/gogs/pkg/process"
- "github.com/gogits/gogs/pkg/setting"
- "github.com/gogits/gogs/pkg/tool"
-)
-
-const (
- DASHBOARD = "admin/dashboard"
- CONFIG = "admin/config"
- MONITOR = "admin/monitor"
-)
-
-var (
- startTime = time.Now()
-)
-
-var sysStatus struct {
- Uptime string
- NumGoroutine int
-
- // General statistics.
- MemAllocated string // bytes allocated and still in use
- MemTotal string // bytes allocated (even if freed)
- MemSys string // bytes obtained from system (sum of XxxSys below)
- Lookups uint64 // number of pointer lookups
- MemMallocs uint64 // number of mallocs
- MemFrees uint64 // number of frees
-
- // Main allocation heap statistics.
- HeapAlloc string // bytes allocated and still in use
- HeapSys string // bytes obtained from system
- HeapIdle string // bytes in idle spans
- HeapInuse string // bytes in non-idle span
- HeapReleased string // bytes released to the OS
- HeapObjects uint64 // total number of allocated objects
-
- // Low-level fixed-size structure allocator statistics.
- // Inuse is bytes used now.
- // Sys is bytes obtained from system.
- StackInuse string // bootstrap stacks
- StackSys string
- MSpanInuse string // mspan structures
- MSpanSys string
- MCacheInuse string // mcache structures
- MCacheSys string
- BuckHashSys string // profiling bucket hash table
- GCSys string // GC metadata
- OtherSys string // other system allocations
-
- // Garbage collector statistics.
- NextGC string // next run in HeapAlloc time (bytes)
- LastGC string // last run in absolute time (ns)
- PauseTotalNs string
- PauseNs string // circular buffer of recent GC pause times, most recent at [(NumGC+255)%256]
- NumGC uint32
-}
-
-func updateSystemStatus() {
- sysStatus.Uptime = tool.TimeSincePro(startTime)
-
- m := new(runtime.MemStats)
- runtime.ReadMemStats(m)
- sysStatus.NumGoroutine = runtime.NumGoroutine()
-
- sysStatus.MemAllocated = tool.FileSize(int64(m.Alloc))
- sysStatus.MemTotal = tool.FileSize(int64(m.TotalAlloc))
- sysStatus.MemSys = tool.FileSize(int64(m.Sys))
- sysStatus.Lookups = m.Lookups
- sysStatus.MemMallocs = m.Mallocs
- sysStatus.MemFrees = m.Frees
-
- sysStatus.HeapAlloc = tool.FileSize(int64(m.HeapAlloc))
- sysStatus.HeapSys = tool.FileSize(int64(m.HeapSys))
- sysStatus.HeapIdle = tool.FileSize(int64(m.HeapIdle))
- sysStatus.HeapInuse = tool.FileSize(int64(m.HeapInuse))
- sysStatus.HeapReleased = tool.FileSize(int64(m.HeapReleased))
- sysStatus.HeapObjects = m.HeapObjects
-
- sysStatus.StackInuse = tool.FileSize(int64(m.StackInuse))
- sysStatus.StackSys = tool.FileSize(int64(m.StackSys))
- sysStatus.MSpanInuse = tool.FileSize(int64(m.MSpanInuse))
- sysStatus.MSpanSys = tool.FileSize(int64(m.MSpanSys))
- sysStatus.MCacheInuse = tool.FileSize(int64(m.MCacheInuse))
- sysStatus.MCacheSys = tool.FileSize(int64(m.MCacheSys))
- sysStatus.BuckHashSys = tool.FileSize(int64(m.BuckHashSys))
- sysStatus.GCSys = tool.FileSize(int64(m.GCSys))
- sysStatus.OtherSys = tool.FileSize(int64(m.OtherSys))
-
- sysStatus.NextGC = tool.FileSize(int64(m.NextGC))
- sysStatus.LastGC = fmt.Sprintf("%.1fs", float64(time.Now().UnixNano()-int64(m.LastGC))/1000/1000/1000)
- sysStatus.PauseTotalNs = fmt.Sprintf("%.1fs", float64(m.PauseTotalNs)/1000/1000/1000)
- sysStatus.PauseNs = fmt.Sprintf("%.3fs", float64(m.PauseNs[(m.NumGC+255)%256])/1000/1000/1000)
- sysStatus.NumGC = m.NumGC
-}
-
-// Operation types.
-type AdminOperation int
-
-const (
- CLEAN_INACTIVATE_USER AdminOperation = iota + 1
- CLEAN_REPO_ARCHIVES
- CLEAN_MISSING_REPOS
- GIT_GC_REPOS
- SYNC_SSH_AUTHORIZED_KEY
- SYNC_REPOSITORY_HOOKS
- REINIT_MISSING_REPOSITORY
-)
-
-func Dashboard(c *context.Context) {
- c.Data["Title"] = c.Tr("admin.dashboard")
- c.Data["PageIsAdmin"] = true
- c.Data["PageIsAdminDashboard"] = true
-
- // Run operation.
- op, _ := com.StrTo(c.Query("op")).Int()
- if op > 0 {
- var err error
- var success string
-
- switch AdminOperation(op) {
- case CLEAN_INACTIVATE_USER:
- success = c.Tr("admin.dashboard.delete_inactivate_accounts_success")
- err = models.DeleteInactivateUsers()
- case CLEAN_REPO_ARCHIVES:
- success = c.Tr("admin.dashboard.delete_repo_archives_success")
- err = models.DeleteRepositoryArchives()
- case CLEAN_MISSING_REPOS:
- success = c.Tr("admin.dashboard.delete_missing_repos_success")
- err = models.DeleteMissingRepositories()
- case GIT_GC_REPOS:
- success = c.Tr("admin.dashboard.git_gc_repos_success")
- err = models.GitGcRepos()
- case SYNC_SSH_AUTHORIZED_KEY:
- success = c.Tr("admin.dashboard.resync_all_sshkeys_success")
- err = models.RewriteAllPublicKeys()
- case SYNC_REPOSITORY_HOOKS:
- success = c.Tr("admin.dashboard.resync_all_hooks_success")
- err = models.SyncRepositoryHooks()
- case REINIT_MISSING_REPOSITORY:
- success = c.Tr("admin.dashboard.reinit_missing_repos_success")
- err = models.ReinitMissingRepositories()
- }
-
- if err != nil {
- c.Flash.Error(err.Error())
- } else {
- c.Flash.Success(success)
- }
- c.Redirect(setting.AppSubURL + "/admin")
- return
- }
-
- c.Data["Stats"] = models.GetStatistic()
- // FIXME: update periodically
- updateSystemStatus()
- c.Data["SysStatus"] = sysStatus
- c.HTML(200, DASHBOARD)
-}
-
-func SendTestMail(c *context.Context) {
- email := c.Query("email")
- // Send a test email to the user's email address and redirect back to Config
- if err := mailer.SendTestMail(email); err != nil {
- c.Flash.Error(c.Tr("admin.config.test_mail_failed", email, err))
- } else {
- c.Flash.Info(c.Tr("admin.config.test_mail_sent", email))
- }
-
- c.Redirect(setting.AppSubURL + "/admin/config")
-}
-
-func Config(c *context.Context) {
- c.Data["Title"] = c.Tr("admin.config")
- c.Data["PageIsAdmin"] = true
- c.Data["PageIsAdminConfig"] = true
-
- c.Data["AppURL"] = setting.AppURL
- c.Data["Domain"] = setting.Domain
- c.Data["OfflineMode"] = setting.OfflineMode
- c.Data["DisableRouterLog"] = setting.DisableRouterLog
- c.Data["RunUser"] = setting.RunUser
- c.Data["RunMode"] = strings.Title(macaron.Env)
- c.Data["StaticRootPath"] = setting.StaticRootPath
- c.Data["LogRootPath"] = setting.LogRootPath
- c.Data["ReverseProxyAuthUser"] = setting.ReverseProxyAuthUser
-
- c.Data["SSH"] = setting.SSH
-
- c.Data["RepoRootPath"] = setting.RepoRootPath
- c.Data["ScriptType"] = setting.ScriptType
- c.Data["Repository"] = setting.Repository
-
- c.Data["Service"] = setting.Service
- c.Data["DbCfg"] = models.DbCfg
- c.Data["Webhook"] = setting.Webhook
-
- c.Data["MailerEnabled"] = false
- if setting.MailService != nil {
- c.Data["MailerEnabled"] = true
- c.Data["Mailer"] = setting.MailService
- }
-
- c.Data["CacheAdapter"] = setting.CacheAdapter
- c.Data["CacheInterval"] = setting.CacheInterval
- c.Data["CacheConn"] = setting.CacheConn
-
- c.Data["SessionConfig"] = setting.SessionConfig
-
- c.Data["DisableGravatar"] = setting.DisableGravatar
- c.Data["EnableFederatedAvatar"] = setting.EnableFederatedAvatar
-
- c.Data["GitVersion"] = setting.Git.Version
- c.Data["Git"] = setting.Git
-
- type logger struct {
- Mode, Config string
- }
- loggers := make([]*logger, len(setting.LogModes))
- for i := range setting.LogModes {
- loggers[i] = &logger{
- Mode: strings.Title(setting.LogModes[i]),
- }
-
- result, _ := json.MarshalIndent(setting.LogConfigs[i], "", " ")
- loggers[i].Config = string(result)
- }
- c.Data["Loggers"] = loggers
-
- c.HTML(200, CONFIG)
-}
-
-func Monitor(c *context.Context) {
- c.Data["Title"] = c.Tr("admin.monitor")
- c.Data["PageIsAdmin"] = true
- c.Data["PageIsAdminMonitor"] = true
- c.Data["Processes"] = process.Processes
- c.Data["Entries"] = cron.ListTasks()
- c.HTML(200, MONITOR)
-}
diff --git a/routers/admin/auths.go b/routers/admin/auths.go
deleted file mode 100644
index 56a0aad6..00000000
--- a/routers/admin/auths.go
+++ /dev/null
@@ -1,265 +0,0 @@
-// 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 (
- "fmt"
-
- "github.com/Unknwon/com"
- "github.com/go-xorm/core"
- log "gopkg.in/clog.v1"
-
- "github.com/gogits/gogs/models"
- "github.com/gogits/gogs/pkg/auth/ldap"
- "github.com/gogits/gogs/pkg/context"
- "github.com/gogits/gogs/pkg/form"
- "github.com/gogits/gogs/pkg/setting"
-)
-
-const (
- AUTHS = "admin/auth/list"
- AUTH_NEW = "admin/auth/new"
- AUTH_EDIT = "admin/auth/edit"
-)
-
-func Authentications(c *context.Context) {
- c.Data["Title"] = c.Tr("admin.authentication")
- c.Data["PageIsAdmin"] = true
- c.Data["PageIsAdminAuthentications"] = true
-
- var err error
- c.Data["Sources"], err = models.LoginSources()
- if err != nil {
- c.Handle(500, "LoginSources", err)
- return
- }
-
- c.Data["Total"] = models.CountLoginSources()
- c.HTML(200, AUTHS)
-}
-
-type dropdownItem struct {
- Name string
- Type interface{}
-}
-
-var (
- authSources = []dropdownItem{
- {models.LoginNames[models.LOGIN_LDAP], models.LOGIN_LDAP},
- {models.LoginNames[models.LOGIN_DLDAP], models.LOGIN_DLDAP},
- {models.LoginNames[models.LOGIN_SMTP], models.LOGIN_SMTP},
- {models.LoginNames[models.LOGIN_PAM], models.LOGIN_PAM},
- }
- securityProtocols = []dropdownItem{
- {models.SecurityProtocolNames[ldap.SECURITY_PROTOCOL_UNENCRYPTED], ldap.SECURITY_PROTOCOL_UNENCRYPTED},
- {models.SecurityProtocolNames[ldap.SECURITY_PROTOCOL_LDAPS], ldap.SECURITY_PROTOCOL_LDAPS},
- {models.SecurityProtocolNames[ldap.SECURITY_PROTOCOL_START_TLS], ldap.SECURITY_PROTOCOL_START_TLS},
- }
-)
-
-func NewAuthSource(c *context.Context) {
- c.Data["Title"] = c.Tr("admin.auths.new")
- c.Data["PageIsAdmin"] = true
- c.Data["PageIsAdminAuthentications"] = true
-
- c.Data["type"] = models.LOGIN_LDAP
- c.Data["CurrentTypeName"] = models.LoginNames[models.LOGIN_LDAP]
- c.Data["CurrentSecurityProtocol"] = models.SecurityProtocolNames[ldap.SECURITY_PROTOCOL_UNENCRYPTED]
- c.Data["smtp_auth"] = "PLAIN"
- c.Data["is_active"] = true
- c.Data["AuthSources"] = authSources
- c.Data["SecurityProtocols"] = securityProtocols
- c.Data["SMTPAuths"] = models.SMTPAuths
- c.HTML(200, AUTH_NEW)
-}
-
-func parseLDAPConfig(f form.Authentication) *models.LDAPConfig {
- return &models.LDAPConfig{
- Source: &ldap.Source{
- Name: f.Name,
- Host: f.Host,
- Port: f.Port,
- SecurityProtocol: ldap.SecurityProtocol(f.SecurityProtocol),
- SkipVerify: f.SkipVerify,
- BindDN: f.BindDN,
- UserDN: f.UserDN,
- BindPassword: f.BindPassword,
- UserBase: f.UserBase,
- AttributeUsername: f.AttributeUsername,
- AttributeName: f.AttributeName,
- AttributeSurname: f.AttributeSurname,
- AttributeMail: f.AttributeMail,
- AttributesInBind: f.AttributesInBind,
- Filter: f.Filter,
- GroupEnabled: f.GroupEnabled,
- GroupDN: f.GroupDN,
- GroupFilter: f.GroupFilter,
- GroupMemberUID: f.GroupMemberUID,
- UserUID: f.UserUID,
- AdminFilter: f.AdminFilter,
- Enabled: true,
- },
- }
-}
-
-func parseSMTPConfig(f form.Authentication) *models.SMTPConfig {
- return &models.SMTPConfig{
- Auth: f.SMTPAuth,
- Host: f.SMTPHost,
- Port: f.SMTPPort,
- AllowedDomains: f.AllowedDomains,
- TLS: f.TLS,
- SkipVerify: f.SkipVerify,
- }
-}
-
-func NewAuthSourcePost(c *context.Context, f form.Authentication) {
- c.Data["Title"] = c.Tr("admin.auths.new")
- c.Data["PageIsAdmin"] = true
- c.Data["PageIsAdminAuthentications"] = true
-
- c.Data["CurrentTypeName"] = models.LoginNames[models.LoginType(f.Type)]
- c.Data["CurrentSecurityProtocol"] = models.SecurityProtocolNames[ldap.SecurityProtocol(f.SecurityProtocol)]
- c.Data["AuthSources"] = authSources
- c.Data["SecurityProtocols"] = securityProtocols
- c.Data["SMTPAuths"] = models.SMTPAuths
-
- hasTLS := false
- var config core.Conversion
- switch models.LoginType(f.Type) {
- case models.LOGIN_LDAP, models.LOGIN_DLDAP:
- config = parseLDAPConfig(f)
- hasTLS = ldap.SecurityProtocol(f.SecurityProtocol) > ldap.SECURITY_PROTOCOL_UNENCRYPTED
- case models.LOGIN_SMTP:
- config = parseSMTPConfig(f)
- hasTLS = true
- case models.LOGIN_PAM:
- config = &models.PAMConfig{
- ServiceName: f.PAMServiceName,
- }
- default:
- c.Error(400)
- return
- }
- c.Data["HasTLS"] = hasTLS
-
- if c.HasError() {
- c.HTML(200, AUTH_NEW)
- return
- }
-
- if err := models.CreateLoginSource(&models.LoginSource{
- Type: models.LoginType(f.Type),
- Name: f.Name,
- IsActived: f.IsActive,
- Cfg: config,
- }); err != nil {
- if models.IsErrLoginSourceAlreadyExist(err) {
- c.Data["Err_Name"] = true
- c.RenderWithErr(c.Tr("admin.auths.login_source_exist", err.(models.ErrLoginSourceAlreadyExist).Name), AUTH_NEW, f)
- } else {
- c.Handle(500, "CreateSource", err)
- }
- return
- }
-
- log.Trace("Authentication created by admin(%s): %s", c.User.Name, f.Name)
-
- c.Flash.Success(c.Tr("admin.auths.new_success", f.Name))
- c.Redirect(setting.AppSubURL + "/admin/auths")
-}
-
-func EditAuthSource(c *context.Context) {
- c.Data["Title"] = c.Tr("admin.auths.edit")
- c.Data["PageIsAdmin"] = true
- c.Data["PageIsAdminAuthentications"] = true
-
- c.Data["SecurityProtocols"] = securityProtocols
- c.Data["SMTPAuths"] = models.SMTPAuths
-
- source, err := models.GetLoginSourceByID(c.ParamsInt64(":authid"))
- if err != nil {
- c.Handle(500, "GetLoginSourceByID", err)
- return
- }
- c.Data["Source"] = source
- c.Data["HasTLS"] = source.HasTLS()
-
- c.HTML(200, AUTH_EDIT)
-}
-
-func EditAuthSourcePost(c *context.Context, f form.Authentication) {
- c.Data["Title"] = c.Tr("admin.auths.edit")
- c.Data["PageIsAdmin"] = true
- c.Data["PageIsAdminAuthentications"] = true
-
- c.Data["SMTPAuths"] = models.SMTPAuths
-
- source, err := models.GetLoginSourceByID(c.ParamsInt64(":authid"))
- if err != nil {
- c.Handle(500, "GetLoginSourceByID", err)
- return
- }
- c.Data["Source"] = source
- c.Data["HasTLS"] = source.HasTLS()
-
- if c.HasError() {
- c.HTML(200, AUTH_EDIT)
- return
- }
-
- var config core.Conversion
- switch models.LoginType(f.Type) {
- case models.LOGIN_LDAP, models.LOGIN_DLDAP:
- config = parseLDAPConfig(f)
- case models.LOGIN_SMTP:
- config = parseSMTPConfig(f)
- case models.LOGIN_PAM:
- config = &models.PAMConfig{
- ServiceName: f.PAMServiceName,
- }
- default:
- c.Error(400)
- return
- }
-
- source.Name = f.Name
- source.IsActived = f.IsActive
- source.Cfg = config
- if err := models.UpdateSource(source); err != nil {
- c.Handle(500, "UpdateSource", err)
- return
- }
- log.Trace("Authentication changed by admin(%s): %d", c.User.Name, source.ID)
-
- c.Flash.Success(c.Tr("admin.auths.update_success"))
- c.Redirect(setting.AppSubURL + "/admin/auths/" + com.ToStr(f.ID))
-}
-
-func DeleteAuthSource(c *context.Context) {
- source, err := models.GetLoginSourceByID(c.ParamsInt64(":authid"))
- if err != nil {
- c.Handle(500, "GetLoginSourceByID", err)
- return
- }
-
- if err = models.DeleteSource(source); err != nil {
- if models.IsErrLoginSourceInUse(err) {
- c.Flash.Error(c.Tr("admin.auths.still_in_used"))
- } else {
- c.Flash.Error(fmt.Sprintf("DeleteSource: %v", err))
- }
- c.JSON(200, map[string]interface{}{
- "redirect": setting.AppSubURL + "/admin/auths/" + c.Params(":authid"),
- })
- return
- }
- log.Trace("Authentication deleted by admin(%s): %d", c.User.Name, source.ID)
-
- c.Flash.Success(c.Tr("admin.auths.deletion_success"))
- c.JSON(200, map[string]interface{}{
- "redirect": setting.AppSubURL + "/admin/auths",
- })
-}
diff --git a/routers/admin/notice.go b/routers/admin/notice.go
deleted file mode 100644
index c743a1da..00000000
--- a/routers/admin/notice.go
+++ /dev/null
@@ -1,72 +0,0 @@
-// 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 (
- "github.com/Unknwon/com"
- "github.com/Unknwon/paginater"
- log "gopkg.in/clog.v1"
-
- "github.com/gogits/gogs/models"
- "github.com/gogits/gogs/pkg/context"
- "github.com/gogits/gogs/pkg/setting"
-)
-
-const (
- NOTICES = "admin/notice"
-)
-
-func Notices(c *context.Context) {
- c.Data["Title"] = c.Tr("admin.notices")
- c.Data["PageIsAdmin"] = true
- c.Data["PageIsAdminNotices"] = true
-
- total := models.CountNotices()
- page := c.QueryInt("page")
- if page <= 1 {
- page = 1
- }
- c.Data["Page"] = paginater.New(int(total), setting.UI.Admin.NoticePagingNum, page, 5)
-
- notices, err := models.Notices(page, setting.UI.Admin.NoticePagingNum)
- if err != nil {
- c.Handle(500, "Notices", err)
- return
- }
- c.Data["Notices"] = notices
-
- c.Data["Total"] = total
- c.HTML(200, NOTICES)
-}
-
-func DeleteNotices(c *context.Context) {
- strs := c.QueryStrings("ids[]")
- ids := make([]int64, 0, len(strs))
- for i := range strs {
- id := com.StrTo(strs[i]).MustInt64()
- if id > 0 {
- ids = append(ids, id)
- }
- }
-
- if err := models.DeleteNoticesByIDs(ids); err != nil {
- c.Flash.Error("DeleteNoticesByIDs: " + err.Error())
- c.Status(500)
- } else {
- c.Flash.Success(c.Tr("admin.notices.delete_success"))
- c.Status(200)
- }
-}
-
-func EmptyNotices(c *context.Context) {
- if err := models.DeleteNotices(0, 0); err != nil {
- c.Handle(500, "DeleteNotices", err)
- return
- }
-
- log.Trace("System notices deleted by admin (%s): [start: %d]", c.User.Name, 0)
- c.Flash.Success(c.Tr("admin.notices.delete_success"))
- c.Redirect(setting.AppSubURL + "/admin/notices")
-}
diff --git a/routers/admin/orgs.go b/routers/admin/orgs.go
deleted file mode 100644
index 4b995acd..00000000
--- a/routers/admin/orgs.go
+++ /dev/null
@@ -1,31 +0,0 @@
-// 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 (
- "github.com/gogits/gogs/models"
- "github.com/gogits/gogs/pkg/context"
- "github.com/gogits/gogs/pkg/setting"
- "github.com/gogits/gogs/routers"
-)
-
-const (
- ORGS = "admin/org/list"
-)
-
-func Organizations(c *context.Context) {
- c.Data["Title"] = c.Tr("admin.organizations")
- c.Data["PageIsAdmin"] = true
- c.Data["PageIsAdminOrganizations"] = true
-
- routers.RenderUserSearch(c, &routers.UserSearchOptions{
- Type: models.USER_TYPE_ORGANIZATION,
- Counter: models.CountOrganizations,
- Ranger: models.Organizations,
- PageSize: setting.UI.Admin.OrgPagingNum,
- OrderBy: "id ASC",
- TplName: ORGS,
- })
-}
diff --git a/routers/admin/repos.go b/routers/admin/repos.go
deleted file mode 100644
index b4fa2266..00000000
--- a/routers/admin/repos.go
+++ /dev/null
@@ -1,87 +0,0 @@
-// 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 (
- "github.com/Unknwon/paginater"
- log "gopkg.in/clog.v1"
-
- "github.com/gogits/gogs/models"
- "github.com/gogits/gogs/pkg/context"
- "github.com/gogits/gogs/pkg/setting"
-)
-
-const (
- REPOS = "admin/repo/list"
-)
-
-func Repos(c *context.Context) {
- c.Data["Title"] = c.Tr("admin.repositories")
- c.Data["PageIsAdmin"] = true
- c.Data["PageIsAdminRepositories"] = true
-
- page := c.QueryInt("page")
- if page <= 0 {
- page = 1
- }
-
- var (
- repos []*models.Repository
- count int64
- err error
- )
-
- keyword := c.Query("q")
- if len(keyword) == 0 {
- repos, err = models.Repositories(page, setting.UI.Admin.RepoPagingNum)
- if err != nil {
- c.Handle(500, "Repositories", err)
- return
- }
- count = models.CountRepositories(true)
- } else {
- repos, count, err = models.SearchRepositoryByName(&models.SearchRepoOptions{
- Keyword: keyword,
- OrderBy: "id ASC",
- Private: true,
- Page: page,
- PageSize: setting.UI.Admin.RepoPagingNum,
- })
- if err != nil {
- c.Handle(500, "SearchRepositoryByName", err)
- return
- }
- }
- c.Data["Keyword"] = keyword
- c.Data["Total"] = count
- c.Data["Page"] = paginater.New(int(count), setting.UI.Admin.RepoPagingNum, page, 5)
-
- if err = models.RepositoryList(repos).LoadAttributes(); err != nil {
- c.Handle(500, "LoadAttributes", err)
- return
- }
- c.Data["Repos"] = repos
-
- c.HTML(200, REPOS)
-}
-
-func DeleteRepo(c *context.Context) {
- repo, err := models.GetRepositoryByID(c.QueryInt64("id"))
- if err != nil {
- c.Handle(500, "GetRepositoryByID", err)
- return
- }
-
- if err := models.DeleteRepository(repo.MustOwner().ID, repo.ID); err != nil {
- c.Handle(500, "DeleteRepository", err)
- return
- }
- log.Trace("Repository deleted: %s/%s", repo.MustOwner().Name, repo.Name)
-
- c.Flash.Success(c.Tr("repo.settings.deletion_success"))
- c.JSON(200, map[string]interface{}{
- "redirect": setting.AppSubURL + "/admin/repos?page=" + c.Query("page"),
- })
-}
diff --git a/routers/admin/users.go b/routers/admin/users.go
deleted file mode 100644
index 237f2dc6..00000000
--- a/routers/admin/users.go
+++ /dev/null
@@ -1,262 +0,0 @@
-// 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 (
- "strings"
-
- "github.com/Unknwon/com"
- log "gopkg.in/clog.v1"
-
- "github.com/gogits/gogs/models"
- "github.com/gogits/gogs/pkg/context"
- "github.com/gogits/gogs/pkg/form"
- "github.com/gogits/gogs/pkg/mailer"
- "github.com/gogits/gogs/pkg/setting"
- "github.com/gogits/gogs/routers"
-)
-
-const (
- USERS = "admin/user/list"
- USER_NEW = "admin/user/new"
- USER_EDIT = "admin/user/edit"
-)
-
-func Users(c *context.Context) {
- c.Data["Title"] = c.Tr("admin.users")
- c.Data["PageIsAdmin"] = true
- c.Data["PageIsAdminUsers"] = true
-
- routers.RenderUserSearch(c, &routers.UserSearchOptions{
- Type: models.USER_TYPE_INDIVIDUAL,
- Counter: models.CountUsers,
- Ranger: models.Users,
- PageSize: setting.UI.Admin.UserPagingNum,
- OrderBy: "id ASC",
- TplName: USERS,
- })
-}
-
-func NewUser(c *context.Context) {
- c.Data["Title"] = c.Tr("admin.users.new_account")
- c.Data["PageIsAdmin"] = true
- c.Data["PageIsAdminUsers"] = true
-
- c.Data["login_type"] = "0-0"
-
- sources, err := models.LoginSources()
- if err != nil {
- c.Handle(500, "LoginSources", err)
- return
- }
- c.Data["Sources"] = sources
-
- c.Data["CanSendEmail"] = setting.MailService != nil
- c.HTML(200, USER_NEW)
-}
-
-func NewUserPost(c *context.Context, f form.AdminCrateUser) {
- c.Data["Title"] = c.Tr("admin.users.new_account")
- c.Data["PageIsAdmin"] = true
- c.Data["PageIsAdminUsers"] = true
-
- sources, err := models.LoginSources()
- if err != nil {
- c.Handle(500, "LoginSources", err)
- return
- }
- c.Data["Sources"] = sources
-
- c.Data["CanSendEmail"] = setting.MailService != nil
-
- if c.HasError() {
- c.HTML(200, USER_NEW)
- return
- }
-
- u := &models.User{
- Name: f.UserName,
- Email: f.Email,
- Passwd: f.Password,
- IsActive: true,
- LoginType: models.LOGIN_PLAIN,
- }
-
- if len(f.LoginType) > 0 {
- fields := strings.Split(f.LoginType, "-")
- if len(fields) == 2 {
- u.LoginType = models.LoginType(com.StrTo(fields[0]).MustInt())
- u.LoginSource = com.StrTo(fields[1]).MustInt64()
- u.LoginName = f.LoginName
- }
- }
-
- if err := models.CreateUser(u); err != nil {
- switch {
- case models.IsErrUserAlreadyExist(err):
- c.Data["Err_UserName"] = true
- c.RenderWithErr(c.Tr("form.username_been_taken"), USER_NEW, &f)
- case models.IsErrEmailAlreadyUsed(err):
- c.Data["Err_Email"] = true
- c.RenderWithErr(c.Tr("form.email_been_used"), USER_NEW, &f)
- case models.IsErrNameReserved(err):
- c.Data["Err_UserName"] = true
- c.RenderWithErr(c.Tr("user.form.name_reserved", err.(models.ErrNameReserved).Name), USER_NEW, &f)
- case models.IsErrNamePatternNotAllowed(err):
- c.Data["Err_UserName"] = true
- c.RenderWithErr(c.Tr("user.form.name_pattern_not_allowed", err.(models.ErrNamePatternNotAllowed).Pattern), USER_NEW, &f)
- default:
- c.Handle(500, "CreateUser", err)
- }
- return
- }
- log.Trace("Account created by admin (%s): %s", c.User.Name, u.Name)
-
- // Send email notification.
- if f.SendNotify && setting.MailService != nil {
- mailer.SendRegisterNotifyMail(c.Context, models.NewMailerUser(u))
- }
-
- c.Flash.Success(c.Tr("admin.users.new_success", u.Name))
- c.Redirect(setting.AppSubURL + "/admin/users/" + com.ToStr(u.ID))
-}
-
-func prepareUserInfo(c *context.Context) *models.User {
- u, err := models.GetUserByID(c.ParamsInt64(":userid"))
- if err != nil {
- c.Handle(500, "GetUserByID", err)
- return nil
- }
- c.Data["User"] = u
-
- if u.LoginSource > 0 {
- c.Data["LoginSource"], err = models.GetLoginSourceByID(u.LoginSource)
- if err != nil {
- c.Handle(500, "GetLoginSourceByID", err)
- return nil
- }
- } else {
- c.Data["LoginSource"] = &models.LoginSource{}
- }
-
- sources, err := models.LoginSources()
- if err != nil {
- c.Handle(500, "LoginSources", err)
- return nil
- }
- c.Data["Sources"] = sources
-
- return u
-}
-
-func EditUser(c *context.Context) {
- c.Data["Title"] = c.Tr("admin.users.edit_account")
- c.Data["PageIsAdmin"] = true
- c.Data["PageIsAdminUsers"] = true
- c.Data["EnableLocalPathMigration"] = setting.Repository.EnableLocalPathMigration
-
- prepareUserInfo(c)
- if c.Written() {
- return
- }
-
- c.HTML(200, USER_EDIT)
-}
-
-func EditUserPost(c *context.Context, f form.AdminEditUser) {
- c.Data["Title"] = c.Tr("admin.users.edit_account")
- c.Data["PageIsAdmin"] = true
- c.Data["PageIsAdminUsers"] = true
- c.Data["EnableLocalPathMigration"] = setting.Repository.EnableLocalPathMigration
-
- u := prepareUserInfo(c)
- if c.Written() {
- return
- }
-
- if c.HasError() {
- c.HTML(200, USER_EDIT)
- return
- }
-
- fields := strings.Split(f.LoginType, "-")
- if len(fields) == 2 {
- loginType := models.LoginType(com.StrTo(fields[0]).MustInt())
- loginSource := com.StrTo(fields[1]).MustInt64()
-
- if u.LoginSource != loginSource {
- u.LoginSource = loginSource
- u.LoginType = loginType
- }
- }
-
- if len(f.Password) > 0 {
- u.Passwd = f.Password
- var err error
- if u.Salt, err = models.GetUserSalt(); err != nil {
- c.Handle(500, "UpdateUser", err)
- return
- }
- u.EncodePasswd()
- }
-
- u.LoginName = f.LoginName
- u.FullName = f.FullName
- u.Email = f.Email
- u.Website = f.Website
- u.Location = f.Location
- u.MaxRepoCreation = f.MaxRepoCreation
- u.IsActive = f.Active
- u.IsAdmin = f.Admin
- u.AllowGitHook = f.AllowGitHook
- u.AllowImportLocal = f.AllowImportLocal
- u.ProhibitLogin = f.ProhibitLogin
-
- if err := models.UpdateUser(u); err != nil {
- if models.IsErrEmailAlreadyUsed(err) {
- c.Data["Err_Email"] = true
- c.RenderWithErr(c.Tr("form.email_been_used"), USER_EDIT, &f)
- } else {
- c.Handle(500, "UpdateUser", err)
- }
- return
- }
- log.Trace("Account profile updated by admin (%s): %s", c.User.Name, u.Name)
-
- c.Flash.Success(c.Tr("admin.users.update_profile_success"))
- c.Redirect(setting.AppSubURL + "/admin/users/" + c.Params(":userid"))
-}
-
-func DeleteUser(c *context.Context) {
- u, err := models.GetUserByID(c.ParamsInt64(":userid"))
- if err != nil {
- c.Handle(500, "GetUserByID", err)
- return
- }
-
- if err = models.DeleteUser(u); err != nil {
- switch {
- case models.IsErrUserOwnRepos(err):
- c.Flash.Error(c.Tr("admin.users.still_own_repo"))
- c.JSON(200, map[string]interface{}{
- "redirect": setting.AppSubURL + "/admin/users/" + c.Params(":userid"),
- })
- case models.IsErrUserHasOrgs(err):
- c.Flash.Error(c.Tr("admin.users.still_has_org"))
- c.JSON(200, map[string]interface{}{
- "redirect": setting.AppSubURL + "/admin/users/" + c.Params(":userid"),
- })
- default:
- c.Handle(500, "DeleteUser", err)
- }
- return
- }
- log.Trace("Account deleted by admin (%s): %s", c.User.Name, u.Name)
-
- c.Flash.Success(c.Tr("admin.users.deletion_success"))
- c.JSON(200, map[string]interface{}{
- "redirect": setting.AppSubURL + "/admin/users",
- })
-}
diff --git a/routers/api/v1/admin/org.go b/routers/api/v1/admin/org.go
deleted file mode 100644
index 996a83bf..00000000
--- a/routers/api/v1/admin/org.go
+++ /dev/null
@@ -1,44 +0,0 @@
-// Copyright 2015 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 (
- api "github.com/gogits/go-gogs-client"
-
- "github.com/gogits/gogs/models"
- "github.com/gogits/gogs/pkg/context"
- "github.com/gogits/gogs/routers/api/v1/convert"
- "github.com/gogits/gogs/routers/api/v1/user"
-)
-
-// https://github.com/gogits/go-gogs-client/wiki/Administration-Organizations#create-a-new-organization
-func CreateOrg(c *context.APIContext, form api.CreateOrgOption) {
- u := user.GetUserByParams(c)
- if c.Written() {
- return
- }
-
- org := &models.User{
- Name: form.UserName,
- FullName: form.FullName,
- Description: form.Description,
- Website: form.Website,
- Location: form.Location,
- IsActive: true,
- Type: models.USER_TYPE_ORGANIZATION,
- }
- if err := models.CreateOrganization(org, u); err != nil {
- if models.IsErrUserAlreadyExist(err) ||
- models.IsErrNameReserved(err) ||
- models.IsErrNamePatternNotAllowed(err) {
- c.Error(422, "", err)
- } else {
- c.Error(500, "CreateOrganization", err)
- }
- return
- }
-
- c.JSON(201, convert.ToOrganization(org))
-}
diff --git a/routers/api/v1/admin/org_repo.go b/routers/api/v1/admin/org_repo.go
deleted file mode 100644
index 7abad1a8..00000000
--- a/routers/api/v1/admin/org_repo.go
+++ /dev/null
@@ -1,50 +0,0 @@
-// Copyright 2016 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 (
- "github.com/gogits/gogs/models"
- "github.com/gogits/gogs/models/errors"
- "github.com/gogits/gogs/pkg/context"
-)
-
-func GetRepositoryByParams(c *context.APIContext) *models.Repository {
- repo, err := models.GetRepositoryByName(c.Org.Team.OrgID, c.Params(":reponame"))
- if err != nil {
- if errors.IsRepoNotExist(err) {
- c.Status(404)
- } else {
- c.Error(500, "GetRepositoryByName", err)
- }
- return nil
- }
- return repo
-}
-
-func AddTeamRepository(c *context.APIContext) {
- repo := GetRepositoryByParams(c)
- if c.Written() {
- return
- }
- if err := c.Org.Team.AddRepository(repo); err != nil {
- c.Error(500, "AddRepository", err)
- return
- }
-
- c.Status(204)
-}
-
-func RemoveTeamRepository(c *context.APIContext) {
- repo := GetRepositoryByParams(c)
- if c.Written() {
- return
- }
- if err := c.Org.Team.RemoveRepository(repo.ID); err != nil {
- c.Error(500, "RemoveRepository", err)
- return
- }
-
- c.Status(204)
-}
diff --git a/routers/api/v1/admin/org_team.go b/routers/api/v1/admin/org_team.go
deleted file mode 100644
index 7ec6c08a..00000000
--- a/routers/api/v1/admin/org_team.go
+++ /dev/null
@@ -1,60 +0,0 @@
-// Copyright 2016 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 (
- api "github.com/gogits/go-gogs-client"
-
- "github.com/gogits/gogs/models"
- "github.com/gogits/gogs/pkg/context"
- "github.com/gogits/gogs/routers/api/v1/convert"
- "github.com/gogits/gogs/routers/api/v1/user"
-)
-
-func CreateTeam(c *context.APIContext, form api.CreateTeamOption) {
- team := &models.Team{
- OrgID: c.Org.Organization.ID,
- Name: form.Name,
- Description: form.Description,
- Authorize: models.ParseAccessMode(form.Permission),
- }
- if err := models.NewTeam(team); err != nil {
- if models.IsErrTeamAlreadyExist(err) {
- c.Error(422, "", err)
- } else {
- c.Error(500, "NewTeam", err)
- }
- return
- }
-
- c.JSON(201, convert.ToTeam(team))
-}
-
-func AddTeamMember(c *context.APIContext) {
- u := user.GetUserByParams(c)
- if c.Written() {
- return
- }
- if err := c.Org.Team.AddMember(u.ID); err != nil {
- c.Error(500, "AddMember", err)
- return
- }
-
- c.Status(204)
-}
-
-func RemoveTeamMember(c *context.APIContext) {
- u := user.GetUserByParams(c)
- if c.Written() {
- return
- }
-
- if err := c.Org.Team.RemoveMember(u.ID); err != nil {
- c.Error(500, "RemoveMember", err)
- return
- }
-
- c.Status(204)
-}
diff --git a/routers/api/v1/admin/repo.go b/routers/api/v1/admin/repo.go
deleted file mode 100644
index 6c8e8e8d..00000000
--- a/routers/api/v1/admin/repo.go
+++ /dev/null
@@ -1,23 +0,0 @@
-// Copyright 2015 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 (
- api "github.com/gogits/go-gogs-client"
-
- "github.com/gogits/gogs/pkg/context"
- "github.com/gogits/gogs/routers/api/v1/repo"
- "github.com/gogits/gogs/routers/api/v1/user"
-)
-
-// https://github.com/gogits/go-gogs-client/wiki/Administration-Repositories#create-a-new-repository
-func CreateRepo(c *context.APIContext, form api.CreateRepoOption) {
- owner := user.GetUserByParams(c)
- if c.Written() {
- return
- }
-
- repo.CreateUserRepo(c, owner, form)
-}
diff --git a/routers/api/v1/admin/user.go b/routers/api/v1/admin/user.go
deleted file mode 100644
index 8776217d..00000000
--- a/routers/api/v1/admin/user.go
+++ /dev/null
@@ -1,160 +0,0 @@
-// Copyright 2015 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 (
- log "gopkg.in/clog.v1"
-
- api "github.com/gogits/go-gogs-client"
-
- "github.com/gogits/gogs/models"
- "github.com/gogits/gogs/pkg/context"
- "github.com/gogits/gogs/pkg/mailer"
- "github.com/gogits/gogs/pkg/setting"
- "github.com/gogits/gogs/routers/api/v1/user"
-)
-
-func parseLoginSource(c *context.APIContext, u *models.User, sourceID int64, loginName string) {
- if sourceID == 0 {
- return
- }
-
- source, err := models.GetLoginSourceByID(sourceID)
- if err != nil {
- if models.IsErrLoginSourceNotExist(err) {
- c.Error(422, "", err)
- } else {
- c.Error(500, "GetLoginSourceByID", err)
- }
- return
- }
-
- u.LoginType = source.Type
- u.LoginSource = source.ID
- u.LoginName = loginName
-}
-
-// https://github.com/gogits/go-gogs-client/wiki/Administration-Users#create-a-new-user
-func CreateUser(c *context.APIContext, form api.CreateUserOption) {
- u := &models.User{
- Name: form.Username,
- FullName: form.FullName,
- Email: form.Email,
- Passwd: form.Password,
- IsActive: true,
- LoginType: models.LOGIN_PLAIN,
- }
-
- parseLoginSource(c, u, form.SourceID, form.LoginName)
- if c.Written() {
- return
- }
-
- if err := models.CreateUser(u); err != nil {
- if models.IsErrUserAlreadyExist(err) ||
- models.IsErrEmailAlreadyUsed(err) ||
- models.IsErrNameReserved(err) ||
- models.IsErrNamePatternNotAllowed(err) {
- c.Error(422, "", err)
- } else {
- c.Error(500, "CreateUser", err)
- }
- return
- }
- log.Trace("Account created by admin (%s): %s", c.User.Name, u.Name)
-
- // Send email notification.
- if form.SendNotify && setting.MailService != nil {
- mailer.SendRegisterNotifyMail(c.Context.Context, models.NewMailerUser(u))
- }
-
- c.JSON(201, u.APIFormat())
-}
-
-// https://github.com/gogits/go-gogs-client/wiki/Administration-Users#edit-an-existing-user
-func EditUser(c *context.APIContext, form api.EditUserOption) {
- u := user.GetUserByParams(c)
- if c.Written() {
- return
- }
-
- parseLoginSource(c, u, form.SourceID, form.LoginName)
- if c.Written() {
- return
- }
-
- if len(form.Password) > 0 {
- u.Passwd = form.Password
- var err error
- if u.Salt, err = models.GetUserSalt(); err != nil {
- c.Error(500, "UpdateUser", err)
- return
- }
- u.EncodePasswd()
- }
-
- u.LoginName = form.LoginName
- u.FullName = form.FullName
- u.Email = form.Email
- u.Website = form.Website
- u.Location = form.Location
- if form.Active != nil {
- u.IsActive = *form.Active
- }
- if form.Admin != nil {
- u.IsAdmin = *form.Admin
- }
- if form.AllowGitHook != nil {
- u.AllowGitHook = *form.AllowGitHook
- }
- if form.AllowImportLocal != nil {
- u.AllowImportLocal = *form.AllowImportLocal
- }
- if form.MaxRepoCreation != nil {
- u.MaxRepoCreation = *form.MaxRepoCreation
- }
-
- if err := models.UpdateUser(u); err != nil {
- if models.IsErrEmailAlreadyUsed(err) {
- c.Error(422, "", err)
- } else {
- c.Error(500, "UpdateUser", err)
- }
- return
- }
- log.Trace("Account profile updated by admin (%s): %s", c.User.Name, u.Name)
-
- c.JSON(200, u.APIFormat())
-}
-
-// https://github.com/gogits/go-gogs-client/wiki/Administration-Users#delete-a-user
-func DeleteUser(c *context.APIContext) {
- u := user.GetUserByParams(c)
- if c.Written() {
- return
- }
-
- if err := models.DeleteUser(u); err != nil {
- if models.IsErrUserOwnRepos(err) ||
- models.IsErrUserHasOrgs(err) {
- c.Error(422, "", err)
- } else {
- c.Error(500, "DeleteUser", err)
- }
- return
- }
- log.Trace("Account deleted by admin(%s): %s", c.User.Name, u.Name)
-
- c.Status(204)
-}
-
-// https://github.com/gogits/go-gogs-client/wiki/Administration-Users#create-a-public-key-for-user
-func CreatePublicKey(c *context.APIContext, form api.CreateKeyOption) {
- u := user.GetUserByParams(c)
- if c.Written() {
- return
- }
- user.CreateUserPublicKey(c, form, u.ID)
-}
diff --git a/routers/api/v1/api.go b/routers/api/v1/api.go
deleted file mode 100644
index 35ca861a..00000000
--- a/routers/api/v1/api.go
+++ /dev/null
@@ -1,356 +0,0 @@
-// Copyright 2015 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 v1
-
-import (
- "strings"
-
- "github.com/go-macaron/binding"
- "gopkg.in/macaron.v1"
-
- api "github.com/gogits/go-gogs-client"
-
- "github.com/gogits/gogs/models"
- "github.com/gogits/gogs/models/errors"
- "github.com/gogits/gogs/pkg/context"
- "github.com/gogits/gogs/pkg/form"
- "github.com/gogits/gogs/routers/api/v1/admin"
- "github.com/gogits/gogs/routers/api/v1/misc"
- "github.com/gogits/gogs/routers/api/v1/org"
- "github.com/gogits/gogs/routers/api/v1/repo"
- "github.com/gogits/gogs/routers/api/v1/user"
-)
-
-func repoAssignment() macaron.Handler {
- return func(c *context.APIContext) {
- userName := c.Params(":username")
- repoName := c.Params(":reponame")
-
- var (
- owner *models.User
- err error
- )
-
- // Check if the user is the same as the repository owner.
- if c.IsLogged && c.User.LowerName == strings.ToLower(userName) {
- owner = c.User
- } else {
- owner, err = models.GetUserByName(userName)
- if err != nil {
- if errors.IsUserNotExist(err) {
- c.Status(404)
- } else {
- c.Error(500, "GetUserByName", err)
- }
- return
- }
- }
- c.Repo.Owner = owner
-
- // Get repository.
- repo, err := models.GetRepositoryByName(owner.ID, repoName)
- if err != nil {
- if errors.IsRepoNotExist(err) {
- c.Status(404)
- } else {
- c.Error(500, "GetRepositoryByName", err)
- }
- return
- } else if err = repo.GetOwner(); err != nil {
- c.Error(500, "GetOwner", err)
- return
- }
-
- if c.IsLogged && c.User.IsAdmin {
- c.Repo.AccessMode = models.ACCESS_MODE_OWNER
- } else {
- mode, err := models.AccessLevel(c.User.ID, repo)
- if err != nil {
- c.Error(500, "AccessLevel", err)
- return
- }
- c.Repo.AccessMode = mode
- }
-
- if !c.Repo.HasAccess() {
- c.Status(404)
- return
- }
-
- c.Repo.Repository = repo
- }
-}
-
-// Contexter middleware already checks token for user sign in process.
-func reqToken() macaron.Handler {
- return func(c *context.Context) {
- if !c.IsLogged {
- c.Error(401)
- return
- }
- }
-}
-
-func reqBasicAuth() macaron.Handler {
- return func(c *context.Context) {
- if !c.IsBasicAuth {
- c.Error(401)
- return
- }
- }
-}
-
-func reqAdmin() macaron.Handler {
- return func(c *context.Context) {
- if !c.IsLogged || !c.User.IsAdmin {
- c.Error(403)
- return
- }
- }
-}
-
-func reqRepoWriter() macaron.Handler {
- return func(c *context.Context) {
- if !c.Repo.IsWriter() {
- c.Error(403)
- return
- }
- }
-}
-
-func orgAssignment(args ...bool) macaron.Handler {
- var (
- assignOrg bool
- assignTeam bool
- )
- if len(args) > 0 {
- assignOrg = args[0]
- }
- if len(args) > 1 {
- assignTeam = args[1]
- }
- return func(c *context.APIContext) {
- c.Org = new(context.APIOrganization)
-
- var err error
- if assignOrg {
- c.Org.Organization, err = models.GetUserByName(c.Params(":orgname"))
- if err != nil {
- if errors.IsUserNotExist(err) {
- c.Status(404)
- } else {
- c.Error(500, "GetUserByName", err)
- }
- return
- }
- }
-
- if assignTeam {
- c.Org.Team, err = models.GetTeamByID(c.ParamsInt64(":teamid"))
- if err != nil {
- if errors.IsUserNotExist(err) {
- c.Status(404)
- } else {
- c.Error(500, "GetTeamById", err)
- }
- return
- }
- }
- }
-}
-
-func mustEnableIssues(c *context.APIContext) {
- if !c.Repo.Repository.EnableIssues || c.Repo.Repository.EnableExternalTracker {
- c.Status(404)
- return
- }
-}
-
-// RegisterRoutes registers all v1 APIs routes to web application.
-// FIXME: custom form error response
-func RegisterRoutes(m *macaron.Macaron) {
- bind := binding.Bind
-
- m.Group("/v1", func() {
- // Handle preflight OPTIONS request
- m.Options("/*", func() {})
-
- // Miscellaneous
- m.Post("/markdown", bind(api.MarkdownOption{}), misc.Markdown)
- m.Post("/markdown/raw", misc.MarkdownRaw)
-
- // Users
- m.Group("/users", func() {
- m.Get("/search", user.Search)
-
- m.Group("/:username", func() {
- m.Get("", user.GetInfo)
-
- m.Group("/tokens", func() {
- m.Combo("").Get(user.ListAccessTokens).
- Post(bind(api.CreateAccessTokenOption{}), user.CreateAccessToken)
- }, reqBasicAuth())
- })
- })
-
- m.Group("/users", func() {
- m.Group("/:username", func() {
- m.Get("/keys", user.ListPublicKeys)
-
- m.Get("/followers", user.ListFollowers)
- m.Group("/following", func() {
- m.Get("", user.ListFollowing)
- m.Get("/:target", user.CheckFollowing)
- })
- })
- }, reqToken())
-
- m.Group("/user", func() {
- m.Get("", user.GetAuthenticatedUser)
- m.Combo("/emails").Get(user.ListEmails).
- Post(bind(api.CreateEmailOption{}), user.AddEmail).
- Delete(bind(api.CreateEmailOption{}), user.DeleteEmail)
-
- m.Get("/followers", user.ListMyFollowers)
- m.Group("/following", func() {
- m.Get("", user.ListMyFollowing)
- m.Combo("/:username").Get(user.CheckMyFollowing).Put(user.Follow).Delete(user.Unfollow)
- })
-
- m.Group("/keys", func() {
- m.Combo("").Get(user.ListMyPublicKeys).
- Post(bind(api.CreateKeyOption{}), user.CreatePublicKey)
- m.Combo("/:id").Get(user.GetPublicKey).
- Delete(user.DeletePublicKey)
- })
-
- m.Combo("/issues").Get(repo.ListUserIssues)
- }, reqToken())
-
- // Repositories
- m.Get("/users/:username/repos", reqToken(), repo.ListUserRepositories)
- m.Get("/orgs/:org/repos", reqToken(), repo.ListOrgRepositories)
- m.Combo("/user/repos", reqToken()).Get(repo.ListMyRepos).
- Post(bind(api.CreateRepoOption{}), repo.Create)
- m.Post("/org/:org/repos", reqToken(), bind(api.CreateRepoOption{}), repo.CreateOrgRepo)
-
- m.Group("/repos", func() {
- m.Get("/search", repo.Search)
- })
-
- m.Group("/repos", func() {
- m.Post("/migrate", bind(form.MigrateRepo{}), repo.Migrate)
- m.Combo("/:username/:reponame", repoAssignment()).Get(repo.Get).
- Delete(repo.Delete)
-
- m.Group("/:username/:reponame", func() {
- m.Group("/hooks", func() {
- m.Combo("").Get(repo.ListHooks).
- Post(bind(api.CreateHookOption{}), repo.CreateHook)
- m.Combo("/:id").Patch(bind(api.EditHookOption{}), repo.EditHook).
- Delete(repo.DeleteHook)
- })
- m.Group("/collaborators", func() {
- m.Get("", repo.ListCollaborators)
- m.Combo("/:collaborator").Get(repo.IsCollaborator).Put(bind(api.AddCollaboratorOption{}), repo.AddCollaborator).
- Delete(repo.DeleteCollaborator)
- })
- m.Get("/raw/*", context.RepoRef(), repo.GetRawFile)
- m.Get("/archive/*", repo.GetArchive)
- m.Get("/forks", repo.ListForks)
- m.Group("/branches", func() {
- m.Get("", repo.ListBranches)
- m.Get("/*", repo.GetBranch)
- })
- m.Group("/keys", func() {
- m.Combo("").Get(repo.ListDeployKeys).
- Post(bind(api.CreateKeyOption{}), repo.CreateDeployKey)
- m.Combo("/:id").Get(repo.GetDeployKey).
- Delete(repo.DeleteDeploykey)
- })
- m.Group("/issues", func() {
- m.Combo("").Get(repo.ListIssues).Post(bind(api.CreateIssueOption{}), repo.CreateIssue)
- m.Group("/comments", func() {
- m.Get("", repo.ListRepoIssueComments)
- m.Combo("/:id").Patch(bind(api.EditIssueCommentOption{}), repo.EditIssueComment)
- })
- m.Group("/:index", func() {
- m.Combo("").Get(repo.GetIssue).Patch(bind(api.EditIssueOption{}), repo.EditIssue)
-
- m.Group("/comments", func() {
- m.Combo("").Get(repo.ListIssueComments).Post(bind(api.CreateIssueCommentOption{}), repo.CreateIssueComment)
- m.Combo("/:id").Patch(bind(api.EditIssueCommentOption{}), repo.EditIssueComment).
- Delete(repo.DeleteIssueComment)
- })
-
- m.Group("/labels", func() {
- m.Combo("").Get(repo.ListIssueLabels).
- Post(bind(api.IssueLabelsOption{}), repo.AddIssueLabels).
- Put(bind(api.IssueLabelsOption{}), repo.ReplaceIssueLabels).
- Delete(repo.ClearIssueLabels)
- m.Delete("/:id", repo.DeleteIssueLabel)
- })
-
- })
- }, mustEnableIssues)
- m.Group("/labels", func() {
- m.Combo("").Get(repo.ListLabels).
- Post(bind(api.CreateLabelOption{}), repo.CreateLabel)
- m.Combo("/:id").Get(repo.GetLabel).Patch(bind(api.EditLabelOption{}), repo.EditLabel).
- Delete(repo.DeleteLabel)
- })
- m.Group("/milestones", func() {
- m.Combo("").Get(repo.ListMilestones).
- Post(reqRepoWriter(), bind(api.CreateMilestoneOption{}), repo.CreateMilestone)
- m.Combo("/:id").Get(repo.GetMilestone).
- Patch(reqRepoWriter(), bind(api.EditMilestoneOption{}), repo.EditMilestone).
- Delete(reqRepoWriter(), repo.DeleteMilestone)
- })
- m.Post("/mirror-sync", repo.MirrorSync)
- m.Get("/editorconfig/:filename", context.RepoRef(), repo.GetEditorconfig)
- }, repoAssignment())
- }, reqToken())
-
- m.Get("/issues", reqToken(), repo.ListUserIssues)
-
- // Organizations
- m.Get("/user/orgs", reqToken(), org.ListMyOrgs)
- m.Get("/users/:username/orgs", org.ListUserOrgs)
- m.Group("/orgs/:orgname", func() {
- m.Combo("").Get(org.Get).Patch(bind(api.EditOrgOption{}), org.Edit)
- m.Combo("/teams").Get(org.ListTeams)
- }, orgAssignment(true))
-
- m.Any("/*", func(c *context.Context) {
- c.Error(404)
- })
-
- m.Group("/admin", func() {
- m.Group("/users", func() {
- m.Post("", bind(api.CreateUserOption{}), admin.CreateUser)
-
- m.Group("/:username", func() {
- m.Combo("").Patch(bind(api.EditUserOption{}), admin.EditUser).
- Delete(admin.DeleteUser)
- m.Post("/keys", bind(api.CreateKeyOption{}), admin.CreatePublicKey)
- m.Post("/orgs", bind(api.CreateOrgOption{}), admin.CreateOrg)
- m.Post("/repos", bind(api.CreateRepoOption{}), admin.CreateRepo)
- })
- })
-
- m.Group("/orgs/:orgname", func() {
- m.Group("/teams", func() {
- m.Post("", orgAssignment(true), bind(api.CreateTeamOption{}), admin.CreateTeam)
- })
- })
- m.Group("/teams", func() {
- m.Group("/:teamid", func() {
- m.Combo("/members/:username").Put(admin.AddTeamMember).Delete(admin.RemoveTeamMember)
- m.Combo("/repos/:reponame").Put(admin.AddTeamRepository).Delete(admin.RemoveTeamRepository)
- }, orgAssignment(false, true))
- })
- }, reqAdmin())
- }, context.APIContexter())
-}
diff --git a/routers/api/v1/convert/convert.go b/routers/api/v1/convert/convert.go
deleted file mode 100644
index fcadb51f..00000000
--- a/routers/api/v1/convert/convert.go
+++ /dev/null
@@ -1,127 +0,0 @@
-// Copyright 2015 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 convert
-
-import (
- "fmt"
-
- "github.com/Unknwon/com"
-
- "github.com/gogits/git-module"
- api "github.com/gogits/go-gogs-client"
-
- "github.com/gogits/gogs/models"
-)
-
-func ToEmail(email *models.EmailAddress) *api.Email {
- return &api.Email{
- Email: email.Email,
- Verified: email.IsActivated,
- Primary: email.IsPrimary,
- }
-}
-
-func ToBranch(b *models.Branch, c *git.Commit) *api.Branch {
- return &api.Branch{
- Name: b.Name,
- Commit: ToCommit(c),
- }
-}
-
-func ToCommit(c *git.Commit) *api.PayloadCommit {
- authorUsername := ""
- author, err := models.GetUserByEmail(c.Author.Email)
- if err == nil {
- authorUsername = author.Name
- }
- committerUsername := ""
- committer, err := models.GetUserByEmail(c.Committer.Email)
- if err == nil {
- committerUsername = committer.Name
- }
- return &api.PayloadCommit{
- ID: c.ID.String(),
- Message: c.Message(),
- URL: "Not implemented",
- Author: &api.PayloadUser{
- Name: c.Author.Name,
- Email: c.Author.Email,
- UserName: authorUsername,
- },
- Committer: &api.PayloadUser{
- Name: c.Committer.Name,
- Email: c.Committer.Email,
- UserName: committerUsername,
- },
- Timestamp: c.Author.When,
- }
-}
-
-func ToPublicKey(apiLink string, key *models.PublicKey) *api.PublicKey {
- return &api.PublicKey{
- ID: key.ID,
- Key: key.Content,
- URL: apiLink + com.ToStr(key.ID),
- Title: key.Name,
- Created: key.Created,
- }
-}
-
-func ToHook(repoLink string, w *models.Webhook) *api.Hook {
- config := map[string]string{
- "url": w.URL,
- "content_type": w.ContentType.Name(),
- }
- if w.HookTaskType == models.SLACK {
- s := w.GetSlackHook()
- config["channel"] = s.Channel
- config["username"] = s.Username
- config["icon_url"] = s.IconURL
- config["color"] = s.Color
- }
-
- return &api.Hook{
- ID: w.ID,
- Type: w.HookTaskType.Name(),
- URL: fmt.Sprintf("%s/settings/hooks/%d", repoLink, w.ID),
- Active: w.IsActive,
- Config: config,
- Events: w.EventsArray(),
- Updated: w.Updated,
- Created: w.Created,
- }
-}
-
-func ToDeployKey(apiLink string, key *models.DeployKey) *api.DeployKey {
- return &api.DeployKey{
- ID: key.ID,
- Key: key.Content,
- URL: apiLink + com.ToStr(key.ID),
- Title: key.Name,
- Created: key.Created,
- ReadOnly: true, // All deploy keys are read-only.
- }
-}
-
-func ToOrganization(org *models.User) *api.Organization {
- return &api.Organization{
- ID: org.ID,
- AvatarUrl: org.AvatarLink(),
- UserName: org.Name,
- FullName: org.FullName,
- Description: org.Description,
- Website: org.Website,
- Location: org.Location,
- }
-}
-
-func ToTeam(team *models.Team) *api.Team {
- return &api.Team{
- ID: team.ID,
- Name: team.Name,
- Description: team.Description,
- Permission: team.Authorize.String(),
- }
-}
diff --git a/routers/api/v1/convert/utils.go b/routers/api/v1/convert/utils.go
deleted file mode 100644
index d0beab3d..00000000
--- a/routers/api/v1/convert/utils.go
+++ /dev/null
@@ -1,19 +0,0 @@
-// Copyright 2016 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 convert
-
-import (
- "github.com/gogits/gogs/pkg/setting"
-)
-
-// ToCorrectPageSize makes sure page size is in allowed range.
-func ToCorrectPageSize(size int) int {
- if size <= 0 {
- size = 10
- } else if size > setting.API.MaxResponseItems {
- size = setting.API.MaxResponseItems
- }
- return size
-}
diff --git a/routers/api/v1/misc/markdown.go b/routers/api/v1/misc/markdown.go
deleted file mode 100644
index 98bfd7d0..00000000
--- a/routers/api/v1/misc/markdown.go
+++ /dev/null
@@ -1,42 +0,0 @@
-// 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 misc
-
-import (
- api "github.com/gogits/go-gogs-client"
-
- "github.com/gogits/gogs/pkg/context"
- "github.com/gogits/gogs/pkg/markup"
-)
-
-// https://github.com/gogits/go-gogs-client/wiki/Miscellaneous#render-an-arbitrary-markdown-document
-func Markdown(c *context.APIContext, form api.MarkdownOption) {
- if c.HasApiError() {
- c.Error(422, "", c.GetErrMsg())
- return
- }
-
- if len(form.Text) == 0 {
- c.Write([]byte(""))
- return
- }
-
- switch form.Mode {
- case "gfm":
- c.Write(markup.Markdown([]byte(form.Text), form.Context, nil))
- default:
- c.Write(markup.RawMarkdown([]byte(form.Text), ""))
- }
-}
-
-// https://github.com/gogits/go-gogs-client/wiki/Miscellaneous#render-a-markdown-document-in-raw-mode
-func MarkdownRaw(c *context.APIContext) {
- body, err := c.Req.Body().Bytes()
- if err != nil {
- c.Error(422, "", err)
- return
- }
- c.Write(markup.RawMarkdown(body, ""))
-}
diff --git a/routers/api/v1/org/org.go b/routers/api/v1/org/org.go
deleted file mode 100644
index 107fc19c..00000000
--- a/routers/api/v1/org/org.go
+++ /dev/null
@@ -1,66 +0,0 @@
-// Copyright 2015 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 org
-
-import (
- api "github.com/gogits/go-gogs-client"
-
- "github.com/gogits/gogs/models"
- "github.com/gogits/gogs/pkg/context"
- "github.com/gogits/gogs/routers/api/v1/convert"
- "github.com/gogits/gogs/routers/api/v1/user"
-)
-
-func listUserOrgs(c *context.APIContext, u *models.User, all bool) {
- if err := u.GetOrganizations(all); err != nil {
- c.Error(500, "GetOrganizations", err)
- return
- }
-
- apiOrgs := make([]*api.Organization, len(u.Orgs))
- for i := range u.Orgs {
- apiOrgs[i] = convert.ToOrganization(u.Orgs[i])
- }
- c.JSON(200, &apiOrgs)
-}
-
-// https://github.com/gogits/go-gogs-client/wiki/Organizations#list-your-organizations
-func ListMyOrgs(c *context.APIContext) {
- listUserOrgs(c, c.User, true)
-}
-
-// https://github.com/gogits/go-gogs-client/wiki/Organizations#list-user-organizations
-func ListUserOrgs(c *context.APIContext) {
- u := user.GetUserByParams(c)
- if c.Written() {
- return
- }
- listUserOrgs(c, u, false)
-}
-
-// https://github.com/gogits/go-gogs-client/wiki/Organizations#get-an-organization
-func Get(c *context.APIContext) {
- c.JSON(200, convert.ToOrganization(c.Org.Organization))
-}
-
-// https://github.com/gogits/go-gogs-client/wiki/Organizations#edit-an-organization
-func Edit(c *context.APIContext, form api.EditOrgOption) {
- org := c.Org.Organization
- if !org.IsOwnedBy(c.User.ID) {
- c.Status(403)
- return
- }
-
- org.FullName = form.FullName
- org.Description = form.Description
- org.Website = form.Website
- org.Location = form.Location
- if err := models.UpdateUser(org); err != nil {
- c.Error(500, "UpdateUser", err)
- return
- }
-
- c.JSON(200, convert.ToOrganization(org))
-}
diff --git a/routers/api/v1/org/team.go b/routers/api/v1/org/team.go
deleted file mode 100644
index a952ea53..00000000
--- a/routers/api/v1/org/team.go
+++ /dev/null
@@ -1,26 +0,0 @@
-// Copyright 2016 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 org
-
-import (
- api "github.com/gogits/go-gogs-client"
-
- "github.com/gogits/gogs/pkg/context"
- "github.com/gogits/gogs/routers/api/v1/convert"
-)
-
-func ListTeams(c *context.APIContext) {
- org := c.Org.Organization
- if err := org.GetTeams(); err != nil {
- c.Error(500, "GetTeams", err)
- return
- }
-
- apiTeams := make([]*api.Team, len(org.Teams))
- for i := range org.Teams {
- apiTeams[i] = convert.ToTeam(org.Teams[i])
- }
- c.JSON(200, apiTeams)
-}
diff --git a/routers/api/v1/repo/branch.go b/routers/api/v1/repo/branch.go
deleted file mode 100644
index 3d5e646c..00000000
--- a/routers/api/v1/repo/branch.go
+++ /dev/null
@@ -1,55 +0,0 @@
-// Copyright 2016 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 repo
-
-import (
- api "github.com/gogits/go-gogs-client"
-
- "github.com/gogits/gogs/models"
- "github.com/gogits/gogs/pkg/context"
- "github.com/gogits/gogs/routers/api/v1/convert"
-)
-
-// https://github.com/gogits/go-gogs-client/wiki/Repositories#get-branch
-func GetBranch(c *context.APIContext) {
- branch, err := c.Repo.Repository.GetBranch(c.Params("*"))
- if err != nil {
- if models.IsErrBranchNotExist(err) {
- c.Error(404, "GetBranch", err)
- } else {
- c.Error(500, "GetBranch", err)
- }
- return
- }
-
- commit, err := branch.GetCommit()
- if err != nil {
- c.Error(500, "GetCommit", err)
- return
- }
-
- c.JSON(200, convert.ToBranch(branch, commit))
-}
-
-// https://github.com/gogits/go-gogs-client/wiki/Repositories#list-branches
-func ListBranches(c *context.APIContext) {
- branches, err := c.Repo.Repository.GetBranches()
- if err != nil {
- c.Error(500, "GetBranches", err)
- return
- }
-
- apiBranches := make([]*api.Branch, len(branches))
- for i := range branches {
- commit, err := branches[i].GetCommit()
- if err != nil {
- c.Error(500, "GetCommit", err)
- return
- }
- apiBranches[i] = convert.ToBranch(branches[i], commit)
- }
-
- c.JSON(200, &apiBranches)
-}
diff --git a/routers/api/v1/repo/collaborators.go b/routers/api/v1/repo/collaborators.go
deleted file mode 100644
index d295ac0f..00000000
--- a/routers/api/v1/repo/collaborators.go
+++ /dev/null
@@ -1,94 +0,0 @@
-// Copyright 2016 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 repo
-
-import (
- api "github.com/gogits/go-gogs-client"
-
- "github.com/gogits/gogs/models"
- "github.com/gogits/gogs/models/errors"
- "github.com/gogits/gogs/pkg/context"
-)
-
-func ListCollaborators(c *context.APIContext) {
- collaborators, err := c.Repo.Repository.GetCollaborators()
- if err != nil {
- if errors.IsUserNotExist(err) {
- c.Error(422, "", err)
- } else {
- c.Error(500, "GetCollaborators", err)
- }
- return
- }
-
- apiCollaborators := make([]*api.Collaborator, len(collaborators))
- for i := range collaborators {
- apiCollaborators[i] = collaborators[i].APIFormat()
- }
- c.JSON(200, &apiCollaborators)
-}
-
-func AddCollaborator(c *context.APIContext, form api.AddCollaboratorOption) {
- collaborator, err := models.GetUserByName(c.Params(":collaborator"))
- if err != nil {
- if errors.IsUserNotExist(err) {
- c.Error(422, "", err)
- } else {
- c.Error(500, "GetUserByName", err)
- }
- return
- }
-
- if err := c.Repo.Repository.AddCollaborator(collaborator); err != nil {
- c.Error(500, "AddCollaborator", err)
- return
- }
-
- if form.Permission != nil {
- if err := c.Repo.Repository.ChangeCollaborationAccessMode(collaborator.ID, models.ParseAccessMode(*form.Permission)); err != nil {
- c.Error(500, "ChangeCollaborationAccessMode", err)
- return
- }
- }
-
- c.Status(204)
-}
-
-func IsCollaborator(c *context.APIContext) {
- collaborator, err := models.GetUserByName(c.Params(":collaborator"))
- if err != nil {
- if errors.IsUserNotExist(err) {
- c.Error(422, "", err)
- } else {
- c.Error(500, "GetUserByName", err)
- }
- return
- }
-
- if !c.Repo.Repository.IsCollaborator(collaborator.ID) {
- c.Status(404)
- } else {
- c.Status(204)
- }
-}
-
-func DeleteCollaborator(c *context.APIContext) {
- collaborator, err := models.GetUserByName(c.Params(":collaborator"))
- if err != nil {
- if errors.IsUserNotExist(err) {
- c.Error(422, "", err)
- } else {
- c.Error(500, "GetUserByName", err)
- }
- return
- }
-
- if err := c.Repo.Repository.DeleteCollaboration(collaborator.ID); err != nil {
- c.Error(500, "DeleteCollaboration", err)
- return
- }
-
- c.Status(204)
-}
diff --git a/routers/api/v1/repo/file.go b/routers/api/v1/repo/file.go
deleted file mode 100644
index df6a4857..00000000
--- a/routers/api/v1/repo/file.go
+++ /dev/null
@@ -1,72 +0,0 @@
-// 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 repo
-
-import (
- "github.com/gogits/git-module"
-
- "github.com/gogits/gogs/models"
- "github.com/gogits/gogs/pkg/context"
- "github.com/gogits/gogs/routers/repo"
-)
-
-// https://github.com/gogits/go-gogs-client/wiki/Repositories-Contents#download-raw-content
-func GetRawFile(c *context.APIContext) {
- if !c.Repo.HasAccess() {
- c.Status(404)
- return
- }
-
- if c.Repo.Repository.IsBare {
- c.Status(404)
- return
- }
-
- blob, err := c.Repo.Commit.GetBlobByPath(c.Repo.TreePath)
- if err != nil {
- if git.IsErrNotExist(err) {
- c.Status(404)
- } else {
- c.Error(500, "GetBlobByPath", err)
- }
- return
- }
- if err = repo.ServeBlob(c.Context, blob); err != nil {
- c.Error(500, "ServeBlob", err)
- }
-}
-
-// https://github.com/gogits/go-gogs-client/wiki/Repositories-Contents#download-archive
-func GetArchive(c *context.APIContext) {
- repoPath := models.RepoPath(c.Params(":username"), c.Params(":reponame"))
- gitRepo, err := git.OpenRepository(repoPath)
- if err != nil {
- c.Error(500, "OpenRepository", err)
- return
- }
- c.Repo.GitRepo = gitRepo
-
- repo.Download(c.Context)
-}
-
-func GetEditorconfig(c *context.APIContext) {
- ec, err := c.Repo.GetEditorconfig()
- if err != nil {
- if git.IsErrNotExist(err) {
- c.Error(404, "GetEditorconfig", err)
- } else {
- c.Error(500, "GetEditorconfig", err)
- }
- return
- }
-
- fileName := c.Params("filename")
- def := ec.GetDefinitionForFilename(fileName)
- if def == nil {
- c.Error(404, "GetDefinitionForFilename", err)
- return
- }
- c.JSON(200, def)
-}
diff --git a/routers/api/v1/repo/hook.go b/routers/api/v1/repo/hook.go
deleted file mode 100644
index 7c2b293e..00000000
--- a/routers/api/v1/repo/hook.go
+++ /dev/null
@@ -1,186 +0,0 @@
-// 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 repo
-
-import (
- "encoding/json"
-
- "github.com/Unknwon/com"
-
- api "github.com/gogits/go-gogs-client"
-
- "github.com/gogits/gogs/models"
- "github.com/gogits/gogs/models/errors"
- "github.com/gogits/gogs/pkg/context"
- "github.com/gogits/gogs/routers/api/v1/convert"
-)
-
-// https://github.com/gogits/go-gogs-client/wiki/Repositories#list-hooks
-func ListHooks(c *context.APIContext) {
- hooks, err := models.GetWebhooksByRepoID(c.Repo.Repository.ID)
- if err != nil {
- c.Error(500, "GetWebhooksByRepoID", err)
- return
- }
-
- apiHooks := make([]*api.Hook, len(hooks))
- for i := range hooks {
- apiHooks[i] = convert.ToHook(c.Repo.RepoLink, hooks[i])
- }
- c.JSON(200, &apiHooks)
-}
-
-// https://github.com/gogits/go-gogs-client/wiki/Repositories#create-a-hook
-func CreateHook(c *context.APIContext, form api.CreateHookOption) {
- if !models.IsValidHookTaskType(form.Type) {
- c.Error(422, "", "Invalid hook type")
- return
- }
- for _, name := range []string{"url", "content_type"} {
- if _, ok := form.Config[name]; !ok {
- c.Error(422, "", "Missing config option: "+name)
- return
- }
- }
- if !models.IsValidHookContentType(form.Config["content_type"]) {
- c.Error(422, "", "Invalid content type")
- return
- }
-
- if len(form.Events) == 0 {
- form.Events = []string{"push"}
- }
- w := &models.Webhook{
- RepoID: c.Repo.Repository.ID,
- URL: form.Config["url"],
- ContentType: models.ToHookContentType(form.Config["content_type"]),
- Secret: form.Config["secret"],
- HookEvent: &models.HookEvent{
- ChooseEvents: true,
- HookEvents: models.HookEvents{
- Create: com.IsSliceContainsStr(form.Events, string(models.HOOK_EVENT_CREATE)),
- Delete: com.IsSliceContainsStr(form.Events, string(models.HOOK_EVENT_DELETE)),
- Fork: com.IsSliceContainsStr(form.Events, string(models.HOOK_EVENT_FORK)),
- Push: com.IsSliceContainsStr(form.Events, string(models.HOOK_EVENT_PUSH)),
- Issues: com.IsSliceContainsStr(form.Events, string(models.HOOK_EVENT_ISSUES)),
- IssueComment: com.IsSliceContainsStr(form.Events, string(models.HOOK_EVENT_ISSUE_COMMENT)),
- PullRequest: com.IsSliceContainsStr(form.Events, string(models.HOOK_EVENT_PULL_REQUEST)),
- Release: com.IsSliceContainsStr(form.Events, string(models.HOOK_EVENT_RELEASE)),
- },
- },
- IsActive: form.Active,
- HookTaskType: models.ToHookTaskType(form.Type),
- }
- if w.HookTaskType == models.SLACK {
- channel, ok := form.Config["channel"]
- if !ok {
- c.Error(422, "", "Missing config option: channel")
- return
- }
- meta, err := json.Marshal(&models.SlackMeta{
- Channel: channel,
- Username: form.Config["username"],
- IconURL: form.Config["icon_url"],
- Color: form.Config["color"],
- })
- if err != nil {
- c.Error(500, "slack: JSON marshal failed", err)
- return
- }
- w.Meta = string(meta)
- }
-
- if err := w.UpdateEvent(); err != nil {
- c.Error(500, "UpdateEvent", err)
- return
- } else if err := models.CreateWebhook(w); err != nil {
- c.Error(500, "CreateWebhook", err)
- return
- }
-
- c.JSON(201, convert.ToHook(c.Repo.RepoLink, w))
-}
-
-// https://github.com/gogits/go-gogs-client/wiki/Repositories#edit-a-hook
-func EditHook(c *context.APIContext, form api.EditHookOption) {
- w, err := models.GetWebhookOfRepoByID(c.Repo.Repository.ID, c.ParamsInt64(":id"))
- if err != nil {
- if errors.IsWebhookNotExist(err) {
- c.Status(404)
- } else {
- c.Error(500, "GetWebhookOfRepoByID", err)
- }
- return
- }
-
- if form.Config != nil {
- if url, ok := form.Config["url"]; ok {
- w.URL = url
- }
- if ct, ok := form.Config["content_type"]; ok {
- if !models.IsValidHookContentType(ct) {
- c.Error(422, "", "Invalid content type")
- return
- }
- w.ContentType = models.ToHookContentType(ct)
- }
-
- if w.HookTaskType == models.SLACK {
- if channel, ok := form.Config["channel"]; ok {
- meta, err := json.Marshal(&models.SlackMeta{
- Channel: channel,
- Username: form.Config["username"],
- IconURL: form.Config["icon_url"],
- Color: form.Config["color"],
- })
- if err != nil {
- c.Error(500, "slack: JSON marshal failed", err)
- return
- }
- w.Meta = string(meta)
- }
- }
- }
-
- // Update events
- if len(form.Events) == 0 {
- form.Events = []string{"push"}
- }
- w.PushOnly = false
- w.SendEverything = false
- w.ChooseEvents = true
- w.Create = com.IsSliceContainsStr(form.Events, string(models.HOOK_EVENT_CREATE))
- w.Delete = com.IsSliceContainsStr(form.Events, string(models.HOOK_EVENT_DELETE))
- w.Fork = com.IsSliceContainsStr(form.Events, string(models.HOOK_EVENT_FORK))
- w.Push = com.IsSliceContainsStr(form.Events, string(models.HOOK_EVENT_PUSH))
- w.Issues = com.IsSliceContainsStr(form.Events, string(models.HOOK_EVENT_ISSUES))
- w.IssueComment = com.IsSliceContainsStr(form.Events, string(models.HOOK_EVENT_ISSUE_COMMENT))
- w.PullRequest = com.IsSliceContainsStr(form.Events, string(models.HOOK_EVENT_PULL_REQUEST))
- w.Release = com.IsSliceContainsStr(form.Events, string(models.HOOK_EVENT_RELEASE))
- if err = w.UpdateEvent(); err != nil {
- c.Error(500, "UpdateEvent", err)
- return
- }
-
- if form.Active != nil {
- w.IsActive = *form.Active
- }
-
- if err := models.UpdateWebhook(w); err != nil {
- c.Error(500, "UpdateWebhook", err)
- return
- }
-
- c.JSON(200, convert.ToHook(c.Repo.RepoLink, w))
-}
-
-func DeleteHook(c *context.APIContext) {
- if err := models.DeleteWebhookOfRepoByID(c.Repo.Repository.ID, c.ParamsInt64(":id")); err != nil {
- c.Error(500, "DeleteWebhookByRepoID", err)
- return
- }
-
- c.Status(204)
-}
diff --git a/routers/api/v1/repo/issue.go b/routers/api/v1/repo/issue.go
deleted file mode 100644
index d6ae7b4d..00000000
--- a/routers/api/v1/repo/issue.go
+++ /dev/null
@@ -1,201 +0,0 @@
-// Copyright 2016 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 repo
-
-import (
- "fmt"
- "strings"
-
- api "github.com/gogits/go-gogs-client"
-
- "github.com/gogits/gogs/models"
- "github.com/gogits/gogs/models/errors"
- "github.com/gogits/gogs/pkg/context"
- "github.com/gogits/gogs/pkg/setting"
-)
-
-func listIssues(c *context.APIContext, opts *models.IssuesOptions) {
- issues, err := models.Issues(opts)
- if err != nil {
- c.Error(500, "Issues", err)
- return
- }
-
- count, err := models.IssuesCount(opts)
- if err != nil {
- c.Error(500, "IssuesCount", err)
- return
- }
-
- // FIXME: use IssueList to improve performance.
- apiIssues := make([]*api.Issue, len(issues))
- for i := range issues {
- if err = issues[i].LoadAttributes(); err != nil {
- c.Error(500, "LoadAttributes", err)
- return
- }
- apiIssues[i] = issues[i].APIFormat()
- }
-
- c.SetLinkHeader(int(count), setting.UI.IssuePagingNum)
- c.JSON(200, &apiIssues)
-}
-
-func ListUserIssues(c *context.APIContext) {
- opts := models.IssuesOptions{
- AssigneeID: c.User.ID,
- Page: c.QueryInt("page"),
- IsClosed: api.StateType(c.Query("state")) == api.STATE_CLOSED,
- }
-
- listIssues(c, &opts)
-}
-
-func ListIssues(c *context.APIContext) {
- opts := models.IssuesOptions{
- RepoID: c.Repo.Repository.ID,
- Page: c.QueryInt("page"),
- IsClosed: api.StateType(c.Query("state")) == api.STATE_CLOSED,
- }
-
- listIssues(c, &opts)
-}
-
-func GetIssue(c *context.APIContext) {
- issue, err := models.GetIssueByIndex(c.Repo.Repository.ID, c.ParamsInt64(":index"))
- if err != nil {
- if errors.IsIssueNotExist(err) {
- c.Status(404)
- } else {
- c.Error(500, "GetIssueByIndex", err)
- }
- return
- }
- c.JSON(200, issue.APIFormat())
-}
-
-func CreateIssue(c *context.APIContext, form api.CreateIssueOption) {
- issue := &models.Issue{
- RepoID: c.Repo.Repository.ID,
- Title: form.Title,
- PosterID: c.User.ID,
- Poster: c.User,
- Content: form.Body,
- }
-
- if c.Repo.IsWriter() {
- if len(form.Assignee) > 0 {
- assignee, err := models.GetUserByName(form.Assignee)
- if err != nil {
- if errors.IsUserNotExist(err) {
- c.Error(422, "", fmt.Sprintf("Assignee does not exist: [name: %s]", form.Assignee))
- } else {
- c.Error(500, "GetUserByName", err)
- }
- return
- }
- issue.AssigneeID = assignee.ID
- }
- issue.MilestoneID = form.Milestone
- } else {
- form.Labels = nil
- }
-
- if err := models.NewIssue(c.Repo.Repository, issue, form.Labels, nil); err != nil {
- c.Error(500, "NewIssue", err)
- return
- }
-
- if form.Closed {
- if err := issue.ChangeStatus(c.User, c.Repo.Repository, true); err != nil {
- c.Error(500, "ChangeStatus", err)
- return
- }
- }
-
- // Refetch from database to assign some automatic values
- var err error
- issue, err = models.GetIssueByID(issue.ID)
- if err != nil {
- c.Error(500, "GetIssueByID", err)
- return
- }
- c.JSON(201, issue.APIFormat())
-}
-
-func EditIssue(c *context.APIContext, form api.EditIssueOption) {
- issue, err := models.GetIssueByIndex(c.Repo.Repository.ID, c.ParamsInt64(":index"))
- if err != nil {
- if errors.IsIssueNotExist(err) {
- c.Status(404)
- } else {
- c.Error(500, "GetIssueByIndex", err)
- }
- return
- }
-
- if !issue.IsPoster(c.User.ID) && !c.Repo.IsWriter() {
- c.Status(403)
- return
- }
-
- if len(form.Title) > 0 {
- issue.Title = form.Title
- }
- if form.Body != nil {
- issue.Content = *form.Body
- }
-
- if c.Repo.IsWriter() && form.Assignee != nil &&
- (issue.Assignee == nil || issue.Assignee.LowerName != strings.ToLower(*form.Assignee)) {
- if len(*form.Assignee) == 0 {
- issue.AssigneeID = 0
- } else {
- assignee, err := models.GetUserByName(*form.Assignee)
- if err != nil {
- if errors.IsUserNotExist(err) {
- c.Error(422, "", fmt.Sprintf("assignee does not exist: [name: %s]", *form.Assignee))
- } else {
- c.Error(500, "GetUserByName", err)
- }
- return
- }
- issue.AssigneeID = assignee.ID
- }
-
- if err = models.UpdateIssueUserByAssignee(issue); err != nil {
- c.Error(500, "UpdateIssueUserByAssignee", err)
- return
- }
- }
- if c.Repo.IsWriter() && form.Milestone != nil &&
- issue.MilestoneID != *form.Milestone {
- oldMilestoneID := issue.MilestoneID
- issue.MilestoneID = *form.Milestone
- if err = models.ChangeMilestoneAssign(c.User, issue, oldMilestoneID); err != nil {
- c.Error(500, "ChangeMilestoneAssign", err)
- return
- }
- }
-
- if err = models.UpdateIssue(issue); err != nil {
- c.Error(500, "UpdateIssue", err)
- return
- }
- if form.State != nil {
- if err = issue.ChangeStatus(c.User, c.Repo.Repository, api.STATE_CLOSED == api.StateType(*form.State)); err != nil {
- c.Error(500, "ChangeStatus", err)
- return
- }
- }
-
- // Refetch from database to assign some automatic values
- issue, err = models.GetIssueByID(issue.ID)
- if err != nil {
- c.Error(500, "GetIssueByID", err)
- return
- }
- c.JSON(201, issue.APIFormat())
-}
diff --git a/routers/api/v1/repo/issue_comment.go b/routers/api/v1/repo/issue_comment.go
deleted file mode 100644
index 4a057d76..00000000
--- a/routers/api/v1/repo/issue_comment.go
+++ /dev/null
@@ -1,128 +0,0 @@
-// Copyright 2015 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 repo
-
-import (
- "time"
-
- api "github.com/gogits/go-gogs-client"
-
- "github.com/gogits/gogs/models"
- "github.com/gogits/gogs/pkg/context"
-)
-
-func ListIssueComments(c *context.APIContext) {
- var since time.Time
- if len(c.Query("since")) > 0 {
- since, _ = time.Parse(time.RFC3339, c.Query("since"))
- }
-
- // comments,err:=models.GetCommentsByIssueIDSince(, since)
- issue, err := models.GetRawIssueByIndex(c.Repo.Repository.ID, c.ParamsInt64(":index"))
- if err != nil {
- c.Error(500, "GetRawIssueByIndex", err)
- return
- }
-
- comments, err := models.GetCommentsByIssueIDSince(issue.ID, since.Unix())
- if err != nil {
- c.Error(500, "GetCommentsByIssueIDSince", err)
- return
- }
-
- apiComments := make([]*api.Comment, len(comments))
- for i := range comments {
- apiComments[i] = comments[i].APIFormat()
- }
- c.JSON(200, &apiComments)
-}
-
-func ListRepoIssueComments(c *context.APIContext) {
- var since time.Time
- if len(c.Query("since")) > 0 {
- since, _ = time.Parse(time.RFC3339, c.Query("since"))
- }
-
- comments, err := models.GetCommentsByRepoIDSince(c.Repo.Repository.ID, since.Unix())
- if err != nil {
- c.Error(500, "GetCommentsByRepoIDSince", err)
- return
- }
-
- apiComments := make([]*api.Comment, len(comments))
- for i := range comments {
- apiComments[i] = comments[i].APIFormat()
- }
- c.JSON(200, &apiComments)
-}
-
-func CreateIssueComment(c *context.APIContext, form api.CreateIssueCommentOption) {
- issue, err := models.GetIssueByIndex(c.Repo.Repository.ID, c.ParamsInt64(":index"))
- if err != nil {
- c.Error(500, "GetIssueByIndex", err)
- return
- }
-
- comment, err := models.CreateIssueComment(c.User, c.Repo.Repository, issue, form.Body, nil)
- if err != nil {
- c.Error(500, "CreateIssueComment", err)
- return
- }
-
- c.JSON(201, comment.APIFormat())
-}
-
-func EditIssueComment(c *context.APIContext, form api.EditIssueCommentOption) {
- comment, err := models.GetCommentByID(c.ParamsInt64(":id"))
- if err != nil {
- if models.IsErrCommentNotExist(err) {
- c.Error(404, "GetCommentByID", err)
- } else {
- c.Error(500, "GetCommentByID", err)
- }
- return
- }
-
- if c.User.ID != comment.PosterID && !c.Repo.IsAdmin() {
- c.Status(403)
- return
- } else if comment.Type != models.COMMENT_TYPE_COMMENT {
- c.Status(204)
- return
- }
-
- oldContent := comment.Content
- comment.Content = form.Body
- if err := models.UpdateComment(c.User, comment, oldContent); err != nil {
- c.Error(500, "UpdateComment", err)
- return
- }
- c.JSON(200, comment.APIFormat())
-}
-
-func DeleteIssueComment(c *context.APIContext) {
- comment, err := models.GetCommentByID(c.ParamsInt64(":id"))
- if err != nil {
- if models.IsErrCommentNotExist(err) {
- c.Error(404, "GetCommentByID", err)
- } else {
- c.Error(500, "GetCommentByID", err)
- }
- return
- }
-
- if c.User.ID != comment.PosterID && !c.Repo.IsAdmin() {
- c.Status(403)
- return
- } else if comment.Type != models.COMMENT_TYPE_COMMENT {
- c.Status(204)
- return
- }
-
- if err = models.DeleteCommentByID(c.User, comment.ID); err != nil {
- c.Error(500, "DeleteCommentByID", err)
- return
- }
- c.Status(204)
-}
diff --git a/routers/api/v1/repo/issue_label.go b/routers/api/v1/repo/issue_label.go
deleted file mode 100644
index f3f2d730..00000000
--- a/routers/api/v1/repo/issue_label.go
+++ /dev/null
@@ -1,169 +0,0 @@
-// Copyright 2016 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 repo
-
-import (
- api "github.com/gogits/go-gogs-client"
-
- "github.com/gogits/gogs/models"
- "github.com/gogits/gogs/models/errors"
- "github.com/gogits/gogs/pkg/context"
-)
-
-func ListIssueLabels(c *context.APIContext) {
- issue, err := models.GetIssueByIndex(c.Repo.Repository.ID, c.ParamsInt64(":index"))
- if err != nil {
- if errors.IsIssueNotExist(err) {
- c.Status(404)
- } else {
- c.Error(500, "GetIssueByIndex", err)
- }
- return
- }
-
- apiLabels := make([]*api.Label, len(issue.Labels))
- for i := range issue.Labels {
- apiLabels[i] = issue.Labels[i].APIFormat()
- }
- c.JSON(200, &apiLabels)
-}
-
-func AddIssueLabels(c *context.APIContext, form api.IssueLabelsOption) {
- if !c.Repo.IsWriter() {
- c.Status(403)
- return
- }
-
- issue, err := models.GetIssueByIndex(c.Repo.Repository.ID, c.ParamsInt64(":index"))
- if err != nil {
- if errors.IsIssueNotExist(err) {
- c.Status(404)
- } else {
- c.Error(500, "GetIssueByIndex", err)
- }
- return
- }
-
- labels, err := models.GetLabelsInRepoByIDs(c.Repo.Repository.ID, form.Labels)
- if err != nil {
- c.Error(500, "GetLabelsInRepoByIDs", err)
- return
- }
-
- if err = issue.AddLabels(c.User, labels); err != nil {
- c.Error(500, "AddLabels", err)
- return
- }
-
- labels, err = models.GetLabelsByIssueID(issue.ID)
- if err != nil {
- c.Error(500, "GetLabelsByIssueID", err)
- return
- }
-
- apiLabels := make([]*api.Label, len(labels))
- for i := range labels {
- apiLabels[i] = issue.Labels[i].APIFormat()
- }
- c.JSON(200, &apiLabels)
-}
-
-func DeleteIssueLabel(c *context.APIContext) {
- if !c.Repo.IsWriter() {
- c.Status(403)
- return
- }
-
- issue, err := models.GetIssueByIndex(c.Repo.Repository.ID, c.ParamsInt64(":index"))
- if err != nil {
- if errors.IsIssueNotExist(err) {
- c.Status(404)
- } else {
- c.Error(500, "GetIssueByIndex", err)
- }
- return
- }
-
- label, err := models.GetLabelOfRepoByID(c.Repo.Repository.ID, c.ParamsInt64(":id"))
- if err != nil {
- if models.IsErrLabelNotExist(err) {
- c.Error(422, "", err)
- } else {
- c.Error(500, "GetLabelInRepoByID", err)
- }
- return
- }
-
- if err := models.DeleteIssueLabel(issue, label); err != nil {
- c.Error(500, "DeleteIssueLabel", err)
- return
- }
-
- c.Status(204)
-}
-
-func ReplaceIssueLabels(c *context.APIContext, form api.IssueLabelsOption) {
- if !c.Repo.IsWriter() {
- c.Status(403)
- return
- }
-
- issue, err := models.GetIssueByIndex(c.Repo.Repository.ID, c.ParamsInt64(":index"))
- if err != nil {
- if errors.IsIssueNotExist(err) {
- c.Status(404)
- } else {
- c.Error(500, "GetIssueByIndex", err)
- }
- return
- }
-
- labels, err := models.GetLabelsInRepoByIDs(c.Repo.Repository.ID, form.Labels)
- if err != nil {
- c.Error(500, "GetLabelsInRepoByIDs", err)
- return
- }
-
- if err := issue.ReplaceLabels(labels); err != nil {
- c.Error(500, "ReplaceLabels", err)
- return
- }
-
- labels, err = models.GetLabelsByIssueID(issue.ID)
- if err != nil {
- c.Error(500, "GetLabelsByIssueID", err)
- return
- }
-
- apiLabels := make([]*api.Label, len(labels))
- for i := range labels {
- apiLabels[i] = issue.Labels[i].APIFormat()
- }
- c.JSON(200, &apiLabels)
-}
-
-func ClearIssueLabels(c *context.APIContext) {
- if !c.Repo.IsWriter() {
- c.Status(403)
- return
- }
-
- issue, err := models.GetIssueByIndex(c.Repo.Repository.ID, c.ParamsInt64(":index"))
- if err != nil {
- if errors.IsIssueNotExist(err) {
- c.Status(404)
- } else {
- c.Error(500, "GetIssueByIndex", err)
- }
- return
- }
-
- if err := issue.ClearLabels(c.User); err != nil {
- c.Error(500, "ClearLabels", err)
- return
- }
-
- c.Status(204)
-}
diff --git a/routers/api/v1/repo/key.go b/routers/api/v1/repo/key.go
deleted file mode 100644
index 901df4c7..00000000
--- a/routers/api/v1/repo/key.go
+++ /dev/null
@@ -1,114 +0,0 @@
-// Copyright 2015 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 repo
-
-import (
- "fmt"
-
- api "github.com/gogits/go-gogs-client"
-
- "github.com/gogits/gogs/models"
- "github.com/gogits/gogs/pkg/context"
- "github.com/gogits/gogs/pkg/setting"
- "github.com/gogits/gogs/routers/api/v1/convert"
-)
-
-func composeDeployKeysAPILink(repoPath string) string {
- return setting.AppURL + "api/v1/repos/" + repoPath + "/keys/"
-}
-
-// https://github.com/gogits/go-gogs-client/wiki/Repositories-Deploy-Keys#list-deploy-keys
-func ListDeployKeys(c *context.APIContext) {
- keys, err := models.ListDeployKeys(c.Repo.Repository.ID)
- if err != nil {
- c.Error(500, "ListDeployKeys", err)
- return
- }
-
- apiLink := composeDeployKeysAPILink(c.Repo.Owner.Name + "/" + c.Repo.Repository.Name)
- apiKeys := make([]*api.DeployKey, len(keys))
- for i := range keys {
- if err = keys[i].GetContent(); err != nil {
- c.Error(500, "GetContent", err)
- return
- }
- apiKeys[i] = convert.ToDeployKey(apiLink, keys[i])
- }
-
- c.JSON(200, &apiKeys)
-}
-
-// https://github.com/gogits/go-gogs-client/wiki/Repositories-Deploy-Keys#get-a-deploy-key
-func GetDeployKey(c *context.APIContext) {
- key, err := models.GetDeployKeyByID(c.ParamsInt64(":id"))
- if err != nil {
- if models.IsErrDeployKeyNotExist(err) {
- c.Status(404)
- } else {
- c.Error(500, "GetDeployKeyByID", err)
- }
- return
- }
-
- if err = key.GetContent(); err != nil {
- c.Error(500, "GetContent", err)
- return
- }
-
- apiLink := composeDeployKeysAPILink(c.Repo.Owner.Name + "/" + c.Repo.Repository.Name)
- c.JSON(200, convert.ToDeployKey(apiLink, key))
-}
-
-func HandleCheckKeyStringError(c *context.APIContext, err error) {
- if models.IsErrKeyUnableVerify(err) {
- c.Error(422, "", "Unable to verify key content")
- } else {
- c.Error(422, "", fmt.Errorf("Invalid key content: %v", err))
- }
-}
-
-func HandleAddKeyError(c *context.APIContext, err error) {
- switch {
- case models.IsErrKeyAlreadyExist(err):
- c.Error(422, "", "Key content has been used as non-deploy key")
- case models.IsErrKeyNameAlreadyUsed(err):
- c.Error(422, "", "Key title has been used")
- default:
- c.Error(500, "AddKey", err)
- }
-}
-
-// https://github.com/gogits/go-gogs-client/wiki/Repositories-Deploy-Keys#add-a-new-deploy-key
-func CreateDeployKey(c *context.APIContext, form api.CreateKeyOption) {
- content, err := models.CheckPublicKeyString(form.Key)
- if err != nil {
- HandleCheckKeyStringError(c, err)
- return
- }
-
- key, err := models.AddDeployKey(c.Repo.Repository.ID, form.Title, content)
- if err != nil {
- HandleAddKeyError(c, err)
- return
- }
-
- key.Content = content
- apiLink := composeDeployKeysAPILink(c.Repo.Owner.Name + "/" + c.Repo.Repository.Name)
- c.JSON(201, convert.ToDeployKey(apiLink, key))
-}
-
-// https://github.com/gogits/go-gogs-client/wiki/Repositories-Deploy-Keys#remove-a-deploy-key
-func DeleteDeploykey(c *context.APIContext) {
- if err := models.DeleteDeployKey(c.User, c.ParamsInt64(":id")); err != nil {
- if models.IsErrKeyAccessDenied(err) {
- c.Error(403, "", "You do not have access to this key")
- } else {
- c.Error(500, "DeleteDeployKey", err)
- }
- return
- }
-
- c.Status(204)
-}
diff --git a/routers/api/v1/repo/label.go b/routers/api/v1/repo/label.go
deleted file mode 100644
index 1161d633..00000000
--- a/routers/api/v1/repo/label.go
+++ /dev/null
@@ -1,110 +0,0 @@
-// Copyright 2016 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 repo
-
-import (
- "github.com/Unknwon/com"
-
- api "github.com/gogits/go-gogs-client"
-
- "github.com/gogits/gogs/models"
- "github.com/gogits/gogs/pkg/context"
-)
-
-func ListLabels(c *context.APIContext) {
- labels, err := models.GetLabelsByRepoID(c.Repo.Repository.ID)
- if err != nil {
- c.Error(500, "GetLabelsByRepoID", err)
- return
- }
-
- apiLabels := make([]*api.Label, len(labels))
- for i := range labels {
- apiLabels[i] = labels[i].APIFormat()
- }
- c.JSON(200, &apiLabels)
-}
-
-func GetLabel(c *context.APIContext) {
- var label *models.Label
- var err error
- idStr := c.Params(":id")
- if id := com.StrTo(idStr).MustInt64(); id > 0 {
- label, err = models.GetLabelOfRepoByID(c.Repo.Repository.ID, id)
- } else {
- label, err = models.GetLabelOfRepoByName(c.Repo.Repository.ID, idStr)
- }
- if err != nil {
- if models.IsErrLabelNotExist(err) {
- c.Status(404)
- } else {
- c.Error(500, "GetLabelByRepoID", err)
- }
- return
- }
-
- c.JSON(200, label.APIFormat())
-}
-
-func CreateLabel(c *context.APIContext, form api.CreateLabelOption) {
- if !c.Repo.IsWriter() {
- c.Status(403)
- return
- }
-
- label := &models.Label{
- Name: form.Name,
- Color: form.Color,
- RepoID: c.Repo.Repository.ID,
- }
- if err := models.NewLabels(label); err != nil {
- c.Error(500, "NewLabel", err)
- return
- }
- c.JSON(201, label.APIFormat())
-}
-
-func EditLabel(c *context.APIContext, form api.EditLabelOption) {
- if !c.Repo.IsWriter() {
- c.Status(403)
- return
- }
-
- label, err := models.GetLabelOfRepoByID(c.Repo.Repository.ID, c.ParamsInt64(":id"))
- if err != nil {
- if models.IsErrLabelNotExist(err) {
- c.Status(404)
- } else {
- c.Error(500, "GetLabelByRepoID", err)
- }
- return
- }
-
- if form.Name != nil {
- label.Name = *form.Name
- }
- if form.Color != nil {
- label.Color = *form.Color
- }
- if err := models.UpdateLabel(label); err != nil {
- c.Handle(500, "UpdateLabel", err)
- return
- }
- c.JSON(200, label.APIFormat())
-}
-
-func DeleteLabel(c *context.APIContext) {
- if !c.Repo.IsWriter() {
- c.Status(403)
- return
- }
-
- if err := models.DeleteLabel(c.Repo.Repository.ID, c.ParamsInt64(":id")); err != nil {
- c.Error(500, "DeleteLabel", err)
- return
- }
-
- c.Status(204)
-}
diff --git a/routers/api/v1/repo/milestone.go b/routers/api/v1/repo/milestone.go
deleted file mode 100644
index baf8eb2f..00000000
--- a/routers/api/v1/repo/milestone.go
+++ /dev/null
@@ -1,103 +0,0 @@
-// Copyright 2016 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 repo
-
-import (
- "time"
-
- api "github.com/gogits/go-gogs-client"
-
- "github.com/gogits/gogs/models"
- "github.com/gogits/gogs/pkg/context"
-)
-
-func ListMilestones(c *context.APIContext) {
- milestones, err := models.GetMilestonesByRepoID(c.Repo.Repository.ID)
- if err != nil {
- c.Error(500, "GetMilestonesByRepoID", err)
- return
- }
-
- apiMilestones := make([]*api.Milestone, len(milestones))
- for i := range milestones {
- apiMilestones[i] = milestones[i].APIFormat()
- }
- c.JSON(200, &apiMilestones)
-}
-
-func GetMilestone(c *context.APIContext) {
- milestone, err := models.GetMilestoneByRepoID(c.Repo.Repository.ID, c.ParamsInt64(":id"))
- if err != nil {
- if models.IsErrMilestoneNotExist(err) {
- c.Status(404)
- } else {
- c.Error(500, "GetMilestoneByRepoID", err)
- }
- return
- }
- c.JSON(200, milestone.APIFormat())
-}
-
-func CreateMilestone(c *context.APIContext, form api.CreateMilestoneOption) {
- if form.Deadline == nil {
- defaultDeadline, _ := time.ParseInLocation("2006-01-02", "9999-12-31", time.Local)
- form.Deadline = &defaultDeadline
- }
-
- milestone := &models.Milestone{
- RepoID: c.Repo.Repository.ID,
- Name: form.Title,
- Content: form.Description,
- Deadline: *form.Deadline,
- }
-
- if err := models.NewMilestone(milestone); err != nil {
- c.Error(500, "NewMilestone", err)
- return
- }
- c.JSON(201, milestone.APIFormat())
-}
-
-func EditMilestone(c *context.APIContext, form api.EditMilestoneOption) {
- milestone, err := models.GetMilestoneByRepoID(c.Repo.Repository.ID, c.ParamsInt64(":id"))
- if err != nil {
- if models.IsErrMilestoneNotExist(err) {
- c.Status(404)
- } else {
- c.Error(500, "GetMilestoneByRepoID", err)
- }
- return
- }
-
- if len(form.Title) > 0 {
- milestone.Name = form.Title
- }
- if form.Description != nil {
- milestone.Content = *form.Description
- }
- if form.Deadline != nil && !form.Deadline.IsZero() {
- milestone.Deadline = *form.Deadline
- }
-
- if form.State != nil {
- if err = milestone.ChangeStatus(api.STATE_CLOSED == api.StateType(*form.State)); err != nil {
- c.Error(500, "ChangeStatus", err)
- return
- }
- } else if err = models.UpdateMilestone(milestone); err != nil {
- c.Handle(500, "UpdateMilestone", err)
- return
- }
-
- c.JSON(200, milestone.APIFormat())
-}
-
-func DeleteMilestone(c *context.APIContext) {
- if err := models.DeleteMilestoneOfRepoByID(c.Repo.Repository.ID, c.ParamsInt64(":id")); err != nil {
- c.Error(500, "DeleteMilestoneByRepoID", err)
- return
- }
- c.Status(204)
-}
diff --git a/routers/api/v1/repo/repo.go b/routers/api/v1/repo/repo.go
deleted file mode 100644
index 727e1678..00000000
--- a/routers/api/v1/repo/repo.go
+++ /dev/null
@@ -1,380 +0,0 @@
-// 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 repo
-
-import (
- "path"
-
- log "gopkg.in/clog.v1"
-
- api "github.com/gogits/go-gogs-client"
-
- "github.com/gogits/gogs/models"
- "github.com/gogits/gogs/models/errors"
- "github.com/gogits/gogs/pkg/context"
- "github.com/gogits/gogs/pkg/form"
- "github.com/gogits/gogs/pkg/setting"
- "github.com/gogits/gogs/routers/api/v1/convert"
-)
-
-// https://github.com/gogits/go-gogs-client/wiki/Repositories#search-repositories
-func Search(c *context.APIContext) {
- opts := &models.SearchRepoOptions{
- Keyword: path.Base(c.Query("q")),
- OwnerID: c.QueryInt64("uid"),
- PageSize: convert.ToCorrectPageSize(c.QueryInt("limit")),
- }
-
- // Check visibility.
- if c.IsLogged && opts.OwnerID > 0 {
- if c.User.ID == opts.OwnerID {
- opts.Private = true
- } else {
- u, err := models.GetUserByID(opts.OwnerID)
- if err != nil {
- c.JSON(500, map[string]interface{}{
- "ok": false,
- "error": err.Error(),
- })
- return
- }
- if u.IsOrganization() && u.IsOwnedBy(c.User.ID) {
- opts.Private = true
- }
- // FIXME: how about collaborators?
- }
- }
-
- repos, count, err := models.SearchRepositoryByName(opts)
- if err != nil {
- c.JSON(500, map[string]interface{}{
- "ok": false,
- "error": err.Error(),
- })
- return
- }
-
- if err = models.RepositoryList(repos).LoadAttributes(); err != nil {
- c.JSON(500, map[string]interface{}{
- "ok": false,
- "error": err.Error(),
- })
- return
- }
-
- results := make([]*api.Repository, len(repos))
- for i := range repos {
- results[i] = repos[i].APIFormat(nil)
- }
-
- c.SetLinkHeader(int(count), setting.API.MaxResponseItems)
- c.JSON(200, map[string]interface{}{
- "ok": true,
- "data": results,
- })
-}
-
-func listUserRepositories(c *context.APIContext, username string) {
- user, err := models.GetUserByName(username)
- if err != nil {
- c.NotFoundOrServerError("GetUserByName", errors.IsUserNotExist, err)
- return
- }
-
- // Only list public repositories if user requests someone else's repository list,
- // or an organization isn't a member of.
- var ownRepos []*models.Repository
- if user.IsOrganization() {
- ownRepos, _, err = user.GetUserRepositories(c.User.ID, 1, user.NumRepos)
- } else {
- ownRepos, err = models.GetUserRepositories(&models.UserRepoOptions{
- UserID: user.ID,
- Private: c.User.ID == user.ID,
- Page: 1,
- PageSize: user.NumRepos,
- })
- }
- if err != nil {
- c.Error(500, "GetUserRepositories", err)
- return
- }
-
- if c.User.ID != user.ID {
- repos := make([]*api.Repository, len(ownRepos))
- for i := range ownRepos {
- repos[i] = ownRepos[i].APIFormat(&api.Permission{true, true, true})
- }
- c.JSON(200, &repos)
- return
- }
-
- accessibleRepos, err := user.GetRepositoryAccesses()
- if err != nil {
- c.Error(500, "GetRepositoryAccesses", err)
- return
- }
-
- numOwnRepos := len(ownRepos)
- repos := make([]*api.Repository, numOwnRepos+len(accessibleRepos))
- for i := range ownRepos {
- repos[i] = ownRepos[i].APIFormat(&api.Permission{true, true, true})
- }
-
- i := numOwnRepos
- for repo, access := range accessibleRepos {
- repos[i] = repo.APIFormat(&api.Permission{
- Admin: access >= models.ACCESS_MODE_ADMIN,
- Push: access >= models.ACCESS_MODE_WRITE,
- Pull: true,
- })
- i++
- }
-
- c.JSON(200, &repos)
-}
-
-func ListMyRepos(c *context.APIContext) {
- listUserRepositories(c, c.User.Name)
-}
-
-func ListUserRepositories(c *context.APIContext) {
- listUserRepositories(c, c.Params(":username"))
-}
-
-func ListOrgRepositories(c *context.APIContext) {
- listUserRepositories(c, c.Params(":org"))
-}
-
-func CreateUserRepo(c *context.APIContext, owner *models.User, opt api.CreateRepoOption) {
- repo, err := models.CreateRepository(c.User, owner, models.CreateRepoOptions{
- Name: opt.Name,
- Description: opt.Description,
- Gitignores: opt.Gitignores,
- License: opt.License,
- Readme: opt.Readme,
- IsPrivate: opt.Private,
- AutoInit: opt.AutoInit,
- })
- if err != nil {
- if models.IsErrRepoAlreadyExist(err) ||
- models.IsErrNameReserved(err) ||
- models.IsErrNamePatternNotAllowed(err) {
- c.Error(422, "", err)
- } else {
- if repo != nil {
- if err = models.DeleteRepository(c.User.ID, repo.ID); err != nil {
- log.Error(2, "DeleteRepository: %v", err)
- }
- }
- c.Error(500, "CreateRepository", err)
- }
- return
- }
-
- c.JSON(201, repo.APIFormat(&api.Permission{true, true, true}))
-}
-
-// https://github.com/gogits/go-gogs-client/wiki/Repositories#create
-func Create(c *context.APIContext, opt api.CreateRepoOption) {
- // Shouldn't reach this condition, but just in case.
- if c.User.IsOrganization() {
- c.Error(422, "", "not allowed creating repository for organization")
- return
- }
- CreateUserRepo(c, c.User, opt)
-}
-
-func CreateOrgRepo(c *context.APIContext, opt api.CreateRepoOption) {
- org, err := models.GetOrgByName(c.Params(":org"))
- if err != nil {
- if errors.IsUserNotExist(err) {
- c.Error(422, "", err)
- } else {
- c.Error(500, "GetOrgByName", err)
- }
- return
- }
-
- if !org.IsOwnedBy(c.User.ID) {
- c.Error(403, "", "Given user is not owner of organization.")
- return
- }
- CreateUserRepo(c, org, opt)
-}
-
-// https://github.com/gogits/go-gogs-client/wiki/Repositories#migrate
-func Migrate(c *context.APIContext, f form.MigrateRepo) {
- ctxUser := c.User
- // Not equal means context user is an organization,
- // or is another user/organization if current user is admin.
- if f.Uid != ctxUser.ID {
- org, err := models.GetUserByID(f.Uid)
- if err != nil {
- if errors.IsUserNotExist(err) {
- c.Error(422, "", err)
- } else {
- c.Error(500, "GetUserByID", err)
- }
- return
- } else if !org.IsOrganization() && !c.User.IsAdmin {
- c.Error(403, "", "Given user is not an organization")
- return
- }
- ctxUser = org
- }
-
- if c.HasError() {
- c.Error(422, "", c.GetErrMsg())
- return
- }
-
- if ctxUser.IsOrganization() && !c.User.IsAdmin {
- // Check ownership of organization.
- if !ctxUser.IsOwnedBy(c.User.ID) {
- c.Error(403, "", "Given user is not owner of organization")
- return
- }
- }
-
- remoteAddr, err := f.ParseRemoteAddr(c.User)
- if err != nil {
- if models.IsErrInvalidCloneAddr(err) {
- addrErr := err.(models.ErrInvalidCloneAddr)
- switch {
- case addrErr.IsURLError:
- c.Error(422, "", err)
- case addrErr.IsPermissionDenied:
- c.Error(422, "", "You are not allowed to import local repositories")
- case addrErr.IsInvalidPath:
- c.Error(422, "", "Invalid local path, it does not exist or not a directory")
- default:
- c.Error(500, "ParseRemoteAddr", "Unknown error type (ErrInvalidCloneAddr): "+err.Error())
- }
- } else {
- c.Error(500, "ParseRemoteAddr", err)
- }
- return
- }
-
- repo, err := models.MigrateRepository(c.User, ctxUser, models.MigrateRepoOptions{
- Name: f.RepoName,
- Description: f.Description,
- IsPrivate: f.Private || setting.Repository.ForcePrivate,
- IsMirror: f.Mirror,
- RemoteAddr: remoteAddr,
- })
- if err != nil {
- if repo != nil {
- if errDelete := models.DeleteRepository(ctxUser.ID, repo.ID); errDelete != nil {
- log.Error(2, "DeleteRepository: %v", errDelete)
- }
- }
-
- if errors.IsReachLimitOfRepo(err) {
- c.Error(422, "", err)
- } else {
- c.Error(500, "MigrateRepository", models.HandleMirrorCredentials(err.Error(), true))
- }
- return
- }
-
- log.Trace("Repository migrated: %s/%s", ctxUser.Name, f.RepoName)
- c.JSON(201, repo.APIFormat(&api.Permission{true, true, true}))
-}
-
-func parseOwnerAndRepo(c *context.APIContext) (*models.User, *models.Repository) {
- owner, err := models.GetUserByName(c.Params(":username"))
- if err != nil {
- if errors.IsUserNotExist(err) {
- c.Error(422, "", err)
- } else {
- c.Error(500, "GetUserByName", err)
- }
- return nil, nil
- }
-
- repo, err := models.GetRepositoryByName(owner.ID, c.Params(":reponame"))
- if err != nil {
- if errors.IsRepoNotExist(err) {
- c.Status(404)
- } else {
- c.Error(500, "GetRepositoryByName", err)
- }
- return nil, nil
- }
-
- return owner, repo
-}
-
-// https://github.com/gogits/go-gogs-client/wiki/Repositories#get
-func Get(c *context.APIContext) {
- _, repo := parseOwnerAndRepo(c)
- if c.Written() {
- return
- }
-
- c.JSON(200, repo.APIFormat(&api.Permission{
- Admin: c.Repo.IsAdmin(),
- Push: c.Repo.IsWriter(),
- Pull: true,
- }))
-}
-
-// https://github.com/gogits/go-gogs-client/wiki/Repositories#delete
-func Delete(c *context.APIContext) {
- owner, repo := parseOwnerAndRepo(c)
- if c.Written() {
- return
- }
-
- if owner.IsOrganization() && !owner.IsOwnedBy(c.User.ID) {
- c.Error(403, "", "Given user is not owner of organization.")
- return
- }
-
- if err := models.DeleteRepository(owner.ID, repo.ID); err != nil {
- c.Error(500, "DeleteRepository", err)
- return
- }
-
- log.Trace("Repository deleted: %s/%s", owner.Name, repo.Name)
- c.Status(204)
-}
-
-func ListForks(c *context.APIContext) {
- forks, err := c.Repo.Repository.GetForks()
- if err != nil {
- c.Error(500, "GetForks", err)
- return
- }
-
- apiForks := make([]*api.Repository, len(forks))
- for i := range forks {
- if err := forks[i].GetOwner(); err != nil {
- c.Error(500, "GetOwner", err)
- return
- }
- apiForks[i] = forks[i].APIFormat(&api.Permission{
- Admin: c.User.IsAdminOfRepo(forks[i]),
- Push: c.User.IsWriterOfRepo(forks[i]),
- Pull: true,
- })
- }
-
- c.JSON(200, &apiForks)
-}
-
-func MirrorSync(c *context.APIContext) {
- _, repo := parseOwnerAndRepo(c)
- if c.Written() {
- return
- } else if !repo.IsMirror {
- c.Status(404)
- return
- }
-
- go models.MirrorQueue.Add(repo.ID)
- c.Status(202)
-}
diff --git a/routers/api/v1/user/app.go b/routers/api/v1/user/app.go
deleted file mode 100644
index bda1e23f..00000000
--- a/routers/api/v1/user/app.go
+++ /dev/null
@@ -1,40 +0,0 @@
-// 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 user
-
-import (
- api "github.com/gogits/go-gogs-client"
-
- "github.com/gogits/gogs/models"
- "github.com/gogits/gogs/pkg/context"
-)
-
-// https://github.com/gogits/go-gogs-client/wiki/Users#list-access-tokens-for-a-user
-func ListAccessTokens(c *context.APIContext) {
- tokens, err := models.ListAccessTokens(c.User.ID)
- if err != nil {
- c.Error(500, "ListAccessTokens", err)
- return
- }
-
- apiTokens := make([]*api.AccessToken, len(tokens))
- for i := range tokens {
- apiTokens[i] = &api.AccessToken{tokens[i].Name, tokens[i].Sha1}
- }
- c.JSON(200, &apiTokens)
-}
-
-// https://github.com/gogits/go-gogs-client/wiki/Users#create-a-access-token
-func CreateAccessToken(c *context.APIContext, form api.CreateAccessTokenOption) {
- t := &models.AccessToken{
- UID: c.User.ID,
- Name: form.Name,
- }
- if err := models.NewAccessToken(t); err != nil {
- c.Error(500, "NewAccessToken", err)
- return
- }
- c.JSON(201, &api.AccessToken{t.Name, t.Sha1})
-}
diff --git a/routers/api/v1/user/email.go b/routers/api/v1/user/email.go
deleted file mode 100644
index 7c527a1a..00000000
--- a/routers/api/v1/user/email.go
+++ /dev/null
@@ -1,82 +0,0 @@
-// Copyright 2015 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 user
-
-import (
- api "github.com/gogits/go-gogs-client"
-
- "github.com/gogits/gogs/models"
- "github.com/gogits/gogs/pkg/context"
- "github.com/gogits/gogs/pkg/setting"
- "github.com/gogits/gogs/routers/api/v1/convert"
-)
-
-// https://github.com/gogits/go-gogs-client/wiki/Users-Emails#list-email-addresses-for-a-user
-func ListEmails(c *context.APIContext) {
- emails, err := models.GetEmailAddresses(c.User.ID)
- if err != nil {
- c.Error(500, "GetEmailAddresses", err)
- return
- }
- apiEmails := make([]*api.Email, len(emails))
- for i := range emails {
- apiEmails[i] = convert.ToEmail(emails[i])
- }
- c.JSON(200, &apiEmails)
-}
-
-// https://github.com/gogits/go-gogs-client/wiki/Users-Emails#add-email-addresses
-func AddEmail(c *context.APIContext, form api.CreateEmailOption) {
- if len(form.Emails) == 0 {
- c.Status(422)
- return
- }
-
- emails := make([]*models.EmailAddress, len(form.Emails))
- for i := range form.Emails {
- emails[i] = &models.EmailAddress{
- UID: c.User.ID,
- Email: form.Emails[i],
- IsActivated: !setting.Service.RegisterEmailConfirm,
- }
- }
-
- if err := models.AddEmailAddresses(emails); err != nil {
- if models.IsErrEmailAlreadyUsed(err) {
- c.Error(422, "", "Email address has been used: "+err.(models.ErrEmailAlreadyUsed).Email)
- } else {
- c.Error(500, "AddEmailAddresses", err)
- }
- return
- }
-
- apiEmails := make([]*api.Email, len(emails))
- for i := range emails {
- apiEmails[i] = convert.ToEmail(emails[i])
- }
- c.JSON(201, &apiEmails)
-}
-
-// https://github.com/gogits/go-gogs-client/wiki/Users-Emails#delete-email-addresses
-func DeleteEmail(c *context.APIContext, form api.CreateEmailOption) {
- if len(form.Emails) == 0 {
- c.Status(204)
- return
- }
-
- emails := make([]*models.EmailAddress, len(form.Emails))
- for i := range form.Emails {
- emails[i] = &models.EmailAddress{
- UID: c.User.ID,
- Email: form.Emails[i],
- }
- }
-
- if err := models.DeleteEmailAddresses(emails); err != nil {
- c.Error(500, "DeleteEmailAddresses", err)
- return
- }
- c.Status(204)
-}
diff --git a/routers/api/v1/user/follower.go b/routers/api/v1/user/follower.go
deleted file mode 100644
index 6bbd4c7e..00000000
--- a/routers/api/v1/user/follower.go
+++ /dev/null
@@ -1,120 +0,0 @@
-// Copyright 2015 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 user
-
-import (
- api "github.com/gogits/go-gogs-client"
-
- "github.com/gogits/gogs/models"
- "github.com/gogits/gogs/pkg/context"
-)
-
-func responseApiUsers(c *context.APIContext, users []*models.User) {
- apiUsers := make([]*api.User, len(users))
- for i := range users {
- apiUsers[i] = users[i].APIFormat()
- }
- c.JSON(200, &apiUsers)
-}
-
-func listUserFollowers(c *context.APIContext, u *models.User) {
- users, err := u.GetFollowers(c.QueryInt("page"))
- if err != nil {
- c.Error(500, "GetUserFollowers", err)
- return
- }
- responseApiUsers(c, users)
-}
-
-func ListMyFollowers(c *context.APIContext) {
- listUserFollowers(c, c.User)
-}
-
-// https://github.com/gogits/go-gogs-client/wiki/Users-Followers#list-followers-of-a-user
-func ListFollowers(c *context.APIContext) {
- u := GetUserByParams(c)
- if c.Written() {
- return
- }
- listUserFollowers(c, u)
-}
-
-func listUserFollowing(c *context.APIContext, u *models.User) {
- users, err := u.GetFollowing(c.QueryInt("page"))
- if err != nil {
- c.Error(500, "GetFollowing", err)
- return
- }
- responseApiUsers(c, users)
-}
-
-func ListMyFollowing(c *context.APIContext) {
- listUserFollowing(c, c.User)
-}
-
-// https://github.com/gogits/go-gogs-client/wiki/Users-Followers#list-users-followed-by-another-user
-func ListFollowing(c *context.APIContext) {
- u := GetUserByParams(c)
- if c.Written() {
- return
- }
- listUserFollowing(c, u)
-}
-
-func checkUserFollowing(c *context.APIContext, u *models.User, followID int64) {
- if u.IsFollowing(followID) {
- c.Status(204)
- } else {
- c.Status(404)
- }
-}
-
-// https://github.com/gogits/go-gogs-client/wiki/Users-Followers#check-if-you-are-following-a-user
-func CheckMyFollowing(c *context.APIContext) {
- target := GetUserByParams(c)
- if c.Written() {
- return
- }
- checkUserFollowing(c, c.User, target.ID)
-}
-
-// https://github.com/gogits/go-gogs-client/wiki/Users-Followers#check-if-one-user-follows-another
-func CheckFollowing(c *context.APIContext) {
- u := GetUserByParams(c)
- if c.Written() {
- return
- }
- target := GetUserByParamsName(c, ":target")
- if c.Written() {
- return
- }
- checkUserFollowing(c, u, target.ID)
-}
-
-// https://github.com/gogits/go-gogs-client/wiki/Users-Followers#follow-a-user
-func Follow(c *context.APIContext) {
- target := GetUserByParams(c)
- if c.Written() {
- return
- }
- if err := models.FollowUser(c.User.ID, target.ID); err != nil {
- c.Error(500, "FollowUser", err)
- return
- }
- c.Status(204)
-}
-
-// https://github.com/gogits/go-gogs-client/wiki/Users-Followers#unfollow-a-user
-func Unfollow(c *context.APIContext) {
- target := GetUserByParams(c)
- if c.Written() {
- return
- }
- if err := models.UnfollowUser(c.User.ID, target.ID); err != nil {
- c.Error(500, "UnfollowUser", err)
- return
- }
- c.Status(204)
-}
diff --git a/routers/api/v1/user/key.go b/routers/api/v1/user/key.go
deleted file mode 100644
index f0c833f5..00000000
--- a/routers/api/v1/user/key.go
+++ /dev/null
@@ -1,120 +0,0 @@
-// Copyright 2015 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 user
-
-import (
- api "github.com/gogits/go-gogs-client"
-
- "github.com/gogits/gogs/models"
- "github.com/gogits/gogs/models/errors"
- "github.com/gogits/gogs/pkg/context"
- "github.com/gogits/gogs/pkg/setting"
- "github.com/gogits/gogs/routers/api/v1/convert"
- "github.com/gogits/gogs/routers/api/v1/repo"
-)
-
-func GetUserByParamsName(c *context.APIContext, name string) *models.User {
- user, err := models.GetUserByName(c.Params(name))
- if err != nil {
- if errors.IsUserNotExist(err) {
- c.Status(404)
- } else {
- c.Error(500, "GetUserByName", err)
- }
- return nil
- }
- return user
-}
-
-// GetUserByParams returns user whose name is presented in URL paramenter.
-func GetUserByParams(c *context.APIContext) *models.User {
- return GetUserByParamsName(c, ":username")
-}
-
-func composePublicKeysAPILink() string {
- return setting.AppURL + "api/v1/user/keys/"
-}
-
-func listPublicKeys(c *context.APIContext, uid int64) {
- keys, err := models.ListPublicKeys(uid)
- if err != nil {
- c.Error(500, "ListPublicKeys", err)
- return
- }
-
- apiLink := composePublicKeysAPILink()
- apiKeys := make([]*api.PublicKey, len(keys))
- for i := range keys {
- apiKeys[i] = convert.ToPublicKey(apiLink, keys[i])
- }
-
- c.JSON(200, &apiKeys)
-}
-
-// https://github.com/gogits/go-gogs-client/wiki/Users-Public-Keys#list-your-public-keys
-func ListMyPublicKeys(c *context.APIContext) {
- listPublicKeys(c, c.User.ID)
-}
-
-// https://github.com/gogits/go-gogs-client/wiki/Users-Public-Keys#list-public-keys-for-a-user
-func ListPublicKeys(c *context.APIContext) {
- user := GetUserByParams(c)
- if c.Written() {
- return
- }
- listPublicKeys(c, user.ID)
-}
-
-// https://github.com/gogits/go-gogs-client/wiki/Users-Public-Keys#get-a-single-public-key
-func GetPublicKey(c *context.APIContext) {
- key, err := models.GetPublicKeyByID(c.ParamsInt64(":id"))
- if err != nil {
- if models.IsErrKeyNotExist(err) {
- c.Status(404)
- } else {
- c.Error(500, "GetPublicKeyByID", err)
- }
- return
- }
-
- apiLink := composePublicKeysAPILink()
- c.JSON(200, convert.ToPublicKey(apiLink, key))
-}
-
-// CreateUserPublicKey creates new public key to given user by ID.
-func CreateUserPublicKey(c *context.APIContext, form api.CreateKeyOption, uid int64) {
- content, err := models.CheckPublicKeyString(form.Key)
- if err != nil {
- repo.HandleCheckKeyStringError(c, err)
- return
- }
-
- key, err := models.AddPublicKey(uid, form.Title, content)
- if err != nil {
- repo.HandleAddKeyError(c, err)
- return
- }
- apiLink := composePublicKeysAPILink()
- c.JSON(201, convert.ToPublicKey(apiLink, key))
-}
-
-// https://github.com/gogits/go-gogs-client/wiki/Users-Public-Keys#create-a-public-key
-func CreatePublicKey(c *context.APIContext, form api.CreateKeyOption) {
- CreateUserPublicKey(c, form, c.User.ID)
-}
-
-// https://github.com/gogits/go-gogs-client/wiki/Users-Public-Keys#delete-a-public-key
-func DeletePublicKey(c *context.APIContext) {
- if err := models.DeletePublicKey(c.User, c.ParamsInt64(":id")); err != nil {
- if models.IsErrKeyAccessDenied(err) {
- c.Error(403, "", "You do not have access to this key")
- } else {
- c.Error(500, "DeletePublicKey", err)
- }
- return
- }
-
- c.Status(204)
-}
diff --git a/routers/api/v1/user/user.go b/routers/api/v1/user/user.go
deleted file mode 100644
index dbf727de..00000000
--- a/routers/api/v1/user/user.go
+++ /dev/null
@@ -1,75 +0,0 @@
-// 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 user
-
-import (
- "github.com/Unknwon/com"
-
- api "github.com/gogits/go-gogs-client"
-
- "github.com/gogits/gogs/models"
- "github.com/gogits/gogs/models/errors"
- "github.com/gogits/gogs/pkg/context"
-)
-
-func Search(c *context.APIContext) {
- opts := &models.SearchUserOptions{
- Keyword: c.Query("q"),
- Type: models.USER_TYPE_INDIVIDUAL,
- PageSize: com.StrTo(c.Query("limit")).MustInt(),
- }
- if opts.PageSize == 0 {
- opts.PageSize = 10
- }
-
- users, _, err := models.SearchUserByName(opts)
- if err != nil {
- c.JSON(500, map[string]interface{}{
- "ok": false,
- "error": err.Error(),
- })
- return
- }
-
- results := make([]*api.User, len(users))
- for i := range users {
- results[i] = &api.User{
- ID: users[i].ID,
- UserName: users[i].Name,
- AvatarUrl: users[i].AvatarLink(),
- FullName: users[i].FullName,
- }
- if c.IsLogged {
- results[i].Email = users[i].Email
- }
- }
-
- c.JSON(200, map[string]interface{}{
- "ok": true,
- "data": results,
- })
-}
-
-func GetInfo(c *context.APIContext) {
- u, err := models.GetUserByName(c.Params(":username"))
- if err != nil {
- if errors.IsUserNotExist(err) {
- c.Status(404)
- } else {
- c.Error(500, "GetUserByName", err)
- }
- return
- }
-
- // Hide user e-mail when API caller isn't signed in.
- if !c.IsLogged {
- u.Email = ""
- }
- c.JSON(200, u.APIFormat())
-}
-
-func GetAuthenticatedUser(c *context.APIContext) {
- c.JSON(200, c.User.APIFormat())
-}
diff --git a/routers/dev/template.go b/routers/dev/template.go
deleted file mode 100644
index 00afa5c4..00000000
--- a/routers/dev/template.go
+++ /dev/null
@@ -1,24 +0,0 @@
-// 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 dev
-
-import (
- "github.com/gogits/gogs/models"
- "github.com/gogits/gogs/pkg/context"
- "github.com/gogits/gogs/pkg/setting"
-)
-
-func TemplatePreview(c *context.Context) {
- c.Data["User"] = models.User{Name: "Unknown"}
- c.Data["AppName"] = setting.AppName
- c.Data["AppVer"] = setting.AppVer
- c.Data["AppURL"] = setting.AppURL
- c.Data["Code"] = "2014031910370000009fff6782aadb2162b4a997acb69d4400888e0b9274657374"
- c.Data["ActiveCodeLives"] = setting.Service.ActiveCodeLives / 60
- c.Data["ResetPwdCodeLives"] = setting.Service.ResetPwdCodeLives / 60
- c.Data["CurDbValue"] = ""
-
- c.HTML(200, (c.Params("*")))
-}
diff --git a/routers/home.go b/routers/home.go
deleted file mode 100644
index bb43dc58..00000000
--- a/routers/home.go
+++ /dev/null
@@ -1,163 +0,0 @@
-// 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 routers
-
-import (
- "github.com/Unknwon/paginater"
-
- "github.com/gogits/gogs/models"
- "github.com/gogits/gogs/pkg/context"
- "github.com/gogits/gogs/pkg/setting"
- "github.com/gogits/gogs/routers/user"
-)
-
-const (
- HOME = "home"
- EXPLORE_REPOS = "explore/repos"
- EXPLORE_USERS = "explore/users"
- EXPLORE_ORGANIZATIONS = "explore/organizations"
-)
-
-func Home(c *context.Context) {
- if c.IsLogged {
- if !c.User.IsActive && setting.Service.RegisterEmailConfirm {
- c.Data["Title"] = c.Tr("auth.active_your_account")
- c.HTML(200, user.ACTIVATE)
- } else {
- user.Dashboard(c)
- }
- return
- }
-
- // Check auto-login.
- uname := c.GetCookie(setting.CookieUserName)
- if len(uname) != 0 {
- c.Redirect(setting.AppSubURL + "/user/login")
- return
- }
-
- c.Data["PageIsHome"] = true
- c.HTML(200, HOME)
-}
-
-func ExploreRepos(c *context.Context) {
- c.Data["Title"] = c.Tr("explore")
- c.Data["PageIsExplore"] = true
- c.Data["PageIsExploreRepositories"] = true
-
- page := c.QueryInt("page")
- if page <= 0 {
- page = 1
- }
-
- keyword := c.Query("q")
- repos, count, err := models.SearchRepositoryByName(&models.SearchRepoOptions{
- Keyword: keyword,
- UserID: c.UserID(),
- OrderBy: "updated_unix DESC",
- Page: page,
- PageSize: setting.UI.ExplorePagingNum,
- })
- if err != nil {
- c.Handle(500, "SearchRepositoryByName", err)
- return
- }
- c.Data["Keyword"] = keyword
- c.Data["Total"] = count
- c.Data["Page"] = paginater.New(int(count), setting.UI.ExplorePagingNum, page, 5)
-
- if err = models.RepositoryList(repos).LoadAttributes(); err != nil {
- c.Handle(500, "LoadAttributes", err)
- return
- }
- c.Data["Repos"] = repos
-
- c.HTML(200, EXPLORE_REPOS)
-}
-
-type UserSearchOptions struct {
- Type models.UserType
- Counter func() int64
- Ranger func(int, int) ([]*models.User, error)
- PageSize int
- OrderBy string
- TplName string
-}
-
-func RenderUserSearch(c *context.Context, opts *UserSearchOptions) {
- page := c.QueryInt("page")
- if page <= 1 {
- page = 1
- }
-
- var (
- users []*models.User
- count int64
- err error
- )
-
- keyword := c.Query("q")
- if len(keyword) == 0 {
- users, err = opts.Ranger(page, opts.PageSize)
- if err != nil {
- c.Handle(500, "opts.Ranger", err)
- return
- }
- count = opts.Counter()
- } else {
- users, count, err = models.SearchUserByName(&models.SearchUserOptions{
- Keyword: keyword,
- Type: opts.Type,
- OrderBy: opts.OrderBy,
- Page: page,
- PageSize: opts.PageSize,
- })
- if err != nil {
- c.Handle(500, "SearchUserByName", err)
- return
- }
- }
- c.Data["Keyword"] = keyword
- c.Data["Total"] = count
- c.Data["Page"] = paginater.New(int(count), opts.PageSize, page, 5)
- c.Data["Users"] = users
-
- c.HTML(200, opts.TplName)
-}
-
-func ExploreUsers(c *context.Context) {
- c.Data["Title"] = c.Tr("explore")
- c.Data["PageIsExplore"] = true
- c.Data["PageIsExploreUsers"] = true
-
- RenderUserSearch(c, &UserSearchOptions{
- Type: models.USER_TYPE_INDIVIDUAL,
- Counter: models.CountUsers,
- Ranger: models.Users,
- PageSize: setting.UI.ExplorePagingNum,
- OrderBy: "updated_unix DESC",
- TplName: EXPLORE_USERS,
- })
-}
-
-func ExploreOrganizations(c *context.Context) {
- c.Data["Title"] = c.Tr("explore")
- c.Data["PageIsExplore"] = true
- c.Data["PageIsExploreOrganizations"] = true
-
- RenderUserSearch(c, &UserSearchOptions{
- Type: models.USER_TYPE_ORGANIZATION,
- Counter: models.CountOrganizations,
- Ranger: models.Organizations,
- PageSize: setting.UI.ExplorePagingNum,
- OrderBy: "updated_unix DESC",
- TplName: EXPLORE_ORGANIZATIONS,
- })
-}
-
-func NotFound(c *context.Context) {
- c.Data["Title"] = "Page Not Found"
- c.NotFound()
-}
diff --git a/routers/install.go b/routers/install.go
deleted file mode 100644
index 3b48d8d3..00000000
--- a/routers/install.go
+++ /dev/null
@@ -1,392 +0,0 @@
-// 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 routers
-
-import (
- "net/mail"
- "os"
- "os/exec"
- "path/filepath"
- "strings"
-
- "github.com/Unknwon/com"
- "github.com/go-xorm/xorm"
- log "gopkg.in/clog.v1"
- "gopkg.in/ini.v1"
- "gopkg.in/macaron.v1"
-
- "github.com/gogits/git-module"
-
- "github.com/gogits/gogs/models"
- "github.com/gogits/gogs/pkg/context"
- "github.com/gogits/gogs/pkg/cron"
- "github.com/gogits/gogs/pkg/form"
- "github.com/gogits/gogs/pkg/mailer"
- "github.com/gogits/gogs/pkg/markup"
- "github.com/gogits/gogs/pkg/setting"
- "github.com/gogits/gogs/pkg/ssh"
- "github.com/gogits/gogs/pkg/template/highlight"
- "github.com/gogits/gogs/pkg/tool"
- "github.com/gogits/gogs/pkg/user"
-)
-
-const (
- INSTALL = "install"
-)
-
-func checkRunMode() {
- if setting.ProdMode {
- macaron.Env = macaron.PROD
- macaron.ColorLog = false
- } else {
- git.Debug = true
- }
- log.Info("Run Mode: %s", strings.Title(macaron.Env))
-}
-
-func NewServices() {
- setting.NewServices()
- mailer.NewContext()
-}
-
-// GlobalInit is for global configuration reload-able.
-func GlobalInit() {
- setting.NewContext()
- log.Trace("Custom path: %s", setting.CustomPath)
- log.Trace("Log path: %s", setting.LogRootPath)
- models.LoadConfigs()
- NewServices()
-
- if setting.InstallLock {
- highlight.NewContext()
- markup.NewSanitizer()
- if err := models.NewEngine(); err != nil {
- log.Fatal(2, "Fail to initialize ORM engine: %v", err)
- }
- models.HasEngine = true
-
- models.LoadRepoConfig()
- models.NewRepoContext()
-
- // Booting long running goroutines.
- cron.NewContext()
- models.InitSyncMirrors()
- models.InitDeliverHooks()
- models.InitTestPullRequests()
- }
- if models.EnableSQLite3 {
- log.Info("SQLite3 Supported")
- }
- if setting.SupportMiniWinService {
- log.Info("Builtin Windows Service Supported")
- }
- checkRunMode()
-
- if setting.InstallLock && setting.SSH.StartBuiltinServer {
- ssh.Listen(setting.SSH.ListenHost, setting.SSH.ListenPort, setting.SSH.ServerCiphers)
- log.Info("SSH server started on %s:%v", setting.SSH.ListenHost, setting.SSH.ListenPort)
- log.Trace("SSH server cipher list: %v", setting.SSH.ServerCiphers)
- }
-}
-
-func InstallInit(c *context.Context) {
- if setting.InstallLock {
- c.NotFound()
- return
- }
-
- c.Title("install.install")
- c.PageIs("Install")
-
- dbOpts := []string{"MySQL", "PostgreSQL", "MSSQL"}
- if models.EnableSQLite3 {
- dbOpts = append(dbOpts, "SQLite3")
- }
- c.Data["DbOptions"] = dbOpts
-}
-
-func Install(c *context.Context) {
- f := form.Install{}
-
- // Database settings
- f.DbHost = models.DbCfg.Host
- f.DbUser = models.DbCfg.User
- f.DbName = models.DbCfg.Name
- f.DbPath = models.DbCfg.Path
-
- c.Data["CurDbOption"] = "MySQL"
- switch models.DbCfg.Type {
- case "postgres":
- c.Data["CurDbOption"] = "PostgreSQL"
- case "mssql":
- c.Data["CurDbOption"] = "MSSQL"
- case "sqlite3":
- if models.EnableSQLite3 {
- c.Data["CurDbOption"] = "SQLite3"
- }
- }
-
- // Application general settings
- f.AppName = setting.AppName
- f.RepoRootPath = setting.RepoRootPath
-
- // Note(unknwon): it's hard for Windows users change a running user,
- // so just use current one if config says default.
- if setting.IsWindows && setting.RunUser == "git" {
- f.RunUser = user.CurrentUsername()
- } else {
- f.RunUser = setting.RunUser
- }
-
- f.Domain = setting.Domain
- f.SSHPort = setting.SSH.Port
- f.UseBuiltinSSHServer = setting.SSH.StartBuiltinServer
- f.HTTPPort = setting.HTTPPort
- f.AppUrl = setting.AppURL
- f.LogRootPath = setting.LogRootPath
-
- // E-mail service settings
- if setting.MailService != nil {
- f.SMTPHost = setting.MailService.Host
- f.SMTPFrom = setting.MailService.From
- f.SMTPUser = setting.MailService.User
- }
- f.RegisterConfirm = setting.Service.RegisterEmailConfirm
- f.MailNotify = setting.Service.EnableNotifyMail
-
- // Server and other services settings
- f.OfflineMode = setting.OfflineMode
- f.DisableGravatar = setting.DisableGravatar
- f.EnableFederatedAvatar = setting.EnableFederatedAvatar
- f.DisableRegistration = setting.Service.DisableRegistration
- f.EnableCaptcha = setting.Service.EnableCaptcha
- f.RequireSignInView = setting.Service.RequireSignInView
-
- form.Assign(f, c.Data)
- c.Success(INSTALL)
-}
-
-func InstallPost(c *context.Context, f form.Install) {
- c.Data["CurDbOption"] = f.DbType
-
- if c.HasError() {
- if c.HasValue("Err_SMTPEmail") {
- c.FormErr("SMTP")
- }
- if c.HasValue("Err_AdminName") ||
- c.HasValue("Err_AdminPasswd") ||
- c.HasValue("Err_AdminEmail") {
- c.FormErr("Admin")
- }
-
- c.Success(INSTALL)
- return
- }
-
- if _, err := exec.LookPath("git"); err != nil {
- c.RenderWithErr(c.Tr("install.test_git_failed", err), INSTALL, &f)
- return
- }
-
- // Pass basic check, now test configuration.
- // Test database setting.
- dbTypes := map[string]string{"MySQL": "mysql", "PostgreSQL": "postgres", "MSSQL": "mssql", "SQLite3": "sqlite3", "TiDB": "tidb"}
- models.DbCfg.Type = dbTypes[f.DbType]
- models.DbCfg.Host = f.DbHost
- models.DbCfg.User = f.DbUser
- models.DbCfg.Passwd = f.DbPasswd
- models.DbCfg.Name = f.DbName
- models.DbCfg.SSLMode = f.SSLMode
- models.DbCfg.Path = f.DbPath
-
- if models.DbCfg.Type == "sqlite3" && len(models.DbCfg.Path) == 0 {
- c.FormErr("DbPath")
- c.RenderWithErr(c.Tr("install.err_empty_db_path"), INSTALL, &f)
- return
- }
-
- // Set test engine.
- var x *xorm.Engine
- if err := models.NewTestEngine(x); err != nil {
- if strings.Contains(err.Error(), `Unknown database type: sqlite3`) {
- c.FormErr("DbType")
- c.RenderWithErr(c.Tr("install.sqlite3_not_available", "https://gogs.io/docs/installation/install_from_binary.html"), INSTALL, &f)
- } else {
- c.FormErr("DbSetting")
- c.RenderWithErr(c.Tr("install.invalid_db_setting", err), INSTALL, &f)
- }
- return
- }
-
- // Test repository root path.
- f.RepoRootPath = strings.Replace(f.RepoRootPath, "\\", "/", -1)
- if err := os.MkdirAll(f.RepoRootPath, os.ModePerm); err != nil {
- c.FormErr("RepoRootPath")
- c.RenderWithErr(c.Tr("install.invalid_repo_path", err), INSTALL, &f)
- return
- }
-
- // Test log root path.
- f.LogRootPath = strings.Replace(f.LogRootPath, "\\", "/", -1)
- if err := os.MkdirAll(f.LogRootPath, os.ModePerm); err != nil {
- c.FormErr("LogRootPath")
- c.RenderWithErr(c.Tr("install.invalid_log_root_path", err), INSTALL, &f)
- return
- }
-
- currentUser, match := setting.IsRunUserMatchCurrentUser(f.RunUser)
- if !match {
- c.FormErr("RunUser")
- c.RenderWithErr(c.Tr("install.run_user_not_match", f.RunUser, currentUser), INSTALL, &f)
- return
- }
-
- // Check host address and port
- if len(f.SMTPHost) > 0 && !strings.Contains(f.SMTPHost, ":") {
- c.FormErr("SMTP", "SMTPHost")
- c.RenderWithErr(c.Tr("install.smtp_host_missing_port"), INSTALL, &f)
- return
- }
-
- // Make sure FROM field is valid
- if len(f.SMTPFrom) > 0 {
- _, err := mail.ParseAddress(f.SMTPFrom)
- if err != nil {
- c.FormErr("SMTP", "SMTPFrom")
- c.RenderWithErr(c.Tr("install.invalid_smtp_from", err), INSTALL, &f)
- return
- }
- }
-
- // Check logic loophole between disable self-registration and no admin account.
- if f.DisableRegistration && len(f.AdminName) == 0 {
- c.FormErr("Services", "Admin")
- c.RenderWithErr(c.Tr("install.no_admin_and_disable_registration"), INSTALL, f)
- return
- }
-
- // Check admin password.
- if len(f.AdminName) > 0 && len(f.AdminPasswd) == 0 {
- c.FormErr("Admin", "AdminPasswd")
- c.RenderWithErr(c.Tr("install.err_empty_admin_password"), INSTALL, f)
- return
- }
- if f.AdminPasswd != f.AdminConfirmPasswd {
- c.FormErr("Admin", "AdminPasswd")
- c.RenderWithErr(c.Tr("form.password_not_match"), INSTALL, f)
- return
- }
-
- if f.AppUrl[len(f.AppUrl)-1] != '/' {
- f.AppUrl += "/"
- }
-
- // Save settings.
- cfg := ini.Empty()
- if com.IsFile(setting.CustomConf) {
- // Keeps custom settings if there is already something.
- if err := cfg.Append(setting.CustomConf); err != nil {
- log.Error(2, "Fail to load custom conf '%s': %v", setting.CustomConf, err)
- }
- }
- cfg.Section("database").Key("DB_TYPE").SetValue(models.DbCfg.Type)
- cfg.Section("database").Key("HOST").SetValue(models.DbCfg.Host)
- cfg.Section("database").Key("NAME").SetValue(models.DbCfg.Name)
- cfg.Section("database").Key("USER").SetValue(models.DbCfg.User)
- cfg.Section("database").Key("PASSWD").SetValue(models.DbCfg.Passwd)
- cfg.Section("database").Key("SSL_MODE").SetValue(models.DbCfg.SSLMode)
- cfg.Section("database").Key("PATH").SetValue(models.DbCfg.Path)
-
- cfg.Section("").Key("APP_NAME").SetValue(f.AppName)
- cfg.Section("repository").Key("ROOT").SetValue(f.RepoRootPath)
- cfg.Section("").Key("RUN_USER").SetValue(f.RunUser)
- cfg.Section("server").Key("DOMAIN").SetValue(f.Domain)
- cfg.Section("server").Key("HTTP_PORT").SetValue(f.HTTPPort)
- cfg.Section("server").Key("ROOT_URL").SetValue(f.AppUrl)
-
- if f.SSHPort == 0 {
- cfg.Section("server").Key("DISABLE_SSH").SetValue("true")
- } else {
- cfg.Section("server").Key("DISABLE_SSH").SetValue("false")
- cfg.Section("server").Key("SSH_PORT").SetValue(com.ToStr(f.SSHPort))
- cfg.Section("server").Key("START_SSH_SERVER").SetValue(com.ToStr(f.UseBuiltinSSHServer))
- }
-
- if len(strings.TrimSpace(f.SMTPHost)) > 0 {
- cfg.Section("mailer").Key("ENABLED").SetValue("true")
- cfg.Section("mailer").Key("HOST").SetValue(f.SMTPHost)
- cfg.Section("mailer").Key("FROM").SetValue(f.SMTPFrom)
- cfg.Section("mailer").Key("USER").SetValue(f.SMTPUser)
- cfg.Section("mailer").Key("PASSWD").SetValue(f.SMTPPasswd)
- } else {
- cfg.Section("mailer").Key("ENABLED").SetValue("false")
- }
- cfg.Section("service").Key("REGISTER_EMAIL_CONFIRM").SetValue(com.ToStr(f.RegisterConfirm))
- cfg.Section("service").Key("ENABLE_NOTIFY_MAIL").SetValue(com.ToStr(f.MailNotify))
-
- cfg.Section("server").Key("OFFLINE_MODE").SetValue(com.ToStr(f.OfflineMode))
- cfg.Section("picture").Key("DISABLE_GRAVATAR").SetValue(com.ToStr(f.DisableGravatar))
- cfg.Section("picture").Key("ENABLE_FEDERATED_AVATAR").SetValue(com.ToStr(f.EnableFederatedAvatar))
- cfg.Section("service").Key("DISABLE_REGISTRATION").SetValue(com.ToStr(f.DisableRegistration))
- cfg.Section("service").Key("ENABLE_CAPTCHA").SetValue(com.ToStr(f.EnableCaptcha))
- cfg.Section("service").Key("REQUIRE_SIGNIN_VIEW").SetValue(com.ToStr(f.RequireSignInView))
-
- cfg.Section("").Key("RUN_MODE").SetValue("prod")
-
- cfg.Section("session").Key("PROVIDER").SetValue("file")
-
- mode := "file"
- if f.EnableConsoleMode {
- mode = "console, file"
- }
- cfg.Section("log").Key("MODE").SetValue(mode)
- cfg.Section("log").Key("LEVEL").SetValue("Info")
- cfg.Section("log").Key("ROOT_PATH").SetValue(f.LogRootPath)
-
- cfg.Section("security").Key("INSTALL_LOCK").SetValue("true")
- secretKey, err := tool.RandomString(15)
- if err != nil {
- c.RenderWithErr(c.Tr("install.secret_key_failed", err), INSTALL, &f)
- return
- }
- cfg.Section("security").Key("SECRET_KEY").SetValue(secretKey)
-
- os.MkdirAll(filepath.Dir(setting.CustomConf), os.ModePerm)
- if err := cfg.SaveTo(setting.CustomConf); err != nil {
- c.RenderWithErr(c.Tr("install.save_config_failed", err), INSTALL, &f)
- return
- }
-
- GlobalInit()
-
- // Create admin account
- if len(f.AdminName) > 0 {
- u := &models.User{
- Name: f.AdminName,
- Email: f.AdminEmail,
- Passwd: f.AdminPasswd,
- IsAdmin: true,
- IsActive: true,
- }
- if err := models.CreateUser(u); err != nil {
- if !models.IsErrUserAlreadyExist(err) {
- setting.InstallLock = false
- c.FormErr("AdminName", "AdminEmail")
- c.RenderWithErr(c.Tr("install.invalid_admin_setting", err), INSTALL, &f)
- return
- }
- log.Info("Admin account already exist")
- u, _ = models.GetUserByName(u.Name)
- }
-
- // Auto-login for admin
- c.Session.Set("uid", u.ID)
- c.Session.Set("uname", u.Name)
- }
-
- log.Info("First-time run install finished!")
- c.Flash.Success(c.Tr("install.install_success"))
- c.Redirect(f.AppUrl + "user/login")
-}
diff --git a/routers/org/members.go b/routers/org/members.go
deleted file mode 100644
index b529748c..00000000
--- a/routers/org/members.go
+++ /dev/null
@@ -1,123 +0,0 @@
-// 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 org
-
-import (
- "github.com/Unknwon/com"
- log "gopkg.in/clog.v1"
-
- "github.com/gogits/gogs/models"
- "github.com/gogits/gogs/models/errors"
- "github.com/gogits/gogs/pkg/context"
- "github.com/gogits/gogs/pkg/setting"
-)
-
-const (
- MEMBERS = "org/member/members"
- MEMBER_INVITE = "org/member/invite"
-)
-
-func Members(c *context.Context) {
- org := c.Org.Organization
- c.Data["Title"] = org.FullName
- c.Data["PageIsOrgMembers"] = true
-
- if err := org.GetMembers(); err != nil {
- c.Handle(500, "GetMembers", err)
- return
- }
- c.Data["Members"] = org.Members
-
- c.HTML(200, MEMBERS)
-}
-
-func MembersAction(c *context.Context) {
- uid := com.StrTo(c.Query("uid")).MustInt64()
- if uid == 0 {
- c.Redirect(c.Org.OrgLink + "/members")
- return
- }
-
- org := c.Org.Organization
- var err error
- switch c.Params(":action") {
- case "private":
- if c.User.ID != uid && !c.Org.IsOwner {
- c.Error(404)
- return
- }
- err = models.ChangeOrgUserStatus(org.ID, uid, false)
- case "public":
- if c.User.ID != uid && !c.Org.IsOwner {
- c.Error(404)
- return
- }
- err = models.ChangeOrgUserStatus(org.ID, uid, true)
- case "remove":
- if !c.Org.IsOwner {
- c.Error(404)
- return
- }
- err = org.RemoveMember(uid)
- if models.IsErrLastOrgOwner(err) {
- c.Flash.Error(c.Tr("form.last_org_owner"))
- c.Redirect(c.Org.OrgLink + "/members")
- return
- }
- case "leave":
- err = org.RemoveMember(c.User.ID)
- if models.IsErrLastOrgOwner(err) {
- c.Flash.Error(c.Tr("form.last_org_owner"))
- c.Redirect(c.Org.OrgLink + "/members")
- return
- }
- }
-
- if err != nil {
- log.Error(4, "Action(%s): %v", c.Params(":action"), err)
- c.JSON(200, map[string]interface{}{
- "ok": false,
- "err": err.Error(),
- })
- return
- }
-
- if c.Params(":action") != "leave" {
- c.Redirect(c.Org.OrgLink + "/members")
- } else {
- c.Redirect(setting.AppSubURL + "/")
- }
-}
-
-func Invitation(c *context.Context) {
- org := c.Org.Organization
- c.Data["Title"] = org.FullName
- c.Data["PageIsOrgMembers"] = true
-
- if c.Req.Method == "POST" {
- uname := c.Query("uname")
- u, err := models.GetUserByName(uname)
- if err != nil {
- if errors.IsUserNotExist(err) {
- c.Flash.Error(c.Tr("form.user_not_exist"))
- c.Redirect(c.Org.OrgLink + "/invitations/new")
- } else {
- c.Handle(500, " GetUserByName", err)
- }
- return
- }
-
- if err = org.AddMember(u.ID); err != nil {
- c.Handle(500, " AddMember", err)
- return
- }
-
- log.Trace("New member added(%s): %s", org.Name, u.Name)
- c.Redirect(c.Org.OrgLink + "/members")
- return
- }
-
- c.HTML(200, MEMBER_INVITE)
-}
diff --git a/routers/org/org.go b/routers/org/org.go
deleted file mode 100644
index 775e9915..00000000
--- a/routers/org/org.go
+++ /dev/null
@@ -1,56 +0,0 @@
-// 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 org
-
-import (
- log "gopkg.in/clog.v1"
-
- "github.com/gogits/gogs/models"
- "github.com/gogits/gogs/pkg/context"
- "github.com/gogits/gogs/pkg/form"
- "github.com/gogits/gogs/pkg/setting"
-)
-
-const (
- CREATE = "org/create"
-)
-
-func Create(c *context.Context) {
- c.Data["Title"] = c.Tr("new_org")
- c.HTML(200, CREATE)
-}
-
-func CreatePost(c *context.Context, f form.CreateOrg) {
- c.Data["Title"] = c.Tr("new_org")
-
- if c.HasError() {
- c.HTML(200, CREATE)
- return
- }
-
- org := &models.User{
- Name: f.OrgName,
- IsActive: true,
- Type: models.USER_TYPE_ORGANIZATION,
- }
-
- if err := models.CreateOrganization(org, c.User); err != nil {
- c.Data["Err_OrgName"] = true
- switch {
- case models.IsErrUserAlreadyExist(err):
- c.RenderWithErr(c.Tr("form.org_name_been_taken"), CREATE, &f)
- case models.IsErrNameReserved(err):
- c.RenderWithErr(c.Tr("org.form.name_reserved", err.(models.ErrNameReserved).Name), CREATE, &f)
- case models.IsErrNamePatternNotAllowed(err):
- c.RenderWithErr(c.Tr("org.form.name_pattern_not_allowed", err.(models.ErrNamePatternNotAllowed).Pattern), CREATE, &f)
- default:
- c.Handle(500, "CreateOrganization", err)
- }
- return
- }
- log.Trace("Organization created: %s", org.Name)
-
- c.Redirect(setting.AppSubURL + "/org/" + f.OrgName + "/dashboard")
-}
diff --git a/routers/org/setting.go b/routers/org/setting.go
deleted file mode 100644
index 8e2e556f..00000000
--- a/routers/org/setting.go
+++ /dev/null
@@ -1,168 +0,0 @@
-// 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 org
-
-import (
- "strings"
-
- log "gopkg.in/clog.v1"
-
- "github.com/gogits/gogs/models"
- "github.com/gogits/gogs/models/errors"
- "github.com/gogits/gogs/pkg/context"
- "github.com/gogits/gogs/pkg/form"
- "github.com/gogits/gogs/pkg/setting"
- "github.com/gogits/gogs/routers/user"
-)
-
-const (
- SETTINGS_OPTIONS = "org/settings/options"
- SETTINGS_DELETE = "org/settings/delete"
- SETTINGS_WEBHOOKS = "org/settings/webhooks"
-)
-
-func Settings(c *context.Context) {
- c.Data["Title"] = c.Tr("org.settings")
- c.Data["PageIsSettingsOptions"] = true
- c.HTML(200, SETTINGS_OPTIONS)
-}
-
-func SettingsPost(c *context.Context, f form.UpdateOrgSetting) {
- c.Data["Title"] = c.Tr("org.settings")
- c.Data["PageIsSettingsOptions"] = true
-
- if c.HasError() {
- c.HTML(200, SETTINGS_OPTIONS)
- return
- }
-
- org := c.Org.Organization
-
- // Check if organization name has been changed.
- if org.LowerName != strings.ToLower(f.Name) {
- isExist, err := models.IsUserExist(org.ID, f.Name)
- if err != nil {
- c.Handle(500, "IsUserExist", err)
- return
- } else if isExist {
- c.Data["OrgName"] = true
- c.RenderWithErr(c.Tr("form.username_been_taken"), SETTINGS_OPTIONS, &f)
- return
- } else if err = models.ChangeUserName(org, f.Name); err != nil {
- c.Data["OrgName"] = true
- switch {
- case models.IsErrNameReserved(err):
- c.RenderWithErr(c.Tr("user.form.name_reserved"), SETTINGS_OPTIONS, &f)
- case models.IsErrNamePatternNotAllowed(err):
- c.RenderWithErr(c.Tr("user.form.name_pattern_not_allowed"), SETTINGS_OPTIONS, &f)
- default:
- c.Handle(500, "ChangeUserName", err)
- }
- return
- }
- // reset c.org.OrgLink with new name
- c.Org.OrgLink = setting.AppSubURL + "/org/" + f.Name
- log.Trace("Organization name changed: %s -> %s", org.Name, f.Name)
- }
- // In case it's just a case change.
- org.Name = f.Name
- org.LowerName = strings.ToLower(f.Name)
-
- if c.User.IsAdmin {
- org.MaxRepoCreation = f.MaxRepoCreation
- }
-
- org.FullName = f.FullName
- org.Description = f.Description
- org.Website = f.Website
- org.Location = f.Location
- if err := models.UpdateUser(org); err != nil {
- c.Handle(500, "UpdateUser", err)
- return
- }
- log.Trace("Organization setting updated: %s", org.Name)
- c.Flash.Success(c.Tr("org.settings.update_setting_success"))
- c.Redirect(c.Org.OrgLink + "/settings")
-}
-
-func SettingsAvatar(c *context.Context, f form.Avatar) {
- f.Source = form.AVATAR_LOCAL
- if err := user.UpdateAvatarSetting(c, f, c.Org.Organization); err != nil {
- c.Flash.Error(err.Error())
- } else {
- c.Flash.Success(c.Tr("org.settings.update_avatar_success"))
- }
-
- c.Redirect(c.Org.OrgLink + "/settings")
-}
-
-func SettingsDeleteAvatar(c *context.Context) {
- if err := c.Org.Organization.DeleteAvatar(); err != nil {
- c.Flash.Error(err.Error())
- }
-
- c.Redirect(c.Org.OrgLink + "/settings")
-}
-
-func SettingsDelete(c *context.Context) {
- c.Data["Title"] = c.Tr("org.settings")
- c.Data["PageIsSettingsDelete"] = true
-
- org := c.Org.Organization
- if c.Req.Method == "POST" {
- if _, err := models.UserSignIn(c.User.Name, c.Query("password")); err != nil {
- if errors.IsUserNotExist(err) {
- c.RenderWithErr(c.Tr("form.enterred_invalid_password"), SETTINGS_DELETE, nil)
- } else {
- c.Handle(500, "UserSignIn", err)
- }
- return
- }
-
- if err := models.DeleteOrganization(org); err != nil {
- if models.IsErrUserOwnRepos(err) {
- c.Flash.Error(c.Tr("form.org_still_own_repo"))
- c.Redirect(c.Org.OrgLink + "/settings/delete")
- } else {
- c.Handle(500, "DeleteOrganization", err)
- }
- } else {
- log.Trace("Organization deleted: %s", org.Name)
- c.Redirect(setting.AppSubURL + "/")
- }
- return
- }
-
- c.HTML(200, SETTINGS_DELETE)
-}
-
-func Webhooks(c *context.Context) {
- c.Data["Title"] = c.Tr("org.settings")
- c.Data["PageIsSettingsHooks"] = true
- c.Data["BaseLink"] = c.Org.OrgLink
- c.Data["Description"] = c.Tr("org.settings.hooks_desc")
- c.Data["Types"] = setting.Webhook.Types
-
- ws, err := models.GetWebhooksByOrgID(c.Org.Organization.ID)
- if err != nil {
- c.Handle(500, "GetWebhooksByOrgId", err)
- return
- }
-
- c.Data["Webhooks"] = ws
- c.HTML(200, SETTINGS_WEBHOOKS)
-}
-
-func DeleteWebhook(c *context.Context) {
- if err := models.DeleteWebhookOfOrgByID(c.Org.Organization.ID, c.QueryInt64("id")); err != nil {
- c.Flash.Error("DeleteWebhookByOrgID: " + err.Error())
- } else {
- c.Flash.Success(c.Tr("repo.settings.webhook_deletion_success"))
- }
-
- c.JSON(200, map[string]interface{}{
- "redirect": c.Org.OrgLink + "/settings/hooks",
- })
-}
diff --git a/routers/org/teams.go b/routers/org/teams.go
deleted file mode 100644
index c97d470d..00000000
--- a/routers/org/teams.go
+++ /dev/null
@@ -1,271 +0,0 @@
-// 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 org
-
-import (
- "path"
-
- "github.com/Unknwon/com"
- log "gopkg.in/clog.v1"
-
- "github.com/gogits/gogs/models"
- "github.com/gogits/gogs/models/errors"
- "github.com/gogits/gogs/pkg/context"
- "github.com/gogits/gogs/pkg/form"
-)
-
-const (
- TEAMS = "org/team/teams"
- TEAM_NEW = "org/team/new"
- TEAM_MEMBERS = "org/team/members"
- TEAM_REPOSITORIES = "org/team/repositories"
-)
-
-func Teams(c *context.Context) {
- org := c.Org.Organization
- c.Data["Title"] = org.FullName
- c.Data["PageIsOrgTeams"] = true
-
- for _, t := range org.Teams {
- if err := t.GetMembers(); err != nil {
- c.Handle(500, "GetMembers", err)
- return
- }
- }
- c.Data["Teams"] = org.Teams
-
- c.HTML(200, TEAMS)
-}
-
-func TeamsAction(c *context.Context) {
- uid := com.StrTo(c.Query("uid")).MustInt64()
- if uid == 0 {
- c.Redirect(c.Org.OrgLink + "/teams")
- return
- }
-
- page := c.Query("page")
- var err error
- switch c.Params(":action") {
- case "join":
- if !c.Org.IsOwner {
- c.Error(404)
- return
- }
- err = c.Org.Team.AddMember(c.User.ID)
- case "leave":
- err = c.Org.Team.RemoveMember(c.User.ID)
- case "remove":
- if !c.Org.IsOwner {
- c.Error(404)
- return
- }
- err = c.Org.Team.RemoveMember(uid)
- page = "team"
- case "add":
- if !c.Org.IsOwner {
- c.Error(404)
- return
- }
- uname := c.Query("uname")
- var u *models.User
- u, err = models.GetUserByName(uname)
- if err != nil {
- if errors.IsUserNotExist(err) {
- c.Flash.Error(c.Tr("form.user_not_exist"))
- c.Redirect(c.Org.OrgLink + "/teams/" + c.Org.Team.LowerName)
- } else {
- c.Handle(500, " GetUserByName", err)
- }
- return
- }
-
- err = c.Org.Team.AddMember(u.ID)
- page = "team"
- }
-
- if err != nil {
- if models.IsErrLastOrgOwner(err) {
- c.Flash.Error(c.Tr("form.last_org_owner"))
- } else {
- log.Error(3, "Action(%s): %v", c.Params(":action"), err)
- c.JSON(200, map[string]interface{}{
- "ok": false,
- "err": err.Error(),
- })
- return
- }
- }
-
- switch page {
- case "team":
- c.Redirect(c.Org.OrgLink + "/teams/" + c.Org.Team.LowerName)
- default:
- c.Redirect(c.Org.OrgLink + "/teams")
- }
-}
-
-func TeamsRepoAction(c *context.Context) {
- if !c.Org.IsOwner {
- c.Error(404)
- return
- }
-
- var err error
- switch c.Params(":action") {
- case "add":
- repoName := path.Base(c.Query("repo_name"))
- var repo *models.Repository
- repo, err = models.GetRepositoryByName(c.Org.Organization.ID, repoName)
- if err != nil {
- if errors.IsRepoNotExist(err) {
- c.Flash.Error(c.Tr("org.teams.add_nonexistent_repo"))
- c.Redirect(c.Org.OrgLink + "/teams/" + c.Org.Team.LowerName + "/repositories")
- return
- }
- c.Handle(500, "GetRepositoryByName", err)
- return
- }
- err = c.Org.Team.AddRepository(repo)
- case "remove":
- err = c.Org.Team.RemoveRepository(com.StrTo(c.Query("repoid")).MustInt64())
- }
-
- if err != nil {
- log.Error(3, "Action(%s): '%s' %v", c.Params(":action"), c.Org.Team.Name, err)
- c.Handle(500, "TeamsRepoAction", err)
- return
- }
- c.Redirect(c.Org.OrgLink + "/teams/" + c.Org.Team.LowerName + "/repositories")
-}
-
-func NewTeam(c *context.Context) {
- c.Data["Title"] = c.Org.Organization.FullName
- c.Data["PageIsOrgTeams"] = true
- c.Data["PageIsOrgTeamsNew"] = true
- c.Data["Team"] = &models.Team{}
- c.HTML(200, TEAM_NEW)
-}
-
-func NewTeamPost(c *context.Context, f form.CreateTeam) {
- c.Data["Title"] = c.Org.Organization.FullName
- c.Data["PageIsOrgTeams"] = true
- c.Data["PageIsOrgTeamsNew"] = true
-
- t := &models.Team{
- OrgID: c.Org.Organization.ID,
- Name: f.TeamName,
- Description: f.Description,
- Authorize: models.ParseAccessMode(f.Permission),
- }
- c.Data["Team"] = t
-
- if c.HasError() {
- c.HTML(200, TEAM_NEW)
- return
- }
-
- if err := models.NewTeam(t); err != nil {
- c.Data["Err_TeamName"] = true
- switch {
- case models.IsErrTeamAlreadyExist(err):
- c.RenderWithErr(c.Tr("form.team_name_been_taken"), TEAM_NEW, &f)
- case models.IsErrNameReserved(err):
- c.RenderWithErr(c.Tr("org.form.team_name_reserved", err.(models.ErrNameReserved).Name), TEAM_NEW, &f)
- default:
- c.Handle(500, "NewTeam", err)
- }
- return
- }
- log.Trace("Team created: %s/%s", c.Org.Organization.Name, t.Name)
- c.Redirect(c.Org.OrgLink + "/teams/" + t.LowerName)
-}
-
-func TeamMembers(c *context.Context) {
- c.Data["Title"] = c.Org.Team.Name
- c.Data["PageIsOrgTeams"] = true
- if err := c.Org.Team.GetMembers(); err != nil {
- c.Handle(500, "GetMembers", err)
- return
- }
- c.HTML(200, TEAM_MEMBERS)
-}
-
-func TeamRepositories(c *context.Context) {
- c.Data["Title"] = c.Org.Team.Name
- c.Data["PageIsOrgTeams"] = true
- if err := c.Org.Team.GetRepositories(); err != nil {
- c.Handle(500, "GetRepositories", err)
- return
- }
- c.HTML(200, TEAM_REPOSITORIES)
-}
-
-func EditTeam(c *context.Context) {
- c.Data["Title"] = c.Org.Organization.FullName
- c.Data["PageIsOrgTeams"] = true
- c.Data["team_name"] = c.Org.Team.Name
- c.Data["desc"] = c.Org.Team.Description
- c.HTML(200, TEAM_NEW)
-}
-
-func EditTeamPost(c *context.Context, f form.CreateTeam) {
- t := c.Org.Team
- c.Data["Title"] = c.Org.Organization.FullName
- c.Data["PageIsOrgTeams"] = true
- c.Data["Team"] = t
-
- if c.HasError() {
- c.HTML(200, TEAM_NEW)
- return
- }
-
- isAuthChanged := false
- if !t.IsOwnerTeam() {
- // Validate permission level.
- var auth models.AccessMode
- switch f.Permission {
- case "read":
- auth = models.ACCESS_MODE_READ
- case "write":
- auth = models.ACCESS_MODE_WRITE
- case "admin":
- auth = models.ACCESS_MODE_ADMIN
- default:
- c.Error(401)
- return
- }
-
- t.Name = f.TeamName
- if t.Authorize != auth {
- isAuthChanged = true
- t.Authorize = auth
- }
- }
- t.Description = f.Description
- if err := models.UpdateTeam(t, isAuthChanged); err != nil {
- c.Data["Err_TeamName"] = true
- switch {
- case models.IsErrTeamAlreadyExist(err):
- c.RenderWithErr(c.Tr("form.team_name_been_taken"), TEAM_NEW, &f)
- default:
- c.Handle(500, "UpdateTeam", err)
- }
- return
- }
- c.Redirect(c.Org.OrgLink + "/teams/" + t.LowerName)
-}
-
-func DeleteTeam(c *context.Context) {
- if err := models.DeleteTeam(c.Org.Team); err != nil {
- c.Flash.Error("DeleteTeam: " + err.Error())
- } else {
- c.Flash.Success(c.Tr("org.teams.delete_team_success"))
- }
-
- c.JSON(200, map[string]interface{}{
- "redirect": c.Org.OrgLink + "/teams",
- })
-}
diff --git a/routers/repo/branch.go b/routers/repo/branch.go
deleted file mode 100644
index 685df2e7..00000000
--- a/routers/repo/branch.go
+++ /dev/null
@@ -1,142 +0,0 @@
-// 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 repo
-
-import (
- "time"
-
- log "gopkg.in/clog.v1"
-
- "github.com/gogits/git-module"
-
- "github.com/gogits/gogs/models"
- "github.com/gogits/gogs/pkg/context"
-)
-
-const (
- BRANCHES_OVERVIEW = "repo/branches/overview"
- BRANCHES_ALL = "repo/branches/all"
-)
-
-type Branch struct {
- Name string
- Commit *git.Commit
- IsProtected bool
-}
-
-func loadBranches(c *context.Context) []*Branch {
- rawBranches, err := c.Repo.Repository.GetBranches()
- if err != nil {
- c.Handle(500, "GetBranches", err)
- return nil
- }
-
- protectBranches, err := models.GetProtectBranchesByRepoID(c.Repo.Repository.ID)
- if err != nil {
- c.Handle(500, "GetProtectBranchesByRepoID", err)
- return nil
- }
-
- branches := make([]*Branch, len(rawBranches))
- for i := range rawBranches {
- commit, err := rawBranches[i].GetCommit()
- if err != nil {
- c.Handle(500, "GetCommit", err)
- return nil
- }
-
- branches[i] = &Branch{
- Name: rawBranches[i].Name,
- Commit: commit,
- }
-
- for j := range protectBranches {
- if branches[i].Name == protectBranches[j].Name {
- branches[i].IsProtected = true
- break
- }
- }
- }
-
- c.Data["AllowPullRequest"] = c.Repo.Repository.AllowsPulls()
- return branches
-}
-
-func Branches(c *context.Context) {
- c.Data["Title"] = c.Tr("repo.git_branches")
- c.Data["PageIsBranchesOverview"] = true
-
- branches := loadBranches(c)
- if c.Written() {
- return
- }
-
- now := time.Now()
- activeBranches := make([]*Branch, 0, 3)
- staleBranches := make([]*Branch, 0, 3)
- for i := range branches {
- switch {
- case branches[i].Name == c.Repo.BranchName:
- c.Data["DefaultBranch"] = branches[i]
- case branches[i].Commit.Committer.When.Add(30 * 24 * time.Hour).After(now): // 30 days
- activeBranches = append(activeBranches, branches[i])
- case branches[i].Commit.Committer.When.Add(3 * 30 * 24 * time.Hour).Before(now): // 90 days
- staleBranches = append(staleBranches, branches[i])
- }
- }
-
- c.Data["ActiveBranches"] = activeBranches
- c.Data["StaleBranches"] = staleBranches
- c.HTML(200, BRANCHES_OVERVIEW)
-}
-
-func AllBranches(c *context.Context) {
- c.Data["Title"] = c.Tr("repo.git_branches")
- c.Data["PageIsBranchesAll"] = true
-
- branches := loadBranches(c)
- if c.Written() {
- return
- }
- c.Data["Branches"] = branches
-
- c.HTML(200, BRANCHES_ALL)
-}
-
-func DeleteBranchPost(c *context.Context) {
- branchName := c.Params("*")
- commitID := c.Query("commit")
-
- defer func() {
- redirectTo := c.Query("redirect_to")
- if len(redirectTo) == 0 {
- redirectTo = c.Repo.RepoLink
- }
- c.Redirect(redirectTo)
- }()
-
- if !c.Repo.GitRepo.IsBranchExist(branchName) {
- return
- }
- if len(commitID) > 0 {
- branchCommitID, err := c.Repo.GitRepo.GetBranchCommitID(branchName)
- if err != nil {
- log.Error(2, "GetBranchCommitID: %v", err)
- return
- }
-
- if branchCommitID != commitID {
- c.Flash.Error(c.Tr("repo.pulls.delete_branch_has_new_commits"))
- return
- }
- }
-
- if err := c.Repo.GitRepo.DeleteBranch(branchName, git.DeleteBranchOptions{
- Force: true,
- }); err != nil {
- log.Error(2, "DeleteBranch '%s': %v", branchName, err)
- return
- }
-}
diff --git a/routers/repo/commit.go b/routers/repo/commit.go
deleted file mode 100644
index 17ea5dbe..00000000
--- a/routers/repo/commit.go
+++ /dev/null
@@ -1,239 +0,0 @@
-// 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 repo
-
-import (
- "container/list"
- "path"
-
- "github.com/gogits/git-module"
-
- "github.com/gogits/gogs/models"
- "github.com/gogits/gogs/pkg/context"
- "github.com/gogits/gogs/pkg/setting"
- "github.com/gogits/gogs/pkg/tool"
-)
-
-const (
- COMMITS = "repo/commits"
- DIFF = "repo/diff/page"
-)
-
-func RefCommits(c *context.Context) {
- c.Data["PageIsViewFiles"] = true
- switch {
- case len(c.Repo.TreePath) == 0:
- Commits(c)
- case c.Repo.TreePath == "search":
- SearchCommits(c)
- default:
- FileHistory(c)
- }
-}
-
-func RenderIssueLinks(oldCommits *list.List, repoLink string) *list.List {
- newCommits := list.New()
- for e := oldCommits.Front(); e != nil; e = e.Next() {
- c := e.Value.(*git.Commit)
- newCommits.PushBack(c)
- }
- return newCommits
-}
-
-func renderCommits(c *context.Context, filename string) {
- c.Data["Title"] = c.Tr("repo.commits.commit_history") + " · " + c.Repo.Repository.FullName()
- c.Data["PageIsCommits"] = true
-
- page := c.QueryInt("page")
- if page < 1 {
- page = 1
- }
- pageSize := c.QueryInt("pageSize")
- if pageSize < 1 {
- pageSize = git.DefaultCommitsPageSize
- }
-
- // Both 'git log branchName' and 'git log commitID' work.
- var err error
- var commits *list.List
- if len(filename) == 0 {
- commits, err = c.Repo.Commit.CommitsByRangeSize(page, pageSize)
- } else {
- commits, err = c.Repo.GitRepo.CommitsByFileAndRangeSize(c.Repo.BranchName, filename, page, pageSize)
- }
- if err != nil {
- c.Handle(500, "CommitsByRangeSize/CommitsByFileAndRangeSize", err)
- return
- }
- commits = RenderIssueLinks(commits, c.Repo.RepoLink)
- commits = models.ValidateCommitsWithEmails(commits)
- c.Data["Commits"] = commits
-
- if page > 1 {
- c.Data["HasPrevious"] = true
- c.Data["PreviousPage"] = page - 1
- }
- if commits.Len() == pageSize {
- c.Data["HasNext"] = true
- c.Data["NextPage"] = page + 1
- }
- c.Data["PageSize"] = pageSize
-
- c.Data["Username"] = c.Repo.Owner.Name
- c.Data["Reponame"] = c.Repo.Repository.Name
- c.HTML(200, COMMITS)
-}
-
-func Commits(c *context.Context) {
- renderCommits(c, "")
-}
-
-func SearchCommits(c *context.Context) {
- c.Data["PageIsCommits"] = true
-
- keyword := c.Query("q")
- if len(keyword) == 0 {
- c.Redirect(c.Repo.RepoLink + "/commits/" + c.Repo.BranchName)
- return
- }
-
- commits, err := c.Repo.Commit.SearchCommits(keyword)
- if err != nil {
- c.Handle(500, "SearchCommits", err)
- return
- }
- commits = RenderIssueLinks(commits, c.Repo.RepoLink)
- commits = models.ValidateCommitsWithEmails(commits)
- c.Data["Commits"] = commits
-
- c.Data["Keyword"] = keyword
- c.Data["Username"] = c.Repo.Owner.Name
- c.Data["Reponame"] = c.Repo.Repository.Name
- c.Data["Branch"] = c.Repo.BranchName
- c.HTML(200, COMMITS)
-}
-
-func FileHistory(c *context.Context) {
- renderCommits(c, c.Repo.TreePath)
-}
-
-func Diff(c *context.Context) {
- c.Data["PageIsDiff"] = true
- c.Data["RequireHighlightJS"] = true
-
- userName := c.Repo.Owner.Name
- repoName := c.Repo.Repository.Name
- commitID := c.Params(":sha")
-
- commit, err := c.Repo.GitRepo.GetCommit(commitID)
- if err != nil {
- if git.IsErrNotExist(err) {
- c.Handle(404, "Repo.GitRepo.GetCommit", err)
- } else {
- c.Handle(500, "Repo.GitRepo.GetCommit", err)
- }
- return
- }
-
- diff, err := models.GetDiffCommit(models.RepoPath(userName, repoName),
- commitID, setting.Git.MaxGitDiffLines,
- setting.Git.MaxGitDiffLineCharacters, setting.Git.MaxGitDiffFiles)
- if err != nil {
- c.NotFoundOrServerError("GetDiffCommit", git.IsErrNotExist, err)
- return
- }
-
- parents := make([]string, commit.ParentCount())
- for i := 0; i < commit.ParentCount(); i++ {
- sha, err := commit.ParentID(i)
- parents[i] = sha.String()
- if err != nil {
- c.Handle(404, "repo.Diff", err)
- return
- }
- }
-
- setEditorconfigIfExists(c)
- if c.Written() {
- return
- }
-
- c.Data["CommitID"] = commitID
- c.Data["IsSplitStyle"] = c.Query("style") == "split"
- c.Data["Username"] = userName
- c.Data["Reponame"] = repoName
- c.Data["IsImageFile"] = commit.IsImageFile
- c.Data["Title"] = commit.Summary() + " · " + tool.ShortSHA1(commitID)
- c.Data["Commit"] = commit
- c.Data["Author"] = models.ValidateCommitWithEmail(commit)
- c.Data["Diff"] = diff
- c.Data["Parents"] = parents
- c.Data["DiffNotAvailable"] = diff.NumFiles() == 0
- c.Data["SourcePath"] = setting.AppSubURL + "/" + path.Join(userName, repoName, "src", commitID)
- if commit.ParentCount() > 0 {
- c.Data["BeforeSourcePath"] = setting.AppSubURL + "/" + path.Join(userName, repoName, "src", parents[0])
- }
- c.Data["RawPath"] = setting.AppSubURL + "/" + path.Join(userName, repoName, "raw", commitID)
- c.HTML(200, DIFF)
-}
-
-func RawDiff(c *context.Context) {
- if err := git.GetRawDiff(
- models.RepoPath(c.Repo.Owner.Name, c.Repo.Repository.Name),
- c.Params(":sha"),
- git.RawDiffType(c.Params(":ext")),
- c.Resp,
- ); err != nil {
- c.NotFoundOrServerError("GetRawDiff", git.IsErrNotExist, err)
- return
- }
-}
-
-func CompareDiff(c *context.Context) {
- c.Data["IsDiffCompare"] = true
- userName := c.Repo.Owner.Name
- repoName := c.Repo.Repository.Name
- beforeCommitID := c.Params(":before")
- afterCommitID := c.Params(":after")
-
- commit, err := c.Repo.GitRepo.GetCommit(afterCommitID)
- if err != nil {
- c.Handle(404, "GetCommit", err)
- return
- }
-
- diff, err := models.GetDiffRange(models.RepoPath(userName, repoName), beforeCommitID,
- afterCommitID, setting.Git.MaxGitDiffLines,
- setting.Git.MaxGitDiffLineCharacters, setting.Git.MaxGitDiffFiles)
- if err != nil {
- c.Handle(404, "GetDiffRange", err)
- return
- }
-
- commits, err := commit.CommitsBeforeUntil(beforeCommitID)
- if err != nil {
- c.Handle(500, "CommitsBeforeUntil", err)
- return
- }
- commits = models.ValidateCommitsWithEmails(commits)
-
- c.Data["IsSplitStyle"] = c.Query("style") == "split"
- c.Data["CommitRepoLink"] = c.Repo.RepoLink
- c.Data["Commits"] = commits
- c.Data["CommitsCount"] = commits.Len()
- c.Data["BeforeCommitID"] = beforeCommitID
- c.Data["AfterCommitID"] = afterCommitID
- c.Data["Username"] = userName
- c.Data["Reponame"] = repoName
- c.Data["IsImageFile"] = commit.IsImageFile
- c.Data["Title"] = "Comparing " + tool.ShortSHA1(beforeCommitID) + "..." + tool.ShortSHA1(afterCommitID) + " · " + userName + "/" + repoName
- c.Data["Commit"] = commit
- c.Data["Diff"] = diff
- c.Data["DiffNotAvailable"] = diff.NumFiles() == 0
- c.Data["SourcePath"] = setting.AppSubURL + "/" + path.Join(userName, repoName, "src", afterCommitID)
- c.Data["BeforeSourcePath"] = setting.AppSubURL + "/" + path.Join(userName, repoName, "src", beforeCommitID)
- c.Data["RawPath"] = setting.AppSubURL + "/" + path.Join(userName, repoName, "raw", afterCommitID)
- c.HTML(200, DIFF)
-}
diff --git a/routers/repo/download.go b/routers/repo/download.go
deleted file mode 100644
index e9a29989..00000000
--- a/routers/repo/download.go
+++ /dev/null
@@ -1,60 +0,0 @@
-// 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 repo
-
-import (
- "io"
- "path"
-
- "github.com/gogits/git-module"
-
- "github.com/gogits/gogs/pkg/tool"
- "github.com/gogits/gogs/pkg/context"
- "github.com/gogits/gogs/pkg/setting"
-)
-
-func ServeData(c *context.Context, name string, reader io.Reader) error {
- buf := make([]byte, 1024)
- n, _ := reader.Read(buf)
- if n >= 0 {
- buf = buf[:n]
- }
-
- if !tool.IsTextFile(buf) {
- if !tool.IsImageFile(buf) {
- c.Resp.Header().Set("Content-Disposition", "attachment; filename=\""+name+"\"")
- c.Resp.Header().Set("Content-Transfer-Encoding", "binary")
- }
- } else if !setting.Repository.EnableRawFileRenderMode || !c.QueryBool("render") {
- c.Resp.Header().Set("Content-Type", "text/plain; charset=utf-8")
- }
- c.Resp.Write(buf)
- _, err := io.Copy(c.Resp, reader)
- return err
-}
-
-func ServeBlob(c *context.Context, blob *git.Blob) error {
- dataRc, err := blob.Data()
- if err != nil {
- return err
- }
-
- return ServeData(c, path.Base(c.Repo.TreePath), dataRc)
-}
-
-func SingleDownload(c *context.Context) {
- blob, err := c.Repo.Commit.GetBlobByPath(c.Repo.TreePath)
- if err != nil {
- if git.IsErrNotExist(err) {
- c.Handle(404, "GetBlobByPath", nil)
- } else {
- c.Handle(500, "GetBlobByPath", err)
- }
- return
- }
- if err = ServeBlob(c, blob); err != nil {
- c.Handle(500, "ServeBlob", err)
- }
-}
diff --git a/routers/repo/editor.go b/routers/repo/editor.go
deleted file mode 100644
index 4cd78d70..00000000
--- a/routers/repo/editor.go
+++ /dev/null
@@ -1,571 +0,0 @@
-// Copyright 2016 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 repo
-
-import (
- "fmt"
- "io/ioutil"
- "net/http"
- "path"
- "strings"
-
- log "gopkg.in/clog.v1"
-
- "github.com/gogits/git-module"
- "github.com/gogits/gogs/models"
- "github.com/gogits/gogs/pkg/context"
- "github.com/gogits/gogs/pkg/form"
- "github.com/gogits/gogs/pkg/setting"
- "github.com/gogits/gogs/pkg/template"
- "github.com/gogits/gogs/pkg/tool"
-)
-
-const (
- EDIT_FILE = "repo/editor/edit"
- EDIT_DIFF_PREVIEW = "repo/editor/diff_preview"
- DELETE_FILE = "repo/editor/delete"
- UPLOAD_FILE = "repo/editor/upload"
-)
-
-// getParentTreeFields returns list of parent tree names and corresponding tree paths
-// based on given tree path.
-func getParentTreeFields(treePath string) (treeNames []string, treePaths []string) {
- if len(treePath) == 0 {
- return treeNames, treePaths
- }
-
- treeNames = strings.Split(treePath, "/")
- treePaths = make([]string, len(treeNames))
- for i := range treeNames {
- treePaths[i] = strings.Join(treeNames[:i+1], "/")
- }
- return treeNames, treePaths
-}
-
-func editFile(c *context.Context, isNewFile bool) {
- c.PageIs("Edit")
- c.RequireHighlightJS()
- c.RequireSimpleMDE()
- c.Data["IsNewFile"] = isNewFile
-
- treeNames, treePaths := getParentTreeFields(c.Repo.TreePath)
-
- if !isNewFile {
- entry, err := c.Repo.Commit.GetTreeEntryByPath(c.Repo.TreePath)
- if err != nil {
- c.NotFoundOrServerError("GetTreeEntryByPath", git.IsErrNotExist, err)
- return
- }
-
- // No way to edit a directory online.
- if entry.IsDir() {
- c.NotFound()
- return
- }
-
- blob := entry.Blob()
- dataRc, err := blob.Data()
- if err != nil {
- c.ServerError("blob.Data", err)
- return
- }
-
- c.Data["FileSize"] = blob.Size()
- c.Data["FileName"] = blob.Name()
-
- buf := make([]byte, 1024)
- n, _ := dataRc.Read(buf)
- buf = buf[:n]
-
- // Only text file are editable online.
- if !tool.IsTextFile(buf) {
- c.NotFound()
- return
- }
-
- d, _ := ioutil.ReadAll(dataRc)
- buf = append(buf, d...)
- if err, content := template.ToUTF8WithErr(buf); err != nil {
- if err != nil {
- log.Error(2, "ToUTF8WithErr: %v", err)
- }
- c.Data["FileContent"] = string(buf)
- } else {
- c.Data["FileContent"] = content
- }
- } else {
- treeNames = append(treeNames, "") // Append empty string to allow user name the new file.
- }
-
- c.Data["ParentTreePath"] = path.Dir(c.Repo.TreePath)
- c.Data["TreeNames"] = treeNames
- c.Data["TreePaths"] = treePaths
- c.Data["BranchLink"] = c.Repo.RepoLink + "/src/" + c.Repo.BranchName
- c.Data["commit_summary"] = ""
- c.Data["commit_message"] = ""
- c.Data["commit_choice"] = "direct"
- c.Data["new_branch_name"] = ""
- c.Data["last_commit"] = c.Repo.Commit.ID
- c.Data["MarkdownFileExts"] = strings.Join(setting.Markdown.FileExtensions, ",")
- c.Data["LineWrapExtensions"] = strings.Join(setting.Repository.Editor.LineWrapExtensions, ",")
- c.Data["PreviewableFileModes"] = strings.Join(setting.Repository.Editor.PreviewableFileModes, ",")
- c.Data["EditorconfigURLPrefix"] = fmt.Sprintf("%s/api/v1/repos/%s/editorconfig/", setting.AppSubURL, c.Repo.Repository.FullName())
-
- c.Success(EDIT_FILE)
-}
-
-func EditFile(c *context.Context) {
- editFile(c, false)
-}
-
-func NewFile(c *context.Context) {
- editFile(c, true)
-}
-
-func editFilePost(c *context.Context, f form.EditRepoFile, isNewFile bool) {
- c.PageIs("Edit")
- c.RequireHighlightJS()
- c.RequireSimpleMDE()
- c.Data["IsNewFile"] = isNewFile
-
- oldBranchName := c.Repo.BranchName
- branchName := oldBranchName
- oldTreePath := c.Repo.TreePath
- lastCommit := f.LastCommit
- f.LastCommit = c.Repo.Commit.ID.String()
-
- if f.IsNewBrnach() {
- branchName = f.NewBranchName
- }
-
- f.TreePath = strings.Trim(f.TreePath, " /")
- treeNames, treePaths := getParentTreeFields(f.TreePath)
-
- c.Data["ParentTreePath"] = path.Dir(c.Repo.TreePath)
- c.Data["TreePath"] = f.TreePath
- c.Data["TreeNames"] = treeNames
- c.Data["TreePaths"] = treePaths
- c.Data["BranchLink"] = c.Repo.RepoLink + "/src/" + branchName
- c.Data["FileContent"] = f.Content
- c.Data["commit_summary"] = f.CommitSummary
- c.Data["commit_message"] = f.CommitMessage
- c.Data["commit_choice"] = f.CommitChoice
- c.Data["new_branch_name"] = branchName
- c.Data["last_commit"] = f.LastCommit
- c.Data["MarkdownFileExts"] = strings.Join(setting.Markdown.FileExtensions, ",")
- c.Data["LineWrapExtensions"] = strings.Join(setting.Repository.Editor.LineWrapExtensions, ",")
- c.Data["PreviewableFileModes"] = strings.Join(setting.Repository.Editor.PreviewableFileModes, ",")
-
- if c.HasError() {
- c.Success(EDIT_FILE)
- return
- }
-
- if len(f.TreePath) == 0 {
- c.FormErr("TreePath")
- c.RenderWithErr(c.Tr("repo.editor.filename_cannot_be_empty"), EDIT_FILE, &f)
- return
- }
-
- if oldBranchName != branchName {
- if _, err := c.Repo.Repository.GetBranch(branchName); err == nil {
- c.FormErr("NewBranchName")
- c.RenderWithErr(c.Tr("repo.editor.branch_already_exists", branchName), EDIT_FILE, &f)
- return
- }
- }
-
- var newTreePath string
- for index, part := range treeNames {
- newTreePath = path.Join(newTreePath, part)
- entry, err := c.Repo.Commit.GetTreeEntryByPath(newTreePath)
- if err != nil {
- if git.IsErrNotExist(err) {
- // Means there is no item with that name, so we're good
- break
- }
-
- c.ServerError("Repo.Commit.GetTreeEntryByPath", err)
- return
- }
- if index != len(treeNames)-1 {
- if !entry.IsDir() {
- c.FormErr("TreePath")
- c.RenderWithErr(c.Tr("repo.editor.directory_is_a_file", part), EDIT_FILE, &f)
- return
- }
- } else {
- if entry.IsLink() {
- c.FormErr("TreePath")
- c.RenderWithErr(c.Tr("repo.editor.file_is_a_symlink", part), EDIT_FILE, &f)
- return
- } else if entry.IsDir() {
- c.FormErr("TreePath")
- c.RenderWithErr(c.Tr("repo.editor.filename_is_a_directory", part), EDIT_FILE, &f)
- return
- }
- }
- }
-
- if !isNewFile {
- _, err := c.Repo.Commit.GetTreeEntryByPath(oldTreePath)
- if err != nil {
- if git.IsErrNotExist(err) {
- c.FormErr("TreePath")
- c.RenderWithErr(c.Tr("repo.editor.file_editing_no_longer_exists", oldTreePath), EDIT_FILE, &f)
- } else {
- c.ServerError("GetTreeEntryByPath", err)
- }
- return
- }
- if lastCommit != c.Repo.CommitID {
- files, err := c.Repo.Commit.GetFilesChangedSinceCommit(lastCommit)
- if err != nil {
- c.ServerError("GetFilesChangedSinceCommit", err)
- return
- }
-
- for _, file := range files {
- if file == f.TreePath {
- c.RenderWithErr(c.Tr("repo.editor.file_changed_while_editing", c.Repo.RepoLink+"/compare/"+lastCommit+"..."+c.Repo.CommitID), EDIT_FILE, &f)
- return
- }
- }
- }
- }
-
- if oldTreePath != f.TreePath {
- // We have a new filename (rename or completely new file) so we need to make sure it doesn't already exist, can't clobber.
- entry, err := c.Repo.Commit.GetTreeEntryByPath(f.TreePath)
- if err != nil {
- if !git.IsErrNotExist(err) {
- c.ServerError("GetTreeEntryByPath", err)
- return
- }
- }
- if entry != nil {
- c.FormErr("TreePath")
- c.RenderWithErr(c.Tr("repo.editor.file_already_exists", f.TreePath), EDIT_FILE, &f)
- return
- }
- }
-
- message := strings.TrimSpace(f.CommitSummary)
- if len(message) == 0 {
- if isNewFile {
- message = c.Tr("repo.editor.add", f.TreePath)
- } else {
- message = c.Tr("repo.editor.update", f.TreePath)
- }
- }
-
- f.CommitMessage = strings.TrimSpace(f.CommitMessage)
- if len(f.CommitMessage) > 0 {
- message += "\n\n" + f.CommitMessage
- }
-
- if err := c.Repo.Repository.UpdateRepoFile(c.User, models.UpdateRepoFileOptions{
- LastCommitID: lastCommit,
- OldBranch: oldBranchName,
- NewBranch: branchName,
- OldTreeName: oldTreePath,
- NewTreeName: f.TreePath,
- Message: message,
- Content: strings.Replace(f.Content, "\r", "", -1),
- IsNewFile: isNewFile,
- }); err != nil {
- c.FormErr("TreePath")
- c.RenderWithErr(c.Tr("repo.editor.fail_to_update_file", f.TreePath, err), EDIT_FILE, &f)
- return
- }
-
- if f.IsNewBrnach() && c.Repo.PullRequest.Allowed {
- c.Redirect(c.Repo.PullRequestURL(oldBranchName, f.NewBranchName))
- } else {
- c.Redirect(c.Repo.RepoLink + "/src/" + branchName + "/" + template.EscapePound(f.TreePath))
- }
-}
-
-func EditFilePost(c *context.Context, f form.EditRepoFile) {
- editFilePost(c, f, false)
-}
-
-func NewFilePost(c *context.Context, f form.EditRepoFile) {
- editFilePost(c, f, true)
-}
-
-func DiffPreviewPost(c *context.Context, f form.EditPreviewDiff) {
- treePath := c.Repo.TreePath
-
- entry, err := c.Repo.Commit.GetTreeEntryByPath(treePath)
- if err != nil {
- c.Error(500, "GetTreeEntryByPath: "+err.Error())
- return
- } else if entry.IsDir() {
- c.Error(422)
- return
- }
-
- diff, err := c.Repo.Repository.GetDiffPreview(c.Repo.BranchName, treePath, f.Content)
- if err != nil {
- c.Error(500, "GetDiffPreview: "+err.Error())
- return
- }
-
- if diff.NumFiles() == 0 {
- c.PlainText(200, []byte(c.Tr("repo.editor.no_changes_to_show")))
- return
- }
- c.Data["File"] = diff.Files[0]
-
- c.HTML(200, EDIT_DIFF_PREVIEW)
-}
-
-func DeleteFile(c *context.Context) {
- c.Data["PageIsDelete"] = true
- c.Data["BranchLink"] = c.Repo.RepoLink + "/src/" + c.Repo.BranchName
- c.Data["TreePath"] = c.Repo.TreePath
- c.Data["commit_summary"] = ""
- c.Data["commit_message"] = ""
- c.Data["commit_choice"] = "direct"
- c.Data["new_branch_name"] = ""
- c.HTML(200, DELETE_FILE)
-}
-
-func DeleteFilePost(c *context.Context, f form.DeleteRepoFile) {
- c.Data["PageIsDelete"] = true
- c.Data["BranchLink"] = c.Repo.RepoLink + "/src/" + c.Repo.BranchName
- c.Data["TreePath"] = c.Repo.TreePath
-
- oldBranchName := c.Repo.BranchName
- branchName := oldBranchName
-
- if f.IsNewBrnach() {
- branchName = f.NewBranchName
- }
- c.Data["commit_summary"] = f.CommitSummary
- c.Data["commit_message"] = f.CommitMessage
- c.Data["commit_choice"] = f.CommitChoice
- c.Data["new_branch_name"] = branchName
-
- if c.HasError() {
- c.HTML(200, DELETE_FILE)
- return
- }
-
- if oldBranchName != branchName {
- if _, err := c.Repo.Repository.GetBranch(branchName); err == nil {
- c.Data["Err_NewBranchName"] = true
- c.RenderWithErr(c.Tr("repo.editor.branch_already_exists", branchName), DELETE_FILE, &f)
- return
- }
- }
-
- message := strings.TrimSpace(f.CommitSummary)
- if len(message) == 0 {
- message = c.Tr("repo.editor.delete", c.Repo.TreePath)
- }
-
- f.CommitMessage = strings.TrimSpace(f.CommitMessage)
- if len(f.CommitMessage) > 0 {
- message += "\n\n" + f.CommitMessage
- }
-
- if err := c.Repo.Repository.DeleteRepoFile(c.User, models.DeleteRepoFileOptions{
- LastCommitID: c.Repo.CommitID,
- OldBranch: oldBranchName,
- NewBranch: branchName,
- TreePath: c.Repo.TreePath,
- Message: message,
- }); err != nil {
- c.Handle(500, "DeleteRepoFile", err)
- return
- }
-
- if f.IsNewBrnach() && c.Repo.PullRequest.Allowed {
- c.Redirect(c.Repo.PullRequestURL(oldBranchName, f.NewBranchName))
- } else {
- c.Flash.Success(c.Tr("repo.editor.file_delete_success", c.Repo.TreePath))
- c.Redirect(c.Repo.RepoLink + "/src/" + branchName)
- }
-}
-
-func renderUploadSettings(c *context.Context) {
- c.Data["RequireDropzone"] = true
- c.Data["UploadAllowedTypes"] = strings.Join(setting.Repository.Upload.AllowedTypes, ",")
- c.Data["UploadMaxSize"] = setting.Repository.Upload.FileMaxSize
- c.Data["UploadMaxFiles"] = setting.Repository.Upload.MaxFiles
-}
-
-func UploadFile(c *context.Context) {
- c.Data["PageIsUpload"] = true
- renderUploadSettings(c)
-
- treeNames, treePaths := getParentTreeFields(c.Repo.TreePath)
- if len(treeNames) == 0 {
- // We must at least have one element for user to input.
- treeNames = []string{""}
- }
-
- c.Data["TreeNames"] = treeNames
- c.Data["TreePaths"] = treePaths
- c.Data["BranchLink"] = c.Repo.RepoLink + "/src/" + c.Repo.BranchName
- c.Data["commit_summary"] = ""
- c.Data["commit_message"] = ""
- c.Data["commit_choice"] = "direct"
- c.Data["new_branch_name"] = ""
-
- c.HTML(200, UPLOAD_FILE)
-}
-
-func UploadFilePost(c *context.Context, f form.UploadRepoFile) {
- c.Data["PageIsUpload"] = true
- renderUploadSettings(c)
-
- oldBranchName := c.Repo.BranchName
- branchName := oldBranchName
-
- if f.IsNewBrnach() {
- branchName = f.NewBranchName
- }
-
- f.TreePath = strings.Trim(f.TreePath, " /")
- treeNames, treePaths := getParentTreeFields(f.TreePath)
- if len(treeNames) == 0 {
- // We must at least have one element for user to input.
- treeNames = []string{""}
- }
-
- c.Data["TreePath"] = f.TreePath
- c.Data["TreeNames"] = treeNames
- c.Data["TreePaths"] = treePaths
- c.Data["BranchLink"] = c.Repo.RepoLink + "/src/" + branchName
- c.Data["commit_summary"] = f.CommitSummary
- c.Data["commit_message"] = f.CommitMessage
- c.Data["commit_choice"] = f.CommitChoice
- c.Data["new_branch_name"] = branchName
-
- if c.HasError() {
- c.HTML(200, UPLOAD_FILE)
- return
- }
-
- if oldBranchName != branchName {
- if _, err := c.Repo.Repository.GetBranch(branchName); err == nil {
- c.Data["Err_NewBranchName"] = true
- c.RenderWithErr(c.Tr("repo.editor.branch_already_exists", branchName), UPLOAD_FILE, &f)
- return
- }
- }
-
- var newTreePath string
- for _, part := range treeNames {
- newTreePath = path.Join(newTreePath, part)
- entry, err := c.Repo.Commit.GetTreeEntryByPath(newTreePath)
- if err != nil {
- if git.IsErrNotExist(err) {
- // Means there is no item with that name, so we're good
- break
- }
-
- c.Handle(500, "Repo.Commit.GetTreeEntryByPath", err)
- return
- }
-
- // User can only upload files to a directory.
- if !entry.IsDir() {
- c.Data["Err_TreePath"] = true
- c.RenderWithErr(c.Tr("repo.editor.directory_is_a_file", part), UPLOAD_FILE, &f)
- return
- }
- }
-
- message := strings.TrimSpace(f.CommitSummary)
- if len(message) == 0 {
- message = c.Tr("repo.editor.upload_files_to_dir", f.TreePath)
- }
-
- f.CommitMessage = strings.TrimSpace(f.CommitMessage)
- if len(f.CommitMessage) > 0 {
- message += "\n\n" + f.CommitMessage
- }
-
- if err := c.Repo.Repository.UploadRepoFiles(c.User, models.UploadRepoFileOptions{
- LastCommitID: c.Repo.CommitID,
- OldBranch: oldBranchName,
- NewBranch: branchName,
- TreePath: f.TreePath,
- Message: message,
- Files: f.Files,
- }); err != nil {
- c.Data["Err_TreePath"] = true
- c.RenderWithErr(c.Tr("repo.editor.unable_to_upload_files", f.TreePath, err), UPLOAD_FILE, &f)
- return
- }
-
- if f.IsNewBrnach() && c.Repo.PullRequest.Allowed {
- c.Redirect(c.Repo.PullRequestURL(oldBranchName, f.NewBranchName))
- } else {
- c.Redirect(c.Repo.RepoLink + "/src/" + branchName + "/" + f.TreePath)
- }
-}
-
-func UploadFileToServer(c *context.Context) {
- file, header, err := c.Req.FormFile("file")
- if err != nil {
- c.Error(500, fmt.Sprintf("FormFile: %v", err))
- return
- }
- defer file.Close()
-
- buf := make([]byte, 1024)
- n, _ := file.Read(buf)
- if n > 0 {
- buf = buf[:n]
- }
- fileType := http.DetectContentType(buf)
-
- if len(setting.Repository.Upload.AllowedTypes) > 0 {
- allowed := false
- for _, t := range setting.Repository.Upload.AllowedTypes {
- t := strings.Trim(t, " ")
- if t == "*/*" || t == fileType {
- allowed = true
- break
- }
- }
-
- if !allowed {
- c.Error(400, ErrFileTypeForbidden.Error())
- return
- }
- }
-
- upload, err := models.NewUpload(header.Filename, buf, file)
- if err != nil {
- c.Error(500, fmt.Sprintf("NewUpload: %v", err))
- return
- }
-
- log.Trace("New file uploaded: %s", upload.UUID)
- c.JSON(200, map[string]string{
- "uuid": upload.UUID,
- })
-}
-
-func RemoveUploadFileFromServer(c *context.Context, f form.RemoveUploadFile) {
- if len(f.File) == 0 {
- c.Status(204)
- return
- }
-
- if err := models.DeleteUploadByUUID(f.File); err != nil {
- c.Error(500, fmt.Sprintf("DeleteUploadByUUID: %v", err))
- return
- }
-
- log.Trace("Upload file removed: %s", f.File)
- c.Status(204)
-}
diff --git a/routers/repo/http.go b/routers/repo/http.go
deleted file mode 100644
index b8f519ba..00000000
--- a/routers/repo/http.go
+++ /dev/null
@@ -1,447 +0,0 @@
-// Copyright 2017 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 repo
-
-import (
- "bytes"
- "compress/gzip"
- "fmt"
- "net/http"
- "os"
- "os/exec"
- "path"
- "regexp"
- "strconv"
- "strings"
- "time"
-
- "github.com/Unknwon/com"
- log "gopkg.in/clog.v1"
- "gopkg.in/macaron.v1"
-
- "github.com/gogits/gogs/models"
- "github.com/gogits/gogs/models/errors"
- "github.com/gogits/gogs/pkg/context"
- "github.com/gogits/gogs/pkg/setting"
- "github.com/gogits/gogs/pkg/tool"
-)
-
-const (
- ENV_AUTH_USER_ID = "GOGS_AUTH_USER_ID"
- ENV_AUTH_USER_NAME = "GOGS_AUTH_USER_NAME"
- ENV_AUTH_USER_EMAIL = "GOGS_AUTH_USER_EMAIL"
- ENV_REPO_OWNER_NAME = "GOGS_REPO_OWNER_NAME"
- ENV_REPO_OWNER_SALT_MD5 = "GOGS_REPO_OWNER_SALT_MD5"
- ENV_REPO_ID = "GOGS_REPO_ID"
- ENV_REPO_NAME = "GOGS_REPO_NAME"
- ENV_REPO_CUSTOM_HOOKS_PATH = "GOGS_REPO_CUSTOM_HOOKS_PATH"
-)
-
-type HTTPContext struct {
- *context.Context
- OwnerName string
- OwnerSalt string
- RepoID int64
- RepoName string
- AuthUser *models.User
-}
-
-// askCredentials responses HTTP header and status which informs client to provide credentials.
-func askCredentials(c *context.Context, status int, text string) {
- c.Resp.Header().Set("WWW-Authenticate", "Basic realm=\".\"")
- c.HandleText(status, text)
-}
-
-func HTTPContexter() macaron.Handler {
- return func(c *context.Context) {
- ownerName := c.Params(":username")
- repoName := strings.TrimSuffix(c.Params(":reponame"), ".git")
- repoName = strings.TrimSuffix(repoName, ".wiki")
-
- isPull := c.Query("service") == "git-upload-pack" ||
- strings.HasSuffix(c.Req.URL.Path, "git-upload-pack") ||
- c.Req.Method == "GET"
-
- owner, err := models.GetUserByName(ownerName)
- if err != nil {
- c.NotFoundOrServerError("GetUserByName", errors.IsUserNotExist, err)
- return
- }
-
- repo, err := models.GetRepositoryByName(owner.ID, repoName)
- if err != nil {
- c.NotFoundOrServerError("GetRepositoryByName", errors.IsRepoNotExist, err)
- return
- }
-
- // Authentication is not required for pulling from public repositories.
- if isPull && !repo.IsPrivate && !setting.Service.RequireSignInView {
- c.Map(&HTTPContext{
- Context: c,
- })
- return
- }
-
- // In case user requested a wrong URL and not intended to access Git objects.
- action := c.Params("*")
- if !strings.Contains(action, "git-") &&
- !strings.Contains(action, "info/") &&
- !strings.Contains(action, "HEAD") &&
- !strings.Contains(action, "objects/") {
- c.NotFound()
- return
- }
-
- // Handle HTTP Basic Authentication
- authHead := c.Req.Header.Get("Authorization")
- if len(authHead) == 0 {
- askCredentials(c, http.StatusUnauthorized, "")
- return
- }
-
- auths := strings.Fields(authHead)
- if len(auths) != 2 || auths[0] != "Basic" {
- askCredentials(c, http.StatusUnauthorized, "")
- return
- }
- authUsername, authPassword, err := tool.BasicAuthDecode(auths[1])
- if err != nil {
- askCredentials(c, http.StatusUnauthorized, "")
- return
- }
-
- authUser, err := models.UserSignIn(authUsername, authPassword)
- if err != nil && !errors.IsUserNotExist(err) {
- c.Handle(http.StatusInternalServerError, "UserSignIn", err)
- return
- }
-
- // If username and password combination failed, try again using username as a token.
- if authUser == nil {
- token, err := models.GetAccessTokenBySHA(authUsername)
- if err != nil {
- if models.IsErrAccessTokenEmpty(err) || models.IsErrAccessTokenNotExist(err) {
- askCredentials(c, http.StatusUnauthorized, "")
- } else {
- c.Handle(http.StatusInternalServerError, "GetAccessTokenBySHA", err)
- }
- return
- }
- token.Updated = time.Now()
-
- authUser, err = models.GetUserByID(token.UID)
- if err != nil {
- // Once we found token, we're supposed to find its related user,
- // thus any error is unexpected.
- c.Handle(http.StatusInternalServerError, "GetUserByID", err)
- return
- }
- } else if authUser.IsEnabledTwoFactor() {
- askCredentials(c, http.StatusUnauthorized, `User with two-factor authentication enabled cannot perform HTTP/HTTPS operations via plain username and password
-Please create and use personal access token on user settings page`)
- return
- }
-
- log.Trace("HTTPGit - Authenticated user: %s", authUser.Name)
-
- mode := models.ACCESS_MODE_WRITE
- if isPull {
- mode = models.ACCESS_MODE_READ
- }
- has, err := models.HasAccess(authUser.ID, repo, mode)
- if err != nil {
- c.Handle(http.StatusInternalServerError, "HasAccess", err)
- return
- } else if !has {
- askCredentials(c, http.StatusForbidden, "User permission denied")
- return
- }
-
- if !isPull && repo.IsMirror {
- c.HandleText(http.StatusForbidden, "Mirror repository is read-only")
- return
- }
-
- c.Map(&HTTPContext{
- Context: c,
- OwnerName: ownerName,
- OwnerSalt: owner.Salt,
- RepoID: repo.ID,
- RepoName: repoName,
- AuthUser: authUser,
- })
- }
-}
-
-type serviceHandler struct {
- w http.ResponseWriter
- r *http.Request
- dir string
- file string
-
- authUser *models.User
- ownerName string
- ownerSalt string
- repoID int64
- repoName string
-}
-
-func (h *serviceHandler) setHeaderNoCache() {
- h.w.Header().Set("Expires", "Fri, 01 Jan 1980 00:00:00 GMT")
- h.w.Header().Set("Pragma", "no-cache")
- h.w.Header().Set("Cache-Control", "no-cache, max-age=0, must-revalidate")
-}
-
-func (h *serviceHandler) setHeaderCacheForever() {
- now := time.Now().Unix()
- expires := now + 31536000
- h.w.Header().Set("Date", fmt.Sprintf("%d", now))
- h.w.Header().Set("Expires", fmt.Sprintf("%d", expires))
- h.w.Header().Set("Cache-Control", "public, max-age=31536000")
-}
-
-func (h *serviceHandler) sendFile(contentType string) {
- reqFile := path.Join(h.dir, h.file)
- fi, err := os.Stat(reqFile)
- if os.IsNotExist(err) {
- h.w.WriteHeader(http.StatusNotFound)
- return
- }
-
- h.w.Header().Set("Content-Type", contentType)
- h.w.Header().Set("Content-Length", fmt.Sprintf("%d", fi.Size()))
- h.w.Header().Set("Last-Modified", fi.ModTime().Format(http.TimeFormat))
- http.ServeFile(h.w, h.r, reqFile)
-}
-
-type ComposeHookEnvsOptions struct {
- AuthUser *models.User
- OwnerName string
- OwnerSalt string
- RepoID int64
- RepoName string
- RepoPath string
-}
-
-func ComposeHookEnvs(opts ComposeHookEnvsOptions) []string {
- envs := []string{
- "SSH_ORIGINAL_COMMAND=1",
- ENV_AUTH_USER_ID + "=" + com.ToStr(opts.AuthUser.ID),
- ENV_AUTH_USER_NAME + "=" + opts.AuthUser.Name,
- ENV_AUTH_USER_EMAIL + "=" + opts.AuthUser.Email,
- ENV_REPO_OWNER_NAME + "=" + opts.OwnerName,
- ENV_REPO_OWNER_SALT_MD5 + "=" + tool.MD5(opts.OwnerSalt),
- ENV_REPO_ID + "=" + com.ToStr(opts.RepoID),
- ENV_REPO_NAME + "=" + opts.RepoName,
- ENV_REPO_CUSTOM_HOOKS_PATH + "=" + path.Join(opts.RepoPath, "custom_hooks"),
- }
- return envs
-}
-
-func serviceRPC(h serviceHandler, service string) {
- defer h.r.Body.Close()
-
- if h.r.Header.Get("Content-Type") != fmt.Sprintf("application/x-git-%s-request", service) {
- h.w.WriteHeader(http.StatusUnauthorized)
- return
- }
- h.w.Header().Set("Content-Type", fmt.Sprintf("application/x-git-%s-result", service))
-
- var (
- reqBody = h.r.Body
- err error
- )
-
- // Handle GZIP
- if h.r.Header.Get("Content-Encoding") == "gzip" {
- reqBody, err = gzip.NewReader(reqBody)
- if err != nil {
- log.Error(2, "HTTP.Get: fail to create gzip reader: %v", err)
- h.w.WriteHeader(http.StatusInternalServerError)
- return
- }
- }
-
- var stderr bytes.Buffer
- cmd := exec.Command("git", service, "--stateless-rpc", h.dir)
- if service == "receive-pack" {
- cmd.Env = append(os.Environ(), ComposeHookEnvs(ComposeHookEnvsOptions{
- AuthUser: h.authUser,
- OwnerName: h.ownerName,
- OwnerSalt: h.ownerSalt,
- RepoID: h.repoID,
- RepoName: h.repoName,
- RepoPath: h.dir,
- })...)
- }
- cmd.Dir = h.dir
- cmd.Stdout = h.w
- cmd.Stderr = &stderr
- cmd.Stdin = reqBody
- if err = cmd.Run(); err != nil {
- log.Error(2, "HTTP.serviceRPC: fail to serve RPC '%s': %v - %s", service, err, stderr)
- h.w.WriteHeader(http.StatusInternalServerError)
- return
- }
-}
-
-func serviceUploadPack(h serviceHandler) {
- serviceRPC(h, "upload-pack")
-}
-
-func serviceReceivePack(h serviceHandler) {
- serviceRPC(h, "receive-pack")
-}
-
-func getServiceType(r *http.Request) string {
- serviceType := r.FormValue("service")
- if !strings.HasPrefix(serviceType, "git-") {
- return ""
- }
- return strings.TrimPrefix(serviceType, "git-")
-}
-
-// FIXME: use process module
-func gitCommand(dir string, args ...string) []byte {
- cmd := exec.Command("git", args...)
- cmd.Dir = dir
- out, err := cmd.Output()
- if err != nil {
- log.Error(2, fmt.Sprintf("Git: %v - %s", err, out))
- }
- return out
-}
-
-func updateServerInfo(dir string) []byte {
- return gitCommand(dir, "update-server-info")
-}
-
-func packetWrite(str string) []byte {
- s := strconv.FormatInt(int64(len(str)+4), 16)
- if len(s)%4 != 0 {
- s = strings.Repeat("0", 4-len(s)%4) + s
- }
- return []byte(s + str)
-}
-
-func getInfoRefs(h serviceHandler) {
- h.setHeaderNoCache()
- service := getServiceType(h.r)
- if service != "upload-pack" && service != "receive-pack" {
- updateServerInfo(h.dir)
- h.sendFile("text/plain; charset=utf-8")
- return
- }
-
- refs := gitCommand(h.dir, service, "--stateless-rpc", "--advertise-refs", ".")
- h.w.Header().Set("Content-Type", fmt.Sprintf("application/x-git-%s-advertisement", service))
- h.w.WriteHeader(http.StatusOK)
- h.w.Write(packetWrite("# service=git-" + service + "\n"))
- h.w.Write([]byte("0000"))
- h.w.Write(refs)
-}
-
-func getTextFile(h serviceHandler) {
- h.setHeaderNoCache()
- h.sendFile("text/plain")
-}
-
-func getInfoPacks(h serviceHandler) {
- h.setHeaderCacheForever()
- h.sendFile("text/plain; charset=utf-8")
-}
-
-func getLooseObject(h serviceHandler) {
- h.setHeaderCacheForever()
- h.sendFile("application/x-git-loose-object")
-}
-
-func getPackFile(h serviceHandler) {
- h.setHeaderCacheForever()
- h.sendFile("application/x-git-packed-objects")
-}
-
-func getIdxFile(h serviceHandler) {
- h.setHeaderCacheForever()
- h.sendFile("application/x-git-packed-objects-toc")
-}
-
-var routes = []struct {
- reg *regexp.Regexp
- method string
- handler func(serviceHandler)
-}{
- {regexp.MustCompile("(.*?)/git-upload-pack$"), "POST", serviceUploadPack},
- {regexp.MustCompile("(.*?)/git-receive-pack$"), "POST", serviceReceivePack},
- {regexp.MustCompile("(.*?)/info/refs$"), "GET", getInfoRefs},
- {regexp.MustCompile("(.*?)/HEAD$"), "GET", getTextFile},
- {regexp.MustCompile("(.*?)/objects/info/alternates$"), "GET", getTextFile},
- {regexp.MustCompile("(.*?)/objects/info/http-alternates$"), "GET", getTextFile},
- {regexp.MustCompile("(.*?)/objects/info/packs$"), "GET", getInfoPacks},
- {regexp.MustCompile("(.*?)/objects/info/[^/]*$"), "GET", getTextFile},
- {regexp.MustCompile("(.*?)/objects/[0-9a-f]{2}/[0-9a-f]{38}$"), "GET", getLooseObject},
- {regexp.MustCompile("(.*?)/objects/pack/pack-[0-9a-f]{40}\\.pack$"), "GET", getPackFile},
- {regexp.MustCompile("(.*?)/objects/pack/pack-[0-9a-f]{40}\\.idx$"), "GET", getIdxFile},
-}
-
-func getGitRepoPath(dir string) (string, error) {
- if !strings.HasSuffix(dir, ".git") {
- dir += ".git"
- }
-
- filename := path.Join(setting.RepoRootPath, dir)
- if _, err := os.Stat(filename); os.IsNotExist(err) {
- return "", err
- }
-
- return filename, nil
-}
-
-func HTTP(c *HTTPContext) {
- for _, route := range routes {
- reqPath := strings.ToLower(c.Req.URL.Path)
- m := route.reg.FindStringSubmatch(reqPath)
- if m == nil {
- continue
- }
-
- // We perform check here because routes matched in cmd/web.go is wider than needed,
- // but we only want to output this message only if user is really trying to access
- // Git HTTP endpoints.
- if setting.Repository.DisableHTTPGit {
- c.HandleText(http.StatusForbidden, "Interacting with repositories by HTTP protocol is not disabled")
- return
- }
-
- if route.method != c.Req.Method {
- c.NotFound()
- return
- }
-
- file := strings.TrimPrefix(reqPath, m[1]+"/")
- dir, err := getGitRepoPath(m[1])
- if err != nil {
- log.Warn("HTTP.getGitRepoPath: %v", err)
- c.NotFound()
- return
- }
-
- route.handler(serviceHandler{
- w: c.Resp,
- r: c.Req.Request,
- dir: dir,
- file: file,
-
- authUser: c.AuthUser,
- ownerName: c.OwnerName,
- ownerSalt: c.OwnerSalt,
- repoID: c.RepoID,
- repoName: c.RepoName,
- })
- return
- }
-
- c.NotFound()
-}
diff --git a/routers/repo/issue.go b/routers/repo/issue.go
deleted file mode 100644
index 8920bc32..00000000
--- a/routers/repo/issue.go
+++ /dev/null
@@ -1,1263 +0,0 @@
-// 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 repo
-
-import (
- "fmt"
- "io"
- "io/ioutil"
- "net/http"
- "net/url"
- "strings"
- "time"
-
- "github.com/Unknwon/com"
- "github.com/Unknwon/paginater"
- log "gopkg.in/clog.v1"
-
- "github.com/gogits/gogs/models"
- "github.com/gogits/gogs/models/errors"
- "github.com/gogits/gogs/pkg/context"
- "github.com/gogits/gogs/pkg/form"
- "github.com/gogits/gogs/pkg/markup"
- "github.com/gogits/gogs/pkg/setting"
- "github.com/gogits/gogs/pkg/tool"
-)
-
-const (
- ISSUES = "repo/issue/list"
- ISSUE_NEW = "repo/issue/new"
- ISSUE_VIEW = "repo/issue/view"
-
- LABELS = "repo/issue/labels"
-
- MILESTONE = "repo/issue/milestones"
- MILESTONE_NEW = "repo/issue/milestone_new"
- MILESTONE_EDIT = "repo/issue/milestone_edit"
-
- ISSUE_TEMPLATE_KEY = "IssueTemplate"
-)
-
-var (
- ErrFileTypeForbidden = errors.New("File type is not allowed")
- ErrTooManyFiles = errors.New("Maximum number of files to upload exceeded")
-
- IssueTemplateCandidates = []string{
- "ISSUE_TEMPLATE.md",
- ".gogs/ISSUE_TEMPLATE.md",
- ".github/ISSUE_TEMPLATE.md",
- }
-)
-
-func MustEnableIssues(c *context.Context) {
- if !c.Repo.Repository.EnableIssues {
- c.Handle(404, "MustEnableIssues", nil)
- return
- }
-
- if c.Repo.Repository.EnableExternalTracker {
- c.Redirect(c.Repo.Repository.ExternalTrackerURL)
- return
- }
-}
-
-func MustAllowPulls(c *context.Context) {
- if !c.Repo.Repository.AllowsPulls() {
- c.Handle(404, "MustAllowPulls", nil)
- return
- }
-
- // User can send pull request if owns a forked repository.
- if c.IsLogged && c.User.HasForkedRepo(c.Repo.Repository.ID) {
- c.Repo.PullRequest.Allowed = true
- c.Repo.PullRequest.HeadInfo = c.User.Name + ":" + c.Repo.BranchName
- }
-}
-
-func RetrieveLabels(c *context.Context) {
- labels, err := models.GetLabelsByRepoID(c.Repo.Repository.ID)
- if err != nil {
- c.Handle(500, "RetrieveLabels.GetLabels", err)
- return
- }
- for _, l := range labels {
- l.CalOpenIssues()
- }
- c.Data["Labels"] = labels
- c.Data["NumLabels"] = len(labels)
-}
-
-func issues(c *context.Context, isPullList bool) {
- if isPullList {
- MustAllowPulls(c)
- if c.Written() {
- return
- }
- c.Data["Title"] = c.Tr("repo.pulls")
- c.Data["PageIsPullList"] = true
-
- } else {
- MustEnableIssues(c)
- if c.Written() {
- return
- }
- c.Data["Title"] = c.Tr("repo.issues")
- c.Data["PageIsIssueList"] = true
- }
-
- viewType := c.Query("type")
- sortType := c.Query("sort")
- types := []string{"assigned", "created_by", "mentioned"}
- if !com.IsSliceContainsStr(types, viewType) {
- viewType = "all"
- }
-
- // Must sign in to see issues about you.
- if viewType != "all" && !c.IsLogged {
- c.SetCookie("redirect_to", "/"+url.QueryEscape(setting.AppSubURL+c.Req.RequestURI), 0, setting.AppSubURL)
- c.Redirect(setting.AppSubURL + "/user/login")
- return
- }
-
- var (
- assigneeID = c.QueryInt64("assignee")
- posterID int64
- )
- filterMode := models.FILTER_MODE_YOUR_REPOS
- switch viewType {
- case "assigned":
- filterMode = models.FILTER_MODE_ASSIGN
- assigneeID = c.User.ID
- case "created_by":
- filterMode = models.FILTER_MODE_CREATE
- posterID = c.User.ID
- case "mentioned":
- filterMode = models.FILTER_MODE_MENTION
- }
-
- var uid int64 = -1
- if c.IsLogged {
- uid = c.User.ID
- }
-
- repo := c.Repo.Repository
- selectLabels := c.Query("labels")
- milestoneID := c.QueryInt64("milestone")
- isShowClosed := c.Query("state") == "closed"
- issueStats := models.GetIssueStats(&models.IssueStatsOptions{
- RepoID: repo.ID,
- UserID: uid,
- Labels: selectLabels,
- MilestoneID: milestoneID,
- AssigneeID: assigneeID,
- FilterMode: filterMode,
- IsPull: isPullList,
- })
-
- page := c.QueryInt("page")
- if page <= 1 {
- page = 1
- }
-
- var total int
- if !isShowClosed {
- total = int(issueStats.OpenCount)
- } else {
- total = int(issueStats.ClosedCount)
- }
- pager := paginater.New(total, setting.UI.IssuePagingNum, page, 5)
- c.Data["Page"] = pager
-
- issues, err := models.Issues(&models.IssuesOptions{
- UserID: uid,
- AssigneeID: assigneeID,
- RepoID: repo.ID,
- PosterID: posterID,
- MilestoneID: milestoneID,
- Page: pager.Current(),
- IsClosed: isShowClosed,
- IsMention: filterMode == models.FILTER_MODE_MENTION,
- IsPull: isPullList,
- Labels: selectLabels,
- SortType: sortType,
- })
- if err != nil {
- c.Handle(500, "Issues", err)
- return
- }
-
- // Get issue-user relations.
- pairs, err := models.GetIssueUsers(repo.ID, posterID, isShowClosed)
- if err != nil {
- c.Handle(500, "GetIssueUsers", err)
- return
- }
-
- // Get posters.
- for i := range issues {
- if !c.IsLogged {
- issues[i].IsRead = true
- continue
- }
-
- // Check read status.
- idx := models.PairsContains(pairs, issues[i].ID, c.User.ID)
- if idx > -1 {
- issues[i].IsRead = pairs[idx].IsRead
- } else {
- issues[i].IsRead = true
- }
- }
- c.Data["Issues"] = issues
-
- // Get milestones.
- c.Data["Milestones"], err = models.GetMilestonesByRepoID(repo.ID)
- if err != nil {
- c.Handle(500, "GetAllRepoMilestones", err)
- return
- }
-
- // Get assignees.
- c.Data["Assignees"], err = repo.GetAssignees()
- if err != nil {
- c.Handle(500, "GetAssignees", err)
- return
- }
-
- if viewType == "assigned" {
- assigneeID = 0 // Reset ID to prevent unexpected selection of assignee.
- }
-
- c.Data["IssueStats"] = issueStats
- c.Data["SelectLabels"] = com.StrTo(selectLabels).MustInt64()
- c.Data["ViewType"] = viewType
- c.Data["SortType"] = sortType
- c.Data["MilestoneID"] = milestoneID
- c.Data["AssigneeID"] = assigneeID
- c.Data["IsShowClosed"] = isShowClosed
- if isShowClosed {
- c.Data["State"] = "closed"
- } else {
- c.Data["State"] = "open"
- }
-
- c.HTML(200, ISSUES)
-}
-
-func Issues(c *context.Context) {
- issues(c, false)
-}
-
-func Pulls(c *context.Context) {
- issues(c, true)
-}
-
-func renderAttachmentSettings(c *context.Context) {
- c.Data["RequireDropzone"] = true
- c.Data["IsAttachmentEnabled"] = setting.AttachmentEnabled
- c.Data["AttachmentAllowedTypes"] = setting.AttachmentAllowedTypes
- c.Data["AttachmentMaxSize"] = setting.AttachmentMaxSize
- c.Data["AttachmentMaxFiles"] = setting.AttachmentMaxFiles
-}
-
-func RetrieveRepoMilestonesAndAssignees(c *context.Context, repo *models.Repository) {
- var err error
- c.Data["OpenMilestones"], err = models.GetMilestones(repo.ID, -1, false)
- if err != nil {
- c.Handle(500, "GetMilestones", err)
- return
- }
- c.Data["ClosedMilestones"], err = models.GetMilestones(repo.ID, -1, true)
- if err != nil {
- c.Handle(500, "GetMilestones", err)
- return
- }
-
- c.Data["Assignees"], err = repo.GetAssignees()
- if err != nil {
- c.Handle(500, "GetAssignees", err)
- return
- }
-}
-
-func RetrieveRepoMetas(c *context.Context, repo *models.Repository) []*models.Label {
- if !c.Repo.IsWriter() {
- return nil
- }
-
- labels, err := models.GetLabelsByRepoID(repo.ID)
- if err != nil {
- c.Handle(500, "GetLabelsByRepoID", err)
- return nil
- }
- c.Data["Labels"] = labels
-
- RetrieveRepoMilestonesAndAssignees(c, repo)
- if c.Written() {
- return nil
- }
-
- return labels
-}
-
-func getFileContentFromDefaultBranch(c *context.Context, filename string) (string, bool) {
- var r io.Reader
- var bytes []byte
-
- if c.Repo.Commit == nil {
- var err error
- c.Repo.Commit, err = c.Repo.GitRepo.GetBranchCommit(c.Repo.Repository.DefaultBranch)
- if err != nil {
- return "", false
- }
- }
-
- entry, err := c.Repo.Commit.GetTreeEntryByPath(filename)
- if err != nil {
- return "", false
- }
- r, err = entry.Blob().Data()
- if err != nil {
- return "", false
- }
- bytes, err = ioutil.ReadAll(r)
- if err != nil {
- return "", false
- }
- return string(bytes), true
-}
-
-func setTemplateIfExists(c *context.Context, ctxDataKey string, possibleFiles []string) {
- for _, filename := range possibleFiles {
- content, found := getFileContentFromDefaultBranch(c, filename)
- if found {
- c.Data[ctxDataKey] = content
- return
- }
- }
-}
-
-func NewIssue(c *context.Context) {
- c.Data["Title"] = c.Tr("repo.issues.new")
- c.Data["PageIsIssueList"] = true
- c.Data["RequireHighlightJS"] = true
- c.Data["RequireSimpleMDE"] = true
- setTemplateIfExists(c, ISSUE_TEMPLATE_KEY, IssueTemplateCandidates)
- renderAttachmentSettings(c)
-
- RetrieveRepoMetas(c, c.Repo.Repository)
- if c.Written() {
- return
- }
-
- c.HTML(200, ISSUE_NEW)
-}
-
-func ValidateRepoMetas(c *context.Context, f form.NewIssue) ([]int64, int64, int64) {
- var (
- repo = c.Repo.Repository
- err error
- )
-
- labels := RetrieveRepoMetas(c, c.Repo.Repository)
- if c.Written() {
- return nil, 0, 0
- }
-
- if !c.Repo.IsWriter() {
- return nil, 0, 0
- }
-
- // Check labels.
- labelIDs := tool.StringsToInt64s(strings.Split(f.LabelIDs, ","))
- labelIDMark := tool.Int64sToMap(labelIDs)
- hasSelected := false
- for i := range labels {
- if labelIDMark[labels[i].ID] {
- labels[i].IsChecked = true
- hasSelected = true
- }
- }
- c.Data["HasSelectedLabel"] = hasSelected
- c.Data["label_ids"] = f.LabelIDs
- c.Data["Labels"] = labels
-
- // Check milestone.
- milestoneID := f.MilestoneID
- if milestoneID > 0 {
- c.Data["Milestone"], err = repo.GetMilestoneByID(milestoneID)
- if err != nil {
- c.Handle(500, "GetMilestoneByID", err)
- return nil, 0, 0
- }
- c.Data["milestone_id"] = milestoneID
- }
-
- // Check assignee.
- assigneeID := f.AssigneeID
- if assigneeID > 0 {
- c.Data["Assignee"], err = repo.GetAssigneeByID(assigneeID)
- if err != nil {
- c.Handle(500, "GetAssigneeByID", err)
- return nil, 0, 0
- }
- c.Data["assignee_id"] = assigneeID
- }
-
- return labelIDs, milestoneID, assigneeID
-}
-
-func NewIssuePost(c *context.Context, f form.NewIssue) {
- c.Data["Title"] = c.Tr("repo.issues.new")
- c.Data["PageIsIssueList"] = true
- c.Data["RequireHighlightJS"] = true
- c.Data["RequireSimpleMDE"] = true
- renderAttachmentSettings(c)
-
- labelIDs, milestoneID, assigneeID := ValidateRepoMetas(c, f)
- if c.Written() {
- return
- }
-
- if c.HasError() {
- c.HTML(200, ISSUE_NEW)
- return
- }
-
- var attachments []string
- if setting.AttachmentEnabled {
- attachments = f.Files
- }
-
- issue := &models.Issue{
- RepoID: c.Repo.Repository.ID,
- Title: f.Title,
- PosterID: c.User.ID,
- Poster: c.User,
- MilestoneID: milestoneID,
- AssigneeID: assigneeID,
- Content: f.Content,
- }
- if err := models.NewIssue(c.Repo.Repository, issue, labelIDs, attachments); err != nil {
- c.Handle(500, "NewIssue", err)
- return
- }
-
- log.Trace("Issue created: %d/%d", c.Repo.Repository.ID, issue.ID)
- c.Redirect(c.Repo.RepoLink + "/issues/" + com.ToStr(issue.Index))
-}
-
-func uploadAttachment(c *context.Context, allowedTypes []string) {
- file, header, err := c.Req.FormFile("file")
- if err != nil {
- c.Error(500, fmt.Sprintf("FormFile: %v", err))
- return
- }
- defer file.Close()
-
- buf := make([]byte, 1024)
- n, _ := file.Read(buf)
- if n > 0 {
- buf = buf[:n]
- }
- fileType := http.DetectContentType(buf)
-
- allowed := false
- for _, t := range allowedTypes {
- t := strings.Trim(t, " ")
- if t == "*/*" || t == fileType {
- allowed = true
- break
- }
- }
-
- if !allowed {
- c.Error(400, ErrFileTypeForbidden.Error())
- return
- }
-
- attach, err := models.NewAttachment(header.Filename, buf, file)
- if err != nil {
- c.Error(500, fmt.Sprintf("NewAttachment: %v", err))
- return
- }
-
- log.Trace("New attachment uploaded: %s", attach.UUID)
- c.JSON(200, map[string]string{
- "uuid": attach.UUID,
- })
-}
-
-func UploadIssueAttachment(c *context.Context) {
- if !setting.AttachmentEnabled {
- c.NotFound()
- return
- }
-
- uploadAttachment(c, strings.Split(setting.AttachmentAllowedTypes, ","))
-}
-
-func viewIssue(c *context.Context, isPullList bool) {
- c.Data["RequireHighlightJS"] = true
- c.Data["RequireDropzone"] = true
- renderAttachmentSettings(c)
-
- index := c.ParamsInt64(":index")
- if index <= 0 {
- c.NotFound()
- return
- }
-
- issue, err := models.GetIssueByIndex(c.Repo.Repository.ID, index)
- if err != nil {
- c.NotFoundOrServerError("GetIssueByIndex", errors.IsIssueNotExist, err)
- return
- }
- c.Data["Title"] = issue.Title
-
- // Make sure type and URL matches.
- if !isPullList && issue.IsPull {
- c.Redirect(c.Repo.RepoLink + "/pulls/" + com.ToStr(issue.Index))
- return
- } else if isPullList && !issue.IsPull {
- c.Redirect(c.Repo.RepoLink + "/issues/" + com.ToStr(issue.Index))
- return
- }
-
- if issue.IsPull {
- MustAllowPulls(c)
- if c.Written() {
- return
- }
- c.Data["PageIsPullList"] = true
- c.Data["PageIsPullConversation"] = true
- } else {
- MustEnableIssues(c)
- if c.Written() {
- return
- }
- c.Data["PageIsIssueList"] = true
- }
-
- issue.RenderedContent = string(markup.Markdown(issue.Content, c.Repo.RepoLink, c.Repo.Repository.ComposeMetas()))
-
- repo := c.Repo.Repository
-
- // Get more information if it's a pull request.
- if issue.IsPull {
- if issue.PullRequest.HasMerged {
- c.Data["DisableStatusChange"] = issue.PullRequest.HasMerged
- PrepareMergedViewPullInfo(c, issue)
- } else {
- PrepareViewPullInfo(c, issue)
- }
- if c.Written() {
- return
- }
- }
-
- // Metas.
- // Check labels.
- labelIDMark := make(map[int64]bool)
- for i := range issue.Labels {
- labelIDMark[issue.Labels[i].ID] = true
- }
- labels, err := models.GetLabelsByRepoID(repo.ID)
- if err != nil {
- c.Handle(500, "GetLabelsByRepoID", err)
- return
- }
- hasSelected := false
- for i := range labels {
- if labelIDMark[labels[i].ID] {
- labels[i].IsChecked = true
- hasSelected = true
- }
- }
- c.Data["HasSelectedLabel"] = hasSelected
- c.Data["Labels"] = labels
-
- // Check milestone and assignee.
- if c.Repo.IsWriter() {
- RetrieveRepoMilestonesAndAssignees(c, repo)
- if c.Written() {
- return
- }
- }
-
- if c.IsLogged {
- // Update issue-user.
- if err = issue.ReadBy(c.User.ID); err != nil {
- c.Handle(500, "ReadBy", err)
- return
- }
- }
-
- var (
- tag models.CommentTag
- ok bool
- marked = make(map[int64]models.CommentTag)
- comment *models.Comment
- participants = make([]*models.User, 1, 10)
- )
-
- // Render comments and and fetch participants.
- participants[0] = issue.Poster
- for _, comment = range issue.Comments {
- if comment.Type == models.COMMENT_TYPE_COMMENT {
- comment.RenderedContent = string(markup.Markdown(comment.Content, c.Repo.RepoLink, c.Repo.Repository.ComposeMetas()))
-
- // Check tag.
- tag, ok = marked[comment.PosterID]
- if ok {
- comment.ShowTag = tag
- continue
- }
-
- if repo.IsOwnedBy(comment.PosterID) ||
- (repo.Owner.IsOrganization() && repo.Owner.IsOwnedBy(comment.PosterID)) {
- comment.ShowTag = models.COMMENT_TAG_OWNER
- } else if comment.Poster.IsWriterOfRepo(repo) {
- comment.ShowTag = models.COMMENT_TAG_WRITER
- } else if comment.PosterID == issue.PosterID {
- comment.ShowTag = models.COMMENT_TAG_POSTER
- }
-
- marked[comment.PosterID] = comment.ShowTag
-
- isAdded := false
- for j := range participants {
- if comment.Poster == participants[j] {
- isAdded = true
- break
- }
- }
- if !isAdded && !issue.IsPoster(comment.Poster.ID) {
- participants = append(participants, comment.Poster)
- }
- }
- }
-
- if issue.IsPull && issue.PullRequest.HasMerged {
- pull := issue.PullRequest
- c.Data["IsPullBranchDeletable"] = pull.BaseRepoID == pull.HeadRepoID &&
- c.Repo.IsWriter() && c.Repo.GitRepo.IsBranchExist(pull.HeadBranch)
-
- deleteBranchUrl := c.Repo.RepoLink + "/branches/delete/" + pull.HeadBranch
- c.Data["DeleteBranchLink"] = fmt.Sprintf("%s?commit=%s&redirect_to=%s", deleteBranchUrl, pull.MergedCommitID, c.Data["Link"])
- }
-
- c.Data["Participants"] = participants
- c.Data["NumParticipants"] = len(participants)
- c.Data["Issue"] = issue
- c.Data["IsIssueOwner"] = c.Repo.IsWriter() || (c.IsLogged && issue.IsPoster(c.User.ID))
- c.Data["SignInLink"] = setting.AppSubURL + "/user/login?redirect_to=" + c.Data["Link"].(string)
- c.HTML(200, ISSUE_VIEW)
-}
-
-func ViewIssue(c *context.Context) {
- viewIssue(c, false)
-}
-
-func ViewPull(c *context.Context) {
- viewIssue(c, true)
-}
-
-func getActionIssue(c *context.Context) *models.Issue {
- issue, err := models.GetIssueByIndex(c.Repo.Repository.ID, c.ParamsInt64(":index"))
- if err != nil {
- c.NotFoundOrServerError("GetIssueByIndex", errors.IsIssueNotExist, err)
- return nil
- }
-
- // Prevent guests accessing pull requests
- if !c.Repo.HasAccess() && issue.IsPull {
- c.NotFound()
- return nil
- }
-
- return issue
-}
-
-func UpdateIssueTitle(c *context.Context) {
- issue := getActionIssue(c)
- if c.Written() {
- return
- }
-
- if !c.IsLogged || (!issue.IsPoster(c.User.ID) && !c.Repo.IsWriter()) {
- c.Error(403)
- return
- }
-
- title := c.QueryTrim("title")
- if len(title) == 0 {
- c.Error(204)
- return
- }
-
- if err := issue.ChangeTitle(c.User, title); err != nil {
- c.Handle(500, "ChangeTitle", err)
- return
- }
-
- c.JSON(200, map[string]interface{}{
- "title": issue.Title,
- })
-}
-
-func UpdateIssueContent(c *context.Context) {
- issue := getActionIssue(c)
- if c.Written() {
- return
- }
-
- if !c.IsLogged || (c.User.ID != issue.PosterID && !c.Repo.IsWriter()) {
- c.Error(403)
- return
- }
-
- content := c.Query("content")
- if err := issue.ChangeContent(c.User, content); err != nil {
- c.Handle(500, "ChangeContent", err)
- return
- }
-
- c.JSON(200, map[string]string{
- "content": string(markup.Markdown(issue.Content, c.Query("context"), c.Repo.Repository.ComposeMetas())),
- })
-}
-
-func UpdateIssueLabel(c *context.Context) {
- issue := getActionIssue(c)
- if c.Written() {
- return
- }
-
- if c.Query("action") == "clear" {
- if err := issue.ClearLabels(c.User); err != nil {
- c.Handle(500, "ClearLabels", err)
- return
- }
- } else {
- isAttach := c.Query("action") == "attach"
- label, err := models.GetLabelOfRepoByID(c.Repo.Repository.ID, c.QueryInt64("id"))
- if err != nil {
- if models.IsErrLabelNotExist(err) {
- c.Error(404, "GetLabelByID")
- } else {
- c.Handle(500, "GetLabelByID", err)
- }
- return
- }
-
- if isAttach && !issue.HasLabel(label.ID) {
- if err = issue.AddLabel(c.User, label); err != nil {
- c.Handle(500, "AddLabel", err)
- return
- }
- } else if !isAttach && issue.HasLabel(label.ID) {
- if err = issue.RemoveLabel(c.User, label); err != nil {
- c.Handle(500, "RemoveLabel", err)
- return
- }
- }
- }
-
- c.JSON(200, map[string]interface{}{
- "ok": true,
- })
-}
-
-func UpdateIssueMilestone(c *context.Context) {
- issue := getActionIssue(c)
- if c.Written() {
- return
- }
-
- oldMilestoneID := issue.MilestoneID
- milestoneID := c.QueryInt64("id")
- if oldMilestoneID == milestoneID {
- c.JSON(200, map[string]interface{}{
- "ok": true,
- })
- return
- }
-
- // Not check for invalid milestone id and give responsibility to owners.
- issue.MilestoneID = milestoneID
- if err := models.ChangeMilestoneAssign(c.User, issue, oldMilestoneID); err != nil {
- c.Handle(500, "ChangeMilestoneAssign", err)
- return
- }
-
- c.JSON(200, map[string]interface{}{
- "ok": true,
- })
-}
-
-func UpdateIssueAssignee(c *context.Context) {
- issue := getActionIssue(c)
- if c.Written() {
- return
- }
-
- assigneeID := c.QueryInt64("id")
- if issue.AssigneeID == assigneeID {
- c.JSON(200, map[string]interface{}{
- "ok": true,
- })
- return
- }
-
- if err := issue.ChangeAssignee(c.User, assigneeID); err != nil {
- c.Handle(500, "ChangeAssignee", err)
- return
- }
-
- c.JSON(200, map[string]interface{}{
- "ok": true,
- })
-}
-
-func NewComment(c *context.Context, f form.CreateComment) {
- issue := getActionIssue(c)
- if c.Written() {
- return
- }
-
- var attachments []string
- if setting.AttachmentEnabled {
- attachments = f.Files
- }
-
- if c.HasError() {
- c.Flash.Error(c.Data["ErrorMsg"].(string))
- c.Redirect(fmt.Sprintf("%s/issues/%d", c.Repo.RepoLink, issue.Index))
- return
- }
-
- var err error
- var comment *models.Comment
- defer func() {
- // Check if issue admin/poster changes the status of issue.
- if (c.Repo.IsWriter() || (c.IsLogged && issue.IsPoster(c.User.ID))) &&
- (f.Status == "reopen" || f.Status == "close") &&
- !(issue.IsPull && issue.PullRequest.HasMerged) {
-
- // Duplication and conflict check should apply to reopen pull request.
- var pr *models.PullRequest
-
- if f.Status == "reopen" && issue.IsPull {
- pull := issue.PullRequest
- pr, err = models.GetUnmergedPullRequest(pull.HeadRepoID, pull.BaseRepoID, pull.HeadBranch, pull.BaseBranch)
- if err != nil {
- if !models.IsErrPullRequestNotExist(err) {
- c.ServerError("GetUnmergedPullRequest", err)
- return
- }
- }
-
- // Regenerate patch and test conflict.
- if pr == nil {
- if err = issue.PullRequest.UpdatePatch(); err != nil {
- c.ServerError("UpdatePatch", err)
- return
- }
-
- issue.PullRequest.AddToTaskQueue()
- }
- }
-
- if pr != nil {
- c.Flash.Info(c.Tr("repo.pulls.open_unmerged_pull_exists", pr.Index))
- } else {
- if err = issue.ChangeStatus(c.User, c.Repo.Repository, f.Status == "close"); err != nil {
- log.Error(2, "ChangeStatus: %v", err)
- } else {
- log.Trace("Issue [%d] status changed to closed: %v", issue.ID, issue.IsClosed)
- }
- }
- }
-
- // Redirect to comment hashtag if there is any actual content.
- typeName := "issues"
- if issue.IsPull {
- typeName = "pulls"
- }
- if comment != nil {
- c.Redirect(fmt.Sprintf("%s/%s/%d#%s", c.Repo.RepoLink, typeName, issue.Index, comment.HashTag()))
- } else {
- c.Redirect(fmt.Sprintf("%s/%s/%d", c.Repo.RepoLink, typeName, issue.Index))
- }
- }()
-
- // Fix #321: Allow empty comments, as long as we have attachments.
- if len(f.Content) == 0 && len(attachments) == 0 {
- return
- }
-
- comment, err = models.CreateIssueComment(c.User, c.Repo.Repository, issue, f.Content, attachments)
- if err != nil {
- c.ServerError("CreateIssueComment", err)
- return
- }
-
- log.Trace("Comment created: %d/%d/%d", c.Repo.Repository.ID, issue.ID, comment.ID)
-}
-
-func UpdateCommentContent(c *context.Context) {
- comment, err := models.GetCommentByID(c.ParamsInt64(":id"))
- if err != nil {
- c.NotFoundOrServerError("GetCommentByID", models.IsErrCommentNotExist, err)
- return
- }
-
- if c.UserID() != comment.PosterID && !c.Repo.IsAdmin() {
- c.Error(404)
- return
- } else if comment.Type != models.COMMENT_TYPE_COMMENT {
- c.Error(204)
- return
- }
-
- oldContent := comment.Content
- comment.Content = c.Query("content")
- if len(comment.Content) == 0 {
- c.JSON(200, map[string]interface{}{
- "content": "",
- })
- return
- }
- if err = models.UpdateComment(c.User, comment, oldContent); err != nil {
- c.Handle(500, "UpdateComment", err)
- return
- }
-
- c.JSON(200, map[string]string{
- "content": string(markup.Markdown(comment.Content, c.Query("context"), c.Repo.Repository.ComposeMetas())),
- })
-}
-
-func DeleteComment(c *context.Context) {
- comment, err := models.GetCommentByID(c.ParamsInt64(":id"))
- if err != nil {
- c.NotFoundOrServerError("GetCommentByID", models.IsErrCommentNotExist, err)
- return
- }
-
- if c.UserID() != comment.PosterID && !c.Repo.IsAdmin() {
- c.Error(404)
- return
- } else if comment.Type != models.COMMENT_TYPE_COMMENT {
- c.Error(204)
- return
- }
-
- if err = models.DeleteCommentByID(c.User, comment.ID); err != nil {
- c.Handle(500, "DeleteCommentByID", err)
- return
- }
-
- c.Status(200)
-}
-
-func Labels(c *context.Context) {
- c.Data["Title"] = c.Tr("repo.labels")
- c.Data["PageIsIssueList"] = true
- c.Data["PageIsLabels"] = true
- c.Data["RequireMinicolors"] = true
- c.Data["LabelTemplates"] = models.LabelTemplates
- c.HTML(200, LABELS)
-}
-
-func InitializeLabels(c *context.Context, f form.InitializeLabels) {
- if c.HasError() {
- c.Redirect(c.Repo.RepoLink + "/labels")
- return
- }
- list, err := models.GetLabelTemplateFile(f.TemplateName)
- if err != nil {
- c.Flash.Error(c.Tr("repo.issues.label_templates.fail_to_load_file", f.TemplateName, err))
- c.Redirect(c.Repo.RepoLink + "/labels")
- return
- }
-
- labels := make([]*models.Label, len(list))
- for i := 0; i < len(list); i++ {
- labels[i] = &models.Label{
- RepoID: c.Repo.Repository.ID,
- Name: list[i][0],
- Color: list[i][1],
- }
- }
- if err := models.NewLabels(labels...); err != nil {
- c.Handle(500, "NewLabels", err)
- return
- }
- c.Redirect(c.Repo.RepoLink + "/labels")
-}
-
-func NewLabel(c *context.Context, f form.CreateLabel) {
- c.Data["Title"] = c.Tr("repo.labels")
- c.Data["PageIsLabels"] = true
-
- if c.HasError() {
- c.Flash.Error(c.Data["ErrorMsg"].(string))
- c.Redirect(c.Repo.RepoLink + "/labels")
- return
- }
-
- l := &models.Label{
- RepoID: c.Repo.Repository.ID,
- Name: f.Title,
- Color: f.Color,
- }
- if err := models.NewLabels(l); err != nil {
- c.Handle(500, "NewLabel", err)
- return
- }
- c.Redirect(c.Repo.RepoLink + "/labels")
-}
-
-func UpdateLabel(c *context.Context, f form.CreateLabel) {
- l, err := models.GetLabelByID(f.ID)
- if err != nil {
- switch {
- case models.IsErrLabelNotExist(err):
- c.Error(404)
- default:
- c.Handle(500, "UpdateLabel", err)
- }
- return
- }
-
- l.Name = f.Title
- l.Color = f.Color
- if err := models.UpdateLabel(l); err != nil {
- c.Handle(500, "UpdateLabel", err)
- return
- }
- c.Redirect(c.Repo.RepoLink + "/labels")
-}
-
-func DeleteLabel(c *context.Context) {
- if err := models.DeleteLabel(c.Repo.Repository.ID, c.QueryInt64("id")); err != nil {
- c.Flash.Error("DeleteLabel: " + err.Error())
- } else {
- c.Flash.Success(c.Tr("repo.issues.label_deletion_success"))
- }
-
- c.JSON(200, map[string]interface{}{
- "redirect": c.Repo.RepoLink + "/labels",
- })
- return
-}
-
-func Milestones(c *context.Context) {
- c.Data["Title"] = c.Tr("repo.milestones")
- c.Data["PageIsIssueList"] = true
- c.Data["PageIsMilestones"] = true
-
- isShowClosed := c.Query("state") == "closed"
- openCount, closedCount := models.MilestoneStats(c.Repo.Repository.ID)
- c.Data["OpenCount"] = openCount
- c.Data["ClosedCount"] = closedCount
-
- page := c.QueryInt("page")
- if page <= 1 {
- page = 1
- }
-
- var total int
- if !isShowClosed {
- total = int(openCount)
- } else {
- total = int(closedCount)
- }
- c.Data["Page"] = paginater.New(total, setting.UI.IssuePagingNum, page, 5)
-
- miles, err := models.GetMilestones(c.Repo.Repository.ID, page, isShowClosed)
- if err != nil {
- c.Handle(500, "GetMilestones", err)
- return
- }
- for _, m := range miles {
- m.NumOpenIssues = int(m.CountIssues(false, false))
- m.NumClosedIssues = int(m.CountIssues(true, false))
- if m.NumOpenIssues+m.NumClosedIssues > 0 {
- m.Completeness = m.NumClosedIssues * 100 / (m.NumOpenIssues + m.NumClosedIssues)
- }
- m.RenderedContent = string(markup.Markdown(m.Content, c.Repo.RepoLink, c.Repo.Repository.ComposeMetas()))
- }
- c.Data["Milestones"] = miles
-
- if isShowClosed {
- c.Data["State"] = "closed"
- } else {
- c.Data["State"] = "open"
- }
-
- c.Data["IsShowClosed"] = isShowClosed
- c.HTML(200, MILESTONE)
-}
-
-func NewMilestone(c *context.Context) {
- c.Data["Title"] = c.Tr("repo.milestones.new")
- c.Data["PageIsIssueList"] = true
- c.Data["PageIsMilestones"] = true
- c.Data["RequireDatetimepicker"] = true
- c.Data["DateLang"] = setting.DateLang(c.Locale.Language())
- c.HTML(200, MILESTONE_NEW)
-}
-
-func NewMilestonePost(c *context.Context, f form.CreateMilestone) {
- c.Data["Title"] = c.Tr("repo.milestones.new")
- c.Data["PageIsIssueList"] = true
- c.Data["PageIsMilestones"] = true
- c.Data["RequireDatetimepicker"] = true
- c.Data["DateLang"] = setting.DateLang(c.Locale.Language())
-
- if c.HasError() {
- c.HTML(200, MILESTONE_NEW)
- return
- }
-
- if len(f.Deadline) == 0 {
- f.Deadline = "9999-12-31"
- }
- deadline, err := time.ParseInLocation("2006-01-02", f.Deadline, time.Local)
- if err != nil {
- c.Data["Err_Deadline"] = true
- c.RenderWithErr(c.Tr("repo.milestones.invalid_due_date_format"), MILESTONE_NEW, &f)
- return
- }
-
- if err = models.NewMilestone(&models.Milestone{
- RepoID: c.Repo.Repository.ID,
- Name: f.Title,
- Content: f.Content,
- Deadline: deadline,
- }); err != nil {
- c.Handle(500, "NewMilestone", err)
- return
- }
-
- c.Flash.Success(c.Tr("repo.milestones.create_success", f.Title))
- c.Redirect(c.Repo.RepoLink + "/milestones")
-}
-
-func EditMilestone(c *context.Context) {
- c.Data["Title"] = c.Tr("repo.milestones.edit")
- c.Data["PageIsMilestones"] = true
- c.Data["PageIsEditMilestone"] = true
- c.Data["RequireDatetimepicker"] = true
- c.Data["DateLang"] = setting.DateLang(c.Locale.Language())
-
- m, err := models.GetMilestoneByRepoID(c.Repo.Repository.ID, c.ParamsInt64(":id"))
- if err != nil {
- if models.IsErrMilestoneNotExist(err) {
- c.Handle(404, "", nil)
- } else {
- c.Handle(500, "GetMilestoneByRepoID", err)
- }
- return
- }
- c.Data["title"] = m.Name
- c.Data["content"] = m.Content
- if len(m.DeadlineString) > 0 {
- c.Data["deadline"] = m.DeadlineString
- }
- c.HTML(200, MILESTONE_NEW)
-}
-
-func EditMilestonePost(c *context.Context, f form.CreateMilestone) {
- c.Data["Title"] = c.Tr("repo.milestones.edit")
- c.Data["PageIsMilestones"] = true
- c.Data["PageIsEditMilestone"] = true
- c.Data["RequireDatetimepicker"] = true
- c.Data["DateLang"] = setting.DateLang(c.Locale.Language())
-
- if c.HasError() {
- c.HTML(200, MILESTONE_NEW)
- return
- }
-
- if len(f.Deadline) == 0 {
- f.Deadline = "9999-12-31"
- }
- deadline, err := time.ParseInLocation("2006-01-02", f.Deadline, time.Local)
- if err != nil {
- c.Data["Err_Deadline"] = true
- c.RenderWithErr(c.Tr("repo.milestones.invalid_due_date_format"), MILESTONE_NEW, &f)
- return
- }
-
- m, err := models.GetMilestoneByRepoID(c.Repo.Repository.ID, c.ParamsInt64(":id"))
- if err != nil {
- if models.IsErrMilestoneNotExist(err) {
- c.Handle(404, "", nil)
- } else {
- c.Handle(500, "GetMilestoneByRepoID", err)
- }
- return
- }
- m.Name = f.Title
- m.Content = f.Content
- m.Deadline = deadline
- if err = models.UpdateMilestone(m); err != nil {
- c.Handle(500, "UpdateMilestone", err)
- return
- }
-
- c.Flash.Success(c.Tr("repo.milestones.edit_success", m.Name))
- c.Redirect(c.Repo.RepoLink + "/milestones")
-}
-
-func ChangeMilestonStatus(c *context.Context) {
- m, err := models.GetMilestoneByRepoID(c.Repo.Repository.ID, c.ParamsInt64(":id"))
- if err != nil {
- if models.IsErrMilestoneNotExist(err) {
- c.Handle(404, "", err)
- } else {
- c.Handle(500, "GetMilestoneByRepoID", err)
- }
- return
- }
-
- switch c.Params(":action") {
- case "open":
- if m.IsClosed {
- if err = models.ChangeMilestoneStatus(m, false); err != nil {
- c.Handle(500, "ChangeMilestoneStatus", err)
- return
- }
- }
- c.Redirect(c.Repo.RepoLink + "/milestones?state=open")
- case "close":
- if !m.IsClosed {
- m.ClosedDate = time.Now()
- if err = models.ChangeMilestoneStatus(m, true); err != nil {
- c.Handle(500, "ChangeMilestoneStatus", err)
- return
- }
- }
- c.Redirect(c.Repo.RepoLink + "/milestones?state=closed")
- default:
- c.Redirect(c.Repo.RepoLink + "/milestones")
- }
-}
-
-func DeleteMilestone(c *context.Context) {
- if err := models.DeleteMilestoneOfRepoByID(c.Repo.Repository.ID, c.QueryInt64("id")); err != nil {
- c.Flash.Error("DeleteMilestoneByRepoID: " + err.Error())
- } else {
- c.Flash.Success(c.Tr("repo.milestones.deletion_success"))
- }
-
- c.JSON(200, map[string]interface{}{
- "redirect": c.Repo.RepoLink + "/milestones",
- })
-}
diff --git a/routers/repo/pull.go b/routers/repo/pull.go
deleted file mode 100644
index 73757280..00000000
--- a/routers/repo/pull.go
+++ /dev/null
@@ -1,763 +0,0 @@
-// 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 repo
-
-import (
- "container/list"
- "path"
- "strings"
-
- "github.com/Unknwon/com"
- log "gopkg.in/clog.v1"
-
- "github.com/gogits/git-module"
-
- "github.com/gogits/gogs/models"
- "github.com/gogits/gogs/models/errors"
- "github.com/gogits/gogs/pkg/context"
- "github.com/gogits/gogs/pkg/form"
- "github.com/gogits/gogs/pkg/setting"
- "github.com/gogits/gogs/pkg/tool"
-)
-
-const (
- FORK = "repo/pulls/fork"
- COMPARE_PULL = "repo/pulls/compare"
- PULL_COMMITS = "repo/pulls/commits"
- PULL_FILES = "repo/pulls/files"
-
- PULL_REQUEST_TEMPLATE_KEY = "PullRequestTemplate"
-)
-
-var (
- PullRequestTemplateCandidates = []string{
- "PULL_REQUEST.md",
- ".gogs/PULL_REQUEST.md",
- ".github/PULL_REQUEST.md",
- }
-)
-
-func parseBaseRepository(c *context.Context) *models.Repository {
- baseRepo, err := models.GetRepositoryByID(c.ParamsInt64(":repoid"))
- if err != nil {
- c.NotFoundOrServerError("GetRepositoryByID", errors.IsRepoNotExist, err)
- return nil
- }
-
- if !baseRepo.CanBeForked() || !baseRepo.HasAccess(c.User.ID) {
- c.NotFound()
- return nil
- }
-
- c.Data["repo_name"] = baseRepo.Name
- c.Data["description"] = baseRepo.Description
- c.Data["IsPrivate"] = baseRepo.IsPrivate
-
- if err = baseRepo.GetOwner(); err != nil {
- c.ServerError("GetOwner", err)
- return nil
- }
- c.Data["ForkFrom"] = baseRepo.Owner.Name + "/" + baseRepo.Name
-
- if err := c.User.GetOrganizations(true); err != nil {
- c.ServerError("GetOrganizations", err)
- return nil
- }
- c.Data["Orgs"] = c.User.Orgs
-
- return baseRepo
-}
-
-func Fork(c *context.Context) {
- c.Data["Title"] = c.Tr("new_fork")
-
- parseBaseRepository(c)
- if c.Written() {
- return
- }
-
- c.Data["ContextUser"] = c.User
- c.Success(FORK)
-}
-
-func ForkPost(c *context.Context, f form.CreateRepo) {
- c.Data["Title"] = c.Tr("new_fork")
-
- baseRepo := parseBaseRepository(c)
- if c.Written() {
- return
- }
-
- ctxUser := checkContextUser(c, f.UserID)
- if c.Written() {
- return
- }
- c.Data["ContextUser"] = ctxUser
-
- if c.HasError() {
- c.Success(FORK)
- return
- }
-
- repo, has := models.HasForkedRepo(ctxUser.ID, baseRepo.ID)
- if has {
- c.Redirect(repo.Link())
- return
- }
-
- // Check ownership of organization.
- if ctxUser.IsOrganization() && !ctxUser.IsOwnedBy(c.User.ID) {
- c.Error(403)
- return
- }
-
- // Cannot fork to same owner
- if ctxUser.ID == baseRepo.OwnerID {
- c.RenderWithErr(c.Tr("repo.settings.cannot_fork_to_same_owner"), FORK, &f)
- return
- }
-
- repo, err := models.ForkRepository(c.User, ctxUser, baseRepo, f.RepoName, f.Description)
- if err != nil {
- c.Data["Err_RepoName"] = true
- switch {
- case models.IsErrRepoAlreadyExist(err):
- c.RenderWithErr(c.Tr("repo.settings.new_owner_has_same_repo"), FORK, &f)
- case models.IsErrNameReserved(err):
- c.RenderWithErr(c.Tr("repo.form.name_reserved", err.(models.ErrNameReserved).Name), FORK, &f)
- case models.IsErrNamePatternNotAllowed(err):
- c.RenderWithErr(c.Tr("repo.form.name_pattern_not_allowed", err.(models.ErrNamePatternNotAllowed).Pattern), FORK, &f)
- default:
- c.ServerError("ForkPost", err)
- }
- return
- }
-
- log.Trace("Repository forked from '%s' -> '%s'", baseRepo.FullName(), repo.FullName())
- c.Redirect(repo.Link())
-}
-
-func checkPullInfo(c *context.Context) *models.Issue {
- issue, err := models.GetIssueByIndex(c.Repo.Repository.ID, c.ParamsInt64(":index"))
- if err != nil {
- c.NotFoundOrServerError("GetIssueByIndex", errors.IsIssueNotExist, err)
- return nil
- }
- c.Data["Title"] = issue.Title
- c.Data["Issue"] = issue
-
- if !issue.IsPull {
- c.Handle(404, "ViewPullCommits", nil)
- return nil
- }
-
- if c.IsLogged {
- // Update issue-user.
- if err = issue.ReadBy(c.User.ID); err != nil {
- c.ServerError("ReadBy", err)
- return nil
- }
- }
-
- return issue
-}
-
-func PrepareMergedViewPullInfo(c *context.Context, issue *models.Issue) {
- pull := issue.PullRequest
- c.Data["HasMerged"] = true
- c.Data["HeadTarget"] = issue.PullRequest.HeadUserName + "/" + pull.HeadBranch
- c.Data["BaseTarget"] = c.Repo.Owner.Name + "/" + pull.BaseBranch
-
- var err error
- c.Data["NumCommits"], err = c.Repo.GitRepo.CommitsCountBetween(pull.MergeBase, pull.MergedCommitID)
- if err != nil {
- c.ServerError("Repo.GitRepo.CommitsCountBetween", err)
- return
- }
- c.Data["NumFiles"], err = c.Repo.GitRepo.FilesCountBetween(pull.MergeBase, pull.MergedCommitID)
- if err != nil {
- c.ServerError("Repo.GitRepo.FilesCountBetween", err)
- return
- }
-}
-
-func PrepareViewPullInfo(c *context.Context, issue *models.Issue) *git.PullRequestInfo {
- repo := c.Repo.Repository
- pull := issue.PullRequest
-
- c.Data["HeadTarget"] = pull.HeadUserName + "/" + pull.HeadBranch
- c.Data["BaseTarget"] = c.Repo.Owner.Name + "/" + pull.BaseBranch
-
- var (
- headGitRepo *git.Repository
- err error
- )
-
- if pull.HeadRepo != nil {
- headGitRepo, err = git.OpenRepository(pull.HeadRepo.RepoPath())
- if err != nil {
- c.ServerError("OpenRepository", err)
- return nil
- }
- }
-
- if pull.HeadRepo == nil || !headGitRepo.IsBranchExist(pull.HeadBranch) {
- c.Data["IsPullReuqestBroken"] = true
- c.Data["HeadTarget"] = "deleted"
- c.Data["NumCommits"] = 0
- c.Data["NumFiles"] = 0
- return nil
- }
-
- prInfo, err := headGitRepo.GetPullRequestInfo(models.RepoPath(repo.Owner.Name, repo.Name),
- pull.BaseBranch, pull.HeadBranch)
- if err != nil {
- if strings.Contains(err.Error(), "fatal: Not a valid object name") {
- c.Data["IsPullReuqestBroken"] = true
- c.Data["BaseTarget"] = "deleted"
- c.Data["NumCommits"] = 0
- c.Data["NumFiles"] = 0
- return nil
- }
-
- c.ServerError("GetPullRequestInfo", err)
- return nil
- }
- c.Data["NumCommits"] = prInfo.Commits.Len()
- c.Data["NumFiles"] = prInfo.NumFiles
- return prInfo
-}
-
-func ViewPullCommits(c *context.Context) {
- c.Data["PageIsPullList"] = true
- c.Data["PageIsPullCommits"] = true
-
- issue := checkPullInfo(c)
- if c.Written() {
- return
- }
- pull := issue.PullRequest
-
- if pull.HeadRepo != nil {
- c.Data["Username"] = pull.HeadUserName
- c.Data["Reponame"] = pull.HeadRepo.Name
- }
-
- var commits *list.List
- if pull.HasMerged {
- PrepareMergedViewPullInfo(c, issue)
- if c.Written() {
- return
- }
- startCommit, err := c.Repo.GitRepo.GetCommit(pull.MergeBase)
- if err != nil {
- c.ServerError("Repo.GitRepo.GetCommit", err)
- return
- }
- endCommit, err := c.Repo.GitRepo.GetCommit(pull.MergedCommitID)
- if err != nil {
- c.ServerError("Repo.GitRepo.GetCommit", err)
- return
- }
- commits, err = c.Repo.GitRepo.CommitsBetween(endCommit, startCommit)
- if err != nil {
- c.ServerError("Repo.GitRepo.CommitsBetween", err)
- return
- }
-
- } else {
- prInfo := PrepareViewPullInfo(c, issue)
- if c.Written() {
- return
- } else if prInfo == nil {
- c.Handle(404, "ViewPullCommits", nil)
- return
- }
- commits = prInfo.Commits
- }
-
- commits = models.ValidateCommitsWithEmails(commits)
- c.Data["Commits"] = commits
- c.Data["CommitsCount"] = commits.Len()
-
- c.Success(PULL_COMMITS)
-}
-
-func ViewPullFiles(c *context.Context) {
- c.Data["PageIsPullList"] = true
- c.Data["PageIsPullFiles"] = true
-
- issue := checkPullInfo(c)
- if c.Written() {
- return
- }
- pull := issue.PullRequest
-
- var (
- diffRepoPath string
- startCommitID string
- endCommitID string
- gitRepo *git.Repository
- )
-
- if pull.HasMerged {
- PrepareMergedViewPullInfo(c, issue)
- if c.Written() {
- return
- }
-
- diffRepoPath = c.Repo.GitRepo.Path
- startCommitID = pull.MergeBase
- endCommitID = pull.MergedCommitID
- gitRepo = c.Repo.GitRepo
- } else {
- prInfo := PrepareViewPullInfo(c, issue)
- if c.Written() {
- return
- } else if prInfo == nil {
- c.Handle(404, "ViewPullFiles", nil)
- return
- }
-
- headRepoPath := models.RepoPath(pull.HeadUserName, pull.HeadRepo.Name)
-
- headGitRepo, err := git.OpenRepository(headRepoPath)
- if err != nil {
- c.ServerError("OpenRepository", err)
- return
- }
-
- headCommitID, err := headGitRepo.GetBranchCommitID(pull.HeadBranch)
- if err != nil {
- c.ServerError("GetBranchCommitID", err)
- return
- }
-
- diffRepoPath = headRepoPath
- startCommitID = prInfo.MergeBase
- endCommitID = headCommitID
- gitRepo = headGitRepo
- }
-
- diff, err := models.GetDiffRange(diffRepoPath,
- startCommitID, endCommitID, setting.Git.MaxGitDiffLines,
- setting.Git.MaxGitDiffLineCharacters, setting.Git.MaxGitDiffFiles)
- if err != nil {
- c.ServerError("GetDiffRange", err)
- return
- }
- c.Data["Diff"] = diff
- c.Data["DiffNotAvailable"] = diff.NumFiles() == 0
-
- commit, err := gitRepo.GetCommit(endCommitID)
- if err != nil {
- c.ServerError("GetCommit", err)
- return
- }
-
- setEditorconfigIfExists(c)
- if c.Written() {
- return
- }
-
- c.Data["IsSplitStyle"] = c.Query("style") == "split"
- c.Data["IsImageFile"] = commit.IsImageFile
-
- // It is possible head repo has been deleted for merged pull requests
- if pull.HeadRepo != nil {
- c.Data["Username"] = pull.HeadUserName
- c.Data["Reponame"] = pull.HeadRepo.Name
-
- headTarget := path.Join(pull.HeadUserName, pull.HeadRepo.Name)
- c.Data["SourcePath"] = setting.AppSubURL + "/" + path.Join(headTarget, "src", endCommitID)
- c.Data["BeforeSourcePath"] = setting.AppSubURL + "/" + path.Join(headTarget, "src", startCommitID)
- c.Data["RawPath"] = setting.AppSubURL + "/" + path.Join(headTarget, "raw", endCommitID)
- }
-
- c.Data["RequireHighlightJS"] = true
- c.Success(PULL_FILES)
-}
-
-func MergePullRequest(c *context.Context) {
- issue := checkPullInfo(c)
- if c.Written() {
- return
- }
- if issue.IsClosed {
- c.Handle(404, "MergePullRequest", nil)
- return
- }
-
- pr, err := models.GetPullRequestByIssueID(issue.ID)
- if err != nil {
- c.NotFoundOrServerError("GetPullRequestByIssueID", models.IsErrPullRequestNotExist, err)
- return
- }
-
- if !pr.CanAutoMerge() || pr.HasMerged {
- c.Handle(404, "MergePullRequest", nil)
- return
- }
-
- pr.Issue = issue
- pr.Issue.Repo = c.Repo.Repository
- if err = pr.Merge(c.User, c.Repo.GitRepo); err != nil {
- c.ServerError("Merge", err)
- return
- }
-
- log.Trace("Pull request merged: %d", pr.ID)
- c.Redirect(c.Repo.RepoLink + "/pulls/" + com.ToStr(pr.Index))
-}
-
-func ParseCompareInfo(c *context.Context) (*models.User, *models.Repository, *git.Repository, *git.PullRequestInfo, string, string) {
- baseRepo := c.Repo.Repository
-
- // Get compared branches information
- // format: <base branch>...[<head repo>:]<head branch>
- // base<-head: master...head:feature
- // same repo: master...feature
- infos := strings.Split(c.Params("*"), "...")
- if len(infos) != 2 {
- log.Trace("ParseCompareInfo[%d]: not enough compared branches information %s", baseRepo.ID, infos)
- c.NotFound()
- return nil, nil, nil, nil, "", ""
- }
-
- baseBranch := infos[0]
- c.Data["BaseBranch"] = baseBranch
-
- var (
- headUser *models.User
- headBranch string
- isSameRepo bool
- err error
- )
-
- // If there is no head repository, it means pull request between same repository.
- headInfos := strings.Split(infos[1], ":")
- if len(headInfos) == 1 {
- isSameRepo = true
- headUser = c.Repo.Owner
- headBranch = headInfos[0]
-
- } else if len(headInfos) == 2 {
- headUser, err = models.GetUserByName(headInfos[0])
- if err != nil {
- c.NotFoundOrServerError("GetUserByName", errors.IsUserNotExist, err)
- return nil, nil, nil, nil, "", ""
- }
- headBranch = headInfos[1]
- isSameRepo = headUser.ID == baseRepo.OwnerID
-
- } else {
- c.NotFound()
- return nil, nil, nil, nil, "", ""
- }
- c.Data["HeadUser"] = headUser
- c.Data["HeadBranch"] = headBranch
- c.Repo.PullRequest.SameRepo = isSameRepo
-
- // Check if base branch is valid.
- if !c.Repo.GitRepo.IsBranchExist(baseBranch) {
- c.NotFound()
- return nil, nil, nil, nil, "", ""
- }
-
- var (
- headRepo *models.Repository
- headGitRepo *git.Repository
- )
-
- // In case user included redundant head user name for comparison in same repository,
- // no need to check the fork relation.
- if !isSameRepo {
- var has bool
- headRepo, has = models.HasForkedRepo(headUser.ID, baseRepo.ID)
- if !has {
- log.Trace("ParseCompareInfo [base_repo_id: %d]: does not have fork or in same repository", baseRepo.ID)
- c.NotFound()
- return nil, nil, nil, nil, "", ""
- }
-
- headGitRepo, err = git.OpenRepository(models.RepoPath(headUser.Name, headRepo.Name))
- if err != nil {
- c.ServerError("OpenRepository", err)
- return nil, nil, nil, nil, "", ""
- }
- } else {
- headRepo = c.Repo.Repository
- headGitRepo = c.Repo.GitRepo
- }
-
- if !c.User.IsWriterOfRepo(headRepo) && !c.User.IsAdmin {
- log.Trace("ParseCompareInfo [base_repo_id: %d]: does not have write access or site admin", baseRepo.ID)
- c.NotFound()
- return nil, nil, nil, nil, "", ""
- }
-
- // Check if head branch is valid.
- if !headGitRepo.IsBranchExist(headBranch) {
- c.NotFound()
- return nil, nil, nil, nil, "", ""
- }
-
- headBranches, err := headGitRepo.GetBranches()
- if err != nil {
- c.ServerError("GetBranches", err)
- return nil, nil, nil, nil, "", ""
- }
- c.Data["HeadBranches"] = headBranches
-
- prInfo, err := headGitRepo.GetPullRequestInfo(models.RepoPath(baseRepo.Owner.Name, baseRepo.Name), baseBranch, headBranch)
- if err != nil {
- if git.IsErrNoMergeBase(err) {
- c.Data["IsNoMergeBase"] = true
- c.Success(COMPARE_PULL)
- } else {
- c.ServerError("GetPullRequestInfo", err)
- }
- return nil, nil, nil, nil, "", ""
- }
- c.Data["BeforeCommitID"] = prInfo.MergeBase
-
- return headUser, headRepo, headGitRepo, prInfo, baseBranch, headBranch
-}
-
-func PrepareCompareDiff(
- c *context.Context,
- headUser *models.User,
- headRepo *models.Repository,
- headGitRepo *git.Repository,
- prInfo *git.PullRequestInfo,
- baseBranch, headBranch string) bool {
-
- var (
- repo = c.Repo.Repository
- err error
- )
-
- // Get diff information.
- c.Data["CommitRepoLink"] = headRepo.Link()
-
- headCommitID, err := headGitRepo.GetBranchCommitID(headBranch)
- if err != nil {
- c.ServerError("GetBranchCommitID", err)
- return false
- }
- c.Data["AfterCommitID"] = headCommitID
-
- if headCommitID == prInfo.MergeBase {
- c.Data["IsNothingToCompare"] = true
- return true
- }
-
- diff, err := models.GetDiffRange(models.RepoPath(headUser.Name, headRepo.Name),
- prInfo.MergeBase, headCommitID, setting.Git.MaxGitDiffLines,
- setting.Git.MaxGitDiffLineCharacters, setting.Git.MaxGitDiffFiles)
- if err != nil {
- c.ServerError("GetDiffRange", err)
- return false
- }
- c.Data["Diff"] = diff
- c.Data["DiffNotAvailable"] = diff.NumFiles() == 0
-
- headCommit, err := headGitRepo.GetCommit(headCommitID)
- if err != nil {
- c.ServerError("GetCommit", err)
- return false
- }
-
- prInfo.Commits = models.ValidateCommitsWithEmails(prInfo.Commits)
- c.Data["Commits"] = prInfo.Commits
- c.Data["CommitCount"] = prInfo.Commits.Len()
- c.Data["Username"] = headUser.Name
- c.Data["Reponame"] = headRepo.Name
- c.Data["IsImageFile"] = headCommit.IsImageFile
-
- headTarget := path.Join(headUser.Name, repo.Name)
- c.Data["SourcePath"] = setting.AppSubURL + "/" + path.Join(headTarget, "src", headCommitID)
- c.Data["BeforeSourcePath"] = setting.AppSubURL + "/" + path.Join(headTarget, "src", prInfo.MergeBase)
- c.Data["RawPath"] = setting.AppSubURL + "/" + path.Join(headTarget, "raw", headCommitID)
- return false
-}
-
-func CompareAndPullRequest(c *context.Context) {
- c.Data["Title"] = c.Tr("repo.pulls.compare_changes")
- c.Data["PageIsComparePull"] = true
- c.Data["IsDiffCompare"] = true
- c.Data["RequireHighlightJS"] = true
- setTemplateIfExists(c, PULL_REQUEST_TEMPLATE_KEY, PullRequestTemplateCandidates)
- renderAttachmentSettings(c)
-
- headUser, headRepo, headGitRepo, prInfo, baseBranch, headBranch := ParseCompareInfo(c)
- if c.Written() {
- return
- }
-
- pr, err := models.GetUnmergedPullRequest(headRepo.ID, c.Repo.Repository.ID, headBranch, baseBranch)
- if err != nil {
- if !models.IsErrPullRequestNotExist(err) {
- c.ServerError("GetUnmergedPullRequest", err)
- return
- }
- } else {
- c.Data["HasPullRequest"] = true
- c.Data["PullRequest"] = pr
- c.Success(COMPARE_PULL)
- return
- }
-
- nothingToCompare := PrepareCompareDiff(c, headUser, headRepo, headGitRepo, prInfo, baseBranch, headBranch)
- if c.Written() {
- return
- }
-
- if !nothingToCompare {
- // Setup information for new form.
- RetrieveRepoMetas(c, c.Repo.Repository)
- if c.Written() {
- return
- }
- }
-
- setEditorconfigIfExists(c)
- if c.Written() {
- return
- }
-
- c.Data["IsSplitStyle"] = c.Query("style") == "split"
- c.Success(COMPARE_PULL)
-}
-
-func CompareAndPullRequestPost(c *context.Context, f form.NewIssue) {
- c.Data["Title"] = c.Tr("repo.pulls.compare_changes")
- c.Data["PageIsComparePull"] = true
- c.Data["IsDiffCompare"] = true
- c.Data["RequireHighlightJS"] = true
- renderAttachmentSettings(c)
-
- var (
- repo = c.Repo.Repository
- attachments []string
- )
-
- headUser, headRepo, headGitRepo, prInfo, baseBranch, headBranch := ParseCompareInfo(c)
- if c.Written() {
- return
- }
-
- labelIDs, milestoneID, assigneeID := ValidateRepoMetas(c, f)
- if c.Written() {
- return
- }
-
- if setting.AttachmentEnabled {
- attachments = f.Files
- }
-
- if c.HasError() {
- form.Assign(f, c.Data)
-
- // This stage is already stop creating new pull request, so it does not matter if it has
- // something to compare or not.
- PrepareCompareDiff(c, headUser, headRepo, headGitRepo, prInfo, baseBranch, headBranch)
- if c.Written() {
- return
- }
-
- c.Success(COMPARE_PULL)
- return
- }
-
- patch, err := headGitRepo.GetPatch(prInfo.MergeBase, headBranch)
- if err != nil {
- c.ServerError("GetPatch", err)
- return
- }
-
- pullIssue := &models.Issue{
- RepoID: repo.ID,
- Index: repo.NextIssueIndex(),
- Title: f.Title,
- PosterID: c.User.ID,
- Poster: c.User,
- MilestoneID: milestoneID,
- AssigneeID: assigneeID,
- IsPull: true,
- Content: f.Content,
- }
- pullRequest := &models.PullRequest{
- HeadRepoID: headRepo.ID,
- BaseRepoID: repo.ID,
- HeadUserName: headUser.Name,
- HeadBranch: headBranch,
- BaseBranch: baseBranch,
- HeadRepo: headRepo,
- BaseRepo: repo,
- MergeBase: prInfo.MergeBase,
- Type: models.PULL_REQUEST_GOGS,
- }
- // FIXME: check error in the case two people send pull request at almost same time, give nice error prompt
- // instead of 500.
- if err := models.NewPullRequest(repo, pullIssue, labelIDs, attachments, pullRequest, patch); err != nil {
- c.ServerError("NewPullRequest", err)
- return
- } else if err := pullRequest.PushToBaseRepo(); err != nil {
- c.ServerError("PushToBaseRepo", err)
- return
- }
-
- log.Trace("Pull request created: %d/%d", repo.ID, pullIssue.ID)
- c.Redirect(c.Repo.RepoLink + "/pulls/" + com.ToStr(pullIssue.Index))
-}
-
-func parseOwnerAndRepo(c *context.Context) (*models.User, *models.Repository) {
- owner, err := models.GetUserByName(c.Params(":username"))
- if err != nil {
- c.NotFoundOrServerError("GetUserByName", errors.IsUserNotExist, err)
- return nil, nil
- }
-
- repo, err := models.GetRepositoryByName(owner.ID, c.Params(":reponame"))
- if err != nil {
- c.NotFoundOrServerError("GetRepositoryByName", errors.IsRepoNotExist, err)
- return nil, nil
- }
-
- return owner, repo
-}
-
-func TriggerTask(c *context.Context) {
- pusherID := c.QueryInt64("pusher")
- branch := c.Query("branch")
- secret := c.Query("secret")
- if len(branch) == 0 || len(secret) == 0 || pusherID <= 0 {
- c.Error(404)
- log.Trace("TriggerTask: branch or secret is empty, or pusher ID is not valid")
- return
- }
- owner, repo := parseOwnerAndRepo(c)
- if c.Written() {
- return
- }
- if secret != tool.MD5(owner.Salt) {
- c.Error(404)
- log.Trace("TriggerTask [%s/%s]: invalid secret", owner.Name, repo.Name)
- return
- }
-
- pusher, err := models.GetUserByID(pusherID)
- if err != nil {
- c.NotFoundOrServerError("GetUserByID", errors.IsUserNotExist, err)
- return
- }
-
- log.Trace("TriggerTask '%s/%s' by '%s'", repo.Name, branch, pusher.Name)
-
- go models.HookQueue.Add(repo.ID)
- go models.AddTestPullRequestTask(pusher, repo.ID, branch, true)
- c.Status(202)
-}
diff --git a/routers/repo/release.go b/routers/repo/release.go
deleted file mode 100644
index 86dfe6f7..00000000
--- a/routers/repo/release.go
+++ /dev/null
@@ -1,332 +0,0 @@
-// 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 repo
-
-import (
- "fmt"
- "strings"
-
- log "gopkg.in/clog.v1"
-
- "github.com/gogits/gogs/models"
- "github.com/gogits/gogs/pkg/context"
- "github.com/gogits/gogs/pkg/form"
- "github.com/gogits/gogs/pkg/markup"
- "github.com/gogits/gogs/pkg/setting"
-)
-
-const (
- RELEASES = "repo/release/list"
- RELEASE_NEW = "repo/release/new"
-)
-
-// calReleaseNumCommitsBehind calculates given release has how many commits behind release target.
-func calReleaseNumCommitsBehind(repoCtx *context.Repository, release *models.Release, countCache map[string]int64) error {
- // Get count if not exists
- if _, ok := countCache[release.Target]; !ok {
- if repoCtx.GitRepo.IsBranchExist(release.Target) {
- commit, err := repoCtx.GitRepo.GetBranchCommit(release.Target)
- if err != nil {
- return fmt.Errorf("GetBranchCommit: %v", err)
- }
- countCache[release.Target], err = commit.CommitsCount()
- if err != nil {
- return fmt.Errorf("CommitsCount: %v", err)
- }
- } else {
- // Use NumCommits of the newest release on that target
- countCache[release.Target] = release.NumCommits
- }
- }
- release.NumCommitsBehind = countCache[release.Target] - release.NumCommits
- return nil
-}
-
-func Releases(c *context.Context) {
- c.Data["Title"] = c.Tr("repo.release.releases")
- c.Data["PageIsViewFiles"] = true
- c.Data["PageIsReleaseList"] = true
-
- tagsResult, err := c.Repo.GitRepo.GetTagsAfter(c.Query("after"), 10)
- if err != nil {
- c.Handle(500, fmt.Sprintf("GetTags '%s'", c.Repo.Repository.RepoPath()), err)
- return
- }
-
- releases, err := models.GetPublishedReleasesByRepoID(c.Repo.Repository.ID, tagsResult.Tags...)
- if err != nil {
- c.Handle(500, "GetPublishedReleasesByRepoID", err)
- return
- }
-
- // Temproray cache commits count of used branches to speed up.
- countCache := make(map[string]int64)
-
- results := make([]*models.Release, len(tagsResult.Tags))
- for i, rawTag := range tagsResult.Tags {
- for j, r := range releases {
- if r == nil || r.TagName != rawTag {
- continue
- }
- releases[j] = nil // Mark as used.
-
- if err = r.LoadAttributes(); err != nil {
- c.Handle(500, "LoadAttributes", err)
- return
- }
-
- if err := calReleaseNumCommitsBehind(c.Repo, r, countCache); err != nil {
- c.Handle(500, "calReleaseNumCommitsBehind", err)
- return
- }
-
- r.Note = string(markup.Markdown(r.Note, c.Repo.RepoLink, c.Repo.Repository.ComposeMetas()))
- results[i] = r
- break
- }
-
- // No published release matches this tag
- if results[i] == nil {
- commit, err := c.Repo.GitRepo.GetTagCommit(rawTag)
- if err != nil {
- c.Handle(500, "GetTagCommit", err)
- return
- }
-
- results[i] = &models.Release{
- Title: rawTag,
- TagName: rawTag,
- Sha1: commit.ID.String(),
- }
-
- results[i].NumCommits, err = commit.CommitsCount()
- if err != nil {
- c.Handle(500, "CommitsCount", err)
- return
- }
- results[i].NumCommitsBehind = c.Repo.CommitsCount - results[i].NumCommits
- }
- }
- models.SortReleases(results)
-
- // Only show drafts if user is viewing the latest page
- var drafts []*models.Release
- if tagsResult.HasLatest {
- drafts, err = models.GetDraftReleasesByRepoID(c.Repo.Repository.ID)
- if err != nil {
- c.Handle(500, "GetDraftReleasesByRepoID", err)
- return
- }
-
- for _, r := range drafts {
- if err = r.LoadAttributes(); err != nil {
- c.Handle(500, "LoadAttributes", err)
- return
- }
-
- if err := calReleaseNumCommitsBehind(c.Repo, r, countCache); err != nil {
- c.Handle(500, "calReleaseNumCommitsBehind", err)
- return
- }
-
- r.Note = string(markup.Markdown(r.Note, c.Repo.RepoLink, c.Repo.Repository.ComposeMetas()))
- }
-
- if len(drafts) > 0 {
- results = append(drafts, results...)
- }
- }
-
- c.Data["Releases"] = results
- c.Data["HasPrevious"] = !tagsResult.HasLatest
- c.Data["ReachEnd"] = tagsResult.ReachEnd
- c.Data["PreviousAfter"] = tagsResult.PreviousAfter
- if len(results) > 0 {
- c.Data["NextAfter"] = results[len(results)-1].TagName
- }
- c.HTML(200, RELEASES)
-}
-
-func renderReleaseAttachmentSettings(c *context.Context) {
- c.Data["RequireDropzone"] = true
- c.Data["IsAttachmentEnabled"] = setting.Release.Attachment.Enabled
- c.Data["AttachmentAllowedTypes"] = strings.Join(setting.Release.Attachment.AllowedTypes, ",")
- c.Data["AttachmentMaxSize"] = setting.Release.Attachment.MaxSize
- c.Data["AttachmentMaxFiles"] = setting.Release.Attachment.MaxFiles
-}
-
-func NewRelease(c *context.Context) {
- c.Data["Title"] = c.Tr("repo.release.new_release")
- c.Data["PageIsReleaseList"] = true
- c.Data["tag_target"] = c.Repo.Repository.DefaultBranch
- renderReleaseAttachmentSettings(c)
- c.HTML(200, RELEASE_NEW)
-}
-
-func NewReleasePost(c *context.Context, f form.NewRelease) {
- c.Data["Title"] = c.Tr("repo.release.new_release")
- c.Data["PageIsReleaseList"] = true
- renderReleaseAttachmentSettings(c)
-
- if c.HasError() {
- c.HTML(200, RELEASE_NEW)
- return
- }
-
- if !c.Repo.GitRepo.IsBranchExist(f.Target) {
- c.RenderWithErr(c.Tr("form.target_branch_not_exist"), RELEASE_NEW, &f)
- return
- }
-
- // Use current time if tag not yet exist, otherwise get time from Git
- var tagCreatedUnix int64
- tag, err := c.Repo.GitRepo.GetTag(f.TagName)
- if err == nil {
- commit, err := tag.Commit()
- if err == nil {
- tagCreatedUnix = commit.Author.When.Unix()
- }
- }
-
- commit, err := c.Repo.GitRepo.GetBranchCommit(f.Target)
- if err != nil {
- c.Handle(500, "GetBranchCommit", err)
- return
- }
-
- commitsCount, err := commit.CommitsCount()
- if err != nil {
- c.Handle(500, "CommitsCount", err)
- return
- }
-
- var attachments []string
- if setting.Release.Attachment.Enabled {
- attachments = f.Files
- }
-
- rel := &models.Release{
- RepoID: c.Repo.Repository.ID,
- PublisherID: c.User.ID,
- Title: f.Title,
- TagName: f.TagName,
- Target: f.Target,
- Sha1: commit.ID.String(),
- NumCommits: commitsCount,
- Note: f.Content,
- IsDraft: len(f.Draft) > 0,
- IsPrerelease: f.Prerelease,
- CreatedUnix: tagCreatedUnix,
- }
- if err = models.NewRelease(c.Repo.GitRepo, rel, attachments); err != nil {
- c.Data["Err_TagName"] = true
- switch {
- case models.IsErrReleaseAlreadyExist(err):
- c.RenderWithErr(c.Tr("repo.release.tag_name_already_exist"), RELEASE_NEW, &f)
- case models.IsErrInvalidTagName(err):
- c.RenderWithErr(c.Tr("repo.release.tag_name_invalid"), RELEASE_NEW, &f)
- default:
- c.Handle(500, "NewRelease", err)
- }
- return
- }
- log.Trace("Release created: %s/%s:%s", c.User.LowerName, c.Repo.Repository.Name, f.TagName)
-
- c.Redirect(c.Repo.RepoLink + "/releases")
-}
-
-func EditRelease(c *context.Context) {
- c.Data["Title"] = c.Tr("repo.release.edit_release")
- c.Data["PageIsReleaseList"] = true
- c.Data["PageIsEditRelease"] = true
- renderReleaseAttachmentSettings(c)
-
- tagName := c.Params("*")
- rel, err := models.GetRelease(c.Repo.Repository.ID, tagName)
- if err != nil {
- if models.IsErrReleaseNotExist(err) {
- c.Handle(404, "GetRelease", err)
- } else {
- c.Handle(500, "GetRelease", err)
- }
- return
- }
- c.Data["ID"] = rel.ID
- c.Data["tag_name"] = rel.TagName
- c.Data["tag_target"] = rel.Target
- c.Data["title"] = rel.Title
- c.Data["content"] = rel.Note
- c.Data["attachments"] = rel.Attachments
- c.Data["prerelease"] = rel.IsPrerelease
- c.Data["IsDraft"] = rel.IsDraft
-
- c.HTML(200, RELEASE_NEW)
-}
-
-func EditReleasePost(c *context.Context, f form.EditRelease) {
- c.Data["Title"] = c.Tr("repo.release.edit_release")
- c.Data["PageIsReleaseList"] = true
- c.Data["PageIsEditRelease"] = true
- renderReleaseAttachmentSettings(c)
-
- tagName := c.Params("*")
- rel, err := models.GetRelease(c.Repo.Repository.ID, tagName)
- if err != nil {
- if models.IsErrReleaseNotExist(err) {
- c.Handle(404, "GetRelease", err)
- } else {
- c.Handle(500, "GetRelease", err)
- }
- return
- }
- c.Data["tag_name"] = rel.TagName
- c.Data["tag_target"] = rel.Target
- c.Data["title"] = rel.Title
- c.Data["content"] = rel.Note
- c.Data["attachments"] = rel.Attachments
- c.Data["prerelease"] = rel.IsPrerelease
- c.Data["IsDraft"] = rel.IsDraft
-
- if c.HasError() {
- c.HTML(200, RELEASE_NEW)
- return
- }
-
- var attachments []string
- if setting.Release.Attachment.Enabled {
- attachments = f.Files
- }
-
- isPublish := rel.IsDraft && len(f.Draft) == 0
- rel.Title = f.Title
- rel.Note = f.Content
- rel.IsDraft = len(f.Draft) > 0
- rel.IsPrerelease = f.Prerelease
- if err = models.UpdateRelease(c.User, c.Repo.GitRepo, rel, isPublish, attachments); err != nil {
- c.Handle(500, "UpdateRelease", err)
- return
- }
- c.Redirect(c.Repo.RepoLink + "/releases")
-}
-
-func UploadReleaseAttachment(c *context.Context) {
- if !setting.Release.Attachment.Enabled {
- c.NotFound()
- return
- }
- uploadAttachment(c, setting.Release.Attachment.AllowedTypes)
-}
-
-func DeleteRelease(c *context.Context) {
- if err := models.DeleteReleaseOfRepoByID(c.Repo.Repository.ID, c.QueryInt64("id")); err != nil {
- c.Flash.Error("DeleteReleaseByID: " + err.Error())
- } else {
- c.Flash.Success(c.Tr("repo.release.deletion_success"))
- }
-
- c.JSON(200, map[string]interface{}{
- "redirect": c.Repo.RepoLink + "/releases",
- })
-}
diff --git a/routers/repo/repo.go b/routers/repo/repo.go
deleted file mode 100644
index ea3c1a60..00000000
--- a/routers/repo/repo.go
+++ /dev/null
@@ -1,335 +0,0 @@
-// 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 repo
-
-import (
- "fmt"
- "os"
- "path"
- "strings"
-
- "github.com/Unknwon/com"
- log "gopkg.in/clog.v1"
-
- "github.com/gogits/git-module"
-
- "github.com/gogits/gogs/models"
- "github.com/gogits/gogs/models/errors"
- "github.com/gogits/gogs/pkg/context"
- "github.com/gogits/gogs/pkg/form"
- "github.com/gogits/gogs/pkg/setting"
- "github.com/gogits/gogs/pkg/tool"
-)
-
-const (
- CREATE = "repo/create"
- MIGRATE = "repo/migrate"
-)
-
-func MustBeNotBare(c *context.Context) {
- if c.Repo.Repository.IsBare {
- c.Handle(404, "MustBeNotBare", nil)
- }
-}
-
-func checkContextUser(c *context.Context, uid int64) *models.User {
- orgs, err := models.GetOwnedOrgsByUserIDDesc(c.User.ID, "updated_unix")
- if err != nil {
- c.Handle(500, "GetOwnedOrgsByUserIDDesc", err)
- return nil
- }
- c.Data["Orgs"] = orgs
-
- // Not equal means current user is an organization.
- if uid == c.User.ID || uid == 0 {
- return c.User
- }
-
- org, err := models.GetUserByID(uid)
- if errors.IsUserNotExist(err) {
- return c.User
- }
-
- if err != nil {
- c.Handle(500, "GetUserByID", fmt.Errorf("[%d]: %v", uid, err))
- return nil
- }
-
- // Check ownership of organization.
- if !org.IsOrganization() || !(c.User.IsAdmin || org.IsOwnedBy(c.User.ID)) {
- c.Error(403)
- return nil
- }
- return org
-}
-
-func Create(c *context.Context) {
- c.Data["Title"] = c.Tr("new_repo")
-
- // Give default value for template to render.
- c.Data["Gitignores"] = models.Gitignores
- c.Data["Licenses"] = models.Licenses
- c.Data["Readmes"] = models.Readmes
- c.Data["readme"] = "Default"
- c.Data["private"] = c.User.LastRepoVisibility
- c.Data["IsForcedPrivate"] = setting.Repository.ForcePrivate
-
- ctxUser := checkContextUser(c, c.QueryInt64("org"))
- if c.Written() {
- return
- }
- c.Data["ContextUser"] = ctxUser
-
- c.HTML(200, CREATE)
-}
-
-func handleCreateError(c *context.Context, owner *models.User, err error, name, tpl string, form interface{}) {
- switch {
- case errors.IsReachLimitOfRepo(err):
- c.RenderWithErr(c.Tr("repo.form.reach_limit_of_creation", owner.RepoCreationNum()), tpl, form)
- case models.IsErrRepoAlreadyExist(err):
- c.Data["Err_RepoName"] = true
- c.RenderWithErr(c.Tr("form.repo_name_been_taken"), tpl, form)
- case models.IsErrNameReserved(err):
- c.Data["Err_RepoName"] = true
- c.RenderWithErr(c.Tr("repo.form.name_reserved", err.(models.ErrNameReserved).Name), tpl, form)
- case models.IsErrNamePatternNotAllowed(err):
- c.Data["Err_RepoName"] = true
- c.RenderWithErr(c.Tr("repo.form.name_pattern_not_allowed", err.(models.ErrNamePatternNotAllowed).Pattern), tpl, form)
- default:
- c.Handle(500, name, err)
- }
-}
-
-func CreatePost(c *context.Context, f form.CreateRepo) {
- c.Data["Title"] = c.Tr("new_repo")
-
- c.Data["Gitignores"] = models.Gitignores
- c.Data["Licenses"] = models.Licenses
- c.Data["Readmes"] = models.Readmes
-
- ctxUser := checkContextUser(c, f.UserID)
- if c.Written() {
- return
- }
- c.Data["ContextUser"] = ctxUser
-
- if c.HasError() {
- c.HTML(200, CREATE)
- return
- }
-
- repo, err := models.CreateRepository(c.User, ctxUser, models.CreateRepoOptions{
- Name: f.RepoName,
- Description: f.Description,
- Gitignores: f.Gitignores,
- License: f.License,
- Readme: f.Readme,
- IsPrivate: f.Private || setting.Repository.ForcePrivate,
- AutoInit: f.AutoInit,
- })
- if err == nil {
- log.Trace("Repository created [%d]: %s/%s", repo.ID, ctxUser.Name, repo.Name)
- c.Redirect(setting.AppSubURL + "/" + ctxUser.Name + "/" + repo.Name)
- return
- }
-
- if repo != nil {
- if errDelete := models.DeleteRepository(ctxUser.ID, repo.ID); errDelete != nil {
- log.Error(4, "DeleteRepository: %v", errDelete)
- }
- }
-
- handleCreateError(c, ctxUser, err, "CreatePost", CREATE, &f)
-}
-
-func Migrate(c *context.Context) {
- c.Data["Title"] = c.Tr("new_migrate")
- c.Data["private"] = c.User.LastRepoVisibility
- c.Data["IsForcedPrivate"] = setting.Repository.ForcePrivate
- c.Data["mirror"] = c.Query("mirror") == "1"
-
- ctxUser := checkContextUser(c, c.QueryInt64("org"))
- if c.Written() {
- return
- }
- c.Data["ContextUser"] = ctxUser
-
- c.HTML(200, MIGRATE)
-}
-
-func MigratePost(c *context.Context, f form.MigrateRepo) {
- c.Data["Title"] = c.Tr("new_migrate")
-
- ctxUser := checkContextUser(c, f.Uid)
- if c.Written() {
- return
- }
- c.Data["ContextUser"] = ctxUser
-
- if c.HasError() {
- c.HTML(200, MIGRATE)
- return
- }
-
- remoteAddr, err := f.ParseRemoteAddr(c.User)
- if err != nil {
- if models.IsErrInvalidCloneAddr(err) {
- c.Data["Err_CloneAddr"] = true
- addrErr := err.(models.ErrInvalidCloneAddr)
- switch {
- case addrErr.IsURLError:
- c.RenderWithErr(c.Tr("form.url_error"), MIGRATE, &f)
- case addrErr.IsPermissionDenied:
- c.RenderWithErr(c.Tr("repo.migrate.permission_denied"), MIGRATE, &f)
- case addrErr.IsInvalidPath:
- c.RenderWithErr(c.Tr("repo.migrate.invalid_local_path"), MIGRATE, &f)
- default:
- c.Handle(500, "Unknown error", err)
- }
- } else {
- c.Handle(500, "ParseRemoteAddr", err)
- }
- return
- }
-
- repo, err := models.MigrateRepository(c.User, ctxUser, models.MigrateRepoOptions{
- Name: f.RepoName,
- Description: f.Description,
- IsPrivate: f.Private || setting.Repository.ForcePrivate,
- IsMirror: f.Mirror,
- RemoteAddr: remoteAddr,
- })
- if err == nil {
- log.Trace("Repository migrated [%d]: %s/%s", repo.ID, ctxUser.Name, f.RepoName)
- c.Redirect(setting.AppSubURL + "/" + ctxUser.Name + "/" + f.RepoName)
- return
- }
-
- if repo != nil {
- if errDelete := models.DeleteRepository(ctxUser.ID, repo.ID); errDelete != nil {
- log.Error(4, "DeleteRepository: %v", errDelete)
- }
- }
-
- if strings.Contains(err.Error(), "Authentication failed") ||
- strings.Contains(err.Error(), "could not read Username") {
- c.Data["Err_Auth"] = true
- c.RenderWithErr(c.Tr("form.auth_failed", models.HandleMirrorCredentials(err.Error(), true)), MIGRATE, &f)
- return
- } else if strings.Contains(err.Error(), "fatal:") {
- c.Data["Err_CloneAddr"] = true
- c.RenderWithErr(c.Tr("repo.migrate.failed", models.HandleMirrorCredentials(err.Error(), true)), MIGRATE, &f)
- return
- }
-
- handleCreateError(c, ctxUser, err, "MigratePost", MIGRATE, &f)
-}
-
-func Action(c *context.Context) {
- var err error
- switch c.Params(":action") {
- case "watch":
- err = models.WatchRepo(c.User.ID, c.Repo.Repository.ID, true)
- case "unwatch":
- err = models.WatchRepo(c.User.ID, c.Repo.Repository.ID, false)
- case "star":
- err = models.StarRepo(c.User.ID, c.Repo.Repository.ID, true)
- case "unstar":
- err = models.StarRepo(c.User.ID, c.Repo.Repository.ID, false)
- case "desc": // FIXME: this is not used
- if !c.Repo.IsOwner() {
- c.Error(404)
- return
- }
-
- c.Repo.Repository.Description = c.Query("desc")
- c.Repo.Repository.Website = c.Query("site")
- err = models.UpdateRepository(c.Repo.Repository, false)
- }
-
- if err != nil {
- c.Handle(500, fmt.Sprintf("Action (%s)", c.Params(":action")), err)
- return
- }
-
- redirectTo := c.Query("redirect_to")
- if len(redirectTo) == 0 {
- redirectTo = c.Repo.RepoLink
- }
- c.Redirect(redirectTo)
-}
-
-func Download(c *context.Context) {
- var (
- uri = c.Params("*")
- refName string
- ext string
- archivePath string
- archiveType git.ArchiveType
- )
-
- switch {
- case strings.HasSuffix(uri, ".zip"):
- ext = ".zip"
- archivePath = path.Join(c.Repo.GitRepo.Path, "archives/zip")
- archiveType = git.ZIP
- case strings.HasSuffix(uri, ".tar.gz"):
- ext = ".tar.gz"
- archivePath = path.Join(c.Repo.GitRepo.Path, "archives/targz")
- archiveType = git.TARGZ
- default:
- log.Trace("Unknown format: %s", uri)
- c.Error(404)
- return
- }
- refName = strings.TrimSuffix(uri, ext)
-
- if !com.IsDir(archivePath) {
- if err := os.MkdirAll(archivePath, os.ModePerm); err != nil {
- c.Handle(500, "Download -> os.MkdirAll(archivePath)", err)
- return
- }
- }
-
- // Get corresponding commit.
- var (
- commit *git.Commit
- err error
- )
- gitRepo := c.Repo.GitRepo
- if gitRepo.IsBranchExist(refName) {
- commit, err = gitRepo.GetBranchCommit(refName)
- if err != nil {
- c.Handle(500, "GetBranchCommit", err)
- return
- }
- } else if gitRepo.IsTagExist(refName) {
- commit, err = gitRepo.GetTagCommit(refName)
- if err != nil {
- c.Handle(500, "GetTagCommit", err)
- return
- }
- } else if len(refName) >= 7 && len(refName) <= 40 {
- commit, err = gitRepo.GetCommit(refName)
- if err != nil {
- c.NotFound()
- return
- }
- } else {
- c.NotFound()
- return
- }
-
- archivePath = path.Join(archivePath, tool.ShortSHA1(commit.ID.String())+ext)
- if !com.IsFile(archivePath) {
- if err := commit.CreateArchive(archivePath, archiveType); err != nil {
- c.Handle(500, "Download -> CreateArchive "+archivePath, err)
- return
- }
- }
-
- c.ServeFile(archivePath, c.Repo.Repository.Name+"-"+refName+ext)
-}
diff --git a/routers/repo/setting.go b/routers/repo/setting.go
deleted file mode 100644
index 9168b04a..00000000
--- a/routers/repo/setting.go
+++ /dev/null
@@ -1,631 +0,0 @@
-// 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 repo
-
-import (
- "fmt"
- "strings"
- "time"
-
- log "gopkg.in/clog.v1"
-
- "github.com/gogits/git-module"
-
- "github.com/gogits/gogs/models"
- "github.com/gogits/gogs/models/errors"
- "github.com/gogits/gogs/pkg/context"
- "github.com/gogits/gogs/pkg/form"
- "github.com/gogits/gogs/pkg/mailer"
- "github.com/gogits/gogs/pkg/setting"
-)
-
-const (
- SETTINGS_OPTIONS = "repo/settings/options"
- SETTINGS_COLLABORATION = "repo/settings/collaboration"
- SETTINGS_BRANCHES = "repo/settings/branches"
- SETTINGS_PROTECTED_BRANCH = "repo/settings/protected_branch"
- SETTINGS_GITHOOKS = "repo/settings/githooks"
- SETTINGS_GITHOOK_EDIT = "repo/settings/githook_edit"
- SETTINGS_DEPLOY_KEYS = "repo/settings/deploy_keys"
-)
-
-func Settings(c *context.Context) {
- c.Data["Title"] = c.Tr("repo.settings")
- c.Data["PageIsSettingsOptions"] = true
- c.HTML(200, SETTINGS_OPTIONS)
-}
-
-func SettingsPost(c *context.Context, f form.RepoSetting) {
- c.Data["Title"] = c.Tr("repo.settings")
- c.Data["PageIsSettingsOptions"] = true
-
- repo := c.Repo.Repository
-
- switch c.Query("action") {
- case "update":
- if c.HasError() {
- c.HTML(200, SETTINGS_OPTIONS)
- return
- }
-
- isNameChanged := false
- oldRepoName := repo.Name
- newRepoName := f.RepoName
- // Check if repository name has been changed.
- if repo.LowerName != strings.ToLower(newRepoName) {
- isNameChanged = true
- if err := models.ChangeRepositoryName(c.Repo.Owner, repo.Name, newRepoName); err != nil {
- c.Data["Err_RepoName"] = true
- switch {
- case models.IsErrRepoAlreadyExist(err):
- c.RenderWithErr(c.Tr("form.repo_name_been_taken"), SETTINGS_OPTIONS, &f)
- case models.IsErrNameReserved(err):
- c.RenderWithErr(c.Tr("repo.form.name_reserved", err.(models.ErrNameReserved).Name), SETTINGS_OPTIONS, &f)
- case models.IsErrNamePatternNotAllowed(err):
- c.RenderWithErr(c.Tr("repo.form.name_pattern_not_allowed", err.(models.ErrNamePatternNotAllowed).Pattern), SETTINGS_OPTIONS, &f)
- default:
- c.Handle(500, "ChangeRepositoryName", err)
- }
- return
- }
-
- log.Trace("Repository name changed: %s/%s -> %s", c.Repo.Owner.Name, repo.Name, newRepoName)
- }
- // In case it's just a case change.
- repo.Name = newRepoName
- repo.LowerName = strings.ToLower(newRepoName)
-
- repo.Description = f.Description
- repo.Website = f.Website
-
- // Visibility of forked repository is forced sync with base repository.
- if repo.IsFork {
- f.Private = repo.BaseRepo.IsPrivate
- }
-
- visibilityChanged := repo.IsPrivate != f.Private
- repo.IsPrivate = f.Private
- if err := models.UpdateRepository(repo, visibilityChanged); err != nil {
- c.Handle(500, "UpdateRepository", err)
- return
- }
- log.Trace("Repository basic settings updated: %s/%s", c.Repo.Owner.Name, repo.Name)
-
- if isNameChanged {
- if err := models.RenameRepoAction(c.User, oldRepoName, repo); err != nil {
- log.Error(4, "RenameRepoAction: %v", err)
- }
- }
-
- c.Flash.Success(c.Tr("repo.settings.update_settings_success"))
- c.Redirect(repo.Link() + "/settings")
-
- case "mirror":
- if !repo.IsMirror {
- c.Handle(404, "", nil)
- return
- }
-
- if f.Interval > 0 {
- c.Repo.Mirror.EnablePrune = f.EnablePrune
- c.Repo.Mirror.Interval = f.Interval
- c.Repo.Mirror.NextUpdate = time.Now().Add(time.Duration(f.Interval) * time.Hour)
- if err := models.UpdateMirror(c.Repo.Mirror); err != nil {
- c.Handle(500, "UpdateMirror", err)
- return
- }
- }
- if err := c.Repo.Mirror.SaveAddress(f.MirrorAddress); err != nil {
- c.Handle(500, "SaveAddress", err)
- return
- }
-
- c.Flash.Success(c.Tr("repo.settings.update_settings_success"))
- c.Redirect(repo.Link() + "/settings")
-
- case "mirror-sync":
- if !repo.IsMirror {
- c.Handle(404, "", nil)
- return
- }
-
- go models.MirrorQueue.Add(repo.ID)
- c.Flash.Info(c.Tr("repo.settings.mirror_sync_in_progress"))
- c.Redirect(repo.Link() + "/settings")
-
- case "advanced":
- repo.EnableWiki = f.EnableWiki
- repo.AllowPublicWiki = f.AllowPublicWiki
- repo.EnableExternalWiki = f.EnableExternalWiki
- repo.ExternalWikiURL = f.ExternalWikiURL
- repo.EnableIssues = f.EnableIssues
- repo.AllowPublicIssues = f.AllowPublicIssues
- repo.EnableExternalTracker = f.EnableExternalTracker
- repo.ExternalTrackerURL = f.ExternalTrackerURL
- repo.ExternalTrackerFormat = f.TrackerURLFormat
- repo.ExternalTrackerStyle = f.TrackerIssueStyle
- repo.EnablePulls = f.EnablePulls
-
- if err := models.UpdateRepository(repo, false); err != nil {
- c.Handle(500, "UpdateRepository", err)
- return
- }
- log.Trace("Repository advanced settings updated: %s/%s", c.Repo.Owner.Name, repo.Name)
-
- c.Flash.Success(c.Tr("repo.settings.update_settings_success"))
- c.Redirect(c.Repo.RepoLink + "/settings")
-
- case "convert":
- if !c.Repo.IsOwner() {
- c.Error(404)
- return
- }
- if repo.Name != f.RepoName {
- c.RenderWithErr(c.Tr("form.enterred_invalid_repo_name"), SETTINGS_OPTIONS, nil)
- return
- }
-
- if c.Repo.Owner.IsOrganization() {
- if !c.Repo.Owner.IsOwnedBy(c.User.ID) {
- c.Error(404)
- return
- }
- }
-
- if !repo.IsMirror {
- c.Error(404)
- return
- }
- repo.IsMirror = false
-
- if _, err := models.CleanUpMigrateInfo(repo); err != nil {
- c.Handle(500, "CleanUpMigrateInfo", err)
- return
- } else if err = models.DeleteMirrorByRepoID(c.Repo.Repository.ID); err != nil {
- c.Handle(500, "DeleteMirrorByRepoID", err)
- return
- }
- log.Trace("Repository converted from mirror to regular: %s/%s", c.Repo.Owner.Name, repo.Name)
- c.Flash.Success(c.Tr("repo.settings.convert_succeed"))
- c.Redirect(setting.AppSubURL + "/" + c.Repo.Owner.Name + "/" + repo.Name)
-
- case "transfer":
- if !c.Repo.IsOwner() {
- c.Error(404)
- return
- }
- if repo.Name != f.RepoName {
- c.RenderWithErr(c.Tr("form.enterred_invalid_repo_name"), SETTINGS_OPTIONS, nil)
- return
- }
-
- if c.Repo.Owner.IsOrganization() && !c.User.IsAdmin {
- if !c.Repo.Owner.IsOwnedBy(c.User.ID) {
- c.Error(404)
- return
- }
- }
-
- newOwner := c.Query("new_owner_name")
- isExist, err := models.IsUserExist(0, newOwner)
- if err != nil {
- c.Handle(500, "IsUserExist", err)
- return
- } else if !isExist {
- c.RenderWithErr(c.Tr("form.enterred_invalid_owner_name"), SETTINGS_OPTIONS, nil)
- return
- }
-
- if err = models.TransferOwnership(c.User, newOwner, repo); err != nil {
- if models.IsErrRepoAlreadyExist(err) {
- c.RenderWithErr(c.Tr("repo.settings.new_owner_has_same_repo"), SETTINGS_OPTIONS, nil)
- } else {
- c.Handle(500, "TransferOwnership", err)
- }
- return
- }
- log.Trace("Repository transfered: %s/%s -> %s", c.Repo.Owner.Name, repo.Name, newOwner)
- c.Flash.Success(c.Tr("repo.settings.transfer_succeed"))
- c.Redirect(setting.AppSubURL + "/" + newOwner + "/" + repo.Name)
-
- case "delete":
- if !c.Repo.IsOwner() {
- c.Error(404)
- return
- }
- if repo.Name != f.RepoName {
- c.RenderWithErr(c.Tr("form.enterred_invalid_repo_name"), SETTINGS_OPTIONS, nil)
- return
- }
-
- if c.Repo.Owner.IsOrganization() && !c.User.IsAdmin {
- if !c.Repo.Owner.IsOwnedBy(c.User.ID) {
- c.Error(404)
- return
- }
- }
-
- if err := models.DeleteRepository(c.Repo.Owner.ID, repo.ID); err != nil {
- c.Handle(500, "DeleteRepository", err)
- return
- }
- log.Trace("Repository deleted: %s/%s", c.Repo.Owner.Name, repo.Name)
-
- c.Flash.Success(c.Tr("repo.settings.deletion_success"))
- c.Redirect(c.Repo.Owner.DashboardLink())
-
- case "delete-wiki":
- if !c.Repo.IsOwner() {
- c.Error(404)
- return
- }
- if repo.Name != f.RepoName {
- c.RenderWithErr(c.Tr("form.enterred_invalid_repo_name"), SETTINGS_OPTIONS, nil)
- return
- }
-
- if c.Repo.Owner.IsOrganization() && !c.User.IsAdmin {
- if !c.Repo.Owner.IsOwnedBy(c.User.ID) {
- c.Error(404)
- return
- }
- }
-
- repo.DeleteWiki()
- log.Trace("Repository wiki deleted: %s/%s", c.Repo.Owner.Name, repo.Name)
-
- repo.EnableWiki = false
- if err := models.UpdateRepository(repo, false); err != nil {
- c.Handle(500, "UpdateRepository", err)
- return
- }
-
- c.Flash.Success(c.Tr("repo.settings.wiki_deletion_success"))
- c.Redirect(c.Repo.RepoLink + "/settings")
-
- default:
- c.Handle(404, "", nil)
- }
-}
-
-func SettingsCollaboration(c *context.Context) {
- c.Data["Title"] = c.Tr("repo.settings")
- c.Data["PageIsSettingsCollaboration"] = true
-
- users, err := c.Repo.Repository.GetCollaborators()
- if err != nil {
- c.Handle(500, "GetCollaborators", err)
- return
- }
- c.Data["Collaborators"] = users
-
- c.HTML(200, SETTINGS_COLLABORATION)
-}
-
-func SettingsCollaborationPost(c *context.Context) {
- name := strings.ToLower(c.Query("collaborator"))
- if len(name) == 0 || c.Repo.Owner.LowerName == name {
- c.Redirect(setting.AppSubURL + c.Req.URL.Path)
- return
- }
-
- u, err := models.GetUserByName(name)
- if err != nil {
- if errors.IsUserNotExist(err) {
- c.Flash.Error(c.Tr("form.user_not_exist"))
- c.Redirect(setting.AppSubURL + c.Req.URL.Path)
- } else {
- c.Handle(500, "GetUserByName", err)
- }
- return
- }
-
- // Organization is not allowed to be added as a collaborator
- if u.IsOrganization() {
- c.Flash.Error(c.Tr("repo.settings.org_not_allowed_to_be_collaborator"))
- c.Redirect(setting.AppSubURL + c.Req.URL.Path)
- return
- }
-
- if err = c.Repo.Repository.AddCollaborator(u); err != nil {
- c.Handle(500, "AddCollaborator", err)
- return
- }
-
- if setting.Service.EnableNotifyMail {
- mailer.SendCollaboratorMail(models.NewMailerUser(u), models.NewMailerUser(c.User), models.NewMailerRepo(c.Repo.Repository))
- }
-
- c.Flash.Success(c.Tr("repo.settings.add_collaborator_success"))
- c.Redirect(setting.AppSubURL + c.Req.URL.Path)
-}
-
-func ChangeCollaborationAccessMode(c *context.Context) {
- if err := c.Repo.Repository.ChangeCollaborationAccessMode(
- c.QueryInt64("uid"),
- models.AccessMode(c.QueryInt("mode"))); err != nil {
- log.Error(2, "ChangeCollaborationAccessMode: %v", err)
- return
- }
-
- c.Status(204)
-}
-
-func DeleteCollaboration(c *context.Context) {
- if err := c.Repo.Repository.DeleteCollaboration(c.QueryInt64("id")); err != nil {
- c.Flash.Error("DeleteCollaboration: " + err.Error())
- } else {
- c.Flash.Success(c.Tr("repo.settings.remove_collaborator_success"))
- }
-
- c.JSON(200, map[string]interface{}{
- "redirect": c.Repo.RepoLink + "/settings/collaboration",
- })
-}
-
-func SettingsBranches(c *context.Context) {
- c.Data["Title"] = c.Tr("repo.settings.branches")
- c.Data["PageIsSettingsBranches"] = true
-
- if c.Repo.Repository.IsBare {
- c.Flash.Info(c.Tr("repo.settings.branches_bare"), true)
- c.HTML(200, SETTINGS_BRANCHES)
- return
- }
-
- protectBranches, err := models.GetProtectBranchesByRepoID(c.Repo.Repository.ID)
- if err != nil {
- c.Handle(500, "GetProtectBranchesByRepoID", err)
- return
- }
-
- // Filter out deleted branches
- branches := make([]string, 0, len(protectBranches))
- for i := range protectBranches {
- if c.Repo.GitRepo.IsBranchExist(protectBranches[i].Name) {
- branches = append(branches, protectBranches[i].Name)
- }
- }
- c.Data["ProtectBranches"] = branches
-
- c.HTML(200, SETTINGS_BRANCHES)
-}
-
-func UpdateDefaultBranch(c *context.Context) {
- branch := c.Query("branch")
- if c.Repo.GitRepo.IsBranchExist(branch) &&
- c.Repo.Repository.DefaultBranch != branch {
- c.Repo.Repository.DefaultBranch = branch
- if err := c.Repo.GitRepo.SetDefaultBranch(branch); err != nil {
- if !git.IsErrUnsupportedVersion(err) {
- c.Handle(500, "SetDefaultBranch", err)
- return
- }
-
- c.Flash.Warning(c.Tr("repo.settings.update_default_branch_unsupported"))
- c.Redirect(c.Repo.RepoLink + "/settings/branches")
- return
- }
- }
-
- if err := models.UpdateRepository(c.Repo.Repository, false); err != nil {
- c.Handle(500, "UpdateRepository", err)
- return
- }
-
- c.Flash.Success(c.Tr("repo.settings.update_default_branch_success"))
- c.Redirect(c.Repo.RepoLink + "/settings/branches")
-}
-
-func SettingsProtectedBranch(c *context.Context) {
- branch := c.Params("*")
- if !c.Repo.GitRepo.IsBranchExist(branch) {
- c.NotFound()
- return
- }
-
- c.Data["Title"] = c.Tr("repo.settings.protected_branches") + " - " + branch
- c.Data["PageIsSettingsBranches"] = true
-
- protectBranch, err := models.GetProtectBranchOfRepoByName(c.Repo.Repository.ID, branch)
- if err != nil {
- if !models.IsErrBranchNotExist(err) {
- c.Handle(500, "GetProtectBranchOfRepoByName", err)
- return
- }
-
- // No options found, create defaults.
- protectBranch = &models.ProtectBranch{
- Name: branch,
- }
- }
-
- if c.Repo.Owner.IsOrganization() {
- users, err := c.Repo.Repository.GetWriters()
- if err != nil {
- c.Handle(500, "Repo.Repository.GetPushers", err)
- return
- }
- c.Data["Users"] = users
- c.Data["whitelist_users"] = protectBranch.WhitelistUserIDs
-
- teams, err := c.Repo.Owner.TeamsHaveAccessToRepo(c.Repo.Repository.ID, models.ACCESS_MODE_WRITE)
- if err != nil {
- c.Handle(500, "Repo.Owner.TeamsHaveAccessToRepo", err)
- return
- }
- c.Data["Teams"] = teams
- c.Data["whitelist_teams"] = protectBranch.WhitelistTeamIDs
- }
-
- c.Data["Branch"] = protectBranch
- c.HTML(200, SETTINGS_PROTECTED_BRANCH)
-}
-
-func SettingsProtectedBranchPost(c *context.Context, f form.ProtectBranch) {
- branch := c.Params("*")
- if !c.Repo.GitRepo.IsBranchExist(branch) {
- c.NotFound()
- return
- }
-
- protectBranch, err := models.GetProtectBranchOfRepoByName(c.Repo.Repository.ID, branch)
- if err != nil {
- if !models.IsErrBranchNotExist(err) {
- c.Handle(500, "GetProtectBranchOfRepoByName", err)
- return
- }
-
- // No options found, create defaults.
- protectBranch = &models.ProtectBranch{
- RepoID: c.Repo.Repository.ID,
- Name: branch,
- }
- }
-
- protectBranch.Protected = f.Protected
- protectBranch.RequirePullRequest = f.RequirePullRequest
- protectBranch.EnableWhitelist = f.EnableWhitelist
- if c.Repo.Owner.IsOrganization() {
- err = models.UpdateOrgProtectBranch(c.Repo.Repository, protectBranch, f.WhitelistUsers, f.WhitelistTeams)
- } else {
- err = models.UpdateProtectBranch(protectBranch)
- }
- if err != nil {
- c.Handle(500, "UpdateOrgProtectBranch/UpdateProtectBranch", err)
- return
- }
-
- c.Flash.Success(c.Tr("repo.settings.update_protect_branch_success"))
- c.Redirect(fmt.Sprintf("%s/settings/branches/%s", c.Repo.RepoLink, branch))
-}
-
-func SettingsGitHooks(c *context.Context) {
- c.Data["Title"] = c.Tr("repo.settings.githooks")
- c.Data["PageIsSettingsGitHooks"] = true
-
- hooks, err := c.Repo.GitRepo.Hooks()
- if err != nil {
- c.Handle(500, "Hooks", err)
- return
- }
- c.Data["Hooks"] = hooks
-
- c.HTML(200, SETTINGS_GITHOOKS)
-}
-
-func SettingsGitHooksEdit(c *context.Context) {
- c.Data["Title"] = c.Tr("repo.settings.githooks")
- c.Data["PageIsSettingsGitHooks"] = true
- c.Data["RequireSimpleMDE"] = true
-
- name := c.Params(":name")
- hook, err := c.Repo.GitRepo.GetHook(name)
- if err != nil {
- if err == git.ErrNotValidHook {
- c.Handle(404, "GetHook", err)
- } else {
- c.Handle(500, "GetHook", err)
- }
- return
- }
- c.Data["Hook"] = hook
- c.HTML(200, SETTINGS_GITHOOK_EDIT)
-}
-
-func SettingsGitHooksEditPost(c *context.Context) {
- name := c.Params(":name")
- hook, err := c.Repo.GitRepo.GetHook(name)
- if err != nil {
- if err == git.ErrNotValidHook {
- c.Handle(404, "GetHook", err)
- } else {
- c.Handle(500, "GetHook", err)
- }
- return
- }
- hook.Content = c.Query("content")
- if err = hook.Update(); err != nil {
- c.Handle(500, "hook.Update", err)
- return
- }
- c.Redirect(c.Data["Link"].(string))
-}
-
-func SettingsDeployKeys(c *context.Context) {
- c.Data["Title"] = c.Tr("repo.settings.deploy_keys")
- c.Data["PageIsSettingsKeys"] = true
-
- keys, err := models.ListDeployKeys(c.Repo.Repository.ID)
- if err != nil {
- c.Handle(500, "ListDeployKeys", err)
- return
- }
- c.Data["Deploykeys"] = keys
-
- c.HTML(200, SETTINGS_DEPLOY_KEYS)
-}
-
-func SettingsDeployKeysPost(c *context.Context, f form.AddSSHKey) {
- c.Data["Title"] = c.Tr("repo.settings.deploy_keys")
- c.Data["PageIsSettingsKeys"] = true
-
- keys, err := models.ListDeployKeys(c.Repo.Repository.ID)
- if err != nil {
- c.Handle(500, "ListDeployKeys", err)
- return
- }
- c.Data["Deploykeys"] = keys
-
- if c.HasError() {
- c.HTML(200, SETTINGS_DEPLOY_KEYS)
- return
- }
-
- content, err := models.CheckPublicKeyString(f.Content)
- if err != nil {
- if models.IsErrKeyUnableVerify(err) {
- c.Flash.Info(c.Tr("form.unable_verify_ssh_key"))
- } else {
- c.Data["HasError"] = true
- c.Data["Err_Content"] = true
- c.Flash.Error(c.Tr("form.invalid_ssh_key", err.Error()))
- c.Redirect(c.Repo.RepoLink + "/settings/keys")
- return
- }
- }
-
- key, err := models.AddDeployKey(c.Repo.Repository.ID, f.Title, content)
- if err != nil {
- c.Data["HasError"] = true
- switch {
- case models.IsErrKeyAlreadyExist(err):
- c.Data["Err_Content"] = true
- c.RenderWithErr(c.Tr("repo.settings.key_been_used"), SETTINGS_DEPLOY_KEYS, &f)
- case models.IsErrKeyNameAlreadyUsed(err):
- c.Data["Err_Title"] = true
- c.RenderWithErr(c.Tr("repo.settings.key_name_used"), SETTINGS_DEPLOY_KEYS, &f)
- default:
- c.Handle(500, "AddDeployKey", err)
- }
- return
- }
-
- log.Trace("Deploy key added: %d", c.Repo.Repository.ID)
- c.Flash.Success(c.Tr("repo.settings.add_key_success", key.Name))
- c.Redirect(c.Repo.RepoLink + "/settings/keys")
-}
-
-func DeleteDeployKey(c *context.Context) {
- if err := models.DeleteDeployKey(c.User, c.QueryInt64("id")); err != nil {
- c.Flash.Error("DeleteDeployKey: " + err.Error())
- } else {
- c.Flash.Success(c.Tr("repo.settings.deploy_key_deletion_success"))
- }
-
- c.JSON(200, map[string]interface{}{
- "redirect": c.Repo.RepoLink + "/settings/keys",
- })
-}
diff --git a/routers/repo/view.go b/routers/repo/view.go
deleted file mode 100644
index 1ea25d51..00000000
--- a/routers/repo/view.go
+++ /dev/null
@@ -1,367 +0,0 @@
-// 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 repo
-
-import (
- "bytes"
- "fmt"
- gotemplate "html/template"
- "io/ioutil"
- "path"
- "strings"
-
- "github.com/Unknwon/paginater"
- log "gopkg.in/clog.v1"
-
- "github.com/gogits/git-module"
-
- "github.com/gogits/gogs/models"
- "github.com/gogits/gogs/pkg/context"
- "github.com/gogits/gogs/pkg/markup"
- "github.com/gogits/gogs/pkg/setting"
- "github.com/gogits/gogs/pkg/template"
- "github.com/gogits/gogs/pkg/template/highlight"
- "github.com/gogits/gogs/pkg/tool"
-)
-
-const (
- BARE = "repo/bare"
- HOME = "repo/home"
- WATCHERS = "repo/watchers"
- FORKS = "repo/forks"
-)
-
-func renderDirectory(c *context.Context, treeLink string) {
- tree, err := c.Repo.Commit.SubTree(c.Repo.TreePath)
- if err != nil {
- c.NotFoundOrServerError("Repo.Commit.SubTree", git.IsErrNotExist, err)
- return
- }
-
- entries, err := tree.ListEntries()
- if err != nil {
- c.ServerError("ListEntries", err)
- return
- }
- entries.Sort()
-
- c.Data["Files"], err = entries.GetCommitsInfoWithCustomConcurrency(c.Repo.Commit, c.Repo.TreePath, setting.Repository.CommitsFetchConcurrency)
- if err != nil {
- c.ServerError("GetCommitsInfoWithCustomConcurrency", err)
- return
- }
-
- var readmeFile *git.Blob
- for _, entry := range entries {
- if entry.IsDir() || !markup.IsReadmeFile(entry.Name()) {
- continue
- }
-
- // TODO: collect all possible README files and show with priority.
- readmeFile = entry.Blob()
- break
- }
-
- if readmeFile != nil {
- c.Data["RawFileLink"] = ""
- c.Data["ReadmeInList"] = true
- c.Data["ReadmeExist"] = true
-
- dataRc, err := readmeFile.Data()
- if err != nil {
- c.ServerError("readmeFile.Data", err)
- return
- }
-
- buf := make([]byte, 1024)
- n, _ := dataRc.Read(buf)
- buf = buf[:n]
-
- isTextFile := tool.IsTextFile(buf)
- c.Data["IsTextFile"] = isTextFile
- c.Data["FileName"] = readmeFile.Name()
- if isTextFile {
- d, _ := ioutil.ReadAll(dataRc)
- buf = append(buf, d...)
-
- switch markup.Detect(readmeFile.Name()) {
- case markup.MARKDOWN:
- c.Data["IsMarkdown"] = true
- buf = markup.Markdown(buf, treeLink, c.Repo.Repository.ComposeMetas())
- case markup.ORG_MODE:
- c.Data["IsMarkdown"] = true
- buf = markup.OrgMode(buf, treeLink, c.Repo.Repository.ComposeMetas())
- case markup.IPYTHON_NOTEBOOK:
- c.Data["IsIPythonNotebook"] = true
- c.Data["RawFileLink"] = c.Repo.RepoLink + "/raw/" + path.Join(c.Repo.BranchName, c.Repo.TreePath, readmeFile.Name())
- default:
- buf = bytes.Replace(buf, []byte("\n"), []byte(`<br>`), -1)
- }
- c.Data["FileContent"] = string(buf)
- }
- }
-
- // Show latest commit info of repository in table header,
- // or of directory if not in root directory.
- latestCommit := c.Repo.Commit
- if len(c.Repo.TreePath) > 0 {
- latestCommit, err = c.Repo.Commit.GetCommitByPath(c.Repo.TreePath)
- if err != nil {
- c.ServerError("GetCommitByPath", err)
- return
- }
- }
- c.Data["LatestCommit"] = latestCommit
- c.Data["LatestCommitUser"] = models.ValidateCommitWithEmail(latestCommit)
-
- if c.Repo.CanEnableEditor() {
- c.Data["CanAddFile"] = true
- c.Data["CanUploadFile"] = setting.Repository.Upload.Enabled
- }
-}
-
-func renderFile(c *context.Context, entry *git.TreeEntry, treeLink, rawLink string) {
- c.Data["IsViewFile"] = true
-
- blob := entry.Blob()
- dataRc, err := blob.Data()
- if err != nil {
- c.Handle(500, "Data", err)
- return
- }
-
- c.Data["FileSize"] = blob.Size()
- c.Data["FileName"] = blob.Name()
- c.Data["HighlightClass"] = highlight.FileNameToHighlightClass(blob.Name())
- c.Data["RawFileLink"] = rawLink + "/" + c.Repo.TreePath
-
- buf := make([]byte, 1024)
- n, _ := dataRc.Read(buf)
- buf = buf[:n]
-
- isTextFile := tool.IsTextFile(buf)
- c.Data["IsTextFile"] = isTextFile
-
- // Assume file is not editable first.
- if !isTextFile {
- c.Data["EditFileTooltip"] = c.Tr("repo.editor.cannot_edit_non_text_files")
- }
-
- canEnableEditor := c.Repo.CanEnableEditor()
- switch {
- case isTextFile:
- if blob.Size() >= setting.UI.MaxDisplayFileSize {
- c.Data["IsFileTooLarge"] = true
- break
- }
-
- c.Data["ReadmeExist"] = markup.IsReadmeFile(blob.Name())
-
- d, _ := ioutil.ReadAll(dataRc)
- buf = append(buf, d...)
-
- switch markup.Detect(blob.Name()) {
- case markup.MARKDOWN:
- c.Data["IsMarkdown"] = true
- c.Data["FileContent"] = string(markup.Markdown(buf, path.Dir(treeLink), c.Repo.Repository.ComposeMetas()))
- case markup.ORG_MODE:
- c.Data["IsMarkdown"] = true
- c.Data["FileContent"] = string(markup.OrgMode(buf, path.Dir(treeLink), c.Repo.Repository.ComposeMetas()))
- case markup.IPYTHON_NOTEBOOK:
- c.Data["IsIPythonNotebook"] = true
- default:
- // Building code view blocks with line number on server side.
- var fileContent string
- if err, content := template.ToUTF8WithErr(buf); err != nil {
- if err != nil {
- log.Error(4, "ToUTF8WithErr: %s", err)
- }
- fileContent = string(buf)
- } else {
- fileContent = content
- }
-
- var output bytes.Buffer
- lines := strings.Split(fileContent, "\n")
- for index, line := range lines {
- output.WriteString(fmt.Sprintf(`<li class="L%d" rel="L%d">%s</li>`, index+1, index+1, gotemplate.HTMLEscapeString(strings.TrimRight(line, "\r"))) + "\n")
- }
- c.Data["FileContent"] = gotemplate.HTML(output.String())
-
- output.Reset()
- for i := 0; i < len(lines); i++ {
- output.WriteString(fmt.Sprintf(`<span id="L%d">%d</span>`, i+1, i+1))
- }
- c.Data["LineNums"] = gotemplate.HTML(output.String())
- }
-
- if canEnableEditor {
- c.Data["CanEditFile"] = true
- c.Data["EditFileTooltip"] = c.Tr("repo.editor.edit_this_file")
- } else if !c.Repo.IsViewBranch {
- c.Data["EditFileTooltip"] = c.Tr("repo.editor.must_be_on_a_branch")
- } else if !c.Repo.IsWriter() {
- c.Data["EditFileTooltip"] = c.Tr("repo.editor.fork_before_edit")
- }
-
- case tool.IsPDFFile(buf):
- c.Data["IsPDFFile"] = true
- case tool.IsVideoFile(buf):
- c.Data["IsVideoFile"] = true
- case tool.IsImageFile(buf):
- c.Data["IsImageFile"] = true
- }
-
- if canEnableEditor {
- c.Data["CanDeleteFile"] = true
- c.Data["DeleteFileTooltip"] = c.Tr("repo.editor.delete_this_file")
- } else if !c.Repo.IsViewBranch {
- c.Data["DeleteFileTooltip"] = c.Tr("repo.editor.must_be_on_a_branch")
- } else if !c.Repo.IsWriter() {
- c.Data["DeleteFileTooltip"] = c.Tr("repo.editor.must_have_write_access")
- }
-}
-
-func setEditorconfigIfExists(c *context.Context) {
- ec, err := c.Repo.GetEditorconfig()
- if err != nil && !git.IsErrNotExist(err) {
- log.Trace("setEditorconfigIfExists.GetEditorconfig [%d]: %v", c.Repo.Repository.ID, err)
- return
- }
- c.Data["Editorconfig"] = ec
-}
-
-func Home(c *context.Context) {
- c.Data["PageIsViewFiles"] = true
-
- if c.Repo.Repository.IsBare {
- c.HTML(200, BARE)
- return
- }
-
- title := c.Repo.Repository.Owner.Name + "/" + c.Repo.Repository.Name
- if len(c.Repo.Repository.Description) > 0 {
- title += ": " + c.Repo.Repository.Description
- }
- c.Data["Title"] = title
- if c.Repo.BranchName != c.Repo.Repository.DefaultBranch {
- c.Data["Title"] = title + " @ " + c.Repo.BranchName
- }
- c.Data["RequireHighlightJS"] = true
-
- branchLink := c.Repo.RepoLink + "/src/" + c.Repo.BranchName
- treeLink := branchLink
- rawLink := c.Repo.RepoLink + "/raw/" + c.Repo.BranchName
-
- isRootDir := false
- if len(c.Repo.TreePath) > 0 {
- treeLink += "/" + c.Repo.TreePath
- } else {
- isRootDir = true
-
- // Only show Git stats panel when view root directory
- var err error
- c.Repo.CommitsCount, err = c.Repo.Commit.CommitsCount()
- if err != nil {
- c.Handle(500, "CommitsCount", err)
- return
- }
- c.Data["CommitsCount"] = c.Repo.CommitsCount
- }
- c.Data["PageIsRepoHome"] = isRootDir
-
- // Get current entry user currently looking at.
- entry, err := c.Repo.Commit.GetTreeEntryByPath(c.Repo.TreePath)
- if err != nil {
- c.NotFoundOrServerError("Repo.Commit.GetTreeEntryByPath", git.IsErrNotExist, err)
- return
- }
-
- if entry.IsDir() {
- renderDirectory(c, treeLink)
- } else {
- renderFile(c, entry, treeLink, rawLink)
- }
- if c.Written() {
- return
- }
-
- setEditorconfigIfExists(c)
- if c.Written() {
- return
- }
-
- var treeNames []string
- paths := make([]string, 0, 5)
- if len(c.Repo.TreePath) > 0 {
- treeNames = strings.Split(c.Repo.TreePath, "/")
- for i := range treeNames {
- paths = append(paths, strings.Join(treeNames[:i+1], "/"))
- }
-
- c.Data["HasParentPath"] = true
- if len(paths)-2 >= 0 {
- c.Data["ParentPath"] = "/" + paths[len(paths)-2]
- }
- }
-
- c.Data["Paths"] = paths
- c.Data["TreeLink"] = treeLink
- c.Data["TreeNames"] = treeNames
- c.Data["BranchLink"] = branchLink
- c.HTML(200, HOME)
-}
-
-func RenderUserCards(c *context.Context, total int, getter func(page int) ([]*models.User, error), tpl string) {
- page := c.QueryInt("page")
- if page <= 0 {
- page = 1
- }
- pager := paginater.New(total, models.ItemsPerPage, page, 5)
- c.Data["Page"] = pager
-
- items, err := getter(pager.Current())
- if err != nil {
- c.Handle(500, "getter", err)
- return
- }
- c.Data["Cards"] = items
-
- c.HTML(200, tpl)
-}
-
-func Watchers(c *context.Context) {
- c.Data["Title"] = c.Tr("repo.watchers")
- c.Data["CardsTitle"] = c.Tr("repo.watchers")
- c.Data["PageIsWatchers"] = true
- RenderUserCards(c, c.Repo.Repository.NumWatches, c.Repo.Repository.GetWatchers, WATCHERS)
-}
-
-func Stars(c *context.Context) {
- c.Data["Title"] = c.Tr("repo.stargazers")
- c.Data["CardsTitle"] = c.Tr("repo.stargazers")
- c.Data["PageIsStargazers"] = true
- RenderUserCards(c, c.Repo.Repository.NumStars, c.Repo.Repository.GetStargazers, WATCHERS)
-}
-
-func Forks(c *context.Context) {
- c.Data["Title"] = c.Tr("repos.forks")
-
- forks, err := c.Repo.Repository.GetForks()
- if err != nil {
- c.Handle(500, "GetForks", err)
- return
- }
-
- for _, fork := range forks {
- if err = fork.GetOwner(); err != nil {
- c.Handle(500, "GetOwner", err)
- return
- }
- }
- c.Data["Forks"] = forks
-
- c.HTML(200, FORKS)
-}
diff --git a/routers/repo/webhook.go b/routers/repo/webhook.go
deleted file mode 100644
index c572d446..00000000
--- a/routers/repo/webhook.go
+++ /dev/null
@@ -1,558 +0,0 @@
-// Copyright 2015 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 repo
-
-import (
- "encoding/json"
- "fmt"
- "strings"
-
- "github.com/Unknwon/com"
-
- git "github.com/gogits/git-module"
- api "github.com/gogits/go-gogs-client"
-
- "github.com/gogits/gogs/models"
- "github.com/gogits/gogs/models/errors"
- "github.com/gogits/gogs/pkg/context"
- "github.com/gogits/gogs/pkg/form"
- "github.com/gogits/gogs/pkg/setting"
-)
-
-const (
- WEBHOOKS = "repo/settings/webhook/base"
- WEBHOOK_NEW = "repo/settings/webhook/new"
- ORG_WEBHOOK_NEW = "org/settings/webhook_new"
-)
-
-func Webhooks(c *context.Context) {
- c.Data["Title"] = c.Tr("repo.settings.hooks")
- c.Data["PageIsSettingsHooks"] = true
- c.Data["BaseLink"] = c.Repo.RepoLink
- c.Data["Description"] = c.Tr("repo.settings.hooks_desc", "https://github.com/gogits/go-gogs-client/wiki/Repositories-Webhooks")
- c.Data["Types"] = setting.Webhook.Types
-
- ws, err := models.GetWebhooksByRepoID(c.Repo.Repository.ID)
- if err != nil {
- c.Handle(500, "GetWebhooksByRepoID", err)
- return
- }
- c.Data["Webhooks"] = ws
-
- c.HTML(200, WEBHOOKS)
-}
-
-type OrgRepoCtx struct {
- OrgID int64
- RepoID int64
- Link string
- NewTemplate string
-}
-
-// getOrgRepoCtx determines whether this is a repo context or organization context.
-func getOrgRepoCtx(c *context.Context) (*OrgRepoCtx, error) {
- if len(c.Repo.RepoLink) > 0 {
- c.Data["PageIsRepositoryContext"] = true
- return &OrgRepoCtx{
- RepoID: c.Repo.Repository.ID,
- Link: c.Repo.RepoLink,
- NewTemplate: WEBHOOK_NEW,
- }, nil
- }
-
- if len(c.Org.OrgLink) > 0 {
- c.Data["PageIsOrganizationContext"] = true
- return &OrgRepoCtx{
- OrgID: c.Org.Organization.ID,
- Link: c.Org.OrgLink,
- NewTemplate: ORG_WEBHOOK_NEW,
- }, nil
- }
-
- return nil, errors.New("Unable to set OrgRepo context")
-}
-
-func checkHookType(c *context.Context) string {
- hookType := strings.ToLower(c.Params(":type"))
- if !com.IsSliceContainsStr(setting.Webhook.Types, hookType) {
- c.Handle(404, "checkHookType", nil)
- return ""
- }
- return hookType
-}
-
-func WebhooksNew(c *context.Context) {
- c.Data["Title"] = c.Tr("repo.settings.add_webhook")
- c.Data["PageIsSettingsHooks"] = true
- c.Data["PageIsSettingsHooksNew"] = true
- c.Data["Webhook"] = models.Webhook{HookEvent: &models.HookEvent{}}
-
- orCtx, err := getOrgRepoCtx(c)
- if err != nil {
- c.Handle(500, "getOrgRepoCtx", err)
- return
- }
-
- c.Data["HookType"] = checkHookType(c)
- if c.Written() {
- return
- }
- c.Data["BaseLink"] = orCtx.Link
-
- c.HTML(200, orCtx.NewTemplate)
-}
-
-func ParseHookEvent(f form.Webhook) *models.HookEvent {
- return &models.HookEvent{
- PushOnly: f.PushOnly(),
- SendEverything: f.SendEverything(),
- ChooseEvents: f.ChooseEvents(),
- HookEvents: models.HookEvents{
- Create: f.Create,
- Delete: f.Delete,
- Fork: f.Fork,
- Push: f.Push,
- Issues: f.Issues,
- IssueComment: f.IssueComment,
- PullRequest: f.PullRequest,
- Release: f.Release,
- },
- }
-}
-
-func WebHooksNewPost(c *context.Context, f form.NewWebhook) {
- c.Data["Title"] = c.Tr("repo.settings.add_webhook")
- c.Data["PageIsSettingsHooks"] = true
- c.Data["PageIsSettingsHooksNew"] = true
- c.Data["Webhook"] = models.Webhook{HookEvent: &models.HookEvent{}}
- c.Data["HookType"] = "gogs"
-
- orCtx, err := getOrgRepoCtx(c)
- if err != nil {
- c.Handle(500, "getOrgRepoCtx", err)
- return
- }
- c.Data["BaseLink"] = orCtx.Link
-
- if c.HasError() {
- c.HTML(200, orCtx.NewTemplate)
- return
- }
-
- contentType := models.JSON
- if models.HookContentType(f.ContentType) == models.FORM {
- contentType = models.FORM
- }
-
- w := &models.Webhook{
- RepoID: orCtx.RepoID,
- URL: f.PayloadURL,
- ContentType: contentType,
- Secret: f.Secret,
- HookEvent: ParseHookEvent(f.Webhook),
- IsActive: f.Active,
- HookTaskType: models.GOGS,
- OrgID: orCtx.OrgID,
- }
- if err := w.UpdateEvent(); err != nil {
- c.Handle(500, "UpdateEvent", err)
- return
- } else if err := models.CreateWebhook(w); err != nil {
- c.Handle(500, "CreateWebhook", err)
- return
- }
-
- c.Flash.Success(c.Tr("repo.settings.add_hook_success"))
- c.Redirect(orCtx.Link + "/settings/hooks")
-}
-
-func SlackHooksNewPost(c *context.Context, f form.NewSlackHook) {
- c.Data["Title"] = c.Tr("repo.settings")
- c.Data["PageIsSettingsHooks"] = true
- c.Data["PageIsSettingsHooksNew"] = true
- c.Data["Webhook"] = models.Webhook{HookEvent: &models.HookEvent{}}
-
- orCtx, err := getOrgRepoCtx(c)
- if err != nil {
- c.Handle(500, "getOrgRepoCtx", err)
- return
- }
-
- if c.HasError() {
- c.HTML(200, orCtx.NewTemplate)
- return
- }
-
- meta, err := json.Marshal(&models.SlackMeta{
- Channel: f.Channel,
- Username: f.Username,
- IconURL: f.IconURL,
- Color: f.Color,
- })
- if err != nil {
- c.Handle(500, "Marshal", err)
- return
- }
-
- w := &models.Webhook{
- RepoID: orCtx.RepoID,
- URL: f.PayloadURL,
- ContentType: models.JSON,
- HookEvent: ParseHookEvent(f.Webhook),
- IsActive: f.Active,
- HookTaskType: models.SLACK,
- Meta: string(meta),
- OrgID: orCtx.OrgID,
- }
- if err := w.UpdateEvent(); err != nil {
- c.Handle(500, "UpdateEvent", err)
- return
- } else if err := models.CreateWebhook(w); err != nil {
- c.Handle(500, "CreateWebhook", err)
- return
- }
-
- c.Flash.Success(c.Tr("repo.settings.add_hook_success"))
- c.Redirect(orCtx.Link + "/settings/hooks")
-}
-
-// FIXME: merge logic to Slack
-func DiscordHooksNewPost(c *context.Context, f form.NewDiscordHook) {
- c.Data["Title"] = c.Tr("repo.settings")
- c.Data["PageIsSettingsHooks"] = true
- c.Data["PageIsSettingsHooksNew"] = true
- c.Data["Webhook"] = models.Webhook{HookEvent: &models.HookEvent{}}
-
- orCtx, err := getOrgRepoCtx(c)
- if err != nil {
- c.Handle(500, "getOrgRepoCtx", err)
- return
- }
-
- if c.HasError() {
- c.HTML(200, orCtx.NewTemplate)
- return
- }
-
- meta, err := json.Marshal(&models.SlackMeta{
- Username: f.Username,
- IconURL: f.IconURL,
- Color: f.Color,
- })
- if err != nil {
- c.Handle(500, "Marshal", err)
- return
- }
-
- w := &models.Webhook{
- RepoID: orCtx.RepoID,
- URL: f.PayloadURL,
- ContentType: models.JSON,
- HookEvent: ParseHookEvent(f.Webhook),
- IsActive: f.Active,
- HookTaskType: models.DISCORD,
- Meta: string(meta),
- OrgID: orCtx.OrgID,
- }
- if err := w.UpdateEvent(); err != nil {
- c.Handle(500, "UpdateEvent", err)
- return
- } else if err := models.CreateWebhook(w); err != nil {
- c.Handle(500, "CreateWebhook", err)
- return
- }
-
- c.Flash.Success(c.Tr("repo.settings.add_hook_success"))
- c.Redirect(orCtx.Link + "/settings/hooks")
-}
-
-func checkWebhook(c *context.Context) (*OrgRepoCtx, *models.Webhook) {
- c.Data["RequireHighlightJS"] = true
-
- orCtx, err := getOrgRepoCtx(c)
- if err != nil {
- c.Handle(500, "getOrgRepoCtx", err)
- return nil, nil
- }
- c.Data["BaseLink"] = orCtx.Link
-
- var w *models.Webhook
- if orCtx.RepoID > 0 {
- w, err = models.GetWebhookOfRepoByID(c.Repo.Repository.ID, c.ParamsInt64(":id"))
- } else {
- w, err = models.GetWebhookByOrgID(c.Org.Organization.ID, c.ParamsInt64(":id"))
- }
- if err != nil {
- c.NotFoundOrServerError("GetWebhookOfRepoByID/GetWebhookByOrgID", errors.IsWebhookNotExist, err)
- return nil, nil
- }
-
- switch w.HookTaskType {
- case models.SLACK:
- c.Data["SlackHook"] = w.GetSlackHook()
- c.Data["HookType"] = "slack"
- case models.DISCORD:
- c.Data["SlackHook"] = w.GetSlackHook()
- c.Data["HookType"] = "discord"
- default:
- c.Data["HookType"] = "gogs"
- }
-
- c.Data["History"], err = w.History(1)
- if err != nil {
- c.Handle(500, "History", err)
- }
- return orCtx, w
-}
-
-func WebHooksEdit(c *context.Context) {
- c.Data["Title"] = c.Tr("repo.settings.update_webhook")
- c.Data["PageIsSettingsHooks"] = true
- c.Data["PageIsSettingsHooksEdit"] = true
-
- orCtx, w := checkWebhook(c)
- if c.Written() {
- return
- }
- c.Data["Webhook"] = w
-
- c.HTML(200, orCtx.NewTemplate)
-}
-
-func WebHooksEditPost(c *context.Context, f form.NewWebhook) {
- c.Data["Title"] = c.Tr("repo.settings.update_webhook")
- c.Data["PageIsSettingsHooks"] = true
- c.Data["PageIsSettingsHooksEdit"] = true
-
- orCtx, w := checkWebhook(c)
- if c.Written() {
- return
- }
- c.Data["Webhook"] = w
-
- if c.HasError() {
- c.HTML(200, orCtx.NewTemplate)
- return
- }
-
- contentType := models.JSON
- if models.HookContentType(f.ContentType) == models.FORM {
- contentType = models.FORM
- }
-
- w.URL = f.PayloadURL
- w.ContentType = contentType
- w.Secret = f.Secret
- w.HookEvent = ParseHookEvent(f.Webhook)
- w.IsActive = f.Active
- if err := w.UpdateEvent(); err != nil {
- c.Handle(500, "UpdateEvent", err)
- return
- } else if err := models.UpdateWebhook(w); err != nil {
- c.Handle(500, "WebHooksEditPost", err)
- return
- }
-
- c.Flash.Success(c.Tr("repo.settings.update_hook_success"))
- c.Redirect(fmt.Sprintf("%s/settings/hooks/%d", orCtx.Link, w.ID))
-}
-
-func SlackHooksEditPost(c *context.Context, f form.NewSlackHook) {
- c.Data["Title"] = c.Tr("repo.settings")
- c.Data["PageIsSettingsHooks"] = true
- c.Data["PageIsSettingsHooksEdit"] = true
-
- orCtx, w := checkWebhook(c)
- if c.Written() {
- return
- }
- c.Data["Webhook"] = w
-
- if c.HasError() {
- c.HTML(200, orCtx.NewTemplate)
- return
- }
-
- meta, err := json.Marshal(&models.SlackMeta{
- Channel: f.Channel,
- Username: f.Username,
- IconURL: f.IconURL,
- Color: f.Color,
- })
- if err != nil {
- c.Handle(500, "Marshal", err)
- return
- }
-
- w.URL = f.PayloadURL
- w.Meta = string(meta)
- w.HookEvent = ParseHookEvent(f.Webhook)
- w.IsActive = f.Active
- if err := w.UpdateEvent(); err != nil {
- c.Handle(500, "UpdateEvent", err)
- return
- } else if err := models.UpdateWebhook(w); err != nil {
- c.Handle(500, "UpdateWebhook", err)
- return
- }
-
- c.Flash.Success(c.Tr("repo.settings.update_hook_success"))
- c.Redirect(fmt.Sprintf("%s/settings/hooks/%d", orCtx.Link, w.ID))
-}
-
-// FIXME: merge logic to Slack
-func DiscordHooksEditPost(c *context.Context, f form.NewDiscordHook) {
- c.Data["Title"] = c.Tr("repo.settings")
- c.Data["PageIsSettingsHooks"] = true
- c.Data["PageIsSettingsHooksEdit"] = true
-
- orCtx, w := checkWebhook(c)
- if c.Written() {
- return
- }
- c.Data["Webhook"] = w
-
- if c.HasError() {
- c.HTML(200, orCtx.NewTemplate)
- return
- }
-
- meta, err := json.Marshal(&models.SlackMeta{
- Username: f.Username,
- IconURL: f.IconURL,
- Color: f.Color,
- })
- if err != nil {
- c.Handle(500, "Marshal", err)
- return
- }
-
- w.URL = f.PayloadURL
- w.Meta = string(meta)
- w.HookEvent = ParseHookEvent(f.Webhook)
- w.IsActive = f.Active
- if err := w.UpdateEvent(); err != nil {
- c.Handle(500, "UpdateEvent", err)
- return
- } else if err := models.UpdateWebhook(w); err != nil {
- c.Handle(500, "UpdateWebhook", err)
- return
- }
-
- c.Flash.Success(c.Tr("repo.settings.update_hook_success"))
- c.Redirect(fmt.Sprintf("%s/settings/hooks/%d", orCtx.Link, w.ID))
-}
-
-func TestWebhook(c *context.Context) {
- var authorUsername, committerUsername string
-
- // Grab latest commit or fake one if it's empty repository.
- commit := c.Repo.Commit
- if commit == nil {
- ghost := models.NewGhostUser()
- commit = &git.Commit{
- ID: git.MustIDFromString(git.EMPTY_SHA),
- Author: ghost.NewGitSig(),
- Committer: ghost.NewGitSig(),
- CommitMessage: "This is a fake commit",
- }
- authorUsername = ghost.Name
- committerUsername = ghost.Name
- } else {
- // Try to match email with a real user.
- author, err := models.GetUserByEmail(commit.Author.Email)
- if err == nil {
- authorUsername = author.Name
- } else if !errors.IsUserNotExist(err) {
- c.Handle(500, "GetUserByEmail.(author)", err)
- return
- }
-
- committer, err := models.GetUserByEmail(commit.Committer.Email)
- if err == nil {
- committerUsername = committer.Name
- } else if !errors.IsUserNotExist(err) {
- c.Handle(500, "GetUserByEmail.(committer)", err)
- return
- }
- }
-
- fileStatus, err := commit.FileStatus()
- if err != nil {
- c.Handle(500, "FileStatus", err)
- return
- }
-
- apiUser := c.User.APIFormat()
- p := &api.PushPayload{
- Ref: git.BRANCH_PREFIX + c.Repo.Repository.DefaultBranch,
- Before: commit.ID.String(),
- After: commit.ID.String(),
- Commits: []*api.PayloadCommit{
- {
- ID: commit.ID.String(),
- Message: commit.Message(),
- URL: c.Repo.Repository.HTMLURL() + "/commit/" + commit.ID.String(),
- Author: &api.PayloadUser{
- Name: commit.Author.Name,
- Email: commit.Author.Email,
- UserName: authorUsername,
- },
- Committer: &api.PayloadUser{
- Name: commit.Committer.Name,
- Email: commit.Committer.Email,
- UserName: committerUsername,
- },
- Added: fileStatus.Added,
- Removed: fileStatus.Removed,
- Modified: fileStatus.Modified,
- },
- },
- Repo: c.Repo.Repository.APIFormat(nil),
- Pusher: apiUser,
- Sender: apiUser,
- }
- if err := models.TestWebhook(c.Repo.Repository, models.HOOK_EVENT_PUSH, p, c.ParamsInt64("id")); err != nil {
- c.Handle(500, "TestWebhook", err)
- } else {
- c.Flash.Info(c.Tr("repo.settings.webhook.test_delivery_success"))
- c.Status(200)
- }
-}
-
-func RedeliveryWebhook(c *context.Context) {
- webhook, err := models.GetWebhookOfRepoByID(c.Repo.Repository.ID, c.ParamsInt64(":id"))
- if err != nil {
- c.NotFoundOrServerError("GetWebhookOfRepoByID/GetWebhookByOrgID", errors.IsWebhookNotExist, err)
- return
- }
-
- hookTask, err := models.GetHookTaskOfWebhookByUUID(webhook.ID, c.Query("uuid"))
- if err != nil {
- c.NotFoundOrServerError("GetHookTaskOfWebhookByUUID/GetWebhookByOrgID", errors.IsHookTaskNotExist, err)
- return
- }
-
- hookTask.IsDelivered = false
- if err = models.UpdateHookTask(hookTask); err != nil {
- c.Handle(500, "UpdateHookTask", err)
- } else {
- go models.HookQueue.Add(c.Repo.Repository.ID)
- c.Flash.Info(c.Tr("repo.settings.webhook.redelivery_success", hookTask.UUID))
- c.Status(200)
- }
-}
-
-func DeleteWebhook(c *context.Context) {
- if err := models.DeleteWebhookOfRepoByID(c.Repo.Repository.ID, c.QueryInt64("id")); err != nil {
- c.Flash.Error("DeleteWebhookByRepoID: " + err.Error())
- } else {
- c.Flash.Success(c.Tr("repo.settings.webhook_deletion_success"))
- }
-
- c.JSON(200, map[string]interface{}{
- "redirect": c.Repo.RepoLink + "/settings/hooks",
- })
-}
diff --git a/routers/repo/wiki.go b/routers/repo/wiki.go
deleted file mode 100644
index ad2cfbae..00000000
--- a/routers/repo/wiki.go
+++ /dev/null
@@ -1,274 +0,0 @@
-// Copyright 2015 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 repo
-
-import (
- "io/ioutil"
- "strings"
- "time"
-
- "github.com/gogits/git-module"
-
- "github.com/gogits/gogs/models"
- "github.com/gogits/gogs/pkg/context"
- "github.com/gogits/gogs/pkg/form"
- "github.com/gogits/gogs/pkg/markup"
-)
-
-const (
- WIKI_START = "repo/wiki/start"
- WIKI_VIEW = "repo/wiki/view"
- WIKI_NEW = "repo/wiki/new"
- WIKI_PAGES = "repo/wiki/pages"
-)
-
-func MustEnableWiki(c *context.Context) {
- if !c.Repo.Repository.EnableWiki {
- c.Handle(404, "MustEnableWiki", nil)
- return
- }
-
- if c.Repo.Repository.EnableExternalWiki {
- c.Redirect(c.Repo.Repository.ExternalWikiURL)
- return
- }
-}
-
-type PageMeta struct {
- Name string
- URL string
- Updated time.Time
-}
-
-func renderWikiPage(c *context.Context, isViewPage bool) (*git.Repository, string) {
- wikiRepo, err := git.OpenRepository(c.Repo.Repository.WikiPath())
- if err != nil {
- c.Handle(500, "OpenRepository", err)
- return nil, ""
- }
- commit, err := wikiRepo.GetBranchCommit("master")
- if err != nil {
- c.Handle(500, "GetBranchCommit", err)
- return nil, ""
- }
-
- // Get page list.
- if isViewPage {
- entries, err := commit.ListEntries()
- if err != nil {
- c.Handle(500, "ListEntries", err)
- return nil, ""
- }
- pages := make([]PageMeta, 0, len(entries))
- for i := range entries {
- if entries[i].Type == git.OBJECT_BLOB && strings.HasSuffix(entries[i].Name(), ".md") {
- name := strings.TrimSuffix(entries[i].Name(), ".md")
- pages = append(pages, PageMeta{
- Name: name,
- URL: models.ToWikiPageURL(name),
- })
- }
- }
- c.Data["Pages"] = pages
- }
-
- pageURL := c.Params(":page")
- if len(pageURL) == 0 {
- pageURL = "Home"
- }
- c.Data["PageURL"] = pageURL
-
- pageName := models.ToWikiPageName(pageURL)
- c.Data["old_title"] = pageName
- c.Data["Title"] = pageName
- c.Data["title"] = pageName
- c.Data["RequireHighlightJS"] = true
-
- blob, err := commit.GetBlobByPath(pageName + ".md")
- if err != nil {
- if git.IsErrNotExist(err) {
- c.Redirect(c.Repo.RepoLink + "/wiki/_pages")
- } else {
- c.Handle(500, "GetBlobByPath", err)
- }
- return nil, ""
- }
- r, err := blob.Data()
- if err != nil {
- c.Handle(500, "Data", err)
- return nil, ""
- }
- data, err := ioutil.ReadAll(r)
- if err != nil {
- c.Handle(500, "ReadAll", err)
- return nil, ""
- }
- if isViewPage {
- c.Data["content"] = string(markup.Markdown(data, c.Repo.RepoLink, c.Repo.Repository.ComposeMetas()))
- } else {
- c.Data["content"] = string(data)
- }
-
- return wikiRepo, pageName
-}
-
-func Wiki(c *context.Context) {
- c.Data["PageIsWiki"] = true
-
- if !c.Repo.Repository.HasWiki() {
- c.Data["Title"] = c.Tr("repo.wiki")
- c.HTML(200, WIKI_START)
- return
- }
-
- wikiRepo, pageName := renderWikiPage(c, true)
- if c.Written() {
- return
- }
-
- // Get last change information.
- lastCommit, err := wikiRepo.GetCommitByPath(pageName + ".md")
- if err != nil {
- c.Handle(500, "GetCommitByPath", err)
- return
- }
- c.Data["Author"] = lastCommit.Author
-
- c.HTML(200, WIKI_VIEW)
-}
-
-func WikiPages(c *context.Context) {
- c.Data["Title"] = c.Tr("repo.wiki.pages")
- c.Data["PageIsWiki"] = true
-
- if !c.Repo.Repository.HasWiki() {
- c.Redirect(c.Repo.RepoLink + "/wiki")
- return
- }
-
- wikiRepo, err := git.OpenRepository(c.Repo.Repository.WikiPath())
- if err != nil {
- c.Handle(500, "OpenRepository", err)
- return
- }
- commit, err := wikiRepo.GetBranchCommit("master")
- if err != nil {
- c.Handle(500, "GetBranchCommit", err)
- return
- }
-
- entries, err := commit.ListEntries()
- if err != nil {
- c.Handle(500, "ListEntries", err)
- return
- }
- pages := make([]PageMeta, 0, len(entries))
- for i := range entries {
- if entries[i].Type == git.OBJECT_BLOB && strings.HasSuffix(entries[i].Name(), ".md") {
- commit, err := wikiRepo.GetCommitByPath(entries[i].Name())
- if err != nil {
- c.ServerError("GetCommitByPath", err)
- return
- }
- name := strings.TrimSuffix(entries[i].Name(), ".md")
- pages = append(pages, PageMeta{
- Name: name,
- URL: models.ToWikiPageURL(name),
- Updated: commit.Author.When,
- })
- }
- }
- c.Data["Pages"] = pages
-
- c.HTML(200, WIKI_PAGES)
-}
-
-func NewWiki(c *context.Context) {
- c.Data["Title"] = c.Tr("repo.wiki.new_page")
- c.Data["PageIsWiki"] = true
- c.Data["RequireSimpleMDE"] = true
-
- if !c.Repo.Repository.HasWiki() {
- c.Data["title"] = "Home"
- }
-
- c.HTML(200, WIKI_NEW)
-}
-
-func NewWikiPost(c *context.Context, f form.NewWiki) {
- c.Data["Title"] = c.Tr("repo.wiki.new_page")
- c.Data["PageIsWiki"] = true
- c.Data["RequireSimpleMDE"] = true
-
- if c.HasError() {
- c.HTML(200, WIKI_NEW)
- return
- }
-
- if err := c.Repo.Repository.AddWikiPage(c.User, f.Title, f.Content, f.Message); err != nil {
- if models.IsErrWikiAlreadyExist(err) {
- c.Data["Err_Title"] = true
- c.RenderWithErr(c.Tr("repo.wiki.page_already_exists"), WIKI_NEW, &f)
- } else {
- c.Handle(500, "AddWikiPage", err)
- }
- return
- }
-
- c.Redirect(c.Repo.RepoLink + "/wiki/" + models.ToWikiPageURL(models.ToWikiPageName(f.Title)))
-}
-
-func EditWiki(c *context.Context) {
- c.Data["PageIsWiki"] = true
- c.Data["PageIsWikiEdit"] = true
- c.Data["RequireSimpleMDE"] = true
-
- if !c.Repo.Repository.HasWiki() {
- c.Redirect(c.Repo.RepoLink + "/wiki")
- return
- }
-
- renderWikiPage(c, false)
- if c.Written() {
- return
- }
-
- c.HTML(200, WIKI_NEW)
-}
-
-func EditWikiPost(c *context.Context, f form.NewWiki) {
- c.Data["Title"] = c.Tr("repo.wiki.new_page")
- c.Data["PageIsWiki"] = true
- c.Data["RequireSimpleMDE"] = true
-
- if c.HasError() {
- c.HTML(200, WIKI_NEW)
- return
- }
-
- if err := c.Repo.Repository.EditWikiPage(c.User, f.OldTitle, f.Title, f.Content, f.Message); err != nil {
- c.Handle(500, "EditWikiPage", err)
- return
- }
-
- c.Redirect(c.Repo.RepoLink + "/wiki/" + models.ToWikiPageURL(models.ToWikiPageName(f.Title)))
-}
-
-func DeleteWikiPagePost(c *context.Context) {
- pageURL := c.Params(":page")
- if len(pageURL) == 0 {
- pageURL = "Home"
- }
-
- pageName := models.ToWikiPageName(pageURL)
- if err := c.Repo.Repository.DeleteWikiPage(c.User, pageName); err != nil {
- c.Handle(500, "DeleteWikiPage", err)
- return
- }
-
- c.JSON(200, map[string]interface{}{
- "redirect": c.Repo.RepoLink + "/wiki/",
- })
-}
diff --git a/routers/user/auth.go b/routers/user/auth.go
deleted file mode 100644
index 34fdbd85..00000000
--- a/routers/user/auth.go
+++ /dev/null
@@ -1,534 +0,0 @@
-// 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 user
-
-import (
- "fmt"
- "net/url"
-
- "github.com/go-macaron/captcha"
- log "gopkg.in/clog.v1"
-
- "github.com/gogits/gogs/models"
- "github.com/gogits/gogs/models/errors"
- "github.com/gogits/gogs/pkg/context"
- "github.com/gogits/gogs/pkg/form"
- "github.com/gogits/gogs/pkg/mailer"
- "github.com/gogits/gogs/pkg/setting"
-)
-
-const (
- LOGIN = "user/auth/login"
- TWO_FACTOR = "user/auth/two_factor"
- TWO_FACTOR_RECOVERY_CODE = "user/auth/two_factor_recovery_code"
- SIGNUP = "user/auth/signup"
- ACTIVATE = "user/auth/activate"
- FORGOT_PASSWORD = "user/auth/forgot_passwd"
- RESET_PASSWORD = "user/auth/reset_passwd"
-)
-
-// AutoLogin reads cookie and try to auto-login.
-func AutoLogin(c *context.Context) (bool, error) {
- if !models.HasEngine {
- return false, nil
- }
-
- uname := c.GetCookie(setting.CookieUserName)
- if len(uname) == 0 {
- return false, nil
- }
-
- isSucceed := false
- defer func() {
- if !isSucceed {
- log.Trace("auto-login cookie cleared: %s", uname)
- c.SetCookie(setting.CookieUserName, "", -1, setting.AppSubURL)
- c.SetCookie(setting.CookieRememberName, "", -1, setting.AppSubURL)
- c.SetCookie(setting.LoginStatusCookieName, "", -1, setting.AppSubURL)
- }
- }()
-
- u, err := models.GetUserByName(uname)
- if err != nil {
- if !errors.IsUserNotExist(err) {
- return false, fmt.Errorf("GetUserByName: %v", err)
- }
- return false, nil
- }
-
- if val, ok := c.GetSuperSecureCookie(u.Rands+u.Passwd, setting.CookieRememberName); !ok || val != u.Name {
- return false, nil
- }
-
- isSucceed = true
- c.Session.Set("uid", u.ID)
- c.Session.Set("uname", u.Name)
- c.SetCookie(setting.CSRFCookieName, "", -1, setting.AppSubURL)
- if setting.EnableLoginStatusCookie {
- c.SetCookie(setting.LoginStatusCookieName, "true", 0, setting.AppSubURL)
- }
- return true, nil
-}
-
-// isValidRedirect returns false if the URL does not redirect to same site.
-// False: //url, http://url
-// True: /url
-func isValidRedirect(url string) bool {
- return len(url) >= 2 && url[0] == '/' && url[1] != '/'
-}
-
-func Login(c *context.Context) {
- c.Data["Title"] = c.Tr("sign_in")
-
- // Check auto-login.
- isSucceed, err := AutoLogin(c)
- if err != nil {
- c.Handle(500, "AutoLogin", err)
- return
- }
-
- redirectTo := c.Query("redirect_to")
- if len(redirectTo) > 0 {
- c.SetCookie("redirect_to", redirectTo, 0, setting.AppSubURL)
- } else {
- redirectTo, _ = url.QueryUnescape(c.GetCookie("redirect_to"))
- }
- c.SetCookie("redirect_to", "", -1, setting.AppSubURL)
-
- if isSucceed {
- if isValidRedirect(redirectTo) {
- c.Redirect(redirectTo)
- } else {
- c.Redirect(setting.AppSubURL + "/")
- }
- return
- }
-
- c.HTML(200, LOGIN)
-}
-
-func afterLogin(c *context.Context, u *models.User, remember bool) {
- if remember {
- days := 86400 * setting.LoginRememberDays
- c.SetCookie(setting.CookieUserName, u.Name, days, setting.AppSubURL, "", setting.CookieSecure, true)
- c.SetSuperSecureCookie(u.Rands+u.Passwd, setting.CookieRememberName, u.Name, days, setting.AppSubURL, "", setting.CookieSecure, true)
- }
-
- c.Session.Set("uid", u.ID)
- c.Session.Set("uname", u.Name)
- c.Session.Delete("twoFactorRemember")
- c.Session.Delete("twoFactorUserID")
-
- // Clear whatever CSRF has right now, force to generate a new one
- c.SetCookie(setting.CSRFCookieName, "", -1, setting.AppSubURL)
- if setting.EnableLoginStatusCookie {
- c.SetCookie(setting.LoginStatusCookieName, "true", 0, setting.AppSubURL)
- }
-
- redirectTo, _ := url.QueryUnescape(c.GetCookie("redirect_to"))
- c.SetCookie("redirect_to", "", -1, setting.AppSubURL)
- if isValidRedirect(redirectTo) {
- c.Redirect(redirectTo)
- return
- }
-
- c.Redirect(setting.AppSubURL + "/")
-}
-
-func LoginPost(c *context.Context, f form.SignIn) {
- c.Data["Title"] = c.Tr("sign_in")
-
- if c.HasError() {
- c.Success(LOGIN)
- return
- }
-
- u, err := models.UserSignIn(f.UserName, f.Password)
- if err != nil {
- if errors.IsUserNotExist(err) {
- c.RenderWithErr(c.Tr("form.username_password_incorrect"), LOGIN, &f)
- } else {
- c.ServerError("UserSignIn", err)
- }
- return
- }
-
- if !u.IsEnabledTwoFactor() {
- afterLogin(c, u, f.Remember)
- return
- }
-
- c.Session.Set("twoFactorRemember", f.Remember)
- c.Session.Set("twoFactorUserID", u.ID)
- c.Redirect(setting.AppSubURL + "/user/login/two_factor")
-}
-
-func LoginTwoFactor(c *context.Context) {
- _, ok := c.Session.Get("twoFactorUserID").(int64)
- if !ok {
- c.NotFound()
- return
- }
-
- c.Success(TWO_FACTOR)
-}
-
-func LoginTwoFactorPost(c *context.Context) {
- userID, ok := c.Session.Get("twoFactorUserID").(int64)
- if !ok {
- c.NotFound()
- return
- }
-
- t, err := models.GetTwoFactorByUserID(userID)
- if err != nil {
- c.ServerError("GetTwoFactorByUserID", err)
- return
- }
- valid, err := t.ValidateTOTP(c.Query("passcode"))
- if err != nil {
- c.ServerError("ValidateTOTP", err)
- return
- } else if !valid {
- c.Flash.Error(c.Tr("settings.two_factor_invalid_passcode"))
- c.Redirect(setting.AppSubURL + "/user/login/two_factor")
- return
- }
-
- u, err := models.GetUserByID(userID)
- if err != nil {
- c.ServerError("GetUserByID", err)
- return
- }
- afterLogin(c, u, c.Session.Get("twoFactorRemember").(bool))
-}
-
-func LoginTwoFactorRecoveryCode(c *context.Context) {
- _, ok := c.Session.Get("twoFactorUserID").(int64)
- if !ok {
- c.NotFound()
- return
- }
-
- c.Success(TWO_FACTOR_RECOVERY_CODE)
-}
-
-func LoginTwoFactorRecoveryCodePost(c *context.Context) {
- userID, ok := c.Session.Get("twoFactorUserID").(int64)
- if !ok {
- c.NotFound()
- return
- }
-
- if err := models.UseRecoveryCode(userID, c.Query("recovery_code")); err != nil {
- if errors.IsTwoFactorRecoveryCodeNotFound(err) {
- c.Flash.Error(c.Tr("auth.login_two_factor_invalid_recovery_code"))
- c.Redirect(setting.AppSubURL + "/user/login/two_factor_recovery_code")
- } else {
- c.ServerError("UseRecoveryCode", err)
- }
- return
- }
-
- u, err := models.GetUserByID(userID)
- if err != nil {
- c.ServerError("GetUserByID", err)
- return
- }
- afterLogin(c, u, c.Session.Get("twoFactorRemember").(bool))
-}
-
-func SignOut(c *context.Context) {
- c.Session.Delete("uid")
- c.Session.Delete("uname")
- c.SetCookie(setting.CookieUserName, "", -1, setting.AppSubURL)
- c.SetCookie(setting.CookieRememberName, "", -1, setting.AppSubURL)
- c.SetCookie(setting.CSRFCookieName, "", -1, setting.AppSubURL)
- c.Redirect(setting.AppSubURL + "/")
-}
-
-func SignUp(c *context.Context) {
- c.Data["Title"] = c.Tr("sign_up")
-
- c.Data["EnableCaptcha"] = setting.Service.EnableCaptcha
-
- if setting.Service.DisableRegistration {
- c.Data["DisableRegistration"] = true
- c.HTML(200, SIGNUP)
- return
- }
-
- c.HTML(200, SIGNUP)
-}
-
-func SignUpPost(c *context.Context, cpt *captcha.Captcha, f form.Register) {
- c.Data["Title"] = c.Tr("sign_up")
-
- c.Data["EnableCaptcha"] = setting.Service.EnableCaptcha
-
- if setting.Service.DisableRegistration {
- c.Error(403)
- return
- }
-
- if c.HasError() {
- c.HTML(200, SIGNUP)
- return
- }
-
- if setting.Service.EnableCaptcha && !cpt.VerifyReq(c.Req) {
- c.Data["Err_Captcha"] = true
- c.RenderWithErr(c.Tr("form.captcha_incorrect"), SIGNUP, &f)
- return
- }
-
- if f.Password != f.Retype {
- c.Data["Err_Password"] = true
- c.RenderWithErr(c.Tr("form.password_not_match"), SIGNUP, &f)
- return
- }
-
- u := &models.User{
- Name: f.UserName,
- Email: f.Email,
- Passwd: f.Password,
- IsActive: !setting.Service.RegisterEmailConfirm,
- }
- if err := models.CreateUser(u); err != nil {
- switch {
- case models.IsErrUserAlreadyExist(err):
- c.Data["Err_UserName"] = true
- c.RenderWithErr(c.Tr("form.username_been_taken"), SIGNUP, &f)
- case models.IsErrEmailAlreadyUsed(err):
- c.Data["Err_Email"] = true
- c.RenderWithErr(c.Tr("form.email_been_used"), SIGNUP, &f)
- case models.IsErrNameReserved(err):
- c.Data["Err_UserName"] = true
- c.RenderWithErr(c.Tr("user.form.name_reserved", err.(models.ErrNameReserved).Name), SIGNUP, &f)
- case models.IsErrNamePatternNotAllowed(err):
- c.Data["Err_UserName"] = true
- c.RenderWithErr(c.Tr("user.form.name_pattern_not_allowed", err.(models.ErrNamePatternNotAllowed).Pattern), SIGNUP, &f)
- default:
- c.Handle(500, "CreateUser", err)
- }
- return
- }
- log.Trace("Account created: %s", u.Name)
-
- // Auto-set admin for the only user.
- if models.CountUsers() == 1 {
- u.IsAdmin = true
- u.IsActive = true
- if err := models.UpdateUser(u); err != nil {
- c.Handle(500, "UpdateUser", err)
- return
- }
- }
-
- // Send confirmation email, no need for social account.
- if setting.Service.RegisterEmailConfirm && u.ID > 1 {
- mailer.SendActivateAccountMail(c.Context, models.NewMailerUser(u))
- c.Data["IsSendRegisterMail"] = true
- c.Data["Email"] = u.Email
- c.Data["Hours"] = setting.Service.ActiveCodeLives / 60
- c.HTML(200, ACTIVATE)
-
- if err := c.Cache.Put("MailResendLimit_"+u.LowerName, u.LowerName, 180); err != nil {
- log.Error(4, "Set cache(MailResendLimit) fail: %v", err)
- }
- return
- }
-
- c.Redirect(setting.AppSubURL + "/user/login")
-}
-
-func Activate(c *context.Context) {
- code := c.Query("code")
- if len(code) == 0 {
- c.Data["IsActivatePage"] = true
- if c.User.IsActive {
- c.Error(404)
- return
- }
- // Resend confirmation email.
- if setting.Service.RegisterEmailConfirm {
- if c.Cache.IsExist("MailResendLimit_" + c.User.LowerName) {
- c.Data["ResendLimited"] = true
- } else {
- c.Data["Hours"] = setting.Service.ActiveCodeLives / 60
- mailer.SendActivateAccountMail(c.Context, models.NewMailerUser(c.User))
-
- keyName := "MailResendLimit_" + c.User.LowerName
- if err := c.Cache.Put(keyName, c.User.LowerName, 180); err != nil {
- log.Error(2, "Set cache '%s' fail: %v", keyName, err)
- }
- }
- } else {
- c.Data["ServiceNotEnabled"] = true
- }
- c.HTML(200, ACTIVATE)
- return
- }
-
- // Verify code.
- if user := models.VerifyUserActiveCode(code); user != nil {
- user.IsActive = true
- var err error
- if user.Rands, err = models.GetUserSalt(); err != nil {
- c.Handle(500, "UpdateUser", err)
- return
- }
- if err := models.UpdateUser(user); err != nil {
- c.Handle(500, "UpdateUser", err)
- return
- }
-
- log.Trace("User activated: %s", user.Name)
-
- c.Session.Set("uid", user.ID)
- c.Session.Set("uname", user.Name)
- c.Redirect(setting.AppSubURL + "/")
- return
- }
-
- c.Data["IsActivateFailed"] = true
- c.HTML(200, ACTIVATE)
-}
-
-func ActivateEmail(c *context.Context) {
- code := c.Query("code")
- email_string := c.Query("email")
-
- // Verify code.
- if email := models.VerifyActiveEmailCode(code, email_string); email != nil {
- if err := email.Activate(); err != nil {
- c.Handle(500, "ActivateEmail", err)
- }
-
- log.Trace("Email activated: %s", email.Email)
- c.Flash.Success(c.Tr("settings.add_email_success"))
- }
-
- c.Redirect(setting.AppSubURL + "/user/settings/email")
- return
-}
-
-func ForgotPasswd(c *context.Context) {
- c.Data["Title"] = c.Tr("auth.forgot_password")
-
- if setting.MailService == nil {
- c.Data["IsResetDisable"] = true
- c.HTML(200, FORGOT_PASSWORD)
- return
- }
-
- c.Data["IsResetRequest"] = true
- c.HTML(200, FORGOT_PASSWORD)
-}
-
-func ForgotPasswdPost(c *context.Context) {
- c.Data["Title"] = c.Tr("auth.forgot_password")
-
- if setting.MailService == nil {
- c.Handle(403, "ForgotPasswdPost", nil)
- return
- }
- c.Data["IsResetRequest"] = true
-
- email := c.Query("email")
- c.Data["Email"] = email
-
- u, err := models.GetUserByEmail(email)
- if err != nil {
- if errors.IsUserNotExist(err) {
- c.Data["Hours"] = setting.Service.ActiveCodeLives / 60
- c.Data["IsResetSent"] = true
- c.HTML(200, FORGOT_PASSWORD)
- return
- } else {
- c.Handle(500, "user.ResetPasswd(check existence)", err)
- }
- return
- }
-
- if !u.IsLocal() {
- c.Data["Err_Email"] = true
- c.RenderWithErr(c.Tr("auth.non_local_account"), FORGOT_PASSWORD, nil)
- return
- }
-
- if c.Cache.IsExist("MailResendLimit_" + u.LowerName) {
- c.Data["ResendLimited"] = true
- c.HTML(200, FORGOT_PASSWORD)
- return
- }
-
- mailer.SendResetPasswordMail(c.Context, models.NewMailerUser(u))
- if err = c.Cache.Put("MailResendLimit_"+u.LowerName, u.LowerName, 180); err != nil {
- log.Error(4, "Set cache(MailResendLimit) fail: %v", err)
- }
-
- c.Data["Hours"] = setting.Service.ActiveCodeLives / 60
- c.Data["IsResetSent"] = true
- c.HTML(200, FORGOT_PASSWORD)
-}
-
-func ResetPasswd(c *context.Context) {
- c.Data["Title"] = c.Tr("auth.reset_password")
-
- code := c.Query("code")
- if len(code) == 0 {
- c.Error(404)
- return
- }
- c.Data["Code"] = code
- c.Data["IsResetForm"] = true
- c.HTML(200, RESET_PASSWORD)
-}
-
-func ResetPasswdPost(c *context.Context) {
- c.Data["Title"] = c.Tr("auth.reset_password")
-
- code := c.Query("code")
- if len(code) == 0 {
- c.Error(404)
- return
- }
- c.Data["Code"] = code
-
- if u := models.VerifyUserActiveCode(code); u != nil {
- // Validate password length.
- passwd := c.Query("password")
- if len(passwd) < 6 {
- c.Data["IsResetForm"] = true
- c.Data["Err_Password"] = true
- c.RenderWithErr(c.Tr("auth.password_too_short"), RESET_PASSWORD, nil)
- return
- }
-
- u.Passwd = passwd
- var err error
- if u.Rands, err = models.GetUserSalt(); err != nil {
- c.Handle(500, "UpdateUser", err)
- return
- }
- if u.Salt, err = models.GetUserSalt(); err != nil {
- c.Handle(500, "UpdateUser", err)
- return
- }
- u.EncodePasswd()
- if err := models.UpdateUser(u); err != nil {
- c.Handle(500, "UpdateUser", err)
- return
- }
-
- log.Trace("User password reset: %s", u.Name)
- c.Redirect(setting.AppSubURL + "/user/login")
- return
- }
-
- c.Data["IsResetFailed"] = true
- c.HTML(200, RESET_PASSWORD)
-}
diff --git a/routers/user/home.go b/routers/user/home.go
deleted file mode 100644
index c3b9b182..00000000
--- a/routers/user/home.go
+++ /dev/null
@@ -1,424 +0,0 @@
-// 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 user
-
-import (
- "bytes"
- "fmt"
-
- "github.com/Unknwon/com"
- "github.com/Unknwon/paginater"
-
- "github.com/gogits/gogs/models"
- "github.com/gogits/gogs/models/errors"
- "github.com/gogits/gogs/pkg/context"
- "github.com/gogits/gogs/pkg/setting"
-)
-
-const (
- DASHBOARD = "user/dashboard/dashboard"
- NEWS_FEED = "user/dashboard/feeds"
- ISSUES = "user/dashboard/issues"
- PROFILE = "user/profile"
- ORG_HOME = "org/home"
-)
-
-// getDashboardContextUser finds out dashboard is viewing as which context user.
-func getDashboardContextUser(c *context.Context) *models.User {
- ctxUser := c.User
- orgName := c.Params(":org")
- if len(orgName) > 0 {
- // Organization.
- org, err := models.GetUserByName(orgName)
- if err != nil {
- c.NotFoundOrServerError("GetUserByName", errors.IsUserNotExist, err)
- return nil
- }
- ctxUser = org
- }
- c.Data["ContextUser"] = ctxUser
-
- if err := c.User.GetOrganizations(true); err != nil {
- c.Handle(500, "GetOrganizations", err)
- return nil
- }
- c.Data["Orgs"] = c.User.Orgs
-
- return ctxUser
-}
-
-// retrieveFeeds loads feeds from database by given context user.
-// The user could be organization so it is not always the logged in user,
-// which is why we have to explicitly pass the context user ID.
-func retrieveFeeds(c *context.Context, ctxUser *models.User, userID int64, isProfile bool) {
- actions, err := models.GetFeeds(ctxUser, userID, c.QueryInt64("after_id"), isProfile)
- if err != nil {
- c.Handle(500, "GetFeeds", err)
- return
- }
-
- // Check access of private repositories.
- feeds := make([]*models.Action, 0, len(actions))
- unameAvatars := make(map[string]string)
- for _, act := range actions {
- // Cache results to reduce queries.
- _, ok := unameAvatars[act.ActUserName]
- if !ok {
- u, err := models.GetUserByName(act.ActUserName)
- if err != nil {
- if errors.IsUserNotExist(err) {
- continue
- }
- c.Handle(500, "GetUserByName", err)
- return
- }
- unameAvatars[act.ActUserName] = u.RelAvatarLink()
- }
-
- act.ActAvatar = unameAvatars[act.ActUserName]
- feeds = append(feeds, act)
- }
- c.Data["Feeds"] = feeds
- if len(feeds) > 0 {
- afterID := feeds[len(feeds)-1].ID
- c.Data["AfterID"] = afterID
- c.Header().Set("X-AJAX-URL", fmt.Sprintf("%s?after_id=%d", c.Data["Link"], afterID))
- }
-}
-
-func Dashboard(c *context.Context) {
- ctxUser := getDashboardContextUser(c)
- if c.Written() {
- return
- }
-
- retrieveFeeds(c, ctxUser, c.User.ID, false)
- if c.Written() {
- return
- }
-
- if c.Req.Header.Get("X-AJAX") == "true" {
- c.HTML(200, NEWS_FEED)
- return
- }
-
- c.Data["Title"] = ctxUser.DisplayName() + " - " + c.Tr("dashboard")
- c.Data["PageIsDashboard"] = true
- c.Data["PageIsNews"] = true
-
- // Only user can have collaborative repositories.
- if !ctxUser.IsOrganization() {
- collaborateRepos, err := c.User.GetAccessibleRepositories(setting.UI.User.RepoPagingNum)
- if err != nil {
- c.Handle(500, "GetAccessibleRepositories", err)
- return
- } else if err = models.RepositoryList(collaborateRepos).LoadAttributes(); err != nil {
- c.Handle(500, "RepositoryList.LoadAttributes", err)
- return
- }
- c.Data["CollaborativeRepos"] = collaborateRepos
- }
-
- var err error
- var repos, mirrors []*models.Repository
- var repoCount int64
- if ctxUser.IsOrganization() {
- repos, repoCount, err = ctxUser.GetUserRepositories(c.User.ID, 1, setting.UI.User.RepoPagingNum)
- if err != nil {
- c.Handle(500, "GetUserRepositories", err)
- return
- }
-
- mirrors, err = ctxUser.GetUserMirrorRepositories(c.User.ID)
- if err != nil {
- c.Handle(500, "GetUserMirrorRepositories", err)
- return
- }
- } else {
- if err = ctxUser.GetRepositories(1, setting.UI.User.RepoPagingNum); err != nil {
- c.Handle(500, "GetRepositories", err)
- return
- }
- repos = ctxUser.Repos
- repoCount = int64(ctxUser.NumRepos)
-
- mirrors, err = ctxUser.GetMirrorRepositories()
- if err != nil {
- c.Handle(500, "GetMirrorRepositories", err)
- return
- }
- }
- c.Data["Repos"] = repos
- c.Data["RepoCount"] = repoCount
- c.Data["MaxShowRepoNum"] = setting.UI.User.RepoPagingNum
-
- if err := models.MirrorRepositoryList(mirrors).LoadAttributes(); err != nil {
- c.Handle(500, "MirrorRepositoryList.LoadAttributes", err)
- return
- }
- c.Data["MirrorCount"] = len(mirrors)
- c.Data["Mirrors"] = mirrors
-
- c.HTML(200, DASHBOARD)
-}
-
-func Issues(c *context.Context) {
- isPullList := c.Params(":type") == "pulls"
- if isPullList {
- c.Data["Title"] = c.Tr("pull_requests")
- c.Data["PageIsPulls"] = true
- } else {
- c.Data["Title"] = c.Tr("issues")
- c.Data["PageIsIssues"] = true
- }
-
- ctxUser := getDashboardContextUser(c)
- if c.Written() {
- return
- }
-
- var (
- sortType = c.Query("sort")
- filterMode = models.FILTER_MODE_YOUR_REPOS
- )
-
- // Note: Organization does not have view type and filter mode.
- if !ctxUser.IsOrganization() {
- viewType := c.Query("type")
- types := []string{
- string(models.FILTER_MODE_YOUR_REPOS),
- string(models.FILTER_MODE_ASSIGN),
- string(models.FILTER_MODE_CREATE),
- }
- if !com.IsSliceContainsStr(types, viewType) {
- viewType = string(models.FILTER_MODE_YOUR_REPOS)
- }
- filterMode = models.FilterMode(viewType)
- }
-
- page := c.QueryInt("page")
- if page <= 1 {
- page = 1
- }
-
- repoID := c.QueryInt64("repo")
- isShowClosed := c.Query("state") == "closed"
-
- // Get repositories.
- var (
- err error
- repos []*models.Repository
- userRepoIDs []int64
- showRepos = make([]*models.Repository, 0, 10)
- )
- if ctxUser.IsOrganization() {
- repos, _, err = ctxUser.GetUserRepositories(c.User.ID, 1, ctxUser.NumRepos)
- if err != nil {
- c.Handle(500, "GetRepositories", err)
- return
- }
- } else {
- if err := ctxUser.GetRepositories(1, c.User.NumRepos); err != nil {
- c.Handle(500, "GetRepositories", err)
- return
- }
- repos = ctxUser.Repos
- }
-
- userRepoIDs = make([]int64, 0, len(repos))
- for _, repo := range repos {
- userRepoIDs = append(userRepoIDs, repo.ID)
-
- if filterMode != models.FILTER_MODE_YOUR_REPOS {
- continue
- }
-
- if isPullList {
- if isShowClosed && repo.NumClosedPulls == 0 ||
- !isShowClosed && repo.NumOpenPulls == 0 {
- continue
- }
- } else {
- if !repo.EnableIssues || repo.EnableExternalTracker ||
- isShowClosed && repo.NumClosedIssues == 0 ||
- !isShowClosed && repo.NumOpenIssues == 0 {
- continue
- }
- }
-
- showRepos = append(showRepos, repo)
- }
-
- // Filter repositories if the page shows issues.
- if !isPullList {
- userRepoIDs, err = models.FilterRepositoryWithIssues(userRepoIDs)
- if err != nil {
- c.Handle(500, "FilterRepositoryWithIssues", err)
- return
- }
- }
-
- issueOptions := &models.IssuesOptions{
- RepoID: repoID,
- Page: page,
- IsClosed: isShowClosed,
- IsPull: isPullList,
- SortType: sortType,
- }
- switch filterMode {
- case models.FILTER_MODE_YOUR_REPOS:
- // Get all issues from repositories from this user.
- if userRepoIDs == nil {
- issueOptions.RepoIDs = []int64{-1}
- } else {
- issueOptions.RepoIDs = userRepoIDs
- }
-
- case models.FILTER_MODE_ASSIGN:
- // Get all issues assigned to this user.
- issueOptions.AssigneeID = ctxUser.ID
-
- case models.FILTER_MODE_CREATE:
- // Get all issues created by this user.
- issueOptions.PosterID = ctxUser.ID
- }
-
- issues, err := models.Issues(issueOptions)
- if err != nil {
- c.Handle(500, "Issues", err)
- return
- }
-
- if repoID > 0 {
- repo, err := models.GetRepositoryByID(repoID)
- if err != nil {
- c.Handle(500, "GetRepositoryByID", fmt.Errorf("[#%d] %v", repoID, err))
- return
- }
-
- if err = repo.GetOwner(); err != nil {
- c.Handle(500, "GetOwner", fmt.Errorf("[#%d] %v", repoID, err))
- return
- }
-
- // Check if user has access to given repository.
- if !repo.IsOwnedBy(ctxUser.ID) && !repo.HasAccess(ctxUser.ID) {
- c.Handle(404, "Issues", fmt.Errorf("#%d", repoID))
- return
- }
- }
-
- for _, issue := range issues {
- if err = issue.Repo.GetOwner(); err != nil {
- c.Handle(500, "GetOwner", fmt.Errorf("[#%d] %v", issue.RepoID, err))
- return
- }
- }
-
- issueStats := models.GetUserIssueStats(repoID, ctxUser.ID, userRepoIDs, filterMode, isPullList)
-
- var total int
- if !isShowClosed {
- total = int(issueStats.OpenCount)
- } else {
- total = int(issueStats.ClosedCount)
- }
-
- c.Data["Issues"] = issues
- c.Data["Repos"] = showRepos
- c.Data["Page"] = paginater.New(total, setting.UI.IssuePagingNum, page, 5)
- c.Data["IssueStats"] = issueStats
- c.Data["ViewType"] = string(filterMode)
- c.Data["SortType"] = sortType
- c.Data["RepoID"] = repoID
- c.Data["IsShowClosed"] = isShowClosed
-
- if isShowClosed {
- c.Data["State"] = "closed"
- } else {
- c.Data["State"] = "open"
- }
-
- c.HTML(200, ISSUES)
-}
-
-func ShowSSHKeys(c *context.Context, uid int64) {
- keys, err := models.ListPublicKeys(uid)
- if err != nil {
- c.Handle(500, "ListPublicKeys", err)
- return
- }
-
- var buf bytes.Buffer
- for i := range keys {
- buf.WriteString(keys[i].OmitEmail())
- buf.WriteString("\n")
- }
- c.PlainText(200, buf.Bytes())
-}
-
-func showOrgProfile(c *context.Context) {
- c.SetParams(":org", c.Params(":username"))
- context.HandleOrgAssignment(c)
- if c.Written() {
- return
- }
-
- org := c.Org.Organization
- c.Data["Title"] = org.FullName
-
- page := c.QueryInt("page")
- if page <= 0 {
- page = 1
- }
-
- var (
- repos []*models.Repository
- count int64
- err error
- )
- if c.IsLogged && !c.User.IsAdmin {
- repos, count, err = org.GetUserRepositories(c.User.ID, page, setting.UI.User.RepoPagingNum)
- if err != nil {
- c.Handle(500, "GetUserRepositories", err)
- return
- }
- c.Data["Repos"] = repos
- } else {
- showPrivate := c.IsLogged && c.User.IsAdmin
- repos, err = models.GetUserRepositories(&models.UserRepoOptions{
- UserID: org.ID,
- Private: showPrivate,
- Page: page,
- PageSize: setting.UI.User.RepoPagingNum,
- })
- if err != nil {
- c.Handle(500, "GetRepositories", err)
- return
- }
- c.Data["Repos"] = repos
- count = models.CountUserRepositories(org.ID, showPrivate)
- }
- c.Data["Page"] = paginater.New(int(count), setting.UI.User.RepoPagingNum, page, 5)
-
- if err := org.GetMembers(); err != nil {
- c.Handle(500, "GetMembers", err)
- return
- }
- c.Data["Members"] = org.Members
-
- c.Data["Teams"] = org.Teams
-
- c.HTML(200, ORG_HOME)
-}
-
-func Email2User(c *context.Context) {
- u, err := models.GetUserByEmail(c.Query("email"))
- if err != nil {
- c.NotFoundOrServerError("GetUserByEmail", errors.IsUserNotExist, err)
- return
- }
- c.Redirect(setting.AppSubURL + "/user/" + u.Name)
-}
diff --git a/routers/user/profile.go b/routers/user/profile.go
deleted file mode 100644
index dc8ba6ae..00000000
--- a/routers/user/profile.go
+++ /dev/null
@@ -1,169 +0,0 @@
-// Copyright 2015 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 user
-
-import (
- "fmt"
- "path"
- "strings"
-
- "github.com/Unknwon/paginater"
-
- "github.com/gogits/gogs/models"
- "github.com/gogits/gogs/models/errors"
- "github.com/gogits/gogs/pkg/context"
- "github.com/gogits/gogs/pkg/setting"
- "github.com/gogits/gogs/routers/repo"
-)
-
-const (
- FOLLOWERS = "user/meta/followers"
- STARS = "user/meta/stars"
-)
-
-func GetUserByName(c *context.Context, name string) *models.User {
- user, err := models.GetUserByName(name)
- if err != nil {
- c.NotFoundOrServerError("GetUserByName", errors.IsUserNotExist, err)
- return nil
- }
- return user
-}
-
-// GetUserByParams returns user whose name is presented in URL paramenter.
-func GetUserByParams(c *context.Context) *models.User {
- return GetUserByName(c, c.Params(":username"))
-}
-
-func Profile(c *context.Context) {
- uname := c.Params(":username")
- // Special handle for FireFox requests favicon.ico.
- if uname == "favicon.ico" {
- c.ServeFile(path.Join(setting.StaticRootPath, "public/img/favicon.png"))
- return
- } else if strings.HasSuffix(uname, ".png") {
- c.Error(404)
- return
- }
-
- isShowKeys := false
- if strings.HasSuffix(uname, ".keys") {
- isShowKeys = true
- }
-
- ctxUser := GetUserByName(c, strings.TrimSuffix(uname, ".keys"))
- if c.Written() {
- return
- }
-
- // Show SSH keys.
- if isShowKeys {
- ShowSSHKeys(c, ctxUser.ID)
- return
- }
-
- if ctxUser.IsOrganization() {
- showOrgProfile(c)
- return
- }
-
- c.Data["Title"] = ctxUser.DisplayName()
- c.Data["PageIsUserProfile"] = true
- c.Data["Owner"] = ctxUser
-
- orgs, err := models.GetOrgsByUserID(ctxUser.ID, c.IsLogged && (c.User.IsAdmin || c.User.ID == ctxUser.ID))
- if err != nil {
- c.Handle(500, "GetOrgsByUserIDDesc", err)
- return
- }
-
- c.Data["Orgs"] = orgs
-
- tab := c.Query("tab")
- c.Data["TabName"] = tab
- switch tab {
- case "activity":
- retrieveFeeds(c, ctxUser, -1, true)
- if c.Written() {
- return
- }
- default:
- page := c.QueryInt("page")
- if page <= 0 {
- page = 1
- }
-
- showPrivate := c.IsLogged && (ctxUser.ID == c.User.ID || c.User.IsAdmin)
- c.Data["Repos"], err = models.GetUserRepositories(&models.UserRepoOptions{
- UserID: ctxUser.ID,
- Private: showPrivate,
- Page: page,
- PageSize: setting.UI.User.RepoPagingNum,
- })
- if err != nil {
- c.Handle(500, "GetRepositories", err)
- return
- }
-
- count := models.CountUserRepositories(ctxUser.ID, showPrivate)
- c.Data["Page"] = paginater.New(int(count), setting.UI.User.RepoPagingNum, page, 5)
- }
-
- c.HTML(200, PROFILE)
-}
-
-func Followers(c *context.Context) {
- u := GetUserByParams(c)
- if c.Written() {
- return
- }
- c.Data["Title"] = u.DisplayName()
- c.Data["CardsTitle"] = c.Tr("user.followers")
- c.Data["PageIsFollowers"] = true
- c.Data["Owner"] = u
- repo.RenderUserCards(c, u.NumFollowers, u.GetFollowers, FOLLOWERS)
-}
-
-func Following(c *context.Context) {
- u := GetUserByParams(c)
- if c.Written() {
- return
- }
- c.Data["Title"] = u.DisplayName()
- c.Data["CardsTitle"] = c.Tr("user.following")
- c.Data["PageIsFollowing"] = true
- c.Data["Owner"] = u
- repo.RenderUserCards(c, u.NumFollowing, u.GetFollowing, FOLLOWERS)
-}
-
-func Stars(c *context.Context) {
-
-}
-
-func Action(c *context.Context) {
- u := GetUserByParams(c)
- if c.Written() {
- return
- }
-
- var err error
- switch c.Params(":action") {
- case "follow":
- err = models.FollowUser(c.User.ID, u.ID)
- case "unfollow":
- err = models.UnfollowUser(c.User.ID, u.ID)
- }
-
- if err != nil {
- c.Handle(500, fmt.Sprintf("Action (%s)", c.Params(":action")), err)
- return
- }
-
- redirectTo := c.Query("redirect_to")
- if len(redirectTo) == 0 {
- redirectTo = u.HomeLink()
- }
- c.Redirect(redirectTo)
-}
diff --git a/routers/user/setting.go b/routers/user/setting.go
deleted file mode 100644
index 723b3da2..00000000
--- a/routers/user/setting.go
+++ /dev/null
@@ -1,664 +0,0 @@
-// 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 user
-
-import (
- "bytes"
- "encoding/base64"
- "fmt"
- "html/template"
- "image/png"
- "io/ioutil"
- "strings"
-
- "github.com/Unknwon/com"
- "github.com/pquerna/otp"
- "github.com/pquerna/otp/totp"
- log "gopkg.in/clog.v1"
-
- "github.com/gogits/gogs/models"
- "github.com/gogits/gogs/models/errors"
- "github.com/gogits/gogs/pkg/context"
- "github.com/gogits/gogs/pkg/form"
- "github.com/gogits/gogs/pkg/mailer"
- "github.com/gogits/gogs/pkg/setting"
- "github.com/gogits/gogs/pkg/tool"
-)
-
-const (
- SETTINGS_PROFILE = "user/settings/profile"
- SETTINGS_AVATAR = "user/settings/avatar"
- SETTINGS_PASSWORD = "user/settings/password"
- SETTINGS_EMAILS = "user/settings/email"
- SETTINGS_SSH_KEYS = "user/settings/sshkeys"
- SETTINGS_SECURITY = "user/settings/security"
- SETTINGS_TWO_FACTOR_ENABLE = "user/settings/two_factor_enable"
- SETTINGS_TWO_FACTOR_RECOVERY_CODES = "user/settings/two_factor_recovery_codes"
- SETTINGS_REPOSITORIES = "user/settings/repositories"
- SETTINGS_ORGANIZATIONS = "user/settings/organizations"
- SETTINGS_APPLICATIONS = "user/settings/applications"
- SETTINGS_DELETE = "user/settings/delete"
- NOTIFICATION = "user/notification"
-)
-
-func Settings(c *context.Context) {
- c.Title("settings.profile")
- c.PageIs("SettingsProfile")
- c.Data["origin_name"] = c.User.Name
- c.Data["name"] = c.User.Name
- c.Data["full_name"] = c.User.FullName
- c.Data["email"] = c.User.Email
- c.Data["website"] = c.User.Website
- c.Data["location"] = c.User.Location
- c.Success(SETTINGS_PROFILE)
-}
-
-func SettingsPost(c *context.Context, f form.UpdateProfile) {
- c.Title("settings.profile")
- c.PageIs("SettingsProfile")
- c.Data["origin_name"] = c.User.Name
-
- if c.HasError() {
- c.Success(SETTINGS_PROFILE)
- return
- }
-
- // Non-local users are not allowed to change their username
- if c.User.IsLocal() {
- // Check if username characters have been changed
- if c.User.LowerName != strings.ToLower(f.Name) {
- if err := models.ChangeUserName(c.User, f.Name); err != nil {
- c.FormErr("Name")
- var msg string
- switch {
- case models.IsErrUserAlreadyExist(err):
- msg = c.Tr("form.username_been_taken")
- case models.IsErrEmailAlreadyUsed(err):
- msg = c.Tr("form.email_been_used")
- case models.IsErrNameReserved(err):
- msg = c.Tr("form.name_reserved")
- case models.IsErrNamePatternNotAllowed(err):
- msg = c.Tr("form.name_pattern_not_allowed")
- default:
- c.ServerError("ChangeUserName", err)
- return
- }
-
- c.RenderWithErr(msg, SETTINGS_PROFILE, &f)
- return
- }
-
- log.Trace("Username changed: %s -> %s", c.User.Name, f.Name)
- }
-
- // In case it's just a case change
- c.User.Name = f.Name
- c.User.LowerName = strings.ToLower(f.Name)
- }
-
- c.User.FullName = f.FullName
- c.User.Email = f.Email
- c.User.Website = f.Website
- c.User.Location = f.Location
- if err := models.UpdateUser(c.User); err != nil {
- c.ServerError("UpdateUser", err)
- return
- }
-
- c.Flash.Success(c.Tr("settings.update_profile_success"))
- c.SubURLRedirect("/user/settings")
-}
-
-// FIXME: limit size.
-func UpdateAvatarSetting(c *context.Context, f form.Avatar, ctxUser *models.User) error {
- ctxUser.UseCustomAvatar = f.Source == form.AVATAR_LOCAL
- if len(f.Gravatar) > 0 {
- ctxUser.Avatar = tool.MD5(f.Gravatar)
- ctxUser.AvatarEmail = f.Gravatar
- }
-
- if f.Avatar != nil {
- r, err := f.Avatar.Open()
- if err != nil {
- return fmt.Errorf("Avatar.Open: %v", err)
- }
- defer r.Close()
-
- data, err := ioutil.ReadAll(r)
- if err != nil {
- return fmt.Errorf("ioutil.ReadAll: %v", err)
- }
- if !tool.IsImageFile(data) {
- return errors.New(c.Tr("settings.uploaded_avatar_not_a_image"))
- }
- if err = ctxUser.UploadAvatar(data); err != nil {
- return fmt.Errorf("UploadAvatar: %v", err)
- }
- } else {
- // No avatar is uploaded but setting has been changed to enable,
- // generate a random one when needed.
- if ctxUser.UseCustomAvatar && !com.IsFile(ctxUser.CustomAvatarPath()) {
- if err := ctxUser.GenerateRandomAvatar(); err != nil {
- log.Error(4, "GenerateRandomAvatar[%d]: %v", ctxUser.ID, err)
- }
- }
- }
-
- if err := models.UpdateUser(ctxUser); err != nil {
- return fmt.Errorf("UpdateUser: %v", err)
- }
-
- return nil
-}
-
-func SettingsAvatar(c *context.Context) {
- c.Title("settings.avatar")
- c.PageIs("SettingsAvatar")
- c.Success(SETTINGS_AVATAR)
-}
-
-func SettingsAvatarPost(c *context.Context, f form.Avatar) {
- if err := UpdateAvatarSetting(c, f, c.User); err != nil {
- c.Flash.Error(err.Error())
- } else {
- c.Flash.Success(c.Tr("settings.update_avatar_success"))
- }
-
- c.SubURLRedirect("/user/settings/avatar")
-}
-
-func SettingsDeleteAvatar(c *context.Context) {
- if err := c.User.DeleteAvatar(); err != nil {
- c.Flash.Error(fmt.Sprintf("DeleteAvatar: %v", err))
- }
-
- c.SubURLRedirect("/user/settings/avatar")
-}
-
-func SettingsPassword(c *context.Context) {
- c.Title("settings.password")
- c.PageIs("SettingsPassword")
- c.Success(SETTINGS_PASSWORD)
-}
-
-func SettingsPasswordPost(c *context.Context, f form.ChangePassword) {
- c.Title("settings.password")
- c.PageIs("SettingsPassword")
-
- if c.HasError() {
- c.Success(SETTINGS_PASSWORD)
- return
- }
-
- if !c.User.ValidatePassword(f.OldPassword) {
- c.Flash.Error(c.Tr("settings.password_incorrect"))
- } else if f.Password != f.Retype {
- c.Flash.Error(c.Tr("form.password_not_match"))
- } else {
- c.User.Passwd = f.Password
- var err error
- if c.User.Salt, err = models.GetUserSalt(); err != nil {
- c.ServerError("GetUserSalt", err)
- return
- }
- c.User.EncodePasswd()
- if err := models.UpdateUser(c.User); err != nil {
- c.ServerError("UpdateUser", err)
- return
- }
- c.Flash.Success(c.Tr("settings.change_password_success"))
- }
-
- c.SubURLRedirect("/user/settings/password")
-}
-
-func SettingsEmails(c *context.Context) {
- c.Title("settings.emails")
- c.PageIs("SettingsEmails")
-
- emails, err := models.GetEmailAddresses(c.User.ID)
- if err != nil {
- c.ServerError("GetEmailAddresses", err)
- return
- }
- c.Data["Emails"] = emails
-
- c.Success(SETTINGS_EMAILS)
-}
-
-func SettingsEmailPost(c *context.Context, f form.AddEmail) {
- c.Title("settings.emails")
- c.PageIs("SettingsEmails")
-
- // Make emailaddress primary.
- if c.Query("_method") == "PRIMARY" {
- if err := models.MakeEmailPrimary(&models.EmailAddress{ID: c.QueryInt64("id")}); err != nil {
- c.ServerError("MakeEmailPrimary", err)
- return
- }
-
- c.SubURLRedirect("/user/settings/email")
- return
- }
-
- // Add Email address.
- emails, err := models.GetEmailAddresses(c.User.ID)
- if err != nil {
- c.ServerError("GetEmailAddresses", err)
- return
- }
- c.Data["Emails"] = emails
-
- if c.HasError() {
- c.Success(SETTINGS_EMAILS)
- return
- }
-
- email := &models.EmailAddress{
- UID: c.User.ID,
- Email: f.Email,
- IsActivated: !setting.Service.RegisterEmailConfirm,
- }
- if err := models.AddEmailAddress(email); err != nil {
- if models.IsErrEmailAlreadyUsed(err) {
- c.RenderWithErr(c.Tr("form.email_been_used"), SETTINGS_EMAILS, &f)
- } else {
- c.ServerError("AddEmailAddress", err)
- }
- return
- }
-
- // Send confirmation email
- if setting.Service.RegisterEmailConfirm {
- mailer.SendActivateEmailMail(c.Context, models.NewMailerUser(c.User), email.Email)
-
- if err := c.Cache.Put("MailResendLimit_"+c.User.LowerName, c.User.LowerName, 180); err != nil {
- log.Error(2, "Set cache 'MailResendLimit' failed: %v", err)
- }
- c.Flash.Info(c.Tr("settings.add_email_confirmation_sent", email.Email, setting.Service.ActiveCodeLives/60))
- } else {
- c.Flash.Success(c.Tr("settings.add_email_success"))
- }
-
- c.SubURLRedirect("/user/settings/email")
-}
-
-func DeleteEmail(c *context.Context) {
- if err := models.DeleteEmailAddress(&models.EmailAddress{
- ID: c.QueryInt64("id"),
- UID: c.User.ID,
- }); err != nil {
- c.ServerError("DeleteEmailAddress", err)
- return
- }
-
- c.Flash.Success(c.Tr("settings.email_deletion_success"))
- c.JSONSuccess(map[string]interface{}{
- "redirect": setting.AppSubURL + "/user/settings/email",
- })
-}
-
-func SettingsSSHKeys(c *context.Context) {
- c.Title("settings.ssh_keys")
- c.PageIs("SettingsSSHKeys")
-
- keys, err := models.ListPublicKeys(c.User.ID)
- if err != nil {
- c.ServerError("ListPublicKeys", err)
- return
- }
- c.Data["Keys"] = keys
-
- c.Success(SETTINGS_SSH_KEYS)
-}
-
-func SettingsSSHKeysPost(c *context.Context, f form.AddSSHKey) {
- c.Title("settings.ssh_keys")
- c.PageIs("SettingsSSHKeys")
-
- keys, err := models.ListPublicKeys(c.User.ID)
- if err != nil {
- c.ServerError("ListPublicKeys", err)
- return
- }
- c.Data["Keys"] = keys
-
- if c.HasError() {
- c.Success(SETTINGS_SSH_KEYS)
- return
- }
-
- content, err := models.CheckPublicKeyString(f.Content)
- if err != nil {
- if models.IsErrKeyUnableVerify(err) {
- c.Flash.Info(c.Tr("form.unable_verify_ssh_key"))
- } else {
- c.Flash.Error(c.Tr("form.invalid_ssh_key", err.Error()))
- c.SubURLRedirect("/user/settings/ssh")
- return
- }
- }
-
- if _, err = models.AddPublicKey(c.User.ID, f.Title, content); err != nil {
- c.Data["HasError"] = true
- switch {
- case models.IsErrKeyAlreadyExist(err):
- c.FormErr("Content")
- c.RenderWithErr(c.Tr("settings.ssh_key_been_used"), SETTINGS_SSH_KEYS, &f)
- case models.IsErrKeyNameAlreadyUsed(err):
- c.FormErr("Title")
- c.RenderWithErr(c.Tr("settings.ssh_key_name_used"), SETTINGS_SSH_KEYS, &f)
- default:
- c.ServerError("AddPublicKey", err)
- }
- return
- }
-
- c.Flash.Success(c.Tr("settings.add_key_success", f.Title))
- c.SubURLRedirect("/user/settings/ssh")
-}
-
-func DeleteSSHKey(c *context.Context) {
- if err := models.DeletePublicKey(c.User, c.QueryInt64("id")); err != nil {
- c.Flash.Error("DeletePublicKey: " + err.Error())
- } else {
- c.Flash.Success(c.Tr("settings.ssh_key_deletion_success"))
- }
-
- c.JSONSuccess(map[string]interface{}{
- "redirect": setting.AppSubURL + "/user/settings/ssh",
- })
-}
-
-func SettingsSecurity(c *context.Context) {
- c.Title("settings.security")
- c.PageIs("SettingsSecurity")
-
- t, err := models.GetTwoFactorByUserID(c.UserID())
- if err != nil && !errors.IsTwoFactorNotFound(err) {
- c.ServerError("GetTwoFactorByUserID", err)
- return
- }
- c.Data["TwoFactor"] = t
-
- c.Success(SETTINGS_SECURITY)
-}
-
-func SettingsTwoFactorEnable(c *context.Context) {
- if c.User.IsEnabledTwoFactor() {
- c.NotFound()
- return
- }
-
- c.Title("settings.two_factor_enable_title")
- c.PageIs("SettingsSecurity")
-
- var key *otp.Key
- var err error
- keyURL := c.Session.Get("twoFactorURL")
- if keyURL != nil {
- key, _ = otp.NewKeyFromURL(keyURL.(string))
- }
- if key == nil {
- key, err = totp.Generate(totp.GenerateOpts{
- Issuer: setting.AppName,
- AccountName: c.User.Email,
- })
- if err != nil {
- c.ServerError("Generate", err)
- return
- }
- }
- c.Data["TwoFactorSecret"] = key.Secret()
-
- img, err := key.Image(240, 240)
- if err != nil {
- c.ServerError("Image", err)
- return
- }
-
- var buf bytes.Buffer
- if err = png.Encode(&buf, img); err != nil {
- c.ServerError("Encode", err)
- return
- }
- c.Data["QRCode"] = template.URL("data:image/png;base64," + base64.StdEncoding.EncodeToString(buf.Bytes()))
-
- c.Session.Set("twoFactorSecret", c.Data["TwoFactorSecret"])
- c.Session.Set("twoFactorURL", key.String())
- c.Success(SETTINGS_TWO_FACTOR_ENABLE)
-}
-
-func SettingsTwoFactorEnablePost(c *context.Context) {
- secret, ok := c.Session.Get("twoFactorSecret").(string)
- if !ok {
- c.NotFound()
- return
- }
-
- if !totp.Validate(c.Query("passcode"), secret) {
- c.Flash.Error(c.Tr("settings.two_factor_invalid_passcode"))
- c.SubURLRedirect("/user/settings/security/two_factor_enable")
- return
- }
-
- if err := models.NewTwoFactor(c.UserID(), secret); err != nil {
- c.Flash.Error(c.Tr("settings.two_factor_enable_error", err))
- c.SubURLRedirect("/user/settings/security/two_factor_enable")
- return
- }
-
- c.Session.Delete("twoFactorSecret")
- c.Session.Delete("twoFactorURL")
- c.Flash.Success(c.Tr("settings.two_factor_enable_success"))
- c.SubURLRedirect("/user/settings/security/two_factor_recovery_codes")
-}
-
-func SettingsTwoFactorRecoveryCodes(c *context.Context) {
- if !c.User.IsEnabledTwoFactor() {
- c.NotFound()
- return
- }
-
- c.Title("settings.two_factor_recovery_codes_title")
- c.PageIs("SettingsSecurity")
-
- recoveryCodes, err := models.GetRecoveryCodesByUserID(c.UserID())
- if err != nil {
- c.ServerError("GetRecoveryCodesByUserID", err)
- return
- }
- c.Data["RecoveryCodes"] = recoveryCodes
-
- c.Success(SETTINGS_TWO_FACTOR_RECOVERY_CODES)
-}
-
-func SettingsTwoFactorRecoveryCodesPost(c *context.Context) {
- if !c.User.IsEnabledTwoFactor() {
- c.NotFound()
- return
- }
-
- if err := models.RegenerateRecoveryCodes(c.UserID()); err != nil {
- c.Flash.Error(c.Tr("settings.two_factor_regenerate_recovery_codes_error", err))
- } else {
- c.Flash.Success(c.Tr("settings.two_factor_regenerate_recovery_codes_success"))
- }
-
- c.SubURLRedirect("/user/settings/security/two_factor_recovery_codes")
-}
-
-func SettingsTwoFactorDisable(c *context.Context) {
- if !c.User.IsEnabledTwoFactor() {
- c.NotFound()
- return
- }
-
- if err := models.DeleteTwoFactor(c.UserID()); err != nil {
- c.ServerError("DeleteTwoFactor", err)
- return
- }
-
- c.Flash.Success(c.Tr("settings.two_factor_disable_success"))
- c.JSONSuccess(map[string]interface{}{
- "redirect": setting.AppSubURL + "/user/settings/security",
- })
-}
-
-func SettingsRepos(c *context.Context) {
- c.Title("settings.repos")
- c.PageIs("SettingsRepositories")
-
- repos, err := models.GetUserAndCollaborativeRepositories(c.User.ID)
- if err != nil {
- c.ServerError("GetUserAndCollaborativeRepositories", err)
- return
- }
- if err = models.RepositoryList(repos).LoadAttributes(); err != nil {
- c.ServerError("LoadAttributes", err)
- return
- }
- c.Data["Repos"] = repos
-
- c.Success(SETTINGS_REPOSITORIES)
-}
-
-func SettingsLeaveRepo(c *context.Context) {
- repo, err := models.GetRepositoryByID(c.QueryInt64("id"))
- if err != nil {
- c.NotFoundOrServerError("GetRepositoryByID", errors.IsRepoNotExist, err)
- return
- }
-
- if err = repo.DeleteCollaboration(c.User.ID); err != nil {
- c.ServerError("DeleteCollaboration", err)
- return
- }
-
- c.Flash.Success(c.Tr("settings.repos.leave_success", repo.FullName()))
- c.JSONSuccess(map[string]interface{}{
- "redirect": setting.AppSubURL + "/user/settings/repositories",
- })
-}
-
-func SettingsOrganizations(c *context.Context) {
- c.Title("settings.orgs")
- c.PageIs("SettingsOrganizations")
-
- orgs, err := models.GetOrgsByUserID(c.User.ID, true)
- if err != nil {
- c.ServerError("GetOrgsByUserID", err)
- return
- }
- c.Data["Orgs"] = orgs
-
- c.Success(SETTINGS_ORGANIZATIONS)
-}
-
-func SettingsLeaveOrganization(c *context.Context) {
- if err := models.RemoveOrgUser(c.QueryInt64("id"), c.User.ID); err != nil {
- if models.IsErrLastOrgOwner(err) {
- c.Flash.Error(c.Tr("form.last_org_owner"))
- } else {
- c.ServerError("RemoveOrgUser", err)
- return
- }
- }
-
- c.JSONSuccess(map[string]interface{}{
- "redirect": setting.AppSubURL + "/user/settings/organizations",
- })
-}
-
-func SettingsApplications(c *context.Context) {
- c.Title("settings.applications")
- c.PageIs("SettingsApplications")
-
- tokens, err := models.ListAccessTokens(c.User.ID)
- if err != nil {
- c.ServerError("ListAccessTokens", err)
- return
- }
- c.Data["Tokens"] = tokens
-
- c.Success(SETTINGS_APPLICATIONS)
-}
-
-func SettingsApplicationsPost(c *context.Context, f form.NewAccessToken) {
- c.Title("settings.applications")
- c.PageIs("SettingsApplications")
-
- if c.HasError() {
- tokens, err := models.ListAccessTokens(c.User.ID)
- if err != nil {
- c.ServerError("ListAccessTokens", err)
- return
- }
-
- c.Data["Tokens"] = tokens
- c.Success(SETTINGS_APPLICATIONS)
- return
- }
-
- t := &models.AccessToken{
- UID: c.User.ID,
- Name: f.Name,
- }
- if err := models.NewAccessToken(t); err != nil {
- c.ServerError("NewAccessToken", err)
- return
- }
-
- c.Flash.Success(c.Tr("settings.generate_token_succees"))
- c.Flash.Info(t.Sha1)
- c.SubURLRedirect("/user/settings/applications")
-}
-
-func SettingsDeleteApplication(c *context.Context) {
- if err := models.DeleteAccessTokenOfUserByID(c.User.ID, c.QueryInt64("id")); err != nil {
- c.Flash.Error("DeleteAccessTokenByID: " + err.Error())
- } else {
- c.Flash.Success(c.Tr("settings.delete_token_success"))
- }
-
- c.JSONSuccess(map[string]interface{}{
- "redirect": setting.AppSubURL + "/user/settings/applications",
- })
-}
-
-func SettingsDelete(c *context.Context) {
- c.Title("settings.delete")
- c.PageIs("SettingsDelete")
-
- if c.Req.Method == "POST" {
- if _, err := models.UserSignIn(c.User.Name, c.Query("password")); err != nil {
- if errors.IsUserNotExist(err) {
- c.RenderWithErr(c.Tr("form.enterred_invalid_password"), SETTINGS_DELETE, nil)
- } else {
- c.ServerError("UserSignIn", err)
- }
- return
- }
-
- if err := models.DeleteUser(c.User); err != nil {
- switch {
- case models.IsErrUserOwnRepos(err):
- c.Flash.Error(c.Tr("form.still_own_repo"))
- c.Redirect(setting.AppSubURL + "/user/settings/delete")
- case models.IsErrUserHasOrgs(err):
- c.Flash.Error(c.Tr("form.still_has_org"))
- c.Redirect(setting.AppSubURL + "/user/settings/delete")
- default:
- c.ServerError("DeleteUser", err)
- }
- } else {
- log.Trace("Account deleted: %s", c.User.Name)
- c.Redirect(setting.AppSubURL + "/")
- }
- return
- }
-
- c.Success(SETTINGS_DELETE)
-}