auths.go 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289
  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 admin
  5. import (
  6. "fmt"
  7. "net/http"
  8. "strings"
  9. "github.com/unknwon/com"
  10. log "unknwon.dev/clog/v2"
  11. "gogs.io/gogs/internal/auth/ldap"
  12. "gogs.io/gogs/internal/conf"
  13. "gogs.io/gogs/internal/context"
  14. "gogs.io/gogs/internal/db"
  15. "gogs.io/gogs/internal/form"
  16. )
  17. const (
  18. AUTHS = "admin/auth/list"
  19. AUTH_NEW = "admin/auth/new"
  20. AUTH_EDIT = "admin/auth/edit"
  21. )
  22. func Authentications(c *context.Context) {
  23. c.Title("admin.authentication")
  24. c.PageIs("Admin")
  25. c.PageIs("AdminAuthentications")
  26. var err error
  27. c.Data["Sources"], err = db.LoginSources.List(db.ListLoginSourceOpts{})
  28. if err != nil {
  29. c.Error(err, "list login sources")
  30. return
  31. }
  32. c.Data["Total"] = db.LoginSources.Count()
  33. c.Success(AUTHS)
  34. }
  35. type dropdownItem struct {
  36. Name string
  37. Type interface{}
  38. }
  39. var (
  40. authSources = []dropdownItem{
  41. {db.LoginNames[db.LoginLDAP], db.LoginLDAP},
  42. {db.LoginNames[db.LoginDLDAP], db.LoginDLDAP},
  43. {db.LoginNames[db.LoginSMTP], db.LoginSMTP},
  44. {db.LoginNames[db.LoginPAM], db.LoginPAM},
  45. {db.LoginNames[db.LoginGitHub], db.LoginGitHub},
  46. }
  47. securityProtocols = []dropdownItem{
  48. {db.SecurityProtocolNames[ldap.SecurityProtocolUnencrypted], ldap.SecurityProtocolUnencrypted},
  49. {db.SecurityProtocolNames[ldap.SecurityProtocolLDAPS], ldap.SecurityProtocolLDAPS},
  50. {db.SecurityProtocolNames[ldap.SecurityProtocolStartTLS], ldap.SecurityProtocolStartTLS},
  51. }
  52. )
  53. func NewAuthSource(c *context.Context) {
  54. c.Title("admin.auths.new")
  55. c.PageIs("Admin")
  56. c.PageIs("AdminAuthentications")
  57. c.Data["type"] = db.LoginLDAP
  58. c.Data["CurrentTypeName"] = db.LoginNames[db.LoginLDAP]
  59. c.Data["CurrentSecurityProtocol"] = db.SecurityProtocolNames[ldap.SecurityProtocolUnencrypted]
  60. c.Data["smtp_auth"] = "PLAIN"
  61. c.Data["is_active"] = true
  62. c.Data["is_default"] = true
  63. c.Data["AuthSources"] = authSources
  64. c.Data["SecurityProtocols"] = securityProtocols
  65. c.Data["SMTPAuths"] = db.SMTPAuths
  66. c.Success(AUTH_NEW)
  67. }
  68. func parseLDAPConfig(f form.Authentication) *db.LDAPConfig {
  69. return &db.LDAPConfig{
  70. Source: ldap.Source{
  71. Host: f.Host,
  72. Port: f.Port,
  73. SecurityProtocol: ldap.SecurityProtocol(f.SecurityProtocol),
  74. SkipVerify: f.SkipVerify,
  75. BindDN: f.BindDN,
  76. UserDN: f.UserDN,
  77. BindPassword: f.BindPassword,
  78. UserBase: f.UserBase,
  79. AttributeUsername: f.AttributeUsername,
  80. AttributeName: f.AttributeName,
  81. AttributeSurname: f.AttributeSurname,
  82. AttributeMail: f.AttributeMail,
  83. AttributesInBind: f.AttributesInBind,
  84. Filter: f.Filter,
  85. GroupEnabled: f.GroupEnabled,
  86. GroupDN: f.GroupDN,
  87. GroupFilter: f.GroupFilter,
  88. GroupMemberUID: f.GroupMemberUID,
  89. UserUID: f.UserUID,
  90. AdminFilter: f.AdminFilter,
  91. },
  92. }
  93. }
  94. func parseSMTPConfig(f form.Authentication) *db.SMTPConfig {
  95. return &db.SMTPConfig{
  96. Auth: f.SMTPAuth,
  97. Host: f.SMTPHost,
  98. Port: f.SMTPPort,
  99. AllowedDomains: f.AllowedDomains,
  100. TLS: f.TLS,
  101. SkipVerify: f.SkipVerify,
  102. }
  103. }
  104. func NewAuthSourcePost(c *context.Context, f form.Authentication) {
  105. c.Title("admin.auths.new")
  106. c.PageIs("Admin")
  107. c.PageIs("AdminAuthentications")
  108. c.Data["CurrentTypeName"] = db.LoginNames[db.LoginType(f.Type)]
  109. c.Data["CurrentSecurityProtocol"] = db.SecurityProtocolNames[ldap.SecurityProtocol(f.SecurityProtocol)]
  110. c.Data["AuthSources"] = authSources
  111. c.Data["SecurityProtocols"] = securityProtocols
  112. c.Data["SMTPAuths"] = db.SMTPAuths
  113. hasTLS := false
  114. var config interface{}
  115. switch db.LoginType(f.Type) {
  116. case db.LoginLDAP, db.LoginDLDAP:
  117. config = parseLDAPConfig(f)
  118. hasTLS = ldap.SecurityProtocol(f.SecurityProtocol) > ldap.SecurityProtocolUnencrypted
  119. case db.LoginSMTP:
  120. config = parseSMTPConfig(f)
  121. hasTLS = true
  122. case db.LoginPAM:
  123. config = &db.PAMConfig{
  124. ServiceName: f.PAMServiceName,
  125. }
  126. case db.LoginGitHub:
  127. config = &db.GitHubConfig{
  128. APIEndpoint: strings.TrimSuffix(f.GitHubAPIEndpoint, "/") + "/",
  129. }
  130. default:
  131. c.Status(http.StatusBadRequest)
  132. return
  133. }
  134. c.Data["HasTLS"] = hasTLS
  135. if c.HasError() {
  136. c.Success(AUTH_NEW)
  137. return
  138. }
  139. source, err := db.LoginSources.Create(db.CreateLoginSourceOpts{
  140. Type: db.LoginType(f.Type),
  141. Name: f.Name,
  142. Activated: f.IsActive,
  143. Default: f.IsDefault,
  144. Config: config,
  145. })
  146. if err != nil {
  147. if db.IsErrLoginSourceAlreadyExist(err) {
  148. c.FormErr("Name")
  149. c.RenderWithErr(c.Tr("admin.auths.login_source_exist", f.Name), AUTH_NEW, f)
  150. } else {
  151. c.Error(err, "create login source")
  152. }
  153. return
  154. }
  155. if source.IsDefault {
  156. err = db.LoginSources.ResetNonDefault(source)
  157. if err != nil {
  158. c.Error(err, "reset non-default login sources")
  159. return
  160. }
  161. }
  162. log.Trace("Authentication created by admin(%s): %s", c.User.Name, f.Name)
  163. c.Flash.Success(c.Tr("admin.auths.new_success", f.Name))
  164. c.Redirect(conf.Server.Subpath + "/admin/auths")
  165. }
  166. func EditAuthSource(c *context.Context) {
  167. c.Title("admin.auths.edit")
  168. c.PageIs("Admin")
  169. c.PageIs("AdminAuthentications")
  170. c.Data["SecurityProtocols"] = securityProtocols
  171. c.Data["SMTPAuths"] = db.SMTPAuths
  172. source, err := db.LoginSources.GetByID(c.ParamsInt64(":authid"))
  173. if err != nil {
  174. c.Error(err, "get login source by ID")
  175. return
  176. }
  177. c.Data["Source"] = source
  178. c.Data["HasTLS"] = source.HasTLS()
  179. c.Success(AUTH_EDIT)
  180. }
  181. func EditAuthSourcePost(c *context.Context, f form.Authentication) {
  182. c.Title("admin.auths.edit")
  183. c.PageIs("Admin")
  184. c.PageIs("AdminAuthentications")
  185. c.Data["SMTPAuths"] = db.SMTPAuths
  186. source, err := db.LoginSources.GetByID(c.ParamsInt64(":authid"))
  187. if err != nil {
  188. c.Error(err, "get login source by ID")
  189. return
  190. }
  191. c.Data["Source"] = source
  192. c.Data["HasTLS"] = source.HasTLS()
  193. if c.HasError() {
  194. c.Success(AUTH_EDIT)
  195. return
  196. }
  197. var config interface{}
  198. switch db.LoginType(f.Type) {
  199. case db.LoginLDAP, db.LoginDLDAP:
  200. config = parseLDAPConfig(f)
  201. case db.LoginSMTP:
  202. config = parseSMTPConfig(f)
  203. case db.LoginPAM:
  204. config = &db.PAMConfig{
  205. ServiceName: f.PAMServiceName,
  206. }
  207. case db.LoginGitHub:
  208. config = &db.GitHubConfig{
  209. APIEndpoint: strings.TrimSuffix(f.GitHubAPIEndpoint, "/") + "/",
  210. }
  211. default:
  212. c.Status(http.StatusBadRequest)
  213. return
  214. }
  215. source.Name = f.Name
  216. source.IsActived = f.IsActive
  217. source.IsDefault = f.IsDefault
  218. source.Config = config
  219. if err := db.LoginSources.Save(source); err != nil {
  220. c.Error(err, "update login source")
  221. return
  222. }
  223. if source.IsDefault {
  224. err = db.LoginSources.ResetNonDefault(source)
  225. if err != nil {
  226. c.Error(err, "reset non-default login sources")
  227. return
  228. }
  229. }
  230. log.Trace("Authentication changed by admin '%s': %d", c.User.Name, source.ID)
  231. c.Flash.Success(c.Tr("admin.auths.update_success"))
  232. c.Redirect(conf.Server.Subpath + "/admin/auths/" + com.ToStr(f.ID))
  233. }
  234. func DeleteAuthSource(c *context.Context) {
  235. id := c.ParamsInt64(":authid")
  236. if err := db.LoginSources.DeleteByID(id); err != nil {
  237. if db.IsErrLoginSourceInUse(err) {
  238. c.Flash.Error(c.Tr("admin.auths.still_in_used"))
  239. } else {
  240. c.Flash.Error(fmt.Sprintf("DeleteSource: %v", err))
  241. }
  242. c.JSONSuccess(map[string]interface{}{
  243. "redirect": conf.Server.Subpath + "/admin/auths/" + c.Params(":authid"),
  244. })
  245. return
  246. }
  247. log.Trace("Authentication deleted by admin(%s): %d", c.User.Name, id)
  248. c.Flash.Success(c.Tr("admin.auths.deletion_success"))
  249. c.JSONSuccess(map[string]interface{}{
  250. "redirect": conf.Server.Subpath + "/admin/auths",
  251. })
  252. }