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.

source_authenticate.go 3.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125
  1. // Copyright 2021 The Gitea Authors. All rights reserved.
  2. // SPDX-License-Identifier: MIT
  3. package ldap
  4. import (
  5. "context"
  6. "fmt"
  7. "strings"
  8. asymkey_model "code.gitea.io/gitea/models/asymkey"
  9. "code.gitea.io/gitea/models/auth"
  10. user_model "code.gitea.io/gitea/models/user"
  11. auth_module "code.gitea.io/gitea/modules/auth"
  12. "code.gitea.io/gitea/modules/optional"
  13. asymkey_service "code.gitea.io/gitea/services/asymkey"
  14. source_service "code.gitea.io/gitea/services/auth/source"
  15. user_service "code.gitea.io/gitea/services/user"
  16. )
  17. // Authenticate queries if login/password is valid against the LDAP directory pool,
  18. // and create a local user if success when enabled.
  19. func (source *Source) Authenticate(ctx context.Context, user *user_model.User, userName, password string) (*user_model.User, error) {
  20. loginName := userName
  21. if user != nil {
  22. loginName = user.LoginName
  23. }
  24. sr := source.SearchEntry(loginName, password, source.authSource.Type == auth.DLDAP)
  25. if sr == nil {
  26. // User not in LDAP, do nothing
  27. return nil, user_model.ErrUserNotExist{Name: loginName}
  28. }
  29. // Fallback.
  30. if len(sr.Username) == 0 {
  31. sr.Username = userName
  32. }
  33. if len(sr.Mail) == 0 {
  34. sr.Mail = fmt.Sprintf("%s@localhost.local", sr.Username)
  35. }
  36. isAttributeSSHPublicKeySet := len(strings.TrimSpace(source.AttributeSSHPublicKey)) > 0
  37. // Update User admin flag if exist
  38. if isExist, err := user_model.IsUserExist(ctx, 0, sr.Username); err != nil {
  39. return nil, err
  40. } else if isExist {
  41. if user == nil {
  42. user, err = user_model.GetUserByName(ctx, sr.Username)
  43. if err != nil {
  44. return nil, err
  45. }
  46. }
  47. if user != nil && !user.ProhibitLogin {
  48. opts := &user_service.UpdateOptions{}
  49. if len(source.AdminFilter) > 0 && user.IsAdmin != sr.IsAdmin {
  50. // Change existing admin flag only if AdminFilter option is set
  51. opts.IsAdmin = optional.Some(sr.IsAdmin)
  52. }
  53. if !sr.IsAdmin && len(source.RestrictedFilter) > 0 && user.IsRestricted != sr.IsRestricted {
  54. // Change existing restricted flag only if RestrictedFilter option is set
  55. opts.IsRestricted = optional.Some(sr.IsRestricted)
  56. }
  57. if opts.IsAdmin.Has() || opts.IsRestricted.Has() {
  58. if err := user_service.UpdateUser(ctx, user, opts); err != nil {
  59. return nil, err
  60. }
  61. }
  62. }
  63. }
  64. if user != nil {
  65. if isAttributeSSHPublicKeySet && asymkey_model.SynchronizePublicKeys(ctx, user, source.authSource, sr.SSHPublicKey) {
  66. if err := asymkey_service.RewriteAllPublicKeys(ctx); err != nil {
  67. return user, err
  68. }
  69. }
  70. } else {
  71. user = &user_model.User{
  72. LowerName: strings.ToLower(sr.Username),
  73. Name: sr.Username,
  74. FullName: composeFullName(sr.Name, sr.Surname, sr.Username),
  75. Email: sr.Mail,
  76. LoginType: source.authSource.Type,
  77. LoginSource: source.authSource.ID,
  78. LoginName: userName,
  79. IsAdmin: sr.IsAdmin,
  80. }
  81. overwriteDefault := &user_model.CreateUserOverwriteOptions{
  82. IsRestricted: optional.Some(sr.IsRestricted),
  83. IsActive: optional.Some(true),
  84. }
  85. err := user_model.CreateUser(ctx, user, overwriteDefault)
  86. if err != nil {
  87. return user, err
  88. }
  89. if isAttributeSSHPublicKeySet && asymkey_model.AddPublicKeysBySource(ctx, user, source.authSource, sr.SSHPublicKey) {
  90. if err := asymkey_service.RewriteAllPublicKeys(ctx); err != nil {
  91. return user, err
  92. }
  93. }
  94. if len(source.AttributeAvatar) > 0 {
  95. if err := user_service.UploadAvatar(ctx, user, sr.Avatar); err != nil {
  96. return user, err
  97. }
  98. }
  99. }
  100. if source.GroupsEnabled && (source.GroupTeamMap != "" || source.GroupTeamMapRemoval) {
  101. groupTeamMapping, err := auth_module.UnmarshalGroupTeamMapping(source.GroupTeamMap)
  102. if err != nil {
  103. return user, err
  104. }
  105. if err := source_service.SyncGroupsToTeams(ctx, user, sr.Groups, groupTeamMapping, source.GroupTeamMapRemoval); err != nil {
  106. return user, err
  107. }
  108. }
  109. return user, nil
  110. }
  111. // IsSkipLocalTwoFA returns if this source should skip local 2fa for password authentication
  112. func (source *Source) IsSkipLocalTwoFA() bool {
  113. return source.SkipLocalTwoFA
  114. }