auths.go 7.3 KB

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