diff --git a/backend/go-app/go.mod b/backend/go-app/go.mod index 04b450e1..e6cd9ddf 100644 --- a/backend/go-app/go.mod +++ b/backend/go-app/go.mod @@ -19,7 +19,7 @@ require ( github.com/gorilla/mux v1.8.0 github.com/h2non/filetype v1.1.3 github.com/satori/go.uuid v1.2.0 - github.com/shuffle/shuffle-shared v0.4.17 + github.com/shuffle/shuffle-shared v0.4.18 golang.org/x/crypto v0.3.0 google.golang.org/api v0.103.0 google.golang.org/appengine v1.6.7 diff --git a/backend/go-app/main.go b/backend/go-app/main.go index dc8059b3..3fc9f9fa 100644 --- a/backend/go-app/main.go +++ b/backend/go-app/main.go @@ -791,7 +791,7 @@ func handleRegister(resp http.ResponseWriter, request *http.Request) { CloudSync: false, } - err = shuffle.SetOrg(ctx, newOrg, orgId) + err = shuffle.SetOrg(ctx, newOrg, newOrg.Id) if err != nil { log.Printf("[WARNING] Failed setting init organization: %s", err) } else { @@ -943,48 +943,104 @@ func handleInfo(resp http.ResponseWriter, request *http.Request) { }) // Updating user info if there's something wrong - if (len(userInfo.ActiveOrg.Name) == 0 || len(userInfo.ActiveOrg.Id) == 0) && len(userInfo.Orgs) > 0 { - _, err := shuffle.GetOrg(ctx, userInfo.Orgs[0]) - if err != nil { + if len(userInfo.ActiveOrg.Name) == 0 || len(userInfo.ActiveOrg.Id) == 0 { + if len(userInfo.Orgs) == 0 || (len(userInfo.Orgs) > 0 && userInfo.Orgs[0] == "") { orgs, err := shuffle.GetAllOrgs(ctx) - if err == nil { - newStringOrgs := []string{} - newOrgs := []shuffle.Org{} + log.Printf("[INFO] Fixing organization for user %s (%s). Found orgs: %d", userInfo.Username, userInfo.Id, len(orgs)) + if err == nil && len(orgs) > 0 { for _, org := range orgs { - if strings.ToLower(org.Name) == strings.ToLower(userInfo.Orgs[0]) { - newOrgs = append(newOrgs, org) - newStringOrgs = append(newStringOrgs, org.Id) + if len(org.Id) == 0 { + continue } - } - if len(newOrgs) > 0 { + // Prolly some way here to jump into another org + // when you have access to the DB userInfo.ActiveOrg = shuffle.OrgMini{ - Id: newOrgs[0].Id, - Name: newOrgs[0].Name, - } - - userInfo.Orgs = newStringOrgs - - err = shuffle.SetUser(ctx, &userInfo, true) - if err != nil { - log.Printf("Error patching User for activeOrg: %s", err) - } else { - log.Printf("Updated the users' org") + Name: org.Name, + Id: org.Id, + Role: "admin", } + userInfo.Orgs = []string{org.Id} + break } - } else { - log.Printf("Failed getting orgs for user. Major issue.: %s", err) } - } else { - // 1. Check if the org exists by ID - // 2. if it does, overwrite user - userInfo.ActiveOrg = shuffle.OrgMini{ - Id: userInfo.Orgs[0], + // Make a new one in case we couldn't find one + if len(userInfo.ActiveOrg.Id) == 0 { + orgSetupName := "default" + orgId := uuid.NewV4().String() + newOrg := shuffle.Org{ + Name: orgSetupName, + Id: orgId, + Org: orgSetupName, + Users: []shuffle.User{}, + Roles: []string{"admin", "user"}, + CloudSync: false, + } + + err = shuffle.SetOrg(ctx, newOrg, newOrg.Id) + if err == nil { + userInfo.ActiveOrg = shuffle.OrgMini{ + Name: newOrg.Name, + Id: newOrg.Id, + Role: "admin", + } + userInfo.Orgs = []string{newOrg.Id} + } else { + log.Printf("[WARNING] Failed to set new org: %s", err) + } } + + // Set user err = shuffle.SetUser(ctx, &userInfo, true) if err != nil { - log.Printf("[INFO] Error patching User for activeOrg: %s", err) + log.Printf("[WARNING] Failed fixing org info for user %s (%s)", userInfo.Username, userInfo.Id) + } else { + log.Printf("[INFO] Set organization for %s (%s) to be %s (%s)", userInfo.Username, userInfo.Id, userInfo.ActiveOrg.Name, userInfo.ActiveOrg.Id) + } + } else if len(userInfo.Orgs) > 0 && userInfo.Orgs[0] != "" { + _, err := shuffle.GetOrg(ctx, userInfo.Orgs[0]) + if err != nil { + orgs, err := shuffle.GetAllOrgs(ctx) + if err == nil { + newStringOrgs := []string{} + newOrgs := []shuffle.Org{} + for _, org := range orgs { + if strings.ToLower(org.Name) == strings.ToLower(userInfo.Orgs[0]) { + newOrgs = append(newOrgs, org) + newStringOrgs = append(newStringOrgs, org.Id) + } + } + + if len(newOrgs) > 0 { + userInfo.ActiveOrg = shuffle.OrgMini{ + Id: newOrgs[0].Id, + Name: newOrgs[0].Name, + } + + userInfo.Orgs = newStringOrgs + + err = shuffle.SetUser(ctx, &userInfo, true) + if err != nil { + log.Printf("Error patching User for activeOrg: %s", err) + } else { + log.Printf("Updated the users' org") + } + } + } else { + log.Printf("Failed getting orgs for user. Major issue.: %s", err) + } + + } else { + // 1. Check if the org exists by ID + // 2. if it does, overwrite user + userInfo.ActiveOrg = shuffle.OrgMini{ + Id: userInfo.Orgs[0], + } + err = shuffle.SetUser(ctx, &userInfo, true) + if err != nil { + log.Printf("[INFO] Error patching User for activeOrg: %s", err) + } } } } @@ -1383,7 +1439,7 @@ func fixUserOrg(ctx context.Context, user *shuffle.User) *shuffle.User { org.Users = append(org.Users, *user) } - err = shuffle.SetOrg(ctx, *org, orgId) + err = shuffle.SetOrg(ctx, *org, org.Id) if err != nil { log.Printf("Failed setting org %s", orgId) } @@ -3924,7 +3980,7 @@ func runInitEs(ctx context.Context) { CloudSync: false, } - err = shuffle.SetOrg(ctx, newOrg, orgId) + err = shuffle.SetOrg(ctx, newOrg, newOrg.Id) setUsers := false if err != nil { log.Printf("[WARNING] Failed setting organization when creating original user: %s", err) @@ -3976,6 +4032,11 @@ func runInitEs(ctx context.Context) { } for _, org := range activeOrgs { + if len(org.Id) == 0 { + log.Printf("[DEBUG] No ID found for org with name '%s'. Why was it made?", org.Name) + continue + } + if !org.CloudSync { log.Printf("[INFO] Skipping org syncCheck for '%s' because sync isn't set (1).", org.Id) continue @@ -4151,7 +4212,7 @@ func runInitEs(ctx context.Context) { cloneOptions.ReferenceName = plumbing.ReferenceName(branch) } - log.Printf("[DEBUG] Getting apps from %s", url) + log.Printf("[DEBUG] Getting apps from url '%s'", url) r, err := git.Clone(storer, fs, cloneOptions) @@ -4288,11 +4349,11 @@ func runInit(ctx context.Context) { CloudSync: false, } - err = shuffle.SetOrg(ctx, newOrg, orgId) + err = shuffle.SetOrg(ctx, newOrg, newOrg.Id) if err != nil { - log.Printf("Failed setting organization: %s", err) + log.Printf("[WARNING] Failed setting organization: %s", err) } else { - log.Printf("Successfully created the default org!") + log.Printf("[WARNING] Successfully created the default org!") setUsers = true } } else { @@ -4810,7 +4871,7 @@ func runInit(ctx context.Context) { cloneOptions.ReferenceName = plumbing.ReferenceName(branch) } - log.Printf("[DEBUG] Getting apps from %s", url) + log.Printf("[DEBUG] Getting apps from URL '%s'", url) r, err := git.Clone(storer, fs, cloneOptions) @@ -5930,6 +5991,10 @@ func initHandlers() { r.HandleFunc("/api/v1/workflows/{key}", shuffle.GetSpecificWorkflow).Methods("GET", "OPTIONS") r.HandleFunc("/api/v1/workflows/recommend", shuffle.HandleActionRecommendation).Methods("POST", "OPTIONS") + // New for recommendations in Shuffle + r.HandleFunc("/api/v1/recommendations/get_actions", shuffle.HandleActionRecommendation).Methods("POST", "OPTIONS") + r.HandleFunc("/api/v1/recommendations/modify", shuffle.HandleRecommendationAction).Methods("POST", "OPTIONS") + // Triggers r.HandleFunc("/api/v1/hooks/new", shuffle.HandleNewHook).Methods("POST", "OPTIONS") r.HandleFunc("/api/v1/hooks", shuffle.HandleNewHook).Methods("POST", "OPTIONS") diff --git a/backend/go-app/main_test.go b/backend/go-app/main_test.go index e9d358b6..4e39ea0e 100644 --- a/backend/go-app/main_test.go +++ b/backend/go-app/main_test.go @@ -24,6 +24,7 @@ type endpoint struct { handler http.HandlerFunc path string method string + body []byte } func init() { @@ -44,7 +45,7 @@ func TestAuthenticationRequired(t *testing.T) { {handler: shuffle.HandleNewOutlookRegister, path: "/functions/outlook/register", method: "GET"}, {handler: shuffle.HandleGetOutlookFolders, path: "/functions/outlook/getFolders", method: "GET"}, {handler: shuffle.HandleApiGeneration, path: "/api/v1/users/generateapikey", method: "GET"}, - {handler: handleLogin, path: "/api/v1/users/login", method: "POST"}, // prob not this one + {handler: shuffle.HandleLogin, path: "/api/v1/users/login", method: "POST"}, // prob not this one // handleRegister generates nil pointer exception. Not necessary for this anyway. //{handler: handleRegister, path: "/api/v1/users/register", method: "POST"}, {handler: shuffle.HandleGetUsers, path: "/api/v1/users/getusers", method: "GET"}, @@ -108,8 +109,8 @@ func TestAuthenticationRequired(t *testing.T) { {handler: verifySwagger, path: "/api/v1/verify_swagger", method: "POST"}, {handler: verifySwagger, path: "/api/v1/verify_openapi", method: "POST"}, - {handler: echoOpenapiData, path: "/api/v1/get_openapi_uri", method: "POST"}, - {handler: echoOpenapiData, path: "/api/v1/validate_openapi", method: "POST"}, + {handler: shuffle.EchoOpenapiData, path: "/api/v1/get_openapi_uri", method: "POST"}, + {handler: shuffle.EchoOpenapiData, path: "/api/v1/validate_openapi", method: "POST"}, {handler: shuffle.ValidateSwagger, path: "/api/v1/validate_openapi", method: "POST"}, {handler: getOpenapi, path: "/api/v1/get_openapi", method: "GET"}, @@ -117,7 +118,7 @@ func TestAuthenticationRequired(t *testing.T) { {handler: handleCloudSetup, path: "/api/v1/cloud/setup", method: "POST"}, {handler: shuffle.HandleGetOrgs, path: "/api/v1/orgs", method: "POST"}, - {handler: shuffle.HandleGetFileContent, path: "/api/v1/files/{fileId}/content", method: "POST"}, + {handler: shuffle.HandleGetFileContent, path: "/api/v1/files/{fileId}/content", method: "POST", body: []byte("hi")}, } var err error @@ -197,10 +198,11 @@ func TestAuthenticationNotRequired(t *testing.T) { // requirements might change after the refactor. func TestCors(t *testing.T) { handlers := []endpoint{ + {handler: handleLogin, path: "/api/v1/users/login", method: "POST"}, // prob not this one + {handler: shuffle.HandleNewOutlookRegister, path: "/functions/outlook/register", method: "GET"}, {handler: shuffle.HandleGetOutlookFolders, path: "/functions/outlook/getFolders", method: "GET"}, {handler: shuffle.HandleApiGeneration, path: "/api/v1/users/generateapikey", method: "GET"}, - {handler: handleLogin, path: "/api/v1/users/login", method: "POST"}, // prob not this one // handleRegister generates nil pointer exception {handler: handleRegister, path: "/api/v1/users/register", method: "POST"}, {handler: shuffle.HandleGetUsers, path: "/api/v1/users/getusers", method: "GET"}, diff --git a/frontend/src/App.jsx b/frontend/src/App.jsx index 41922ff4..936a6dad 100644 --- a/frontend/src/App.jsx +++ b/frontend/src/App.jsx @@ -370,6 +370,7 @@ const App = (message, props) => { globalUrl={globalUrl} setCookie={setCookie} cookies={cookies} + checkLogin={checkLogin} {...props} /> } diff --git a/frontend/src/views/Admin.jsx b/frontend/src/views/Admin.jsx index abe0b0e4..fefe1adb 100644 --- a/frontend/src/views/Admin.jsx +++ b/frontend/src/views/Admin.jsx @@ -27,6 +27,7 @@ import { Divider, TextField, Button, + ButtonGroup, Tabs, Tab, Grid, @@ -129,7 +130,7 @@ const FileCategoryInput = (props) => { const Admin = (props) => { - const { globalUrl, userdata, serverside } = props; + const { globalUrl, userdata, serverside, checkLogin } = props; var to_be_copied = ""; const classes = useStyles(); @@ -3554,6 +3555,49 @@ const Admin = (props) => { ) : null; + const changeRecommendation = (recommendation, action) => { + const data = { + action: action, + name: recommendation.name, + }; + + fetch(`${globalUrl}/api/v1/recommendations/modify`, { + mode: "cors", + method: "POST", + body: JSON.stringify(data), + credentials: "include", + crossDomain: true, + withCredentials: true, + headers: { + "Content-Type": "application/json; charset=utf-8", + }, + }) + .then((response) => { + if (response.status === 200) { + } else { + } + + return response.json(); + }) + .then((responseJson) => { + if (responseJson.success === true) { + if (checkLogin !== undefined) { + checkLogin() + getEnvironments() + } + } else { + if (responseJson.success === false && responseJson.reason !== undefined) { + alert.error("Failed change recommendation: ", responseJson.reason) + } else { + alert.error("Failed change recommendation"); + } + } + }) + .catch((error) => { + alert.info("Failed dismissing alert. Please contact support@shuffler.io if this persists."); + }); + } + const environmentView = curTab === 6 ? (