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

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