From a8b22cbe88ba8e2a6b65af490eef5a3d478f31be Mon Sep 17 00:00:00 2001 From: lalitdeore Date: Tue, 25 Jun 2024 12:52:03 +0530 Subject: [PATCH 1/4] added consultation hours management for the users --- shared.go | 102 +++++++++++++++++++++++++++++++++++++++++++++++++++++ structs.go | 5 +++ 2 files changed, 107 insertions(+) diff --git a/shared.go b/shared.go index b745069..21e99ba 100755 --- a/shared.go +++ b/shared.go @@ -10871,6 +10871,105 @@ func HandleChangeUserOrg(resp http.ResponseWriter, request *http.Request) { } +func HandleUserConsultation(resp http.ResponseWriter, request *http.Request) { + cors := HandleCors(resp, request) + if cors { + return + } + + err := ValidateRequestOverload(resp, request) + if err != nil { + log.Printf("[INFO] Request overload for IP %s in consultation management", GetRequestIp(request)) + resp.WriteHeader(http.StatusTooManyRequests) + resp.Write([]byte(fmt.Sprintf(`{"success": false, "reason": "Too many requests"}`))) + return + } + + gceProject := os.Getenv("SHUFFLE_GCEPROJECT") + if gceProject != "shuffler" && gceProject != sandboxProject && len(gceProject) > 0 { + log.Printf("[DEBUG] Redirecting training request to main site handler (shuffler.io). Project: %s", gceProject) + RedirectUserRequest(resp, request) + return + } + + _, userErr := HandleApiAuthentication(resp, request) + if userErr != nil { + log.Printf("[AUDIT] Api authentication failed in consultation: %s", userErr) + resp.WriteHeader(401) + resp.Write([]byte(`{"success": false}`)) + return + } + + body, err := ioutil.ReadAll(request.Body) + if err != nil { + resp.WriteHeader(http.StatusBadRequest) + resp.Write([]byte(fmt.Sprintf(`{"success": false, "reason": "%s"}`, err))) + return + } + + type ConsultationData struct { + OrgId string `json:"org_id" datastore:"org_id"` + Consultation string `json:"consultationHours" datastore:"consultationHours"` + Message string `json:"message" datastore:"message"` + } + + var tmpData ConsultationData + err = json.Unmarshal(body, &tmpData) + if err != nil { + log.Printf("[ERROR] Failed unmarshalling test: %s", err) + resp.WriteHeader(http.StatusBadRequest) + resp.Write([]byte(`{"success": false}`)) + return + } + + if len(tmpData.OrgId) == 0 || len(tmpData.Consultation) == 0 { + log.Printf("[WARNING] Missing org_id or consultation in consultation request") + resp.WriteHeader(http.StatusBadRequest) + resp.Write([]byte(`{"success": false, "reason": "Missing org_id or consultation"}`)) + return + } + + //Get user org + + ctx := GetContext(request) + org, err := GetOrg(ctx, tmpData.OrgId) + if err != nil { + log.Printf("[ERROR] Failed getting org %s: %s", tmpData.OrgId, err) + resp.WriteHeader(http.StatusBadRequest) + resp.Write([]byte(`{"success": false}`)) + return + } + + email := []string{org.Org} + Subject := "Thank you for your consultation request" + Message := fmt.Sprintf("This is confirmation that we have received your consultation request. You have requested a consultation for %v hours. We will get back to you shortly.
Best Regards
Shuffle Team", tmpData.Consultation) + + err = sendMailSendgrid(email, Subject, Message, false) + if err != nil { + log.Printf("[ERROR] Failed sending mail: %s", err) + resp.WriteHeader(http.StatusBadRequest) + resp.Write([]byte(`{"success": false}`)) + return + } + + //Send mail to the shuffle support + email = []string{"support@shuffler.io"} + Subject = fmt.Sprintf("Consultation request") + Message = fmt.Sprintf("Consultation request :
Email: %v
Consultation Hours: %v
Customer: %v
Message: %v", org.Org, tmpData.Consultation, org.LeadInfo.Customer, tmpData.Message) + + err = sendMailSendgrid(email, Subject, Message, false) + if err != nil { + log.Printf("[ERROR] Failed sending mail: %s", err) + resp.WriteHeader(http.StatusBadRequest) + resp.Write([]byte(`{"success": false}`)) + return + } + + log.Printf("[INFO] Consultation request from %s for %s hours. Message: %s", org.Org, tmpData.Consultation, tmpData.Message) + resp.WriteHeader(http.StatusOK) + resp.Write([]byte(`{"success": true}`)) +} + func HandleCreateSubOrg(resp http.ResponseWriter, request *http.Request) { cors := HandleCors(resp, request) if cors { @@ -11617,6 +11716,9 @@ func HandleEditOrg(resp http.ResponseWriter, request *http.Request) { org.SyncFeatures = tmpData.SyncFeatures org.SyncFeatures.Editing = false } + if (len(tmpData.Billing.Consultation.Hours) > 0 || len(tmpData.Billing.Consultation.Minutes) > 0) && user.SupportAccess { + org.Billing.Consultation = tmpData.Billing.Consultation + } // Built a system around this now, which checks for the actual org. // if requestdata.Environment == "cloud" && project.Environment != "cloud" { diff --git a/structs.go b/structs.go index 269d672..88eb398 100755 --- a/structs.go +++ b/structs.go @@ -895,6 +895,7 @@ type Org struct { type Billing struct { Email string `json:"Email" datastore:"Email"` AlertThreshold []AlertThreshold `json:"AlertThreshold" datastore:"AlertThreshold"` + Consultation Consultation `json:"Consultation" datastore:"Consultation"` } type AlertThreshold struct { @@ -902,6 +903,10 @@ type AlertThreshold struct { Count int `json:"count" datastore:"count"` Email_send bool `json:"Email_send" datastore:"Email_send"` } +type Consultation struct { + Hours string `json:"hours" datastore:"hours"` + Minutes string `json:"minutes" datastore:"minutes"` +} // Authentication overrides that times out // Only works for certain features, such as public auth keys From fdd1ab1e1e64bb6c36c64dce1ca0ae714b782e40 Mon Sep 17 00:00:00 2001 From: lalitdeore Date: Tue, 25 Jun 2024 14:27:30 +0530 Subject: [PATCH 2/4] fix the consultation hour email body --- shared.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/shared.go b/shared.go index 21e99ba..fef7bf2 100755 --- a/shared.go +++ b/shared.go @@ -10942,7 +10942,7 @@ func HandleUserConsultation(resp http.ResponseWriter, request *http.Request) { email := []string{org.Org} Subject := "Thank you for your consultation request" - Message := fmt.Sprintf("This is confirmation that we have received your consultation request. You have requested a consultation for %v hours. We will get back to you shortly.
Best Regards
Shuffle Team", tmpData.Consultation) + Message := fmt.Sprintf("Hi there, Thank you for submitting request for shuffle consultaion. This is confirmation that we have received your consultation request. You have requested a consultation for %v hours. We will get back to you shortly.

Best Regards
Shuffle Team", tmpData.Consultation) err = sendMailSendgrid(email, Subject, Message, false) if err != nil { From 625eade09cf82a3c7a05d21e6dd09eff46630bee Mon Sep 17 00:00:00 2001 From: lalitdeore Date: Mon, 1 Jul 2024 11:35:51 +0530 Subject: [PATCH 3/4] fix consultation hours for cloud only --- shared.go | 99 ------------------------------------------------------- 1 file changed, 99 deletions(-) diff --git a/shared.go b/shared.go index 25eb074..9b3d0a8 100755 --- a/shared.go +++ b/shared.go @@ -10884,105 +10884,6 @@ func HandleChangeUserOrg(resp http.ResponseWriter, request *http.Request) { } -func HandleUserConsultation(resp http.ResponseWriter, request *http.Request) { - cors := HandleCors(resp, request) - if cors { - return - } - - err := ValidateRequestOverload(resp, request) - if err != nil { - log.Printf("[INFO] Request overload for IP %s in consultation management", GetRequestIp(request)) - resp.WriteHeader(http.StatusTooManyRequests) - resp.Write([]byte(fmt.Sprintf(`{"success": false, "reason": "Too many requests"}`))) - return - } - - gceProject := os.Getenv("SHUFFLE_GCEPROJECT") - if gceProject != "shuffler" && gceProject != sandboxProject && len(gceProject) > 0 { - log.Printf("[DEBUG] Redirecting training request to main site handler (shuffler.io). Project: %s", gceProject) - RedirectUserRequest(resp, request) - return - } - - _, userErr := HandleApiAuthentication(resp, request) - if userErr != nil { - log.Printf("[AUDIT] Api authentication failed in consultation: %s", userErr) - resp.WriteHeader(401) - resp.Write([]byte(`{"success": false}`)) - return - } - - body, err := ioutil.ReadAll(request.Body) - if err != nil { - resp.WriteHeader(http.StatusBadRequest) - resp.Write([]byte(fmt.Sprintf(`{"success": false, "reason": "%s"}`, err))) - return - } - - type ConsultationData struct { - OrgId string `json:"org_id" datastore:"org_id"` - Consultation string `json:"consultationHours" datastore:"consultationHours"` - Message string `json:"message" datastore:"message"` - } - - var tmpData ConsultationData - err = json.Unmarshal(body, &tmpData) - if err != nil { - log.Printf("[ERROR] Failed unmarshalling test: %s", err) - resp.WriteHeader(http.StatusBadRequest) - resp.Write([]byte(`{"success": false}`)) - return - } - - if len(tmpData.OrgId) == 0 || len(tmpData.Consultation) == 0 { - log.Printf("[WARNING] Missing org_id or consultation in consultation request") - resp.WriteHeader(http.StatusBadRequest) - resp.Write([]byte(`{"success": false, "reason": "Missing org_id or consultation"}`)) - return - } - - //Get user org - - ctx := GetContext(request) - org, err := GetOrg(ctx, tmpData.OrgId) - if err != nil { - log.Printf("[ERROR] Failed getting org %s: %s", tmpData.OrgId, err) - resp.WriteHeader(http.StatusBadRequest) - resp.Write([]byte(`{"success": false}`)) - return - } - - email := []string{org.Org} - Subject := "Thank you for your consultation request" - Message := fmt.Sprintf("Hi there, Thank you for submitting request for shuffle consultaion. This is confirmation that we have received your consultation request. You have requested a consultation for %v hours. We will get back to you shortly.

Best Regards
Shuffle Team", tmpData.Consultation) - - err = sendMailSendgrid(email, Subject, Message, false) - if err != nil { - log.Printf("[ERROR] Failed sending mail: %s", err) - resp.WriteHeader(http.StatusBadRequest) - resp.Write([]byte(`{"success": false}`)) - return - } - - //Send mail to the shuffle support - email = []string{"support@shuffler.io"} - Subject = fmt.Sprintf("Consultation request") - Message = fmt.Sprintf("Consultation request :
Email: %v
Consultation Hours: %v
Customer: %v
Message: %v", org.Org, tmpData.Consultation, org.LeadInfo.Customer, tmpData.Message) - - err = sendMailSendgrid(email, Subject, Message, false) - if err != nil { - log.Printf("[ERROR] Failed sending mail: %s", err) - resp.WriteHeader(http.StatusBadRequest) - resp.Write([]byte(`{"success": false}`)) - return - } - - log.Printf("[INFO] Consultation request from %s for %s hours. Message: %s", org.Org, tmpData.Consultation, tmpData.Message) - resp.WriteHeader(http.StatusOK) - resp.Write([]byte(`{"success": true}`)) -} - func HandleCreateSubOrg(resp http.ResponseWriter, request *http.Request) { cors := HandleCors(resp, request) if cors { From 9907160e30eae6fb5df825f2b46e4812c63b876d Mon Sep 17 00:00:00 2001 From: lalitdeore Date: Thu, 11 Jul 2024 12:26:37 +0530 Subject: [PATCH 4/4] added private training request backend --- shared.go | 97 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 97 insertions(+) diff --git a/shared.go b/shared.go index 9b3d0a8..04b88f7 100755 --- a/shared.go +++ b/shared.go @@ -28051,3 +28051,100 @@ func GetWorkflowValidation(resp http.ResponseWriter, request *http.Request) { resp.Write([]byte(`{"success": false, "reason": "Not implemented"}`)) resp.WriteHeader(500) } +func HandleUserPrivateTraining(resp http.ResponseWriter, request *http.Request) { + cors := HandleCors(resp, request) + if cors { + return + } + + err := ValidateRequestOverload(resp, request) + if err != nil { + log.Printf("[INFO] Request overload for IP %s in private training", GetRequestIp(request)) + resp.WriteHeader(http.StatusTooManyRequests) + resp.Write([]byte(fmt.Sprintf(`{"success": false, "reason": "Too many requests"}`))) + return + } + + gceProject := os.Getenv("SHUFFLE_GCEPROJECT") + if gceProject != "shuffler" && gceProject != sandboxProject && len(gceProject) > 0 { + log.Printf("[DEBUG] Redirecting training request to main site handler (shuffler.io). Project: %s", gceProject) + RedirectUserRequest(resp, request) + return + } + + User, userErr := HandleApiAuthentication(resp, request) + if userErr != nil { + log.Printf("[AUDIT] Api authentication failed in private training: %s", userErr) + resp.WriteHeader(401) + resp.Write([]byte(`{"success": false}`)) + return + } + + body, err := ioutil.ReadAll(request.Body) + if err != nil { + resp.WriteHeader(http.StatusBadRequest) + resp.Write([]byte(fmt.Sprintf(`{"success": false, "reason": "%s"}`, err))) + return + } + + type TrainingData struct { + OrgId string `json:"org_id" datastore:"org_id"` + Training string `json:"trainingMembers" datastore:"trainingMembers"` + Message string `json:"message" datastore:"message"` + } + + var tmpData TrainingData + err = json.Unmarshal(body, &tmpData) + if err != nil { + log.Printf("[ERROR] Failed unmarshalling test: %s", err) + resp.WriteHeader(http.StatusBadRequest) + resp.Write([]byte(`{"success": false}`)) + return + } + + if len(tmpData.OrgId) == 0 || len(tmpData.Training) == 0 { + log.Printf("[WARNING] Missing org_id or training in private training request") + resp.WriteHeader(http.StatusBadRequest) + resp.Write([]byte(`{"success": false, "reason": "Missing org_id or training"}`)) + return + } + + //Get user org + ctx := GetContext(request) + org, err := GetOrg(ctx, tmpData.OrgId) + if err != nil { + log.Printf("[ERROR] Failed getting org %s: %s", tmpData.OrgId, err) + resp.WriteHeader(http.StatusBadRequest) + resp.Write([]byte(`{"success": false}`)) + return + } + + email := []string{org.Org} + Subject := "Thank you for your private training request" + Message := fmt.Sprintf("Hi there, Thank you for submitting request for shuffle private training. This is confirmation that we have received your private training request. You have requested a private training for %v members. We will get back to you shortly.

Best Regards
Shuffle Team", tmpData.Training) + + err = sendMailSendgrid(email, Subject, Message, false) + if err != nil { + log.Printf("[ERROR] Failed sending mail: %s", err) + resp.WriteHeader(http.StatusBadRequest) + resp.Write([]byte(`{"success": false}`)) + return + } + + //Send mail to the shuffle support + email = []string{"support@shuffler.io"} + Subject = fmt.Sprintf("Private training request") + Message = fmt.Sprintf("Private training request :
Org id: %v
Org Name: %v
Username: %v
Training Members: %v
Customer: %v
Message: %v", org.Id, org.Name, User.Username, tmpData.Training, org.LeadInfo.Customer, tmpData.Message) + + err = sendMailSendgrid(email, Subject, Message, false) + if err != nil { + log.Printf("[ERROR] Failed sending mail: %s", err) + resp.WriteHeader(http.StatusBadRequest) + resp.Write([]byte(`{"success": false}`)) + return + } + + log.Printf("[INFO] Private training request from %s for %s members. Message: %s", org.Org, tmpData.Training, tmpData.Message) + resp.WriteHeader(http.StatusOK) + resp.Write([]byte(`{"success": true}`)) +}