Added a default organization with migration
This commit is contained in:
+284
-37
@@ -181,6 +181,7 @@ type User struct {
|
|||||||
Id string `datastore:"id" json:"id"`
|
Id string `datastore:"id" json:"id"`
|
||||||
Orgs []string `datastore:"orgs" json:"orgs"`
|
Orgs []string `datastore:"orgs" json:"orgs"`
|
||||||
CreationTime int64 `datastore:"creation_time" json:"creation_time"`
|
CreationTime int64 `datastore:"creation_time" json:"creation_time"`
|
||||||
|
ActiveOrg Org `json:"active_org" datastore:"active_org"`
|
||||||
Active bool `datastore:"active" json:"active"`
|
Active bool `datastore:"active" json:"active"`
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1013,13 +1014,13 @@ func handleSetEnvironments(resp http.ResponseWriter, request *http.Request) {
|
|||||||
user, err := handleApiAuthentication(resp, request)
|
user, err := handleApiAuthentication(resp, request)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
resp.WriteHeader(401)
|
resp.WriteHeader(401)
|
||||||
resp.Write([]byte(`{"success": false, "reason": "Can't register without being admin"}`))
|
resp.Write([]byte(`{"success": false, "reason": "Can't handle set env auth"}`))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if user.Role != "admin" {
|
if user.Role != "admin" {
|
||||||
resp.WriteHeader(401)
|
resp.WriteHeader(401)
|
||||||
resp.Write([]byte(`{"success": false, "reason": "Can't register without being admin"}`))
|
resp.Write([]byte(`{"success": false, "reason": "Can't set environment without being admin"}`))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1097,7 +1098,7 @@ func handleSetEnvironments(resp http.ResponseWriter, request *http.Request) {
|
|||||||
resp.Write([]byte(`{"success": true}`))
|
resp.Write([]byte(`{"success": true}`))
|
||||||
}
|
}
|
||||||
|
|
||||||
func createNewUser(username, password, role, apikey string) error {
|
func createNewUser(username, password, role, apikey string, org Org) error {
|
||||||
// Returns false if there is an issue
|
// Returns false if there is an issue
|
||||||
// Use this for register
|
// Use this for register
|
||||||
err := checkPasswordStrength(password)
|
err := checkPasswordStrength(password)
|
||||||
@@ -1137,7 +1138,7 @@ func createNewUser(username, password, role, apikey string) error {
|
|||||||
newUser.Verified = false
|
newUser.Verified = false
|
||||||
newUser.CreationTime = time.Now().Unix()
|
newUser.CreationTime = time.Now().Unix()
|
||||||
newUser.Active = true
|
newUser.Active = true
|
||||||
newUser.Orgs = []string{"default"}
|
newUser.Orgs = []string{org.Id}
|
||||||
|
|
||||||
// FIXME - Remove this later
|
// FIXME - Remove this later
|
||||||
if role == "admin" {
|
if role == "admin" {
|
||||||
@@ -1148,6 +1149,8 @@ func createNewUser(username, password, role, apikey string) error {
|
|||||||
newUser.Roles = []string{"user"}
|
newUser.Roles = []string{"user"}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
newUser.ActiveOrg = org
|
||||||
|
|
||||||
if len(apikey) > 0 {
|
if len(apikey) > 0 {
|
||||||
newUser.ApiKey = apikey
|
newUser.ApiKey = apikey
|
||||||
}
|
}
|
||||||
@@ -1182,25 +1185,25 @@ func createNewUser(username, password, role, apikey string) error {
|
|||||||
log.Printf("Error adding User %s: %s", username, err)
|
log.Printf("Error adding User %s: %s", username, err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
url := fmt.Sprintf("https://shuffler.io/register/%s", verifyToken.String())
|
// url := fmt.Sprintf("https://shuffler.io/register/%s", verifyToken.String())
|
||||||
const verifyMessage = `
|
// const verifyMessage = `
|
||||||
Registration URL :)
|
//Registration URL :)
|
||||||
|
//
|
||||||
%s
|
//%s
|
||||||
`
|
// `
|
||||||
addr := newUser.Username
|
// addr := newUser.Username
|
||||||
|
//
|
||||||
msg := &mail.Message{
|
// msg := &mail.Message{
|
||||||
Sender: "Shuffle <frikky@shuffler.io>",
|
// Sender: "Shuffle <frikky@shuffler.io>",
|
||||||
To: []string{addr},
|
// To: []string{addr},
|
||||||
Subject: "Verify your username - Shuffle",
|
// Subject: "Verify your username - Shuffle",
|
||||||
Body: fmt.Sprintf(verifyMessage, url),
|
// Body: fmt.Sprintf(verifyMessage, url),
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
log.Println(msg.Body)
|
// log.Println(msg.Body)
|
||||||
if err := mail.Send(ctx, msg); err != nil {
|
// if err := mail.Send(ctx, msg); err != nil {
|
||||||
log.Printf("Couldn't send email: %v", err)
|
// log.Printf("Couldn't send email: %v", err)
|
||||||
}
|
// }
|
||||||
|
|
||||||
err = increaseStatisticsField(ctx, "successful_register", username, 1)
|
err = increaseStatisticsField(ctx, "successful_register", username, 1)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -1249,7 +1252,8 @@ func handleRegister(resp http.ResponseWriter, request *http.Request) {
|
|||||||
if count == 0 {
|
if count == 0 {
|
||||||
role = "admin"
|
role = "admin"
|
||||||
}
|
}
|
||||||
err = createNewUser(data.Username, data.Password, role, "")
|
|
||||||
|
err = createNewUser(data.Username, data.Password, role, "", user.ActiveOrg)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("Failed registering user: %s", err)
|
log.Printf("Failed registering user: %s", err)
|
||||||
resp.WriteHeader(401)
|
resp.WriteHeader(401)
|
||||||
@@ -1623,6 +1627,10 @@ func handleInfo(resp http.ResponseWriter, request *http.Request) {
|
|||||||
|
|
||||||
// This is a long check to see if an inactive admin can access the site
|
// This is a long check to see if an inactive admin can access the site
|
||||||
parsedAdmin := "false"
|
parsedAdmin := "false"
|
||||||
|
if userInfo.Role == "admin" {
|
||||||
|
parsedAdmin = "true"
|
||||||
|
}
|
||||||
|
|
||||||
if !userInfo.Active {
|
if !userInfo.Active {
|
||||||
if userInfo.Role == "admin" {
|
if userInfo.Role == "admin" {
|
||||||
parsedAdmin = "true"
|
parsedAdmin = "true"
|
||||||
@@ -1692,14 +1700,55 @@ func handleInfo(resp http.ResponseWriter, request *http.Request) {
|
|||||||
Expires: expiration,
|
Expires: expiration,
|
||||||
})
|
})
|
||||||
|
|
||||||
// Migrate this to real Org
|
// Updating user info if there's something wrong
|
||||||
// Need to create org endpoints (create, delete etc)
|
if (len(userInfo.ActiveOrg.Name) == 0 || len(userInfo.ActiveOrg.Id) == 0) && len(userInfo.Orgs) > 0 {
|
||||||
currentOrg := `{
|
_, err := getOrg(ctx, userInfo.Orgs[0])
|
||||||
"name": "Shuffle",
|
if err != nil {
|
||||||
"id": "123",
|
var orgs []Org
|
||||||
"role": "admin",
|
q := datastore.NewQuery("Organizations")
|
||||||
"cloud_sync": false
|
_, err = dbclient.GetAll(ctx, q, &orgs)
|
||||||
}`
|
if err == nil {
|
||||||
|
newStringOrgs := []string{}
|
||||||
|
newOrgs := []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 = newOrgs[0]
|
||||||
|
userInfo.Orgs = newStringOrgs
|
||||||
|
|
||||||
|
err = setUser(ctx, &userInfo)
|
||||||
|
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 = Org{
|
||||||
|
Id: userInfo.Orgs[0],
|
||||||
|
}
|
||||||
|
err = setUser(ctx, &userInfo)
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("Error patching User for activeOrg: %s", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
currentOrg, err := json.Marshal(userInfo.ActiveOrg)
|
||||||
|
if err != nil {
|
||||||
|
currentOrg = []byte("{}")
|
||||||
|
}
|
||||||
|
|
||||||
returnData := fmt.Sprintf(`
|
returnData := fmt.Sprintf(`
|
||||||
{
|
{
|
||||||
@@ -2175,6 +2224,61 @@ func handleGetEnvironments(resp http.ResponseWriter, request *http.Request) {
|
|||||||
resp.Write(newjson)
|
resp.Write(newjson)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func handleGetOrgs(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 set new workflowhandler: %s", err)
|
||||||
|
resp.WriteHeader(401)
|
||||||
|
resp.Write([]byte(`{"success": false}`))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if user.Role != "admin" {
|
||||||
|
resp.WriteHeader(401)
|
||||||
|
resp.Write([]byte(`{"success": false, "reason": "Not admin"}`))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx := context.Background()
|
||||||
|
var orgs []Org
|
||||||
|
q := datastore.NewQuery("Organizations")
|
||||||
|
_, err = dbclient.GetAll(ctx, q, &orgs)
|
||||||
|
if err != nil {
|
||||||
|
resp.WriteHeader(401)
|
||||||
|
resp.Write([]byte(`{"success": false, "reason": "Can't get users"}`))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
//newUsers := []User{}
|
||||||
|
//for _, item := range users {
|
||||||
|
// if len(item.Username) == 0 {
|
||||||
|
// continue
|
||||||
|
// }
|
||||||
|
|
||||||
|
// item.Password = ""
|
||||||
|
// item.Session = ""
|
||||||
|
// item.VerificationToken = ""
|
||||||
|
|
||||||
|
// newUsers = append(newUsers, item)
|
||||||
|
//}
|
||||||
|
|
||||||
|
newjson, err := json.Marshal(orgs)
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("Failed unmarshal: %s", err)
|
||||||
|
resp.WriteHeader(401)
|
||||||
|
resp.Write([]byte(fmt.Sprintf(`{"success": false, "reason": "Failed unpacking"}`)))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
resp.WriteHeader(200)
|
||||||
|
resp.Write(newjson)
|
||||||
|
}
|
||||||
|
|
||||||
func handleGetUsers(resp http.ResponseWriter, request *http.Request) {
|
func handleGetUsers(resp http.ResponseWriter, request *http.Request) {
|
||||||
cors := handleCors(resp, request)
|
cors := handleCors(resp, request)
|
||||||
if cors {
|
if cors {
|
||||||
@@ -2392,6 +2496,28 @@ func getSession(ctx context.Context, thissession string) (*session, error) {
|
|||||||
return curUser, nil
|
return curUser, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ListBooks returns a list of books, ordered by title.
|
||||||
|
func getOrg(ctx context.Context, id string) (*Org, error) {
|
||||||
|
key := datastore.NameKey("Organizations", id, nil)
|
||||||
|
curOrg := &Org{}
|
||||||
|
if err := dbclient.Get(ctx, key, curOrg); err != nil {
|
||||||
|
return &Org{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return curOrg, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func setOrg(ctx context.Context, data Org, id string) error {
|
||||||
|
// clear session_token and API_token for user
|
||||||
|
k := datastore.NameKey("Organizations", id, nil)
|
||||||
|
if _, err := dbclient.Put(ctx, k, &data); err != nil {
|
||||||
|
log.Println(err)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// ListBooks returns a list of books, ordered by title.
|
// ListBooks returns a list of books, ordered by title.
|
||||||
func getUser(ctx context.Context, id string) (*User, error) {
|
func getUser(ctx context.Context, id string) (*User, error) {
|
||||||
key := datastore.NameKey("Users", id, nil)
|
key := datastore.NameKey("Users", id, nil)
|
||||||
@@ -4791,8 +4917,8 @@ func setTriggerAuth(ctx context.Context, trigger TriggerAuth) error {
|
|||||||
func getOutlookClient(ctx context.Context, code string, accessToken OauthToken, redirectUri string) (*http.Client, *oauth2.Token, error) {
|
func getOutlookClient(ctx context.Context, code string, accessToken OauthToken, redirectUri string) (*http.Client, *oauth2.Token, error) {
|
||||||
|
|
||||||
conf := &oauth2.Config{
|
conf := &oauth2.Config{
|
||||||
ClientID: "70e37005-c954-4290-b573-d4b94e484336",
|
ClientID: "",
|
||||||
ClientSecret: ".eNw/A[kQFB5zL.agvRputdEJENeJ392",
|
ClientSecret: "",
|
||||||
Scopes: []string{
|
Scopes: []string{
|
||||||
"Mail.Read",
|
"Mail.Read",
|
||||||
"User.Read",
|
"User.Read",
|
||||||
@@ -6243,6 +6369,91 @@ func runInit(ctx context.Context) {
|
|||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
setUsers := false
|
||||||
|
orgQuery := datastore.NewQuery("Organizations")
|
||||||
|
var activeOrgs []Org
|
||||||
|
_, err = dbclient.GetAll(ctx, orgQuery, &activeOrgs)
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("Error getting organizations!")
|
||||||
|
} else {
|
||||||
|
// Add all users to it
|
||||||
|
if len(activeOrgs) == 1 {
|
||||||
|
setUsers = true
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Printf("Organizations exist!")
|
||||||
|
if len(activeOrgs) == 0 {
|
||||||
|
log.Printf(`No orgs. Setting org "default"`)
|
||||||
|
orgSetupName := "default"
|
||||||
|
orgId := uuid.NewV4().String()
|
||||||
|
newOrg := Org{
|
||||||
|
Name: orgSetupName,
|
||||||
|
Id: orgId,
|
||||||
|
Org: orgSetupName,
|
||||||
|
Users: []User{},
|
||||||
|
Roles: []string{"admin", "user"},
|
||||||
|
CloudSync: false,
|
||||||
|
}
|
||||||
|
|
||||||
|
err = setOrg(ctx, newOrg, orgId)
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("Failed setting organization: %s", err)
|
||||||
|
} else {
|
||||||
|
log.Printf("Successfully created the default org!")
|
||||||
|
setUsers = true
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
log.Printf("There are %d org(s).", len(activeOrgs))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Adding the users to the base organization since only one exists (default)
|
||||||
|
if setUsers && len(activeOrgs) > 0 {
|
||||||
|
activeOrg := activeOrgs[0]
|
||||||
|
|
||||||
|
q := datastore.NewQuery("Users")
|
||||||
|
var users []User
|
||||||
|
_, err = dbclient.GetAll(ctx, q, &users)
|
||||||
|
if err == nil {
|
||||||
|
setOrgBool := false
|
||||||
|
for _, user := range users {
|
||||||
|
newUser := User{
|
||||||
|
Username: user.Username,
|
||||||
|
Id: user.Id,
|
||||||
|
ActiveOrg: Org{
|
||||||
|
Id: activeOrg.Id,
|
||||||
|
},
|
||||||
|
Orgs: []string{activeOrg.Id},
|
||||||
|
Role: user.Role,
|
||||||
|
}
|
||||||
|
|
||||||
|
found := false
|
||||||
|
for _, orgUser := range activeOrg.Users {
|
||||||
|
if user.Id == orgUser.Id {
|
||||||
|
found = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if !found && len(user.Username) > 0 {
|
||||||
|
log.Printf("Adding user %s to org %s", user.Username, activeOrg.Name)
|
||||||
|
activeOrg.Users = append(activeOrg.Users, newUser)
|
||||||
|
setOrgBool = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if setOrgBool {
|
||||||
|
err = setOrg(ctx, activeOrg, activeOrg.Id)
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("Failed setting org %s: %s!", activeOrg.Name, err)
|
||||||
|
} else {
|
||||||
|
log.Printf("UPDATED org %s!", activeOrg.Name)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Printf("Should add %d users to organization default", len(users))
|
||||||
|
}
|
||||||
|
|
||||||
// Fix active users etc
|
// Fix active users etc
|
||||||
q := datastore.NewQuery("Users").Filter("active =", true)
|
q := datastore.NewQuery("Users").Filter("active =", true)
|
||||||
var activeusers []User
|
var activeusers []User
|
||||||
@@ -6253,6 +6464,7 @@ func runInit(ctx context.Context) {
|
|||||||
q := datastore.NewQuery("Users")
|
q := datastore.NewQuery("Users")
|
||||||
var users []User
|
var users []User
|
||||||
_, err := dbclient.GetAll(ctx, q, &users)
|
_, err := dbclient.GetAll(ctx, q, &users)
|
||||||
|
|
||||||
if len(activeusers) == 0 && len(users) > 0 {
|
if len(activeusers) == 0 && len(users) > 0 {
|
||||||
log.Printf("No active users found - setting ALL to active")
|
log.Printf("No active users found - setting ALL to active")
|
||||||
if err == nil {
|
if err == nil {
|
||||||
@@ -6268,7 +6480,12 @@ func runInit(ctx context.Context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if len(user.Orgs) == 0 {
|
if len(user.Orgs) == 0 {
|
||||||
user.Orgs = []string{"default"}
|
defaultName := "default"
|
||||||
|
user.Orgs = []string{defaultName}
|
||||||
|
user.ActiveOrg = Org{
|
||||||
|
Name: defaultName,
|
||||||
|
Role: "user",
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
err = setUser(ctx, &user)
|
err = setUser(ctx, &user)
|
||||||
@@ -6291,7 +6508,11 @@ func runInit(ctx context.Context) {
|
|||||||
log.Printf("SHUFFLE_DEFAULT_USERNAME and SHUFFLE_DEFAULT_PASSWORD not defined as environments. Running without default user.")
|
log.Printf("SHUFFLE_DEFAULT_USERNAME and SHUFFLE_DEFAULT_PASSWORD not defined as environments. Running without default user.")
|
||||||
} else {
|
} else {
|
||||||
apikey := os.Getenv("SHUFFLE_DEFAULT_APIKEY")
|
apikey := os.Getenv("SHUFFLE_DEFAULT_APIKEY")
|
||||||
err = createNewUser(username, password, "admin", apikey)
|
|
||||||
|
tmpOrg := Org{
|
||||||
|
Name: "default",
|
||||||
|
}
|
||||||
|
err = createNewUser(username, password, "admin", apikey, tmpOrg)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("Failed to create default user %s: %s", username, err)
|
log.Printf("Failed to create default user %s: %s", username, err)
|
||||||
} else {
|
} else {
|
||||||
@@ -6504,6 +6725,31 @@ func handleCloudSetup(resp http.ResponseWriter, request *http.Request) {
|
|||||||
log.Printf("Apidata: %s", tmpData.Apikey)
|
log.Printf("Apidata: %s", tmpData.Apikey)
|
||||||
// FIXME: https://docs.google.com/drawings/d/1JJebpPeEVEbmH_qsAC6zf9Noygp7PytvesrkhE19QrY/edit
|
// FIXME: https://docs.google.com/drawings/d/1JJebpPeEVEbmH_qsAC6zf9Noygp7PytvesrkhE19QrY/edit
|
||||||
|
|
||||||
|
client := &http.Client{}
|
||||||
|
syncPath := "http://192.168.3.6:5002/api/v1/cloud/sync"
|
||||||
|
req, err := http.NewRequest(
|
||||||
|
"POST",
|
||||||
|
syncPath,
|
||||||
|
nil,
|
||||||
|
)
|
||||||
|
|
||||||
|
newresp, err := client.Do(req)
|
||||||
|
if err != nil {
|
||||||
|
resp.WriteHeader(401)
|
||||||
|
resp.Write([]byte(fmt.Sprintf(`{"success": false, "reason": "Failed cloud sync: %s"`, err)))
|
||||||
|
//setBadMemcache(ctx, docPath)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
respBody, err := ioutil.ReadAll(newresp.Body)
|
||||||
|
if err != nil {
|
||||||
|
resp.WriteHeader(500)
|
||||||
|
resp.Write([]byte(fmt.Sprintf(`{"success": false, "reason": "Can't parse sync data"`)))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Printf("Respbody: %s", string(respBody))
|
||||||
|
|
||||||
resp.WriteHeader(200)
|
resp.WriteHeader(200)
|
||||||
resp.Write([]byte(fmt.Sprintf(`{"success": true}`)))
|
resp.Write([]byte(fmt.Sprintf(`{"success": true}`)))
|
||||||
}
|
}
|
||||||
@@ -6625,8 +6871,9 @@ func init() {
|
|||||||
r.HandleFunc("/api/v1/validate_openapi", validateSwagger).Methods("POST", "OPTIONS")
|
r.HandleFunc("/api/v1/validate_openapi", validateSwagger).Methods("POST", "OPTIONS")
|
||||||
r.HandleFunc("/api/v1/get_openapi/{key}", getOpenapi).Methods("GET", "OPTIONS")
|
r.HandleFunc("/api/v1/get_openapi/{key}", getOpenapi).Methods("GET", "OPTIONS")
|
||||||
|
|
||||||
|
// NEW for 0.8.0
|
||||||
r.HandleFunc("/api/v1/cloud/setup", handleCloudSetup).Methods("POST", "OPTIONS")
|
r.HandleFunc("/api/v1/cloud/setup", handleCloudSetup).Methods("POST", "OPTIONS")
|
||||||
//r.HandleFunc("/api/v1/execution_cleanup", cleanupExecutions).Methods("GET", "OPTIONS")
|
r.HandleFunc("/api/v1/getorgs", handleGetOrgs).Methods("GET", "OPTIONS")
|
||||||
|
|
||||||
http.Handle("/", r)
|
http.Handle("/", r)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -68,12 +68,13 @@ type ExecutionRequest struct {
|
|||||||
|
|
||||||
// Role is just used for feedback for a user
|
// Role is just used for feedback for a user
|
||||||
type Org struct {
|
type Org struct {
|
||||||
Name string `json:"name"`
|
Name string `json:"name" datastore:"name"`
|
||||||
Org string `json:"org"`
|
Id string `json:"id" datastore:"id"`
|
||||||
Users []User `json:"users"`
|
Org string `json:"org" datastore:"org"`
|
||||||
Id string `json:"id"`
|
Users []User `json:"users" datastore:"users"`
|
||||||
Role string `json:"role"`
|
Role string `json:"role" datastore:"role"`
|
||||||
CloudSync bool `json:"cloud_sync"`
|
Roles []string `json:"roles" datastore:"roles"`
|
||||||
|
CloudSync bool `json:"cloud_sync" datastore:"CloudSync"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type AppAuthenticationStorage struct {
|
type AppAuthenticationStorage struct {
|
||||||
|
|||||||
@@ -101,7 +101,6 @@ const Header = props => {
|
|||||||
// Should be based on some path
|
// Should be based on some path
|
||||||
const logoCheck = !homePage ? null : null
|
const logoCheck = !homePage ? null : null
|
||||||
|
|
||||||
|
|
||||||
// Handle top bar or something
|
// Handle top bar or something
|
||||||
const loginTextBrowser = !isLoggedIn ?
|
const loginTextBrowser = !isLoggedIn ?
|
||||||
<div style={{display: "flex"}}>
|
<div style={{display: "flex"}}>
|
||||||
@@ -184,17 +183,19 @@ const Header = props => {
|
|||||||
color="primary"> Settings</Button>
|
color="primary"> Settings</Button>
|
||||||
</Link>
|
</Link>
|
||||||
</ListItem>
|
</ListItem>
|
||||||
<ListItem>
|
{userdata === undefined || userdata.admin === undefined || userdata.admin === null || !userdata.admin ? null :
|
||||||
<Link to="/admin" style={hrefStyle}>
|
<ListItem>
|
||||||
<Button
|
<Link to="/admin" style={hrefStyle}>
|
||||||
style={{}}
|
<Button
|
||||||
variant="contained"
|
style={{}}
|
||||||
color="primary"
|
variant="contained"
|
||||||
>
|
color="primary"
|
||||||
Admin
|
>
|
||||||
</Button>
|
Admin
|
||||||
</Link>
|
</Button>
|
||||||
</ListItem>
|
</Link>
|
||||||
|
</ListItem>
|
||||||
|
}
|
||||||
{userdata === undefined || userdata.orgs === undefined || userdata.orgs === null || userdata.orgs.length <= 1 ? null :
|
{userdata === undefined || userdata.orgs === undefined || userdata.orgs === null || userdata.orgs.length <= 1 ? null :
|
||||||
<ListItem>
|
<ListItem>
|
||||||
<Select
|
<Select
|
||||||
|
|||||||
@@ -45,6 +45,7 @@ const Admin = (props) => {
|
|||||||
const [loginInfo, setLoginInfo] = React.useState("");
|
const [loginInfo, setLoginInfo] = React.useState("");
|
||||||
const [curTab, setCurTab] = React.useState(0);
|
const [curTab, setCurTab] = React.useState(0);
|
||||||
const [users, setUsers] = React.useState([]);
|
const [users, setUsers] = React.useState([]);
|
||||||
|
const [organizations, setOrganizations] = React.useState([]);
|
||||||
const [environments, setEnvironments] = React.useState([]);
|
const [environments, setEnvironments] = React.useState([]);
|
||||||
const [authentication, setAuthentication] = React.useState([]);
|
const [authentication, setAuthentication] = React.useState([]);
|
||||||
const [schedules, setSchedules] = React.useState([])
|
const [schedules, setSchedules] = React.useState([])
|
||||||
@@ -512,6 +513,31 @@ const Admin = (props) => {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const getOrgs = () => {
|
||||||
|
fetch(globalUrl + "/api/v1/getorgs", {
|
||||||
|
method: 'GET',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
'Accept': 'application/json',
|
||||||
|
},
|
||||||
|
credentials: "include",
|
||||||
|
})
|
||||||
|
.then((response) => {
|
||||||
|
if (response.status !== 200) {
|
||||||
|
console.log("Status not 200 for apps :O!")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
return response.json()
|
||||||
|
})
|
||||||
|
.then((responseJson) => {
|
||||||
|
setOrganizations(responseJson)
|
||||||
|
})
|
||||||
|
.catch(error => {
|
||||||
|
alert.error(error.toString())
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
const getUsers = () => {
|
const getUsers = () => {
|
||||||
fetch(globalUrl + "/api/v1/getusers", {
|
fetch(globalUrl + "/api/v1/getusers", {
|
||||||
method: 'GET',
|
method: 'GET',
|
||||||
@@ -523,7 +549,7 @@ const Admin = (props) => {
|
|||||||
})
|
})
|
||||||
.then((response) => {
|
.then((response) => {
|
||||||
if (response.status !== 200) {
|
if (response.status !== 200) {
|
||||||
console.log("Status not 200 for apps :O!")
|
window.location.pathname = "/workflows"
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -771,7 +797,7 @@ const Admin = (props) => {
|
|||||||
Enable cloud features
|
Enable cloud features
|
||||||
</span></DialogTitle>
|
</span></DialogTitle>
|
||||||
<DialogContent>
|
<DialogContent>
|
||||||
What does <a href="https://shuffler.io/docs/workflows#workflow_variables" target="_blank" style={{textDecoration: "none", color: "#f85a3e"}}>cloud sync</a> do?
|
What does <a href="https://shuffler.io/docs/hybrid#cloud_sync" target="_blank" style={{textDecoration: "none", color: "#f85a3e"}}>cloud sync</a> do?
|
||||||
<div style={{marginTop: 5}}/>
|
<div style={{marginTop: 5}}/>
|
||||||
Cloud Apikey
|
Cloud Apikey
|
||||||
<div style={{display: "flex", marginBottom: 20, }}>
|
<div style={{display: "flex", marginBottom: 20, }}>
|
||||||
@@ -1402,6 +1428,42 @@ const Admin = (props) => {
|
|||||||
:
|
:
|
||||||
null
|
null
|
||||||
}
|
}
|
||||||
|
{organizations !== undefined && organizations !== null && organizations.length > 0 ?
|
||||||
|
<span>
|
||||||
|
{organizations.map((data, index) => {
|
||||||
|
const isSelected = props.userdata.selected_org === undefined ? "False" : props.userdata.selected_org.id === data.id ? "True" : "False"
|
||||||
|
|
||||||
|
return (
|
||||||
|
<ListItem key={index}>
|
||||||
|
<ListItemText
|
||||||
|
primary={data.name}
|
||||||
|
style={{minWidth: 150, maxWidth: 150}}
|
||||||
|
/>
|
||||||
|
<ListItemText
|
||||||
|
primary={data.id}
|
||||||
|
style={{minWidth: 200, maxWidth: 200}}
|
||||||
|
/>
|
||||||
|
<ListItemText
|
||||||
|
primary={data.role}
|
||||||
|
style={{minWidth: 150, maxWidth: 150}}
|
||||||
|
/>
|
||||||
|
<ListItemText
|
||||||
|
primary={isSelected}
|
||||||
|
style={{minWidth: 150, maxWidth: 150}}
|
||||||
|
/>
|
||||||
|
<ListItemText
|
||||||
|
primary=<Switch checked={data.cloud_sync} onChange={() => {
|
||||||
|
setCloudSyncModalOpen(true)
|
||||||
|
setSelectedOrganization(data)
|
||||||
|
console.log("INVERT CLOUD SYNC")
|
||||||
|
}} />
|
||||||
|
style={{minWidth: 150, maxWidth: 150}}
|
||||||
|
/>
|
||||||
|
</ListItem>
|
||||||
|
)
|
||||||
|
})}
|
||||||
|
</span>
|
||||||
|
: null}
|
||||||
</List>
|
</List>
|
||||||
</div>
|
</div>
|
||||||
: null
|
: null
|
||||||
@@ -1455,6 +1517,8 @@ const Admin = (props) => {
|
|||||||
getEnvironments()
|
getEnvironments()
|
||||||
} else if (newValue === 3) {
|
} else if (newValue === 3) {
|
||||||
getSchedules()
|
getSchedules()
|
||||||
|
} else if (newValue === 5) {
|
||||||
|
getOrgs()
|
||||||
}
|
}
|
||||||
|
|
||||||
if (newValue === 6) {
|
if (newValue === 6) {
|
||||||
|
|||||||
@@ -123,8 +123,7 @@ const Settings = (props) => {
|
|||||||
|
|
||||||
return response.json()
|
return response.json()
|
||||||
})
|
})
|
||||||
.then((responseJson) => {
|
.then((responseJson) => {
|
||||||
console.log(responseJson)
|
|
||||||
setUserSettings(responseJson)
|
setUserSettings(responseJson)
|
||||||
})
|
})
|
||||||
.catch(error => {
|
.catch(error => {
|
||||||
|
|||||||
Reference in New Issue
Block a user