gitea源码

oauth_signin_sync.go 2.9KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. // Copyright 2025 The Gitea Authors. All rights reserved.
  2. // SPDX-License-Identifier: MIT
  3. package auth
  4. import (
  5. "fmt"
  6. asymkey_model "code.gitea.io/gitea/models/asymkey"
  7. "code.gitea.io/gitea/models/auth"
  8. user_model "code.gitea.io/gitea/models/user"
  9. "code.gitea.io/gitea/modules/log"
  10. "code.gitea.io/gitea/modules/util"
  11. asymkey_service "code.gitea.io/gitea/services/asymkey"
  12. "code.gitea.io/gitea/services/auth/source/oauth2"
  13. "code.gitea.io/gitea/services/context"
  14. "github.com/markbates/goth"
  15. )
  16. func oauth2SignInSync(ctx *context.Context, authSourceID int64, u *user_model.User, gothUser goth.User) {
  17. oauth2UpdateAvatarIfNeed(ctx, gothUser.AvatarURL, u)
  18. authSource, err := auth.GetSourceByID(ctx, authSourceID)
  19. if err != nil {
  20. ctx.ServerError("GetSourceByID", err)
  21. return
  22. }
  23. oauth2Source, _ := authSource.Cfg.(*oauth2.Source)
  24. if !authSource.IsOAuth2() || oauth2Source == nil {
  25. ctx.ServerError("oauth2SignInSync", fmt.Errorf("source %s is not an OAuth2 source", gothUser.Provider))
  26. return
  27. }
  28. // sync full name
  29. fullNameKey := util.IfZero(oauth2Source.FullNameClaimName, "name")
  30. fullName, _ := gothUser.RawData[fullNameKey].(string)
  31. fullName = util.IfZero(fullName, gothUser.Name)
  32. // need to update if the user has no full name set
  33. shouldUpdateFullName := u.FullName == ""
  34. // force to update if the attribute is set
  35. shouldUpdateFullName = shouldUpdateFullName || oauth2Source.FullNameClaimName != ""
  36. // only update if the full name is different
  37. shouldUpdateFullName = shouldUpdateFullName && u.FullName != fullName
  38. if shouldUpdateFullName {
  39. u.FullName = fullName
  40. if err := user_model.UpdateUserCols(ctx, u, "full_name"); err != nil {
  41. log.Error("Unable to sync OAuth2 user full name %s: %v", gothUser.Provider, err)
  42. }
  43. }
  44. err = oauth2UpdateSSHPubIfNeed(ctx, authSource, &gothUser, u)
  45. if err != nil {
  46. log.Error("Unable to sync OAuth2 SSH public key %s: %v", gothUser.Provider, err)
  47. }
  48. }
  49. func oauth2SyncGetSSHKeys(source *oauth2.Source, gothUser *goth.User) ([]string, error) {
  50. value, exists := gothUser.RawData[source.SSHPublicKeyClaimName]
  51. if !exists {
  52. return []string{}, nil
  53. }
  54. rawSlice, ok := value.([]any)
  55. if !ok {
  56. return nil, fmt.Errorf("invalid SSH public key value type: %T", value)
  57. }
  58. sshKeys := make([]string, 0, len(rawSlice))
  59. for _, v := range rawSlice {
  60. str, ok := v.(string)
  61. if !ok {
  62. return nil, fmt.Errorf("invalid SSH public key value item type: %T", v)
  63. }
  64. sshKeys = append(sshKeys, str)
  65. }
  66. return sshKeys, nil
  67. }
  68. func oauth2UpdateSSHPubIfNeed(ctx *context.Context, authSource *auth.Source, gothUser *goth.User, user *user_model.User) error {
  69. oauth2Source, _ := authSource.Cfg.(*oauth2.Source)
  70. if oauth2Source == nil || oauth2Source.SSHPublicKeyClaimName == "" {
  71. return nil
  72. }
  73. sshKeys, err := oauth2SyncGetSSHKeys(oauth2Source, gothUser)
  74. if err != nil {
  75. return err
  76. }
  77. if !asymkey_model.SynchronizePublicKeys(ctx, user, authSource, sshKeys) {
  78. return nil
  79. }
  80. return asymkey_service.RewriteAllPublicKeys(ctx)
  81. }