oauth.go 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  1. package model
  2. import (
  3. "strconv"
  4. "strings"
  5. )
  6. const OIDC_DEFAULT_SCOPES = "openid,profile,email"
  7. const (
  8. OauthTypeGithub string = "github"
  9. OauthTypeGoogle string = "google"
  10. OauthTypeOidc string = "oidc"
  11. OauthTypeWebauth string = "webauth"
  12. )
  13. const (
  14. OauthNameGithub string = "GitHub"
  15. OauthNameGoogle string = "Google"
  16. OauthNameOidc string = "OIDC"
  17. OauthNameWebauth string = "WebAuth"
  18. )
  19. const (
  20. UserEndpointGithub string = "https://api.github.com/user"
  21. UserEndpointGoogle string = "https://www.googleapis.com/oauth2/v3/userinfo"
  22. UserEndpointOidc string = ""
  23. )
  24. type Oauth struct {
  25. IdModel
  26. Op string `json:"op"`
  27. OauthType string `json:"oauth_type"`
  28. ClientId string `json:"client_id"`
  29. ClientSecret string `json:"client_secret"`
  30. RedirectUrl string `json:"redirect_url"`
  31. AutoRegister *bool `json:"auto_register"`
  32. Scopes string `json:"scopes"`
  33. Issuer string `json:"issuer"`
  34. TimeModel
  35. }
  36. type OauthUser struct {
  37. OpenId string `json:"open_id" gorm:"not null;index"`
  38. Name string `json:"name"`
  39. Username string `json:"username"`
  40. Email string `json:"email"`
  41. VerifiedEmail bool `json:"verified_email,omitempty"`
  42. Picture string `json:"picture,omitempty"`
  43. }
  44. func (ou *OauthUser) ToUser(user *User, overideUsername bool) {
  45. if overideUsername {
  46. user.Username = ou.Username
  47. }
  48. user.Email = ou.Email
  49. user.Nickname = ou.Name
  50. user.Avatar = ou.Picture
  51. }
  52. type OauthUserBase struct {
  53. Name string `json:"name"`
  54. Email string `json:"email"`
  55. }
  56. type OidcUser struct {
  57. OauthUserBase
  58. Sub string `json:"sub"`
  59. VerifiedEmail bool `json:"email_verified"`
  60. PreferredUsername string `json:"preferred_username"`
  61. Picture string `json:"picture"`
  62. }
  63. func (ou *OidcUser) ToOauthUser() *OauthUser {
  64. var username string
  65. // 使用 PreferredUsername,如果不存在,降级到 Email 前缀
  66. if ou.PreferredUsername != "" {
  67. username = ou.PreferredUsername
  68. } else {
  69. username = strings.ToLower(strings.Split(ou.Email, "@")[0])
  70. }
  71. return &OauthUser{
  72. OpenId: ou.Sub,
  73. Name: ou.Name,
  74. Username: username,
  75. Email: ou.Email,
  76. VerifiedEmail: ou.VerifiedEmail,
  77. Picture: ou.Picture,
  78. }
  79. }
  80. type GoogleUser struct {
  81. OidcUser
  82. }
  83. // GoogleUser 使用特定的 Username 规则来调用 ToOauthUser
  84. func (gu *GoogleUser) ToOauthUser() *OauthUser {
  85. return gu.OidcUser.ToOauthUser()
  86. }
  87. type GithubUser struct {
  88. OauthUserBase
  89. Id int `json:"id"`
  90. Login string `json:"login"`
  91. AvatarUrl string `json:"avatar_url"`
  92. VerifiedEmail bool `json:"verified_email"`
  93. }
  94. func (gu *GithubUser) ToOauthUser() *OauthUser {
  95. username := strings.ToLower(gu.Login)
  96. return &OauthUser{
  97. OpenId: strconv.Itoa(gu.Id),
  98. Name: gu.Name,
  99. Username: username,
  100. Email: gu.Email,
  101. VerifiedEmail: gu.VerifiedEmail,
  102. Picture: gu.AvatarUrl,
  103. }
  104. }
  105. type OauthList struct {
  106. Oauths []*Oauth `json:"list"`
  107. Pagination
  108. }