NET-1064: Improved Oauth SignUp message prompts (#2875)

* add pending users api

* insert user to pending users on first time oauth login

* add pending user check on headless login

* fix conflicting apis

* no records error

* add allowed emails domains for oauth singup to config

* check if user is allowed to signup

* improve oauth message prompts

* handle trial enddate  error logs
This commit is contained in:
Abhishek K 2024-04-03 23:59:44 +05:30 committed by GitHub
parent dccb6b5da7
commit b7c8b738d7
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
8 changed files with 47 additions and 30 deletions

View file

@ -67,7 +67,7 @@ func handleAzureCallback(w http.ResponseWriter, r *http.Request) {
} }
// check if user approval is already pending // check if user approval is already pending
if logic.IsPendingUser(content.UserPrincipalName) { if logic.IsPendingUser(content.UserPrincipalName) {
handleOauthUserNotAllowed(w) handleOauthUserSignUpApprovalPending(w)
return return
} }
_, err = logic.GetUser(content.UserPrincipalName) _, err = logic.GetUser(content.UserPrincipalName)
@ -80,7 +80,7 @@ func handleAzureCallback(w http.ResponseWriter, r *http.Request) {
handleSomethingWentWrong(w) handleSomethingWentWrong(w)
return return
} }
handleOauthUserNotAllowed(w) handleFirstTimeOauthUserSignUp(w)
return return
} else { } else {
handleSomethingWentWrong(w) handleSomethingWentWrong(w)

View file

@ -12,12 +12,26 @@ const oauthNotConfigured = `<!DOCTYPE html><html>
const userNotAllowed = `<!DOCTYPE html><html> const userNotAllowed = `<!DOCTYPE html><html>
<body> <body>
<h3>Only Admins are allowed to access Dashboard.</h3> <h3>Only administrators can access the Dashboard. Please contact your administrator to elevate your account.</h3>
<h3>Furthermore, Admin has to approve your identity to have access to netmaker networks</h3> <p>Non-Admins can access the netmaker networks using <a href="https://docs.netmaker.io/pro/rac.html" target="_blank" rel="noopener">RemoteAccessClient.</a></p>
<p>Once your identity is approved, Non-Admins can access the netmaker networks using <a href="https://docs.netmaker.io/pro/rac.html" target="_blank" rel="noopener">RemoteAccessClient.</a></p>
</body> </body>
</html> </html>
` `
const userFirstTimeSignUp = `<!DOCTYPE html><html>
<body>
<h3>Thank you for signing up. Please contact your administrator for access.</h3>
</body>
</html>
`
const userSignUpApprovalPending = `<!DOCTYPE html><html>
<body>
<h3>Your account is yet to be approved. Please contact your administrator for access.</h3>
</body>
</html>
`
const userNotFound = `<!DOCTYPE html><html> const userNotFound = `<!DOCTYPE html><html>
<body> <body>
<h3>User Not Found.</h3> <h3>User Not Found.</h3>
@ -26,13 +40,13 @@ const userNotFound = `<!DOCTYPE html><html>
const somethingwentwrong = `<!DOCTYPE html><html> const somethingwentwrong = `<!DOCTYPE html><html>
<body> <body>
<h3>Something went wrong. Contact Admin</h3> <h3>Something went wrong. Contact Admin.</h3>
</body> </body>
</html>` </html>`
const notallowedtosignup = `<!DOCTYPE html><html> const notallowedtosignup = `<!DOCTYPE html><html>
<body> <body>
<h3>You are not allowed to SignUp.</h3> <h3>Your email is not allowed. Please contact your administrator.</h3>
</body> </body>
</html>` </html>`
@ -47,6 +61,17 @@ func handleOauthUserNotAllowed(response http.ResponseWriter) {
response.WriteHeader(http.StatusForbidden) response.WriteHeader(http.StatusForbidden)
response.Write([]byte(userNotAllowed)) response.Write([]byte(userNotAllowed))
} }
func handleFirstTimeOauthUserSignUp(response http.ResponseWriter) {
response.Header().Set("Content-Type", "text/html; charset=utf-8")
response.WriteHeader(http.StatusForbidden)
response.Write([]byte(userFirstTimeSignUp))
}
func handleOauthUserSignUpApprovalPending(response http.ResponseWriter) {
response.Header().Set("Content-Type", "text/html; charset=utf-8")
response.WriteHeader(http.StatusForbidden)
response.Write([]byte(userSignUpApprovalPending))
}
func handleOauthUserNotAllowedToSignUp(response http.ResponseWriter) { func handleOauthUserNotAllowedToSignUp(response http.ResponseWriter) {
response.Header().Set("Content-Type", "text/html; charset=utf-8") response.Header().Set("Content-Type", "text/html; charset=utf-8")

View file

@ -67,7 +67,7 @@ func handleGithubCallback(w http.ResponseWriter, r *http.Request) {
} }
// check if user approval is already pending // check if user approval is already pending
if logic.IsPendingUser(content.Login) { if logic.IsPendingUser(content.Login) {
handleOauthUserNotAllowed(w) handleOauthUserSignUpApprovalPending(w)
return return
} }
_, err = logic.GetUser(content.Login) _, err = logic.GetUser(content.Login)
@ -80,7 +80,7 @@ func handleGithubCallback(w http.ResponseWriter, r *http.Request) {
handleSomethingWentWrong(w) handleSomethingWentWrong(w)
return return
} }
handleOauthUserNotAllowed(w) handleFirstTimeOauthUserSignUp(w)
return return
} else { } else {
handleSomethingWentWrong(w) handleSomethingWentWrong(w)

View file

@ -69,7 +69,7 @@ func handleGoogleCallback(w http.ResponseWriter, r *http.Request) {
} }
// check if user approval is already pending // check if user approval is already pending
if logic.IsPendingUser(content.Email) { if logic.IsPendingUser(content.Email) {
handleOauthUserNotAllowed(w) handleOauthUserSignUpApprovalPending(w)
return return
} }
_, err = logic.GetUser(content.Email) _, err = logic.GetUser(content.Email)
@ -82,7 +82,7 @@ func handleGoogleCallback(w http.ResponseWriter, r *http.Request) {
handleSomethingWentWrong(w) handleSomethingWentWrong(w)
return return
} }
handleOauthUserNotAllowed(w) handleFirstTimeOauthUserSignUp(w)
return return
} else { } else {
handleSomethingWentWrong(w) handleSomethingWentWrong(w)

View file

@ -80,7 +80,7 @@ func handleOIDCCallback(w http.ResponseWriter, r *http.Request) {
} }
// check if user approval is already pending // check if user approval is already pending
if logic.IsPendingUser(content.Email) { if logic.IsPendingUser(content.Email) {
handleOauthUserNotAllowed(w) handleOauthUserSignUpApprovalPending(w)
return return
} }
_, err = logic.GetUser(content.Email) _, err = logic.GetUser(content.Email)
@ -93,7 +93,7 @@ func handleOIDCCallback(w http.ResponseWriter, r *http.Request) {
handleSomethingWentWrong(w) handleSomethingWentWrong(w)
return return
} }
handleOauthUserNotAllowed(w) handleFirstTimeOauthUserSignUp(w)
return return
} else { } else {
handleSomethingWentWrong(w) handleSomethingWentWrong(w)

View file

@ -39,10 +39,7 @@ func sendTelemetry() error {
return err return err
} }
// get telemetry data // get telemetry data
d, err := FetchTelemetryData() d := FetchTelemetryData()
if err != nil {
slog.Error("error fetching telemetry data", "error", err)
}
// get tenant admin email // get tenant admin email
adminEmail := os.Getenv("NM_EMAIL") adminEmail := os.Getenv("NM_EMAIL")
client, err := posthog.NewWithConfig(posthog_pub_key, posthog.Config{Endpoint: posthog_endpoint}) client, err := posthog.NewWithConfig(posthog_pub_key, posthog.Config{Endpoint: posthog_endpoint})
@ -82,7 +79,7 @@ func sendTelemetry() error {
} }
// FetchTelemetryData - fetches telemetry data: count of various object types in DB // FetchTelemetryData - fetches telemetry data: count of various object types in DB
func FetchTelemetryData() (telemetryData, error) { func FetchTelemetryData() telemetryData {
var data telemetryData var data telemetryData
data.IsPro = servercfg.IsPro data.IsPro = servercfg.IsPro
@ -92,21 +89,16 @@ func FetchTelemetryData() (telemetryData, error) {
data.Hosts = getDBLength(database.HOSTS_TABLE_NAME) data.Hosts = getDBLength(database.HOSTS_TABLE_NAME)
data.Version = servercfg.GetVersion() data.Version = servercfg.GetVersion()
data.Servers = getServerCount() data.Servers = getServerCount()
nodes, err := GetAllNodes() nodes, _ := GetAllNodes()
if err == nil { data.Nodes = len(nodes)
data.Nodes = len(nodes) data.Count = getClientCount(nodes)
data.Count = getClientCount(nodes) endDate, _ := GetTrialEndDate()
}
endDate, err := GetTrialEndDate()
if err != nil {
logger.Log(0, "error getting trial end date", err.Error())
}
data.ProTrialEndDate = endDate data.ProTrialEndDate = endDate
if endDate.After(time.Now()) { if endDate.After(time.Now()) {
data.IsProTrial = true data.IsProTrial = true
} }
data.IsSaasTenant = servercfg.DeployedByOperator() data.IsSaasTenant = servercfg.DeployedByOperator()
return data, err return data
} }
// getServerCount returns number of servers from database // getServerCount returns number of servers from database

View file

@ -177,7 +177,7 @@ func removeInterGw(egressRanges []string) ([]string, bool) {
func updateAcls() { func updateAcls() {
// get all networks // get all networks
networks, err := logic.GetNetworks() networks, err := logic.GetNetworks()
if err != nil { if err != nil && !database.IsEmptyRecord(err) {
slog.Error("acls migration failed. error getting networks", "error", err) slog.Error("acls migration failed. error getting networks", "error", err)
return return
} }

View file

@ -42,7 +42,7 @@ const trial_data_key = "trialdata"
// stores trial end date // stores trial end date
func initTrial() error { func initTrial() error {
telData, _ := logic.FetchTelemetryData() telData := logic.FetchTelemetryData()
if telData.Hosts > 0 || telData.Networks > 0 || telData.Users > 0 { if telData.Hosts > 0 || telData.Networks > 0 || telData.Users > 0 {
return nil // database is already populated, so skip creating trial return nil // database is already populated, so skip creating trial
} }