diff --git a/backend/go-app/main.go b/backend/go-app/main.go
index 413d3ec8..4fa7b193 100644
--- a/backend/go-app/main.go
+++ b/backend/go-app/main.go
@@ -72,7 +72,9 @@ var gceProject = "shuffle"
var bucketName = "shuffler.appspot.com"
var baseAppPath = "/home/frikky/git/shaffuru/tmp/apps"
var baseDockerName = "frikky/shuffle"
-var syncUrl = "http://192.168.3.6:5002"
+
+//var syncUrl = "http://192.168.102.54:5002"
+var syncUrl = "http://localhost:5002"
var dbclient *datastore.Client
@@ -2825,6 +2827,11 @@ func fixUserOrg(ctx context.Context, user *User) *User {
}
if userFound {
+ user.PrivateApps = []WorkflowApp{}
+ user.Executions = ExecutionInfo{}
+ user.Limits = UserLimits{}
+ user.Authentication = []UserAuth{}
+
org.Users[orgIndex] = *user
} else {
org.Users = append(org.Users, *user)
@@ -7500,6 +7507,123 @@ func handleStopCloudSync(syncUrl string, org Org) error {
return nil
}
+func handleEditOrg(resp http.ResponseWriter, request *http.Request) {
+ cors := handleCors(resp, request)
+ if cors {
+ return
+ }
+
+ user, err := handleApiAuthentication(resp, request)
+ if err != nil {
+ log.Printf("Api authentication failed in cloud setup: %s", err)
+ resp.WriteHeader(401)
+ resp.Write([]byte(`{"success": false}`))
+ return
+ }
+
+ if user.Role != "admin" {
+ log.Printf("Not admin.")
+ resp.WriteHeader(401)
+ resp.Write([]byte(`{"success": false, "reason": "Not admin"}`))
+ return
+ }
+
+ body, err := ioutil.ReadAll(request.Body)
+ if err != nil {
+ resp.WriteHeader(401)
+ resp.Write([]byte(`{"success": false, "reason": "Failed reading body"}`))
+ return
+ }
+
+ type ReturnData struct {
+ Image string `json:"image" datastore:"image"`
+ Name string `json:"name" datastore:"name"`
+ Description string `json:"description" datastore:"description"`
+ OrgId string `json:"org_id" datastore:"org_id"`
+ }
+
+ var tmpData ReturnData
+ err = json.Unmarshal(body, &tmpData)
+ if err != nil {
+ log.Printf("Failed unmarshalling test: %s", err)
+ resp.WriteHeader(401)
+ resp.Write([]byte(`{"success": false}`))
+ return
+ }
+
+ var fileId string
+ location := strings.Split(request.URL.String(), "/")
+ if location[1] == "api" {
+ if len(location) <= 4 {
+ log.Printf("Path too short: %d", len(location))
+ resp.WriteHeader(401)
+ resp.Write([]byte(`{"success": false}`))
+ return
+ }
+
+ fileId = location[4]
+ }
+
+ if tmpData.OrgId != user.ActiveOrg.Id || fileId != user.ActiveOrg.Id {
+ log.Printf("User can't edit the org")
+ resp.WriteHeader(401)
+ resp.Write([]byte(`{"success": false, "No permission to edit this org"}`))
+ return
+ }
+
+ ctx := context.Background()
+ org, err := getOrg(ctx, tmpData.OrgId)
+ if err != nil {
+ log.Printf("Organization doesn't exist: %s", err)
+ resp.WriteHeader(401)
+ resp.Write([]byte(`{"success": false}`))
+ return
+ }
+
+ admin := false
+ userFound := false
+ for _, inneruser := range org.Users {
+ if inneruser.Id == user.Id {
+ userFound = true
+ if inneruser.Role == "admin" {
+ admin = true
+ }
+
+ break
+ }
+ }
+
+ if !userFound {
+ log.Printf("User %s doesn't exist in organization for edit %s", user.Id, org.Id)
+ resp.WriteHeader(401)
+ resp.Write([]byte(`{"success": false}`))
+ return
+ }
+
+ if !admin {
+ log.Printf("User %s doesn't have edit rights to %s", user.Id, org.Id)
+ resp.WriteHeader(401)
+ resp.Write([]byte(`{"success": false}`))
+ return
+ }
+
+ org.Image = tmpData.Image
+ org.Name = tmpData.Name
+ org.Description = tmpData.Description
+ //log.Printf("Org: %#v", org)
+ err = setOrg(ctx, *org, org.Id)
+ if err != nil {
+ log.Printf("User %s doesn't have edit rights to %s", user.Id, org.Id)
+ resp.WriteHeader(401)
+ resp.Write([]byte(`{"success": false}`))
+ return
+ }
+
+ resp.WriteHeader(200)
+ resp.Write([]byte(fmt.Sprintf(`{"success": true, "reason": "Successfully updated org"}`)))
+
+}
+
// INFO: https://docs.google.com/drawings/d/1JJebpPeEVEbmH_qsAC6zf9Noygp7PytvesrkhE19QrY/edit
/*
This is here to both enable and disable cloud sync features for an organization
@@ -8023,6 +8147,7 @@ func initHandlers() {
r.HandleFunc("/api/v1/cloud/setup", handleCloudSetup).Methods("POST", "OPTIONS")
r.HandleFunc("/api/v1/orgs", handleGetOrgs).Methods("GET", "OPTIONS")
r.HandleFunc("/api/v1/orgs/{orgId}", handleGetOrg).Methods("GET", "OPTIONS")
+ r.HandleFunc("/api/v1/orgs/{orgId}", handleEditOrg).Methods("POST", "OPTIONS")
//r.HandleFunc("/api/v1/orgs/{orgId}", handleEditOrg).Methods("POST", "OPTIONS")
// Important for email, IDS etc. Create this by:
diff --git a/backend/go-app/walkoff.go b/backend/go-app/walkoff.go
index 6ce5a77b..5315c75b 100644
--- a/backend/go-app/walkoff.go
+++ b/backend/go-app/walkoff.go
@@ -81,6 +81,7 @@ type SyncFeatures struct {
type SyncData struct {
Active bool `json:"active" datastore:"active"`
+ Type string `json:"type" datastore:"type"`
Name string `json:"name" datastore:"name"`
Description string `json:"description" datastore:"description"`
Limit int64 `json:"limit" datastore:"limit"`
@@ -95,7 +96,7 @@ type SyncConfig struct {
type Org struct {
Name string `json:"name" datastore:"name"`
Description string `json:"description" datastore:"description"`
- Image string `json:"image" datastore:"image"`
+ Image string `json:"image" datastore:"image,noindex"`
Id string `json:"id" datastore:"id"`
Org string `json:"org" datastore:"org"`
Users []User `json:"users" datastore:"users"`
diff --git a/frontend/src/views/Admin.jsx b/frontend/src/views/Admin.jsx
index 817a20e2..1e65e5b2 100644
--- a/frontend/src/views/Admin.jsx
+++ b/frontend/src/views/Admin.jsx
@@ -30,6 +30,7 @@ import { useAlert } from "react-alert";
import { Dialog, DialogTitle, DialogActions, DialogContent } from '@material-ui/core';
import { useTheme } from '@material-ui/core/styles';
+import HandlePayment from './HandlePayment'
import PolymerIcon from '@material-ui/icons/Polymer';
import CheckCircleIcon from '@material-ui/icons/CheckCircle';
@@ -253,7 +254,7 @@ const Admin = (props) => {
if (disableSync) {
alert.success("Successfully disabled sync!")
} else {
- alert.success("Sync successfully set up!")
+ alert.success("Cloud Syncronization successfully set up!")
}
selectedOrganization.cloud_sync = !selectedOrganization.cloud_sync
@@ -269,6 +270,51 @@ const Admin = (props) => {
})
}
+ const orgSaveButton =
+
+
+ const handleEditOrg = (name, description, orgId, image) => {
+ const data = {
+ "name": name,
+ "description": description,
+ "org_id": orgId,
+ "image": image,
+ }
+
+ const url = globalUrl + `/api/v1/orgs/${selectedOrganization.id}`;
+ fetch(url, {
+ mode: 'cors',
+ method: 'POST',
+ body: JSON.stringify(data),
+ credentials: 'include',
+ crossDomain: true,
+ withCredentials: true,
+ headers: {
+ 'Content-Type': 'application/json; charset=utf-8',
+ },
+ })
+ .then(response =>
+ response.json().then(responseJson => {
+ if (responseJson["success"] === false) {
+ alert.error("Failed updating org")
+ } else {
+ alert.success("Successfully edited org!")
+ setSelectedUserModalOpen(false)
+ }
+ }),
+ )
+ .catch(error => {
+ alert.error("Err: " + error.toString())
+ });
+ }
+
const onPasswordChange = () => {
const data = { "username": selectedUser.username, "newpassword": newPassword }
const url = globalUrl + '/api/v1/users/passwordchange';
@@ -360,9 +406,13 @@ const Admin = (props) => {
}
Object.keys(responseJson.sync_features).map(function(key, index) {
- console.log(responseJson.sync_features[key])
+ //console.log(responseJson.sync_features[key])
})
+
+ if (responseJson.image !== undefined && responseJson.image !== null && responseJson.image.length > 0) {
+ setFileBase64(responseJson.image)
+ }
setOrganizationFeatures(lists)
}
}),
@@ -668,6 +718,22 @@ const Admin = (props) => {
if (firstRequest) {
setFirstRequest(false)
getUsers()
+
+ const views = {
+ "organization": 0,
+ "users": 1,
+ "app_auth": 2,
+ "environments": 3,
+ "schedules": 4,
+ "categories": 5,
+ }
+
+ if (props.match.params.key !== undefined) {
+ const tmpitem = views[props.match.params.key]
+ if (tmpitem !== undefined) {
+ setCurTab(tmpitem)
+ }
+ }
}
if (selectedOrganization.id === undefined && userdata !== undefined && userdata.active_org !== undefined) {
@@ -1044,25 +1110,33 @@ const Admin = (props) => {
const canvasUrl = canvas.toDataURL()
if (canvasUrl !== fileBase64) {
- //console.log("SET URL TO: ", canvasUrl)
setFileBase64(canvasUrl)
+ selectedOrganization.image = canvasUrl
+ setSelectedOrganization(selectedOrganization)
}
}
}
-
const imageData = file.length > 0 ? file : fileBase64
+ if (imageData !== undefined && imageData.length === 0) {
+ //imageData
+ }
+
const imageInfo =
const organizationView = curTab === 0 ?