diff --git a/go.mod b/go.mod index 4a59f33f5..b5bcfe909 100644 --- a/go.mod +++ b/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 diff --git a/go.sum b/go.sum index 548098229..33d5e376a 100644 --- a/go.sum +++ b/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= diff --git a/logic/security.go b/logic/security.go index aa6922360..84f7a3cf6 100644 --- a/logic/security.go +++ b/logic/security.go @@ -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 } diff --git a/pro/auth/auth.go b/pro/auth/auth.go index 1fb0e3d67..49a34e73a 100644 --- a/pro/auth/auth.go +++ b/pro/auth/auth.go @@ -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 != "" { diff --git a/pro/auth/azure-ad.go b/pro/auth/azure-ad.go index b0981aaeb..c41a96d81 100644 --- a/pro/auth/azure-ad.go +++ b/pro/auth/azure-ad.go @@ -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 } diff --git a/pro/auth/github.go b/pro/auth/github.go index 37c584520..2b65ee2fb 100644 --- a/pro/auth/github.go +++ b/pro/auth/github.go @@ -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 }