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"`
|
||||
Orgs []string `datastore:"orgs" json:"orgs"`
|
||||
CreationTime int64 `datastore:"creation_time" json:"creation_time"`
|
||||
ActiveOrg Org `json:"active_org" datastore:"active_org"`
|
||||
Active bool `datastore:"active" json:"active"`
|
||||
}
|
||||
|
||||
@@ -1013,13 +1014,13 @@ func handleSetEnvironments(resp http.ResponseWriter, request *http.Request) {
|
||||
user, err := handleApiAuthentication(resp, request)
|
||||
if err != nil {
|
||||
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
|
||||
}
|
||||
|
||||
if user.Role != "admin" {
|
||||
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
|
||||
}
|
||||
|
||||
@@ -1097,7 +1098,7 @@ func handleSetEnvironments(resp http.ResponseWriter, request *http.Request) {
|
||||
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
|
||||
// Use this for register
|
||||
err := checkPasswordStrength(password)
|
||||
@@ -1137,7 +1138,7 @@ func createNewUser(username, password, role, apikey string) error {
|
||||
newUser.Verified = false
|
||||
newUser.CreationTime = time.Now().Unix()
|
||||
newUser.Active = true
|
||||
newUser.Orgs = []string{"default"}
|
||||
newUser.Orgs = []string{org.Id}
|
||||
|
||||
// FIXME - Remove this later
|
||||
if role == "admin" {
|
||||
@@ -1148,6 +1149,8 @@ func createNewUser(username, password, role, apikey string) error {
|
||||
newUser.Roles = []string{"user"}
|
||||
}
|
||||
|
||||
newUser.ActiveOrg = org
|
||||
|
||||
if len(apikey) > 0 {
|
||||
newUser.ApiKey = apikey
|
||||
}
|
||||
@@ -1182,25 +1185,25 @@ func createNewUser(username, password, role, apikey string) error {
|
||||
log.Printf("Error adding User %s: %s", username, err)
|
||||
return err
|
||||
}
|
||||
url := fmt.Sprintf("https://shuffler.io/register/%s", verifyToken.String())
|
||||
const verifyMessage = `
|
||||
Registration URL :)
|
||||
|
||||
%s
|
||||
`
|
||||
addr := newUser.Username
|
||||
|
||||
msg := &mail.Message{
|
||||
Sender: "Shuffle <frikky@shuffler.io>",
|
||||
To: []string{addr},
|
||||
Subject: "Verify your username - Shuffle",
|
||||
Body: fmt.Sprintf(verifyMessage, url),
|
||||
}
|
||||
|
||||
log.Println(msg.Body)
|
||||
if err := mail.Send(ctx, msg); err != nil {
|
||||
log.Printf("Couldn't send email: %v", err)
|
||||
}
|
||||
// url := fmt.Sprintf("https://shuffler.io/register/%s", verifyToken.String())
|
||||
// const verifyMessage = `
|
||||
//Registration URL :)
|
||||
//
|
||||
//%s
|
||||
// `
|
||||
// addr := newUser.Username
|
||||
//
|
||||
// msg := &mail.Message{
|
||||
// Sender: "Shuffle <frikky@shuffler.io>",
|
||||
// To: []string{addr},
|
||||
// Subject: "Verify your username - Shuffle",
|
||||
// Body: fmt.Sprintf(verifyMessage, url),
|
||||
// }
|
||||
//
|
||||
// log.Println(msg.Body)
|
||||
// if err := mail.Send(ctx, msg); err != nil {
|
||||
// log.Printf("Couldn't send email: %v", err)
|
||||
// }
|
||||
|
||||
err = increaseStatisticsField(ctx, "successful_register", username, 1)
|
||||
if err != nil {
|
||||
@@ -1249,7 +1252,8 @@ func handleRegister(resp http.ResponseWriter, request *http.Request) {
|
||||
if count == 0 {
|
||||
role = "admin"
|
||||
}
|
||||
err = createNewUser(data.Username, data.Password, role, "")
|
||||
|
||||
err = createNewUser(data.Username, data.Password, role, "", user.ActiveOrg)
|
||||
if err != nil {
|
||||
log.Printf("Failed registering user: %s", err)
|
||||
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
|
||||
parsedAdmin := "false"
|
||||
if userInfo.Role == "admin" {
|
||||
parsedAdmin = "true"
|
||||
}
|
||||
|
||||
if !userInfo.Active {
|
||||
if userInfo.Role == "admin" {
|
||||
parsedAdmin = "true"
|
||||
@@ -1692,14 +1700,55 @@ func handleInfo(resp http.ResponseWriter, request *http.Request) {
|
||||
Expires: expiration,
|
||||
})
|
||||
|
||||
// Migrate this to real Org
|
||||
// Need to create org endpoints (create, delete etc)
|
||||
currentOrg := `{
|
||||
"name": "Shuffle",
|
||||
"id": "123",
|
||||
"role": "admin",
|
||||
"cloud_sync": false
|
||||
}`
|
||||
// Updating user info if there's something wrong
|
||||
if (len(userInfo.ActiveOrg.Name) == 0 || len(userInfo.ActiveOrg.Id) == 0) && len(userInfo.Orgs) > 0 {
|
||||
_, err := getOrg(ctx, userInfo.Orgs[0])
|
||||
if err != nil {
|
||||
var orgs []Org
|
||||
q := datastore.NewQuery("Organizations")
|
||||
_, 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(`
|
||||
{
|
||||
@@ -2175,6 +2224,61 @@ func handleGetEnvironments(resp http.ResponseWriter, request *http.Request) {
|
||||
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) {
|
||||
cors := handleCors(resp, request)
|
||||
if cors {
|
||||
@@ -2392,6 +2496,28 @@ func getSession(ctx context.Context, thissession string) (*session, error) {
|
||||
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.
|
||||
func getUser(ctx context.Context, id string) (*User, error) {
|
||||
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) {
|
||||
|
||||
conf := &oauth2.Config{
|
||||
ClientID: "70e37005-c954-4290-b573-d4b94e484336",
|
||||
ClientSecret: ".eNw/A[kQFB5zL.agvRputdEJENeJ392",
|
||||
ClientID: "",
|
||||
ClientSecret: "",
|
||||
Scopes: []string{
|
||||
"Mail.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
|
||||
q := datastore.NewQuery("Users").Filter("active =", true)
|
||||
var activeusers []User
|
||||
@@ -6253,6 +6464,7 @@ func runInit(ctx context.Context) {
|
||||
q := datastore.NewQuery("Users")
|
||||
var users []User
|
||||
_, err := dbclient.GetAll(ctx, q, &users)
|
||||
|
||||
if len(activeusers) == 0 && len(users) > 0 {
|
||||
log.Printf("No active users found - setting ALL to active")
|
||||
if err == nil {
|
||||
@@ -6268,7 +6480,12 @@ func runInit(ctx context.Context) {
|
||||
}
|
||||
|
||||
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)
|
||||
@@ -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.")
|
||||
} else {
|
||||
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 {
|
||||
log.Printf("Failed to create default user %s: %s", username, err)
|
||||
} else {
|
||||
@@ -6504,6 +6725,31 @@ func handleCloudSetup(resp http.ResponseWriter, request *http.Request) {
|
||||
log.Printf("Apidata: %s", tmpData.Apikey)
|
||||
// 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.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/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/execution_cleanup", cleanupExecutions).Methods("GET", "OPTIONS")
|
||||
r.HandleFunc("/api/v1/getorgs", handleGetOrgs).Methods("GET", "OPTIONS")
|
||||
|
||||
http.Handle("/", r)
|
||||
}
|
||||
|
||||
@@ -68,12 +68,13 @@ type ExecutionRequest struct {
|
||||
|
||||
// Role is just used for feedback for a user
|
||||
type Org struct {
|
||||
Name string `json:"name"`
|
||||
Org string `json:"org"`
|
||||
Users []User `json:"users"`
|
||||
Id string `json:"id"`
|
||||
Role string `json:"role"`
|
||||
CloudSync bool `json:"cloud_sync"`
|
||||
Name string `json:"name" datastore:"name"`
|
||||
Id string `json:"id" datastore:"id"`
|
||||
Org string `json:"org" datastore:"org"`
|
||||
Users []User `json:"users" datastore:"users"`
|
||||
Role string `json:"role" datastore:"role"`
|
||||
Roles []string `json:"roles" datastore:"roles"`
|
||||
CloudSync bool `json:"cloud_sync" datastore:"CloudSync"`
|
||||
}
|
||||
|
||||
type AppAuthenticationStorage struct {
|
||||
|
||||
Reference in New Issue
Block a user