Tao Chen 1 год назад
Родитель
Сommit
1b7c7eef8f
2 измененных файлов с 24 добавлено и 27 удалено
  1. 22 25
      model/oauth.go
  2. 2 2
      service/oauth.go

+ 22 - 25
model/oauth.go

@@ -2,9 +2,10 @@ package model
2 2
 
3 3
 import (
4 4
 	"strconv"
5
-	"fmt"
5
+	"strings"
6 6
 )
7 7
 
8
+const OIDC_DEFAULT_SCOPES = "openid,profile,email"
8 9
 
9 10
 const (
10 11
 	OauthTypeGithub  string = "github"
@@ -57,50 +58,45 @@ func (ou *OauthUser) ToUser(user *User, overideUsername bool) {
57 58
 	user.Avatar = ou.Picture
58 59
 }
59 60
 
60
-
61 61
 type OauthUserBase struct {
62 62
 	Name  string `json:"name"`
63 63
 	Email string `json:"email"`
64 64
 }
65 65
 
66
-
67 66
 type OidcUser struct {
68 67
 	OauthUserBase
69 68
 	Sub               string `json:"sub"`
70 69
 	VerifiedEmail     bool   `json:"email_verified"`
71 70
 	PreferredUsername string `json:"preferred_username"`
72
-	Picture		   	  string `json:"picture"`
71
+	Picture           string `json:"picture"`
73 72
 }
74 73
 
75 74
 func (ou *OidcUser) ToOauthUser() *OauthUser {
75
+	var username string
76
+	// 使用 PreferredUsername,如果不存在,降级到 Email 前缀
77
+	if ou.PreferredUsername != "" {
78
+		username = ou.PreferredUsername
79
+	} else {
80
+		username = strings.ToLower(strings.Split(ou.Email, "@")[0])
81
+	}
82
+
76 83
 	return &OauthUser{
77
-		OpenId: 		ou.Sub,
78
-		Name:   		ou.Name,
79
-		Username: 		ou.PreferredUsername,
80
-		Email:  		ou.Email,
81
-		VerifiedEmail: 	ou.VerifiedEmail,
82
-		Picture:		ou.Picture,
84
+		OpenId:        ou.Sub,
85
+		Name:          ou.Name,
86
+		Username:      username,
87
+		Email:         ou.Email,
88
+		VerifiedEmail: ou.VerifiedEmail,
89
+		Picture:       ou.Picture,
83 90
 	}
84 91
 }
85 92
 
86 93
 type GoogleUser struct {
87
-	OauthUserBase
88
-	FamilyName    string `json:"family_name"`
89
-	GivenName     string `json:"given_name"`
90
-	Id            string `json:"id"`
91
-	Picture       string `json:"picture"`
92
-	VerifiedEmail bool   `json:"verified_email"`
94
+	OidcUser
93 95
 }
94 96
 
97
+// GoogleUser 使用特定的 Username 规则来调用 ToOauthUser
95 98
 func (gu *GoogleUser) ToOauthUser() *OauthUser {
96
-	return &OauthUser{
97
-		OpenId: 		gu.Id,
98
-		Name:   		fmt.Sprintf("%s %s", gu.GivenName, gu.FamilyName),
99
-		Username: 		gu.GivenName,
100
-		Email:  		gu.Email,
101
-		VerifiedEmail: 	gu.VerifiedEmail,
102
-		Picture:		gu.Picture,
103
-	}	
99
+	return gu.OidcUser.ToOauthUser()
104 100
 }
105 101
 
106 102
 
@@ -113,10 +109,11 @@ type GithubUser struct {
113 109
 }
114 110
 
115 111
 func (gu *GithubUser) ToOauthUser() *OauthUser {
112
+	username := strings.ToLower(gu.Login)
116 113
 	return &OauthUser{
117 114
 		OpenId: 		strconv.Itoa(gu.Id),
118 115
 		Name:   		gu.Name,
119
-		Username: 		gu.Login,
116
+		Username: 		username,
120 117
 		Email:  		gu.Email,
121 118
 		VerifiedEmail: 	gu.VerifiedEmail,
122 119
 		Picture:		gu.AvatarUrl,

+ 2 - 2
service/oauth.go

@@ -170,7 +170,7 @@ func (os *OauthService) GetOauthConfig(op string) (err error, oauthInfo *model.O
170 170
 		oauthConfig.Scopes = []string{"read:user", "user:email"}
171 171
 	case model.OauthTypeGoogle:
172 172
 		oauthConfig.Endpoint = google.Endpoint
173
-		oauthConfig.Scopes = []string{"https://www.googleapis.com/auth/userinfo.profile", "https://www.googleapis.com/auth/userinfo.email"}
173
+		oauthConfig.Scopes = os.constructScopes(model.OIDC_DEFAULT_SCOPES)
174 174
 	case model.OauthTypeOidc:
175 175
 		var endpoint OidcEndpoint
176 176
 		err, endpoint = os.FetchOidcEndpoint(oauthInfo.Issuer)
@@ -374,7 +374,7 @@ func (os *OauthService) getScopesByOp(op string) []string {
374 374
 func (os *OauthService) constructScopes(scopes string) []string {
375 375
     scopes = strings.TrimSpace(scopes)
376 376
     if scopes == "" {
377
-        scopes = "openid,profile,email"
377
+        scopes = model.OIDC_DEFAULT_SCOPES
378 378
     }
379 379
     return strings.Split(scopes, ",")
380 380
 }