mirror of
https://github.com/gravitl/netmaker.git
synced 2024-09-20 07:16:06 +08:00
NET-1227: Add Additional Oauth Scopes to fetch user email (#3079)
* add list roles to pro and ce * if not pro set user role to admin * validate update user * add separate validation check for password on update * remove validate check * fix github SSO with invite signup * add oauth scopes for user email * remove debug log * fix azure ad
This commit is contained in:
parent
9ac78e15bc
commit
0463b17ea5
3
go.mod
3
go.mod
|
@ -38,11 +38,9 @@ require (
|
|||
)
|
||||
|
||||
require (
|
||||
github.com/go-jose/go-jose/v3 v3.0.3
|
||||
github.com/guumaster/tablewriter v0.0.10
|
||||
github.com/matryer/is v1.4.1
|
||||
github.com/olekukonko/tablewriter v0.0.5
|
||||
github.com/resendlabs/resend-go v1.7.0
|
||||
github.com/spf13/cobra v1.8.1
|
||||
gopkg.in/mail.v2 v2.3.1
|
||||
)
|
||||
|
@ -50,6 +48,7 @@ require (
|
|||
require (
|
||||
cloud.google.com/go/compute/metadata v0.3.0 // indirect
|
||||
github.com/gabriel-vasile/mimetype v1.4.3 // indirect
|
||||
github.com/go-jose/go-jose/v3 v3.0.3 // indirect
|
||||
github.com/inconshreveable/mousetrap v1.1.0 // indirect
|
||||
github.com/rivo/uniseg v0.2.0 // indirect
|
||||
github.com/seancfoley/bintree v1.3.1 // indirect
|
||||
|
|
12
go.sum
12
go.sum
|
@ -14,8 +14,6 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c
|
|||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/eclipse/paho.mqtt.golang v1.4.3 h1:2kwcUGn8seMUfWndX0hGbvH8r7crgcJguQNCyp70xik=
|
||||
github.com/eclipse/paho.mqtt.golang v1.4.3/go.mod h1:CSYvoAlsMkhYOXh/oKyxa8EcBci6dVkLCbo5tTC1RIE=
|
||||
github.com/eclipse/paho.mqtt.golang v1.5.0 h1:EH+bUVJNgttidWFkLLVKaQPGmkTUfQQqjOsyvMGvD6o=
|
||||
github.com/eclipse/paho.mqtt.golang v1.5.0/go.mod h1:du/2qNQVqJf/Sqs4MEL77kR8QTqANF7XU7Fk0aOTAgk=
|
||||
github.com/felixge/httpsnoop v1.0.3 h1:s/nj+GCswXYzN5v2DpNMuMQYe+0DDwt5WVCU6CWBdXk=
|
||||
github.com/felixge/httpsnoop v1.0.3/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=
|
||||
github.com/gabriel-vasile/mimetype v1.4.3 h1:in2uUcidCuFcDKtdcBxlR0rJ1+fsokWf+uqxgUFjbI0=
|
||||
|
@ -65,10 +63,6 @@ github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZb
|
|||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/posthog/posthog-go v0.0.0-20211028072449-93c17c49e2b0 h1:Y2hUrkfuM0on62KZOci/VLijlkdF/yeWU262BQgvcjE=
|
||||
github.com/posthog/posthog-go v0.0.0-20211028072449-93c17c49e2b0/go.mod h1:oa2sAs9tGai3VldabTV0eWejt/O4/OOD7azP8GaikqU=
|
||||
github.com/posthog/posthog-go v1.2.18 h1:2CBA0LOB0up+gon+xpeXuhFw69gZpjAYxQoBBGwiDWw=
|
||||
github.com/posthog/posthog-go v1.2.18/go.mod h1:QjlpryJtfYLrZF2GUkAhejH4E7WlDbdKkvOi5hLmkdg=
|
||||
github.com/resendlabs/resend-go v1.7.0 h1:DycOqSXtw2q7aB+Nt9DDJUDtaYcrNPGn1t5RFposas0=
|
||||
github.com/resendlabs/resend-go v1.7.0/go.mod h1:yip1STH7Bqfm4fD0So5HgyNbt5taG5Cplc4xXxETyLI=
|
||||
github.com/rivo/uniseg v0.1.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
|
||||
github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY=
|
||||
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
|
||||
|
@ -102,8 +96,6 @@ golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5y
|
|||
golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU=
|
||||
golang.org/x/crypto v0.23.0 h1:dIJU/v2J8Mdglj/8rJ6UUOM3Zc9zLZxVZwwxMooUSAI=
|
||||
golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8=
|
||||
golang.org/x/crypto v0.25.0 h1:ypSNr+bnYL2YhwoMt2zPxHFmbAN1KZs/njMG3hxUp30=
|
||||
golang.org/x/crypto v0.25.0/go.mod h1:T+wALwcMOSE0kXgUAnPAHqTLW+XHgcELELW8VaDgm/M=
|
||||
golang.org/x/exp v0.0.0-20230522175609-2e198f4a06a1 h1:k/i9J1pBpvlfR+9QsetwPyERsqu1GIbi967PQMq3Ivc=
|
||||
golang.org/x/exp v0.0.0-20230522175609-2e198f4a06a1/go.mod h1:V1LtkGg67GoY2N1AnLN78QLrzxkLyJw7RJb1gzOOz9w=
|
||||
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
|
||||
|
@ -115,8 +107,6 @@ golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
|
|||
golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
|
||||
golang.org/x/net v0.23.0 h1:7EYJ93RZ9vYSZAIb2x3lnuvqO5zneoD6IvWjuhfxjTs=
|
||||
golang.org/x/net v0.23.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg=
|
||||
golang.org/x/net v0.27.0 h1:5K3Njcw06/l2y9vpGCSdcxWOYHOUk3dVNGDXN+FvAys=
|
||||
golang.org/x/net v0.27.0/go.mod h1:dDi0PyhWNoiUOrAS8uXv/vnScO4wnHQO4mj9fn/RytE=
|
||||
golang.org/x/oauth2 v0.21.0 h1:tsimM75w1tF/uws5rbeHzIWxEqElMehnc+iW793zsZs=
|
||||
golang.org/x/oauth2 v0.21.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
|
@ -134,8 +124,6 @@ golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
|||
golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/sys v0.21.0 h1:rF+pYz3DAGSQAxAu1CbC7catZg4ebC4UIeIhKxBZvws=
|
||||
golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI=
|
||||
golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
|
||||
|
|
|
@ -6,7 +6,6 @@ import (
|
|||
"strings"
|
||||
|
||||
"github.com/gorilla/mux"
|
||||
"github.com/gravitl/netmaker/logger"
|
||||
"github.com/gravitl/netmaker/models"
|
||||
"github.com/gravitl/netmaker/servercfg"
|
||||
)
|
||||
|
@ -27,12 +26,10 @@ func SecurityCheck(reqAdmin bool, next http.Handler) http.HandlerFunc {
|
|||
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
r.Header.Set("ismaster", "no")
|
||||
logger.Log(0, "next", r.URL.String())
|
||||
isGlobalAccesss := r.Header.Get("IS_GLOBAL_ACCESS") == "yes"
|
||||
bearerToken := r.Header.Get("Authorization")
|
||||
username, err := GetUserNameFromToken(bearerToken)
|
||||
if err != nil {
|
||||
logger.Log(0, "next 1", r.URL.String(), err.Error())
|
||||
ReturnErrorResponse(w, r, FormatError(err, "unauthorized"))
|
||||
return
|
||||
}
|
||||
|
@ -103,7 +100,6 @@ func ContinueIfUserMatch(next http.Handler) http.HandlerFunc {
|
|||
requestedUser, _ = url.QueryUnescape(r.URL.Query().Get("username"))
|
||||
}
|
||||
if requestedUser != r.Header.Get("user") {
|
||||
logger.Log(0, "next 2", r.URL.String(), errorResponse.Message)
|
||||
ReturnErrorResponse(w, r, errorResponse)
|
||||
return
|
||||
}
|
||||
|
|
|
@ -7,6 +7,7 @@ import (
|
|||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/golang-jwt/jwt/v4"
|
||||
"github.com/gorilla/websocket"
|
||||
"github.com/gravitl/netmaker/logger"
|
||||
"github.com/gravitl/netmaker/logic"
|
||||
|
@ -236,6 +237,17 @@ func getStateAndCode(r *http.Request) (string, string) {
|
|||
return state, code
|
||||
}
|
||||
|
||||
func getUserEmailFromClaims(token string) string {
|
||||
accessToken, _ := jwt.Parse(token, func(token *jwt.Token) (interface{}, error) {
|
||||
return []byte(""), nil
|
||||
})
|
||||
if accessToken == nil {
|
||||
return ""
|
||||
}
|
||||
claims, _ := accessToken.Claims.(jwt.MapClaims)
|
||||
return claims["email"].(string)
|
||||
}
|
||||
|
||||
func (user *OAuthUser) getUserName() string {
|
||||
var userName string
|
||||
if user.Email != "" {
|
||||
|
|
|
@ -33,7 +33,7 @@ func initAzureAD(redirectURL string, clientID string, clientSecret string) {
|
|||
RedirectURL: redirectURL,
|
||||
ClientID: clientID,
|
||||
ClientSecret: clientSecret,
|
||||
Scopes: []string{"User.Read"},
|
||||
Scopes: []string{"User.Read", "email", "profile", "openid"},
|
||||
Endpoint: microsoft.AzureADEndpoint(servercfg.GetAzureTenant()),
|
||||
}
|
||||
}
|
||||
|
@ -67,10 +67,9 @@ func handleAzureCallback(w http.ResponseWriter, r *http.Request) {
|
|||
handleOauthNotConfigured(w)
|
||||
return
|
||||
}
|
||||
|
||||
var inviteExists bool
|
||||
// check if invite exists for User
|
||||
in, err := logic.GetUserInvite(content.UserPrincipalName)
|
||||
in, err := logic.GetUserInvite(content.Email)
|
||||
if err == nil {
|
||||
inviteExists = true
|
||||
}
|
||||
|
@ -90,11 +89,12 @@ func handleAzureCallback(w http.ResponseWriter, r *http.Request) {
|
|||
logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
|
||||
return
|
||||
}
|
||||
user.UserName = content.UserPrincipalName // override username with azure id
|
||||
if err = logic.CreateUser(&user); err != nil {
|
||||
handleSomethingWentWrong(w)
|
||||
return
|
||||
}
|
||||
logic.DeleteUserInvite(user.UserName)
|
||||
logic.DeleteUserInvite(content.Email)
|
||||
logic.DeletePendingUser(content.UserPrincipalName)
|
||||
} else {
|
||||
if !isEmailAllowed(content.UserPrincipalName) {
|
||||
|
@ -166,8 +166,9 @@ func getAzureUserInfo(state string, code string) (*OAuthUser, error) {
|
|||
}
|
||||
var httpReq, reqErr = http.NewRequest("GET", "https://graph.microsoft.com/v1.0/me", nil)
|
||||
if reqErr != nil {
|
||||
return nil, fmt.Errorf("failed to create request to GitHub")
|
||||
return nil, fmt.Errorf("failed to create request to microsoft")
|
||||
}
|
||||
|
||||
httpReq.Header.Set("Authorization", "Bearer "+token.AccessToken)
|
||||
response, err := http.DefaultClient.Do(httpReq)
|
||||
if err != nil {
|
||||
|
@ -183,6 +184,9 @@ func getAzureUserInfo(state string, code string) (*OAuthUser, error) {
|
|||
return nil, fmt.Errorf("failed parsing email from response data: %s", err.Error())
|
||||
}
|
||||
userInfo.AccessToken = string(data)
|
||||
if userInfo.Email == "" {
|
||||
userInfo.Email = getUserEmailFromClaims(token.AccessToken)
|
||||
}
|
||||
return userInfo, nil
|
||||
}
|
||||
|
||||
|
|
|
@ -33,7 +33,7 @@ func initGithub(redirectURL string, clientID string, clientSecret string) {
|
|||
RedirectURL: redirectURL,
|
||||
ClientID: clientID,
|
||||
ClientSecret: clientSecret,
|
||||
Scopes: []string{},
|
||||
Scopes: []string{"read:user", "user:email"},
|
||||
Endpoint: github.Endpoint,
|
||||
}
|
||||
}
|
||||
|
@ -186,6 +186,9 @@ func getGithubUserInfo(state string, code string) (*OAuthUser, error) {
|
|||
return nil, fmt.Errorf("failed parsing email from response data: %s", err.Error())
|
||||
}
|
||||
userInfo.AccessToken = string(data)
|
||||
if userInfo.Email == "" {
|
||||
userInfo.Email = getUserEmailFromClaims(token.AccessToken)
|
||||
}
|
||||
return userInfo, nil
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue