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

228 lines
5.5 KiB

10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
  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 auth
  5. import (
  6. "net/http"
  7. "reflect"
  8. "strings"
  9. "github.com/Unknwon/macaron"
  10. "github.com/macaron-contrib/binding"
  11. "github.com/macaron-contrib/session"
  12. "github.com/gogits/gogs/models"
  13. "github.com/gogits/gogs/modules/base"
  14. "github.com/gogits/gogs/modules/log"
  15. "github.com/gogits/gogs/modules/setting"
  16. "github.com/gogits/gogs/modules/uuid"
  17. )
  18. // SignedInId returns the id of signed in user.
  19. func SignedInId(req *http.Request, sess session.Store) int64 {
  20. if !models.HasEngine {
  21. return 0
  22. }
  23. // API calls need to check access token.
  24. if strings.HasPrefix(req.URL.Path, "/api/") {
  25. auHead := req.Header.Get("Authorization")
  26. if len(auHead) > 0 {
  27. auths := strings.Fields(auHead)
  28. if len(auths) == 2 && auths[0] == "token" {
  29. t, err := models.GetAccessTokenBySha(auths[1])
  30. if err != nil {
  31. if err != models.ErrAccessTokenNotExist {
  32. log.Error(4, "GetAccessTokenBySha: %v", err)
  33. }
  34. return 0
  35. }
  36. return t.Uid
  37. }
  38. }
  39. }
  40. uid := sess.Get("uid")
  41. if uid == nil {
  42. return 0
  43. }
  44. if id, ok := uid.(int64); ok {
  45. if _, err := models.GetUserById(id); err != nil {
  46. if err != models.ErrUserNotExist {
  47. log.Error(4, "GetUserById: %v", err)
  48. }
  49. return 0
  50. }
  51. return id
  52. }
  53. return 0
  54. }
  55. // SignedInUser returns the user object of signed user.
  56. // It returns a bool value to indicate whether user uses basic auth or not.
  57. func SignedInUser(req *http.Request, sess session.Store) (*models.User, bool) {
  58. if !models.HasEngine {
  59. return nil, false
  60. }
  61. uid := SignedInId(req, sess)
  62. if uid <= 0 {
  63. if setting.Service.EnableReverseProxyAuth {
  64. webAuthUser := req.Header.Get(setting.ReverseProxyAuthUser)
  65. if len(webAuthUser) > 0 {
  66. u, err := models.GetUserByName(webAuthUser)
  67. if err != nil {
  68. if err != models.ErrUserNotExist {
  69. log.Error(4, "GetUserByName: %v", err)
  70. return nil, false
  71. }
  72. // Check if enabled auto-registration.
  73. if setting.Service.EnableReverseProxyAutoRegister {
  74. u := &models.User{
  75. Name: webAuthUser,
  76. Email: uuid.NewV4().String() + "@localhost",
  77. Passwd: webAuthUser,
  78. IsActive: true,
  79. }
  80. if err = models.CreateUser(u); err != nil {
  81. // FIXME: should I create a system notice?
  82. log.Error(4, "CreateUser: %v", err)
  83. return nil, false
  84. } else {
  85. return u, false
  86. }
  87. }
  88. }
  89. return u, false
  90. }
  91. }
  92. // Check with basic auth.
  93. baHead := req.Header.Get("Authorization")
  94. if len(baHead) > 0 {
  95. auths := strings.Fields(baHead)
  96. if len(auths) == 2 && auths[0] == "Basic" {
  97. uname, passwd, _ := base.BasicAuthDecode(auths[1])
  98. u, err := models.GetUserByName(uname)
  99. if err != nil {
  100. if err != models.ErrUserNotExist {
  101. log.Error(4, "GetUserByName: %v", err)
  102. }
  103. return nil, false
  104. }
  105. if u.ValidtePassword(passwd) {
  106. return u, true
  107. }
  108. }
  109. }
  110. return nil, false
  111. }
  112. u, err := models.GetUserById(uid)
  113. if err != nil {
  114. log.Error(4, "GetUserById: %v", err)
  115. return nil, false
  116. }
  117. return u, false
  118. }
  119. type Form interface {
  120. binding.Validator
  121. }
  122. // AssignForm assign form values back to the template data.
  123. func AssignForm(form interface{}, data map[string]interface{}) {
  124. typ := reflect.TypeOf(form)
  125. val := reflect.ValueOf(form)
  126. if typ.Kind() == reflect.Ptr {
  127. typ = typ.Elem()
  128. val = val.Elem()
  129. }
  130. for i := 0; i < typ.NumField(); i++ {
  131. field := typ.Field(i)
  132. fieldName := field.Tag.Get("form")
  133. // Allow ignored fields in the struct
  134. if fieldName == "-" {
  135. continue
  136. }
  137. data[fieldName] = val.Field(i).Interface()
  138. }
  139. }
  140. func getSize(field reflect.StructField, prefix string) string {
  141. for _, rule := range strings.Split(field.Tag.Get("binding"), ";") {
  142. if strings.HasPrefix(rule, prefix) {
  143. return rule[8 : len(rule)-1]
  144. }
  145. }
  146. return ""
  147. }
  148. func GetMinSize(field reflect.StructField) string {
  149. return getSize(field, "MinSize(")
  150. }
  151. func GetMaxSize(field reflect.StructField) string {
  152. return getSize(field, "MaxSize(")
  153. }
  154. func validate(errs binding.Errors, data map[string]interface{}, f Form, l macaron.Locale) binding.Errors {
  155. if errs.Len() == 0 {
  156. return errs
  157. }
  158. data["HasError"] = true
  159. AssignForm(f, data)
  160. typ := reflect.TypeOf(f)
  161. val := reflect.ValueOf(f)
  162. if typ.Kind() == reflect.Ptr {
  163. typ = typ.Elem()
  164. val = val.Elem()
  165. }
  166. for i := 0; i < typ.NumField(); i++ {
  167. field := typ.Field(i)
  168. fieldName := field.Tag.Get("form")
  169. // Allow ignored fields in the struct
  170. if fieldName == "-" {
  171. continue
  172. }
  173. if errs[0].FieldNames[0] == field.Name {
  174. data["Err_"+field.Name] = true
  175. trName := l.Tr("form." + field.Name)
  176. switch errs[0].Classification {
  177. case binding.ERR_REQUIRED:
  178. data["ErrorMsg"] = trName + l.Tr("form.require_error")
  179. case binding.ERR_ALPHA_DASH:
  180. data["ErrorMsg"] = trName + l.Tr("form.alpha_dash_error")
  181. case binding.ERR_ALPHA_DASH_DOT:
  182. data["ErrorMsg"] = trName + l.Tr("form.alpha_dash_dot_error")
  183. case binding.ERR_MIN_SIZE:
  184. data["ErrorMsg"] = trName + l.Tr("form.min_size_error", GetMinSize(field))
  185. case binding.ERR_MAX_SIZE:
  186. data["ErrorMsg"] = trName + l.Tr("form.max_size_error", GetMaxSize(field))
  187. case binding.ERR_EMAIL:
  188. data["ErrorMsg"] = trName + l.Tr("form.email_error")
  189. case binding.ERR_URL:
  190. data["ErrorMsg"] = trName + l.Tr("form.url_error")
  191. default:
  192. data["ErrorMsg"] = l.Tr("form.unknown_error") + " " + errs[0].Classification
  193. }
  194. return errs
  195. }
  196. }
  197. return errs
  198. }