gitea源码

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  1. // Copyright 2021 The Gitea Authors. All rights reserved.
  2. // SPDX-License-Identifier: MIT
  3. package auth
  4. import (
  5. "context"
  6. "strings"
  7. "code.gitea.io/gitea/models/auth"
  8. "code.gitea.io/gitea/models/db"
  9. user_model "code.gitea.io/gitea/models/user"
  10. "code.gitea.io/gitea/modules/log"
  11. "code.gitea.io/gitea/modules/optional"
  12. "code.gitea.io/gitea/services/auth/source/oauth2"
  13. "code.gitea.io/gitea/services/auth/source/smtp"
  14. _ "code.gitea.io/gitea/services/auth/source/db" // register the sources (and below)
  15. _ "code.gitea.io/gitea/services/auth/source/ldap" // register the ldap source
  16. _ "code.gitea.io/gitea/services/auth/source/pam" // register the pam source
  17. _ "code.gitea.io/gitea/services/auth/source/sspi" // register the sspi source
  18. )
  19. // UserSignIn validates user name and password.
  20. func UserSignIn(ctx context.Context, username, password string) (*user_model.User, *auth.Source, error) {
  21. var user *user_model.User
  22. isEmail := false
  23. if strings.Contains(username, "@") {
  24. isEmail = true
  25. emailAddress := user_model.EmailAddress{LowerEmail: strings.ToLower(strings.TrimSpace(username))}
  26. // check same email
  27. has, err := db.GetEngine(ctx).Get(&emailAddress)
  28. if err != nil {
  29. return nil, nil, err
  30. }
  31. if has {
  32. if !emailAddress.IsActivated {
  33. return nil, nil, user_model.ErrEmailAddressNotExist{
  34. Email: username,
  35. }
  36. }
  37. user = &user_model.User{ID: emailAddress.UID}
  38. }
  39. } else {
  40. trimmedUsername := strings.TrimSpace(username)
  41. if len(trimmedUsername) == 0 {
  42. return nil, nil, user_model.ErrUserNotExist{Name: username}
  43. }
  44. user = &user_model.User{LowerName: strings.ToLower(trimmedUsername)}
  45. }
  46. if user != nil {
  47. hasUser, err := user_model.GetUser(ctx, user)
  48. if err != nil {
  49. return nil, nil, err
  50. }
  51. if hasUser {
  52. source, err := auth.GetSourceByID(ctx, user.LoginSource)
  53. if err != nil {
  54. return nil, nil, err
  55. }
  56. if !source.IsActive {
  57. return nil, nil, oauth2.ErrAuthSourceNotActivated
  58. }
  59. authenticator, ok := source.Cfg.(PasswordAuthenticator)
  60. if !ok {
  61. return nil, nil, smtp.ErrUnsupportedLoginType
  62. }
  63. user, err := authenticator.Authenticate(ctx, user, user.LoginName, password)
  64. if err != nil {
  65. return nil, nil, err
  66. }
  67. // WARN: DON'T check user.IsActive, that will be checked on reqSign so that
  68. // user could be hint to resend confirm email.
  69. if user.ProhibitLogin {
  70. return nil, nil, user_model.ErrUserProhibitLogin{UID: user.ID, Name: user.Name}
  71. }
  72. return user, source, nil
  73. }
  74. }
  75. sources, err := db.Find[auth.Source](ctx, auth.FindSourcesOptions{
  76. IsActive: optional.Some(true),
  77. })
  78. if err != nil {
  79. return nil, nil, err
  80. }
  81. for _, source := range sources {
  82. if !source.IsActive {
  83. // don't try to authenticate non-active sources
  84. continue
  85. }
  86. authenticator, ok := source.Cfg.(PasswordAuthenticator)
  87. if !ok {
  88. continue
  89. }
  90. authUser, err := authenticator.Authenticate(ctx, nil, username, password)
  91. if err == nil {
  92. if !authUser.ProhibitLogin {
  93. return authUser, source, nil
  94. }
  95. err = user_model.ErrUserProhibitLogin{UID: authUser.ID, Name: authUser.Name}
  96. }
  97. if user_model.IsErrUserNotExist(err) {
  98. log.Debug("Failed to login '%s' via '%s': %v", username, source.Name, err)
  99. } else {
  100. log.Warn("Failed to login '%s' via '%s': %v", username, source.Name, err)
  101. }
  102. }
  103. if isEmail {
  104. return nil, nil, user_model.ErrEmailAddressNotExist{Email: username}
  105. }
  106. return nil, nil, user_model.ErrUserNotExist{Name: username}
  107. }