You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

context.go 5.4 kB

11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
10 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
10 years ago
11 years ago
10 years ago
10 years ago
11 years ago
11 years ago
11 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199
  1. // Copyright 2014 The Gogs Authors. All rights reserved.
  2. // Use of this source code is governed by a MIT-style
  3. // license that can be found in the LICENSE file.
  4. package middleware
  5. import (
  6. "fmt"
  7. "html/template"
  8. "io"
  9. "net/http"
  10. "strings"
  11. "time"
  12. "github.com/Unknwon/macaron"
  13. "github.com/macaron-contrib/cache"
  14. "github.com/macaron-contrib/csrf"
  15. "github.com/macaron-contrib/i18n"
  16. "github.com/macaron-contrib/session"
  17. "github.com/gogits/gogs/models"
  18. "github.com/gogits/gogs/modules/auth"
  19. "github.com/gogits/gogs/modules/base"
  20. "github.com/gogits/gogs/modules/git"
  21. "github.com/gogits/gogs/modules/log"
  22. "github.com/gogits/gogs/modules/setting"
  23. )
  24. // Context represents context of a request.
  25. type Context struct {
  26. *macaron.Context
  27. Cache cache.Cache
  28. csrf csrf.CSRF
  29. Flash *session.Flash
  30. Session session.Store
  31. User *models.User
  32. IsSigned bool
  33. IsBasicAuth bool
  34. Repo struct {
  35. IsOwner bool
  36. IsTrueOwner bool
  37. IsWatching bool
  38. IsBranch bool
  39. IsTag bool
  40. IsCommit bool
  41. IsAdmin bool // Current user is admin level.
  42. HasAccess bool
  43. Repository *models.Repository
  44. Owner *models.User
  45. Commit *git.Commit
  46. Tag *git.Tag
  47. GitRepo *git.Repository
  48. BranchName string
  49. TagName string
  50. TreeName string
  51. CommitId string
  52. RepoLink string
  53. CloneLink models.CloneLink
  54. CommitsCount int
  55. Mirror *models.Mirror
  56. }
  57. Org struct {
  58. IsOwner bool
  59. IsMember bool
  60. IsAdminTeam bool // In owner team or team that has admin permission level.
  61. Organization *models.User
  62. OrgLink string
  63. Team *models.Team
  64. }
  65. }
  66. // HasError returns true if error occurs in form validation.
  67. func (ctx *Context) HasApiError() bool {
  68. hasErr, ok := ctx.Data["HasError"]
  69. if !ok {
  70. return false
  71. }
  72. return hasErr.(bool)
  73. }
  74. func (ctx *Context) GetErrMsg() string {
  75. return ctx.Data["ErrorMsg"].(string)
  76. }
  77. // HasError returns true if error occurs in form validation.
  78. func (ctx *Context) HasError() bool {
  79. hasErr, ok := ctx.Data["HasError"]
  80. if !ok {
  81. return false
  82. }
  83. ctx.Flash.ErrorMsg = ctx.Data["ErrorMsg"].(string)
  84. ctx.Data["Flash"] = ctx.Flash
  85. return hasErr.(bool)
  86. }
  87. // HTML calls Context.HTML and converts template name to string.
  88. func (ctx *Context) HTML(status int, name base.TplName) {
  89. ctx.Context.HTML(status, string(name))
  90. }
  91. // RenderWithErr used for page has form validation but need to prompt error to users.
  92. func (ctx *Context) RenderWithErr(msg string, tpl base.TplName, form interface{}) {
  93. if form != nil {
  94. auth.AssignForm(form, ctx.Data)
  95. }
  96. ctx.Flash.ErrorMsg = msg
  97. ctx.Data["Flash"] = ctx.Flash
  98. ctx.HTML(200, tpl)
  99. }
  100. // Handle handles and logs error by given status.
  101. func (ctx *Context) Handle(status int, title string, err error) {
  102. if err != nil {
  103. log.Error(4, "%s: %v", title, err)
  104. if macaron.Env != macaron.PROD {
  105. ctx.Data["ErrorMsg"] = err
  106. }
  107. }
  108. switch status {
  109. case 404:
  110. ctx.Data["Title"] = "Page Not Found"
  111. case 500:
  112. ctx.Data["Title"] = "Internal Server Error"
  113. }
  114. ctx.HTML(status, base.TplName(fmt.Sprintf("status/%d", status)))
  115. }
  116. func (ctx *Context) ServeContent(name string, r io.ReadSeeker, params ...interface{}) {
  117. modtime := time.Now()
  118. for _, p := range params {
  119. switch v := p.(type) {
  120. case time.Time:
  121. modtime = v
  122. }
  123. }
  124. ctx.Resp.Header().Set("Content-Description", "File Transfer")
  125. ctx.Resp.Header().Set("Content-Type", "application/octet-stream")
  126. ctx.Resp.Header().Set("Content-Disposition", "attachment; filename="+name)
  127. ctx.Resp.Header().Set("Content-Transfer-Encoding", "binary")
  128. ctx.Resp.Header().Set("Expires", "0")
  129. ctx.Resp.Header().Set("Cache-Control", "must-revalidate")
  130. ctx.Resp.Header().Set("Pragma", "public")
  131. http.ServeContent(ctx.Resp, ctx.Req.Request, name, modtime, r)
  132. }
  133. // Contexter initializes a classic context for a request.
  134. func Contexter() macaron.Handler {
  135. return func(c *macaron.Context, l i18n.Locale, cache cache.Cache, sess session.Store, f *session.Flash, x csrf.CSRF) {
  136. ctx := &Context{
  137. Context: c,
  138. Cache: cache,
  139. csrf: x,
  140. Flash: f,
  141. Session: sess,
  142. }
  143. // Compute current URL for real-time change language.
  144. link := setting.AppSubUrl + ctx.Req.RequestURI
  145. i := strings.Index(link, "?")
  146. if i > -1 {
  147. link = link[:i]
  148. }
  149. ctx.Data["Link"] = link
  150. ctx.Data["PageStartTime"] = time.Now()
  151. // Get user from session if logined.
  152. ctx.User, ctx.IsBasicAuth = auth.SignedInUser(ctx.Req.Request, ctx.Session)
  153. if ctx.User != nil {
  154. ctx.IsSigned = true
  155. ctx.Data["IsSigned"] = ctx.IsSigned
  156. ctx.Data["SignedUser"] = ctx.User
  157. ctx.Data["SignedUserName"] = ctx.User.Name
  158. ctx.Data["IsAdmin"] = ctx.User.IsAdmin
  159. } else {
  160. ctx.Data["SignedUserName"] = ""
  161. }
  162. // If request sends files, parse them here otherwise the Query() can't be parsed and the CsrfToken will be invalid.
  163. if ctx.Req.Method == "POST" && strings.Contains(ctx.Req.Header.Get("Content-Type"), "multipart/form-data") {
  164. if err := ctx.Req.ParseMultipartForm(setting.AttachmentMaxSize << 20); err != nil && !strings.Contains(err.Error(), "EOF") { // 32MB max size
  165. ctx.Handle(500, "ParseMultipartForm", err)
  166. return
  167. }
  168. }
  169. ctx.Data["CsrfToken"] = x.GetToken()
  170. ctx.Data["CsrfTokenHtml"] = template.HTML(`<input type="hidden" name="_csrf" value="` + x.GetToken() + `">`)
  171. ctx.Data["ShowRegistrationButton"] = setting.Service.ShowRegistrationButton
  172. c.Map(ctx)
  173. }
  174. }