diff --git a/pro/controllers/users.go b/pro/controllers/users.go index c5076d3d..c3bd9df4 100644 --- a/pro/controllers/users.go +++ b/pro/controllers/users.go @@ -206,6 +206,10 @@ func inviteUsers(w http.ResponseWriter, r *http.Request) { } for _, inviteeEmail := range inviteReq.UserEmails { // check if user with email exists, then ignore + if !email.IsValid(inviteeEmail) { + logic.ReturnErrorResponse(w, r, logic.FormatError(errors.New("invalid email "+inviteeEmail), "badrequest")) + return + } _, err := logic.GetUser(inviteeEmail) if err == nil { // user exists already, so ignore @@ -228,6 +232,14 @@ func inviteUsers(w http.ResponseWriter, r *http.Request) { slog.Error("failed to parse to invite url", "error", err) return } + if servercfg.DeployedByOperator() { + u, err = url.Parse(fmt.Sprintf("%s/invite?tenant_id=%s&email=%s&invite_code=%s", + proLogic.GetAccountsUIHost(), url.QueryEscape(servercfg.GetNetmakerTenantID()), url.QueryEscape(invite.Email), url.QueryEscape(invite.InviteCode))) + if err != nil { + slog.Error("failed to parse to invite url", "error", err) + return + } + } invite.InviteURL = u.String() err = logic.InsertUserInvite(invite) if err != nil { diff --git a/pro/email/email.go b/pro/email/email.go index f6a3e80a..7411ae3e 100644 --- a/pro/email/email.go +++ b/pro/email/email.go @@ -2,6 +2,7 @@ package email import ( "context" + "regexp" "github.com/gravitl/netmaker/servercfg" ) @@ -52,3 +53,8 @@ type Notification struct { func GetClient() (e EmailSender) { return client } + +func IsValid(email string) bool { + emailRegex := regexp.MustCompile(`^[a-z0-9._%+\-]+@[a-z0-9.\-]+\.[a-z]{2,4}$`) + return emailRegex.MatchString(email) +} diff --git a/pro/license.go b/pro/license.go index 633728d1..50825d8a 100644 --- a/pro/license.go +++ b/pro/license.go @@ -20,6 +20,7 @@ import ( "github.com/gravitl/netmaker/logic" "github.com/gravitl/netmaker/models" "github.com/gravitl/netmaker/netclient/ncutils" + proLogic "github.com/gravitl/netmaker/pro/logic" "github.com/gravitl/netmaker/servercfg" ) @@ -206,7 +207,7 @@ func validateLicenseKey(encryptedData []byte, publicKey *[32]byte) ([]byte, bool req, err := http.NewRequest( http.MethodPost, - getAccountsHost()+"/api/v1/license/validate", + proLogic.GetAccountsHost()+"/api/v1/license/validate", bytes.NewReader(requestBody), ) if err != nil { @@ -255,17 +256,6 @@ func validateLicenseKey(encryptedData []byte, publicKey *[32]byte) ([]byte, bool return nil, false, err } -func getAccountsHost() string { - switch servercfg.GetEnvironment() { - case "dev": - return accountsHostDevelopment - case "staging": - return accountsHostStaging - default: - return accountsHostProduction - } -} - func cacheResponse(response []byte) error { lrc := licenseResponseCache{ Body: response, diff --git a/pro/license_test.go b/pro/license_test.go index 12d15d3f..549bac0c 100644 --- a/pro/license_test.go +++ b/pro/license_test.go @@ -4,11 +4,13 @@ package pro import ( - "github.com/gravitl/netmaker/config" "testing" + + "github.com/gravitl/netmaker/config" + proLogic "github.com/gravitl/netmaker/pro/logic" ) -func Test_getAccountsHost(t *testing.T) { +func Test_GetAccountsHost(t *testing.T) { tests := []struct { name string envK string @@ -69,8 +71,8 @@ func Test_getAccountsHost(t *testing.T) { if tt.envK != "" { t.Setenv(tt.envK, tt.envV) } - if got := getAccountsHost(); got != tt.want { - t.Errorf("getAccountsHost() = %v, want %v", got, tt.want) + if got := proLogic.GetAccountsHost(); got != tt.want { + t.Errorf("GetAccountsHost() = %v, want %v", got, tt.want) } }) } diff --git a/pro/logic/security.go b/pro/logic/security.go index 508ac656..fcc6d73c 100644 --- a/pro/logic/security.go +++ b/pro/logic/security.go @@ -7,6 +7,27 @@ import ( "github.com/gravitl/netmaker/logic" "github.com/gravitl/netmaker/models" + "github.com/gravitl/netmaker/servercfg" +) + +// constants for accounts api hosts +const ( + // accountsHostDevelopment is the accounts api host for development environment + accountsHostDevelopment = "https://api.dev.accounts.netmaker.io" + // accountsHostStaging is the accounts api host for staging environment + accountsHostStaging = "https://api.staging.accounts.netmaker.io" + // accountsHostProduction is the accounts api host for production environment + accountsHostProduction = "https://api.accounts.netmaker.io" +) + +// constants for accounts UI hosts +const ( + // accountsUIHostDevelopment is the accounts UI host for development environment + accountsUIHostDevelopment = "https://account.dev.netmaker.io" + // accountsUIHostStaging is the accounts UI host for staging environment + accountsUIHostStaging = "https://account.staging.netmaker.io" + // accountsUIHostProduction is the accounts UI host for production environment + accountsUIHostProduction = "https://account.netmaker.io" ) func NetworkPermissionsCheck(username string, r *http.Request) error { @@ -186,3 +207,25 @@ func checkPermissionScopeWithReqMethod(scope models.RsrcPermissionScope, reqmeth } return errors.New("operation not permitted") } + +func GetAccountsHost() string { + switch servercfg.GetEnvironment() { + case "dev": + return accountsHostDevelopment + case "staging": + return accountsHostStaging + default: + return accountsHostProduction + } +} + +func GetAccountsUIHost() string { + switch servercfg.GetEnvironment() { + case "dev": + return accountsUIHostDevelopment + case "staging": + return accountsUIHostStaging + default: + return accountsUIHostProduction + } +} diff --git a/pro/logic/user_mgmt.go b/pro/logic/user_mgmt.go index d9218d22..84c5987b 100644 --- a/pro/logic/user_mgmt.go +++ b/pro/logic/user_mgmt.go @@ -380,7 +380,6 @@ func DeleteRole(rid models.UserRoleID, force bool) error { } } } - return database.DeleteRecord(database.USER_PERMISSIONS_TABLE_NAME, rid.String()) } diff --git a/pro/types.go b/pro/types.go index b4f1fe15..ae31cafe 100644 --- a/pro/types.go +++ b/pro/types.go @@ -7,16 +7,6 @@ import ( "fmt" ) -// constants for accounts api hosts -const ( - // accountsHostDevelopment is the accounts api host for development environment - accountsHostDevelopment = "https://api.dev.accounts.netmaker.io" - // accountsHostStaging is the accounts api host for staging environment - accountsHostStaging = "https://api.staging.accounts.netmaker.io" - // accountsHostProduction is the accounts api host for production environment - accountsHostProduction = "https://api.accounts.netmaker.io" -) - const ( license_cache_key = "license_response_cache" license_validation_err_msg = "invalid license"