auths.go 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294
  1. // Copyright 2015 The Gogs Authors. All rights reserved.
  2. // Copyright 2018 Gitote. All rights reserved.
  3. //
  4. // This source code is licensed under the MIT license found in the
  5. // LICENSE file in the root directory of this source tree.
  6. package admin
  7. import (
  8. "fmt"
  9. "gitote/gitote/models"
  10. "gitote/gitote/pkg/auth/ldap"
  11. "gitote/gitote/pkg/context"
  12. "gitote/gitote/pkg/form"
  13. "gitote/gitote/pkg/setting"
  14. "strings"
  15. "github.com/Unknwon/com"
  16. "github.com/go-xorm/core"
  17. log "gopkg.in/clog.v1"
  18. )
  19. const (
  20. // AUTHS list page template
  21. AUTHS = "admin/auth/list"
  22. // AUTH_NEW page template
  23. AUTH_NEW = "admin/auth/new"
  24. // AUTH_EDIT page template
  25. AUTH_EDIT = "admin/auth/edit"
  26. )
  27. // Authentications shows authentication page
  28. func Authentications(c *context.Context) {
  29. c.Title("admin.authentication")
  30. c.PageIs("Admin")
  31. c.PageIs("AdminAuthentications")
  32. var err error
  33. c.Data["Sources"], err = models.LoginSources()
  34. if err != nil {
  35. c.ServerError("LoginSources", err)
  36. return
  37. }
  38. c.Data["Total"] = models.CountLoginSources()
  39. c.Success(AUTHS)
  40. }
  41. type dropdownItem struct {
  42. Name string
  43. Type interface{}
  44. }
  45. var (
  46. authSources = []dropdownItem{
  47. {models.LoginNames[models.LOGIN_LDAP], models.LOGIN_LDAP},
  48. {models.LoginNames[models.LOGIN_DLDAP], models.LOGIN_DLDAP},
  49. {models.LoginNames[models.LOGIN_SMTP], models.LOGIN_SMTP},
  50. {models.LoginNames[models.LOGIN_PAM], models.LOGIN_PAM},
  51. {models.LoginNames[models.LOGIN_GITHUB], models.LOGIN_GITHUB},
  52. }
  53. securityProtocols = []dropdownItem{
  54. {models.SecurityProtocolNames[ldap.SECURITY_PROTOCOL_UNENCRYPTED], ldap.SECURITY_PROTOCOL_UNENCRYPTED},
  55. {models.SecurityProtocolNames[ldap.SECURITY_PROTOCOL_LDAPS], ldap.SECURITY_PROTOCOL_LDAPS},
  56. {models.SecurityProtocolNames[ldap.SECURITY_PROTOCOL_START_TLS], ldap.SECURITY_PROTOCOL_START_TLS},
  57. }
  58. )
  59. // NewAuthSource shows create auth page
  60. func NewAuthSource(c *context.Context) {
  61. c.Title("admin.auths.new")
  62. c.PageIs("Admin")
  63. c.PageIs("AdminAuthentications")
  64. c.Data["type"] = models.LOGIN_LDAP
  65. c.Data["CurrentTypeName"] = models.LoginNames[models.LOGIN_LDAP]
  66. c.Data["CurrentSecurityProtocol"] = models.SecurityProtocolNames[ldap.SECURITY_PROTOCOL_UNENCRYPTED]
  67. c.Data["smtp_auth"] = "PLAIN"
  68. c.Data["is_active"] = true
  69. c.Data["is_default"] = true
  70. c.Data["AuthSources"] = authSources
  71. c.Data["SecurityProtocols"] = securityProtocols
  72. c.Data["SMTPAuths"] = models.SMTPAuths
  73. c.Success(AUTH_NEW)
  74. }
  75. func parseLDAPConfig(f form.Authentication) *models.LDAPConfig {
  76. return &models.LDAPConfig{
  77. Source: &ldap.Source{
  78. Host: f.Host,
  79. Port: f.Port,
  80. SecurityProtocol: ldap.SecurityProtocol(f.SecurityProtocol),
  81. SkipVerify: f.SkipVerify,
  82. BindDN: f.BindDN,
  83. UserDN: f.UserDN,
  84. BindPassword: f.BindPassword,
  85. UserBase: f.UserBase,
  86. AttributeUsername: f.AttributeUsername,
  87. AttributeName: f.AttributeName,
  88. AttributeSurname: f.AttributeSurname,
  89. AttributeMail: f.AttributeMail,
  90. AttributesInBind: f.AttributesInBind,
  91. Filter: f.Filter,
  92. GroupEnabled: f.GroupEnabled,
  93. GroupDN: f.GroupDN,
  94. GroupFilter: f.GroupFilter,
  95. GroupMemberUID: f.GroupMemberUID,
  96. UserUID: f.UserUID,
  97. AdminFilter: f.AdminFilter,
  98. },
  99. }
  100. }
  101. func parseSMTPConfig(f form.Authentication) *models.SMTPConfig {
  102. return &models.SMTPConfig{
  103. Auth: f.SMTPAuth,
  104. Host: f.SMTPHost,
  105. Port: f.SMTPPort,
  106. AllowedDomains: f.AllowedDomains,
  107. TLS: f.TLS,
  108. SkipVerify: f.SkipVerify,
  109. }
  110. }
  111. // NewAuthSourcePost creates a new auth source
  112. func NewAuthSourcePost(c *context.Context, f form.Authentication) {
  113. c.Title("admin.auths.new")
  114. c.PageIs("Admin")
  115. c.PageIs("AdminAuthentications")
  116. c.Data["CurrentTypeName"] = models.LoginNames[models.LoginType(f.Type)]
  117. c.Data["CurrentSecurityProtocol"] = models.SecurityProtocolNames[ldap.SecurityProtocol(f.SecurityProtocol)]
  118. c.Data["AuthSources"] = authSources
  119. c.Data["SecurityProtocols"] = securityProtocols
  120. c.Data["SMTPAuths"] = models.SMTPAuths
  121. hasTLS := false
  122. var config core.Conversion
  123. switch models.LoginType(f.Type) {
  124. case models.LOGIN_LDAP, models.LOGIN_DLDAP:
  125. config = parseLDAPConfig(f)
  126. hasTLS = ldap.SecurityProtocol(f.SecurityProtocol) > ldap.SECURITY_PROTOCOL_UNENCRYPTED
  127. case models.LOGIN_SMTP:
  128. config = parseSMTPConfig(f)
  129. hasTLS = true
  130. case models.LOGIN_PAM:
  131. config = &models.PAMConfig{
  132. ServiceName: f.PAMServiceName,
  133. }
  134. case models.LOGIN_GITHUB:
  135. config = &models.GITHUBConfig{
  136. ApiEndpoint: f.GithubApiEndpoint,
  137. }
  138. default:
  139. c.Error(400)
  140. return
  141. }
  142. c.Data["HasTLS"] = hasTLS
  143. if c.HasError() {
  144. c.Success(AUTH_NEW)
  145. return
  146. }
  147. if err := models.CreateLoginSource(&models.LoginSource{
  148. Type: models.LoginType(f.Type),
  149. Name: f.Name,
  150. IsActived: f.IsActive,
  151. IsDefault: f.IsDefault,
  152. Cfg: config,
  153. }); err != nil {
  154. if models.IsErrLoginSourceAlreadyExist(err) {
  155. c.Data["Err_Name"] = true
  156. c.RenderWithErr(c.Tr("admin.auths.login_source_exist", err.(models.ErrLoginSourceAlreadyExist).Name), AUTH_NEW, f)
  157. } else {
  158. c.ServerError("CreateSource", err)
  159. }
  160. return
  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(setting.AppSubURL + "/admin/auths")
  165. }
  166. // EditAuthSource shows edit auth source page
  167. func EditAuthSource(c *context.Context) {
  168. c.Title("admin.auths.edit")
  169. c.PageIs("Admin")
  170. c.PageIs("AdminAuthentications")
  171. c.Data["SecurityProtocols"] = securityProtocols
  172. c.Data["SMTPAuths"] = models.SMTPAuths
  173. source, err := models.GetLoginSourceByID(c.ParamsInt64(":authid"))
  174. if err != nil {
  175. c.ServerError("GetLoginSourceByID", err)
  176. return
  177. }
  178. c.Data["Source"] = source
  179. c.Data["HasTLS"] = source.HasTLS()
  180. c.Success(AUTH_EDIT)
  181. }
  182. // EditAuthSourcePost edits an auth source
  183. func EditAuthSourcePost(c *context.Context, f form.Authentication) {
  184. c.Title("admin.auths.edit")
  185. c.PageIs("Admin")
  186. c.PageIs("AdminAuthentications")
  187. c.Data["SMTPAuths"] = models.SMTPAuths
  188. source, err := models.GetLoginSourceByID(c.ParamsInt64(":authid"))
  189. if err != nil {
  190. c.ServerError("GetLoginSourceByID", err)
  191. return
  192. }
  193. c.Data["Source"] = source
  194. c.Data["HasTLS"] = source.HasTLS()
  195. if c.HasError() {
  196. c.Success(AUTH_EDIT)
  197. return
  198. }
  199. var config core.Conversion
  200. switch models.LoginType(f.Type) {
  201. case models.LOGIN_LDAP, models.LOGIN_DLDAP:
  202. config = parseLDAPConfig(f)
  203. case models.LOGIN_SMTP:
  204. config = parseSMTPConfig(f)
  205. case models.LOGIN_PAM:
  206. config = &models.PAMConfig{
  207. ServiceName: f.PAMServiceName,
  208. }
  209. case models.LOGIN_GITHUB:
  210. var apiEndpoint = f.GithubApiEndpoint
  211. if !strings.HasSuffix(apiEndpoint, "/") {
  212. apiEndpoint += "/"
  213. }
  214. config = &models.GITHUBConfig{
  215. ApiEndpoint: apiEndpoint,
  216. }
  217. default:
  218. c.Error(400)
  219. return
  220. }
  221. source.Name = f.Name
  222. source.IsActived = f.IsActive
  223. source.IsDefault = f.IsDefault
  224. source.Cfg = config
  225. if err := models.UpdateLoginSource(source); err != nil {
  226. c.ServerError("UpdateLoginSource", err)
  227. return
  228. }
  229. log.Trace("Authentication changed by admin '%s': %d", c.User.Name, source.ID)
  230. c.Flash.Success("Authentication setting has been updated successfully.")
  231. c.Redirect(setting.AppSubURL + "/admin/auths/" + com.ToStr(f.ID))
  232. }
  233. // DeleteAuthSource deletes an auth source
  234. func DeleteAuthSource(c *context.Context) {
  235. source, err := models.GetLoginSourceByID(c.ParamsInt64(":authid"))
  236. if err != nil {
  237. c.ServerError("GetLoginSourceByID", err)
  238. return
  239. }
  240. if err = models.DeleteSource(source); err != nil {
  241. if models.IsErrLoginSourceInUse(err) {
  242. c.Flash.Error("This authentication is still used by some users, please delete or convert these users to another login type first.")
  243. } else {
  244. c.Flash.Error(fmt.Sprintf("DeleteSource: %v", err))
  245. }
  246. c.JSONSuccess(map[string]interface{}{
  247. "redirect": setting.AppSubURL + "/admin/auths/" + c.Params(":authid"),
  248. })
  249. return
  250. }
  251. log.Trace("Authentication deleted by admin(%s): %d", c.User.Name, source.ID)
  252. c.Flash.Success("Authentication has been deleted successfully!")
  253. c.JSONSuccess(map[string]interface{}{
  254. "redirect": setting.AppSubURL + "/admin/auths",
  255. })
  256. }