func syncUploadedFile(path, sam, pwd string) (string, error) { winPort := utils.Env("WIN_PORT", "") winServer := utils.Env("WIN_SERVER", "") cmd := exec.Command( "sshpass", "-p", pwd, "scp", "-o", "UserKnownHostsFile=/dev/null", "-o", "StrictHostKeyChecking=no", "-P", winPort, path, sam+"@"+winServer+":C:\\Users\\"+sam+"\\Desktop\\", ) output, err := cmd.CombinedOutput() if err != nil { return string(output), err } err = os.Remove(path) if err != nil { log.Error(err) } return string(output), nil }
func Get(w http.ResponseWriter, r *http.Request) { rawuser, oauthErr := oauth2.GetUser(w, r) if rawuser == nil || oauthErr != nil { http.Error(w, "", http.StatusUnauthorized) return } user := rawuser.(*users.User) winUser, err := user.WindowsCredentials() if err != nil { http.Error(w, "", http.StatusUnauthorized) return } sam := winUser.Sam winServer := utils.Env("PLAZA_ADDRESS", "iaas-module") request, err := http.NewRequest("GET", "http://"+winServer+":"+utils.Env("PLAZA_PORT", "9090")+"/upload?sam="+url.QueryEscape(sam), nil) if err != nil { log.Println("Unable de create request ", err) } request.Header = r.Header client := &http.Client{} resp, err := client.Do(request) if err != nil { log.Println("request error", err) } if resp.StatusCode == http.StatusTeapot { http.Error(w, "", http.StatusSeeOther) } return }
func PublishApp(user *users.User, app *Application) error { plazaAddress := utils.Env("PLAZA_ADDRESS", "iaas-module") if plazaAddress == "" { return errors.New("plaza address unknown") } plazaPort, err := strconv.Atoi(utils.Env("PLAZA_PORT", "9090")) if err != nil { return err } winUser, err := user.WindowsCredentials() if err != nil { return err } res, err := plaza.PublishApp( plazaAddress, plazaPort, winUser.Sam, winUser.Domain, winUser.Password, app.CollectionName, app.DisplayName, app.Path, ) if err != nil { log.Error(err) return PublishFailed } a := ApplicationWin{} err = json.Unmarshal(res, &a) if err != nil { return err } id := uuid.NewV4().String() _, err = db.Query( `INSERT INTO apps (id, collection_name, alias, display_name, file_path, icon_content) VALUES ( $1::varchar, $2::varchar, $3::varchar, $4::varchar, $5::varchar, $6::bytea) `, id, a.CollectionName, a.Alias, a.DisplayName, a.FilePath, a.IconContents, ) if err != nil { return err } app.CollectionName = a.CollectionName app.Alias = a.Alias app.DisplayName = a.DisplayName app.FilePath = a.FilePath app.IconContents = a.IconContents app.Id = id return nil }
// ======================================================================================================================== // Procedure: unpublishApplication // // Does: // - Unpublish specified applications from ActiveDirectory // ======================================================================================================================== func UnpublishApp(user *users.User, id string) error { rows, err := db.Query( `SELECT alias, collection_name FROM apps WHERE id = $1::varchar`, id, ) if err != nil { log.Error(err) return UnpublishFailed } defer rows.Close() var alias string var collection string if !rows.Next() { return errors.New("Application not found") } rows.Scan(&alias, &collection) plazaAddress := utils.Env("PLAZA_ADDRESS", "iaas-module") if plazaAddress == "" { return errors.New("plaza address unknown") } plazaPort, err := strconv.Atoi(utils.Env("PLAZA_PORT", "9090")) if err != nil { return err } winUser, err := user.WindowsCredentials() if err != nil { return err } _, err = plaza.UnpublishApp( plazaAddress, plazaPort, winUser.Sam, winUser.Domain, winUser.Password, collection, alias, ) if err != nil { log.Error(err) return UnpublishFailed } _, err = db.Query("DELETE FROM apps WHERE id = $1::varchar", id) if err != nil { log.Error("delete from postgres failed: ", err) return UnpublishFailed } return nil }
func init() { kUsername = utils.Env("LDAP_USERNAME", "CN=Administrator,CN=Users,DC=intra,DC=localdomain,DC=com") kPassword = utils.Env("LDAP_PASSWORD", "Nanocloud123+") kOrganisationUnit = utils.Env("LDAP_OU", "OU=NanocloudUsers,DC=intra,DC=localdomain,DC=com") ldapServer, err := url.Parse(utils.Env("LDAP_SERVER_URI", "ldaps://*****:*****@iaas-module:6360")) if err != nil { panic(err) } kLDAPServer = *ldapServer }
func provExec(p io.Writer, machine vms.Machine, command string) (string, error) { machine.Status() ip, _ := machine.IP() for checkPlaza(ip.String(), utils.Env("PLAZA_PORT", "9090")) != true { machine.Status() ip, _ = machine.IP() time.Sleep(time.Millisecond * 500) } plazaAddress, err := machine.IP() if err != nil { log.Error(err.Error()) return "", err } plazaPort, err := strconv.Atoi(utils.Env("PLAZA_PORT", "9090")) if err != nil { log.Error(err.Error()) return "", err } domain := utils.Env("WINDOWS_DOMAIN", "") if domain == "" { log.Error("domain unknown") return "", errors.New("domain unknown") } username, password, err := machine.Credentials() if err != nil { log.Error(err.Error()) return "", err } res, err := PowershellExec( plazaAddress.String(), plazaPort, username, domain, password, command, ) p.Write([]byte(command)) if err != nil { return "", err } return res.Stdout, nil }
func init() { kProtocol = utils.Env("PROTOCOL", "rdp") kRDPPort = utils.Env("RDP_PORT", "3389") kServer = utils.Env("PLAZA_ADDRESS", "iaas-module") kExecutionServers = strings.Split(utils.Env("EXECUTION_SERVERS", ""), ",") if kServer == "" { panic("PLAZA_ADDRESS not set") } if len(kExecutionServers) == 0 { panic("EXECUTION_SERVERS not set") } }
func initVms() error { iaas := os.Getenv("IAAS") if len(iaas) == 0 { return errors.New("No iaas provided") } m := make(map[string]string, 0) switch iaas { case "vmwarefusion": m["PLAZA_LOCATION"] = os.Getenv("PLAZA_LOCATION") m["STORAGE_DIR"] = os.Getenv("STORAGE_DIR") case "qemu": m["ad"] = utils.Env("PLAZA_ADDRESS", "iaas-module") case "manual": /* env variables are now used in migration. The following variables must be set: - EXECUTION_SERVERS */ } vm, err := vms.Open(iaas, m) if err != nil { return err } vmsConn.SetVM(vm) return nil }
func FindAll() ([]*MachineDriver, error) { drivers := make([]*MachineDriver, 1) drivers[0] = &MachineDriver{ ID: utils.Env("IAAS", ""), } return drivers, nil }
func init() { kUser = utils.Env("USER", "Administrator") kProtocol = utils.Env("PROTOCOL", "rdp") kSSHPort = utils.Env("SSH_PORT", "22") kRDPPort = utils.Env("RDP_PORT", "3389") kServer = utils.Env("SERVER", "62.210.56.76") kPassword = utils.Env("PASSWORD", "ItsPass1942+") kWindowsDomain = utils.Env("WINDOWS_DOMAIN", "intra.localdomain.com") kExecutionServers = strings.Split(utils.Env("EXECUTION_SERVERS", "62.210.56.76"), ",") }
func init() { kUploadDir = utils.Env("UPLOAD_DIR", "uploads/") dir, err := filepath.Abs(filepath.Dir(os.Args[0])) if err != nil { log.Info("Cannot determine program's absolute path") return } kUploadDir = filepath.Join(dir, kUploadDir) }
func Post(w http.ResponseWriter, r *http.Request) { filename := r.URL.Query()["filename"][0] rawuser, oauthErr := oauth2.GetUser(w, r) if rawuser == nil || oauthErr != nil { http.Error(w, "", http.StatusUnauthorized) return } user := rawuser.(*users.User) winUser, err := user.WindowsCredentials() if err != nil { http.Error(w, "", http.StatusUnauthorized) return } sam := winUser.Sam winServer := utils.Env("PLAZA_ADDRESS", "iaas-module") request, err := http.NewRequest( "POST", "http://"+winServer+":"+utils.Env("PLAZA_PORT", "9090")+"/upload?sam="+url.QueryEscape(sam)+"&userId="+url.QueryEscape(user.Id)+"&filename="+url.QueryEscape(filename), r.Body, ) if err != nil { log.Println("Unable de create request ", err) } request.Header = r.Header client := &http.Client{} resp, err := client.Do(request) if err != nil { log.Println("Unable to send request ", err) } log.Error(resp) http.Error(w, "", resp.StatusCode) return }
func Migrate() error { insertAdmin, err := createUsersTable() if err != nil { return err } err = createWindowsUsersTable() if err != nil { return err } err = createUsersWindowsUserTable() if err != nil { return err } if insertAdmin { adminpwd := utils.Env("ADMIN_PASSWORD", "Nanocloud123+") adminfirstname := utils.Env("ADMIN_FIRSTNAME", "Admin") adminlastname := utils.Env("ADMIN_LASTNAME", "Nanocloud") adminmail := utils.Env("ADMIN_MAIL", "*****@*****.**") admin, err := users.CreateUser( true, adminmail, adminfirstname, adminlastname, adminpwd, true, ) if err != nil { return err } password := utils.Env("WINDOWS_PASSWORD", "") sam := utils.Env("WINDOWS_USER", "") domain := utils.Env("WINDOWS_DOMAIN", "") err = users.UpdateUserAd(admin.Id, sam, password, domain) if err != nil { log.Error("Failed to update admin account: ", err) return err } } return nil }
func Get(c *echo.Context) error { w := c.Response() r := c.Request() w.Header().Set("Access-Control-Allow-Origin", "*") w.Header().Set("Cashe-Control", "no-store") w.Header().Set("Expires", "Sat, 01 Jan 2000 00:00:00 GMT") w.Header().Set("Pragma", "no-cache") path := c.Query("path") filename := c.Query("filename") if len(filename) == 0 { return c.JSON( http.StatusBadRequest, hash{ "error": "Invalid Path", }, ) } var user *users.User var err error downloadToken := c.Query("token") if len(downloadToken) > 0 { user, err = checkDownloadToken(downloadToken, filename) if err != nil { return c.JSON( http.StatusBadRequest, hash{ "error": "Invalid Download Token", }, ) } } if user == nil { u, fail := oauth2.GetUser(w, r) if u == nil { return errors.New("no authenticated user") } if fail != nil { return oauthError(c, fail) } user = u.(*users.User) } winUser, err := user.WindowsCredentials() if err != nil { return err } if filename[0] == '.' { path = filepath.Join( fmt.Sprintf( utils.Env("PLAZA_USER_DIR", "C:\\Users\\%s\\Desktop\\Nanocloud"), winUser.Sam, ), filename, ) } else { filename = strings.Replace(filename, "/", "\\", -1) path = filename } resp, err := http.Get("http://" + utils.Env("PLAZA_ADDRESS", "iaas-module") + ":" + utils.Env("PLAZA_PORT", "9090") + "/files?create=true&path=" + url.QueryEscape(path)) if err != nil { log.Error(err) return apiErrors.WindowsNotOnline.Detail(err.Error()) } if resp.StatusCode == http.StatusNotFound { jsonResponse(w, r, http.StatusNotFound, hash{ "error": "File Not Found", }) return nil } if resp.StatusCode != http.StatusOK { contents, err := ioutil.ReadAll(resp.Body) if err != nil { return errors.New("Unable to retrieve the file") } return apiErrors.NeedFirstConnection.Detail(string(contents)) } var contentType string rContentType, exists := resp.Header["Content-Type"] if !exists || len(rContentType) == 0 || len(rContentType[0]) == 0 { contentType = "application/octet-stream" } else { contentType = rContentType[0] } var sent int64 var lastBuffSize int64 contentLength := resp.ContentLength var f string splt := strings.Split(path, "\\") if len(splt) > 0 { f = splt[len(splt)-1] } else { f = path } w.Header().Set("Content-Type", contentType) w.Header().Set("Content-Length", strconv.FormatInt(contentLength, 10)) w.Header().Set("Content-Disposition", "attachment; filename=\""+f+"\"") var buff []byte for sent < contentLength { remaining := contentLength - sent if remaining > 4096 { remaining = 4096 } if buff == nil || remaining != lastBuffSize { buff = make([]byte, remaining) lastBuffSize = remaining } nRead, readErr := resp.Body.Read(buff) if nRead > 0 { nWrite, writeErr := w.Write(buff[0:nRead]) sent = sent + int64(nWrite) if writeErr != nil { log.Errorf("Write error: %s\n", writeErr.Error()) break } } if readErr != nil && readErr.Error() != "EOF" { log.Errorf("Read error: %s\n", readErr.Error()) break } } return nil }
func Provision(machine vms.Machine) provisioner.ProvFunc { return func(p io.Writer) { resp, err := provExec(p, machine, "New-Item HKLM:\\SOFTWARE\\Policies\\Microsoft\\Windows -Name WindowsUpdate") if err != nil { p.Write([]byte(err.Error())) } else { p.Write([]byte(resp)) } username, password, err := machine.Credentials() if err != nil { p.Write([]byte(err.Error())) } pcname, err := provExec(p, machine, "hostname") if err != nil { p.Write([]byte(err.Error())) } pcname = strings.TrimSpace(pcname) domain := utils.Env("WINDOWS_DOMAIN", "") resp, err = provExec(p, machine, "New-Item HKLM:\\SOFTWARE\\Policies\\Microsoft\\Windows\\WindowsUpdate -Name AU") if err != nil { p.Write([]byte(err.Error())) } else { p.Write([]byte(resp)) } resp, err = provExec(p, machine, "New-ItemProperty HKLM:\\SOFTWARE\\Policies\\Microsoft\\Windows\\WindowsUpdate\\AU -Name NoAutoUpdate -Value 1") if err != nil { p.Write([]byte(err.Error())) } else { p.Write([]byte(resp)) } resp, err = provExec(p, machine, "Install-windowsfeature AD-domain-services") if err != nil { p.Write([]byte(err.Error())) } else { p.Write([]byte(resp)) } resp, err = provExec(p, machine, "Import-Module ADDSDeployment; $pwd=ConvertTo-SecureString '"+password+"' -asplaintext -force; Install-ADDSForest -CreateDnsDelegation:$false -DatabasePath 'C:\\Windows\\NTDS' -DomainMode 'Win2012R2' -DomainName '"+domain+"' -SafeModeAdministratorPassword:$pwd -DomainNetbiosName 'INTRA' -ForestMode 'Win2012R2' -InstallDns:$true -LogPath 'C:\\Windows\\NTDS' -NoRebootOnCompletion:$true -SysvolPath 'C:\\Windows\\SYSVOL' -Force:$true") if err != nil { p.Write([]byte(err.Error())) } else { p.Write([]byte(resp)) } machine.Stop() for isStopped(machine) != true { } machine.Start() resp, err = provExec(p, machine, "set-ItemProperty -Path 'HKLM:\\System\\CurrentControlSet\\Control\\Terminal Server'-name 'fDenyTSConnections' -Value 0") if err != nil { p.Write([]byte(err.Error())) } else { p.Write([]byte(resp)) } resp, err = provExec(p, machine, "Enable-NetFirewallRule -DisplayGroup 'Remote Desktop'") if err != nil { p.Write([]byte(err.Error())) } else { p.Write([]byte(resp)) } resp, err = provExec(p, machine, "set-ItemProperty -Path 'HKLM:\\System\\CurrentControlSet\\Control\\Terminal Server\\WinStations\\RDP-Tcp' -name 'UserAuthentication' -Value 1") if err != nil { p.Write([]byte(err.Error())) } else { p.Write([]byte(resp)) } resp, err = provExec(p, machine, "import-module RemoteDesktop; Import-module ServerManager; Add-WindowsFeature -Name RDS-RD-Server -IncludeAllSubFeature; Add-WindowsFeature -Name RDS-Web-Access -IncludeAllSubFeature; Add-WindowsFeature -Name RDS-Connection-Broker -IncludeAllSubFeature") if err != nil { p.Write([]byte(err.Error())) } else { p.Write([]byte(resp)) } resp, err = provExec(p, machine, "import-module RemoteDesktop; Import-module ServerManager; Install-windowsfeature RSAT-AD-AdminCenter") if err != nil { p.Write([]byte(err.Error())) } else { p.Write([]byte(resp)) } machine.Stop() for isStopped(machine) != true { } machine.Start() resp, err = provExec(p, machine, "sc.exe config RDMS start= auto") if err != nil { p.Write([]byte(err.Error())) } else { p.Write([]byte(resp)) } resp, err = provExec(p, machine, "Import-Module ServerManager; Add-WindowsFeature Adcs-Cert-Authority") if err != nil { p.Write([]byte(err.Error())) } else { p.Write([]byte(resp)) } resp, err = provExec(p, machine, "$secpasswd = ConvertTo-SecureString '"+password+"' -AsPlainText -Force;$mycreds = New-Object System.Management.Automation.PSCredential ('"+username+"', $secpasswd); Install-AdcsCertificationAuthority -CAType 'EnterpriseRootCa' -Credential:$mycreds -force:$true ") if err != nil { p.Write([]byte(err.Error())) } else { p.Write([]byte(resp)) } resp, err = provExec(p, machine, "Start-Service RDMS; import-module remotedesktop ; New-RDSessionDeployment -ConnectionBroker "+pcname+"."+domain+" -WebAccessServer "+pcname+"."+domain+" -SessionHost "+pcname+"."+domain) if err != nil { p.Write([]byte(err.Error())) } else { p.Write([]byte(resp)) } time.Sleep(time.Second * 60) resp, err = provExec(p, machine, "import-module remotedesktop ; New-RDSessionCollection -CollectionName collection -SessionHost "+pcname+"."+domain+" -CollectionDescription 'Nanocloud collection' -ConnectionBroker "+pcname+"."+domain) if err != nil { p.Write([]byte(err.Error())) } else { p.Write([]byte(resp)) } resp, err = provExec(p, machine, "(Get-WmiObject -class 'Win32_TSGeneralSetting' -Namespace root\\cimv2\\terminalservices -ComputerName "+pcname+").SetUserAuthenticationRequired(0)") if err != nil { p.Write([]byte(err.Error())) } else { p.Write([]byte(resp)) } resp, err = provExec(p, machine, "NEW-ADOrganizationalUnit 'NanocloudUsers' -path 'DC=intra,DC=localdomain,DC=com'") if err != nil { p.Write([]byte(err.Error())) } else { p.Write([]byte(resp)) } } }
func main() { err := migration.Migrate() if err != nil { log.Error(err) return } err = initVms() if err != nil { log.Error(err) return } e := echo.New() e.SetLogLevel(logger.DEBUG) e.Use(middleware.Logger()) e.Use(middleware.Recover()) /** * LOGOUT */ e.Post("/api/logout", m.OAuth2(logout.Post)) /** * APPS */ e.Get("/api/apps", m.OAuth2(m.Admin(apps.ListApplications))) e.Delete("/api/apps/:app_id", m.OAuth2(m.Admin(apps.UnpublishApplication))) e.Get("/api/apps/me", m.OAuth2(apps.ListUserApps)) e.Post("/api/apps", m.OAuth2(m.Admin(apps.PublishApplication))) e.Get("/api/apps/connections", m.OAuth2(apps.GetConnections)) e.Patch("/api/apps/:app_id", m.OAuth2(m.Admin(apps.ChangeAppName))) go appsModel.CheckPublishedApps() /** * HISTORY */ e.Get("/api/history", m.OAuth2(history.List)) e.Post("/api/history", m.OAuth2(history.Add)) /** * USERS */ e.Patch("/api/users/:id", m.OAuth2(m.Admin(users.Update))) e.Get("/api/users", m.OAuth2(m.Admin(users.Get))) e.Post("/api/users", m.OAuth2(m.Admin(users.Post))) e.Delete("/api/users/:id", m.OAuth2(m.Admin(users.Delete))) e.Put("/api/users/:id", m.OAuth2(m.Admin(users.UpdatePassword))) e.Get("/api/users/:id", m.OAuth2(m.Admin(users.GetUser))) /** * IAAS */ e.Get("/api/iaas", m.OAuth2(m.Admin(iaas.ListRunningVM))) e.Post("/api/iaas/:id/stop", m.OAuth2(m.Admin(iaas.StopVM))) e.Post("/api/iaas/:id/start", m.OAuth2(m.Admin(iaas.StartVM))) e.Post("/api/iaas/:id/download", m.OAuth2(m.Admin(iaas.CreateVM))) /** * FRONT */ e.Static("/canva/", front.StaticCanvaDirectory) e.Static("/", front.StaticDirectory) /** * ME */ e.Get("/api/me", m.OAuth2(me.Get)) /** * VERSION */ e.Get("/api/version", version.Get) /** * OAUTH */ e.Any("/oauth/*", oauth.Handler) /** * TOKENS */ e.Get("/api/tokens", m.OAuth2(tokens.Get)) e.Delete("/api/tokens/:id", m.OAuth2(tokens.Delete)) /** * UPLOAD */ e.Post("/upload", upload.Post) e.Get("/upload", upload.Get) addr := ":" + utils.Env("PORT", "8080") log.Info("Server running at ", addr) e.Run(addr) }
func init() { kServer = utils.Env("EXECUTION_SERVERS", "iaas-module") kPort = utils.Env("PLAZA_PORT", "9090") }
func init() { StaticDirectory = utils.Env("FRONT_DIR", "front") }
func init() { kServer = utils.Env("PLAZA_ADDRESS", "iaas-module") kPort = utils.Env("PLAZA_PORT", "9090") }
func init() { StaticDirectory = utils.Env("FRONT_DIR", "front") StaticCanvaDirectory = utils.Env("CANVA_FRONT_DIR", "canva") }
func main() { err := migration.Migrate() if err != nil { log.Error(err) return } p := echo.New() go p.Run(":8181") err = initVms() if err != nil { log.Error(err) return } e := echo.New() e.SetLogLevel(logger.DEBUG) e.Use(middleware.Logger()) e.Use(middleware.Recover()) e.SetHTTPErrorHandler(apiErrors.Handler) /** * APPS */ e.Get("/api/applications", m.OAuth2(apps.ListApplications)) e.Delete("/api/applications/:app_id", m.OAuth2(m.Admin(apps.UnpublishApplication))) e.Post("/api/applications", m.OAuth2(m.Admin(apps.PublishApplication))) e.Get("/api/applications/connections", m.OAuth2(apps.GetConnections)) e.Patch("/api/applications/:app_id", m.OAuth2(m.Admin(apps.ChangeAppName))) /** * SESSIONS */ e.Get("/api/sessions", m.OAuth2(sessions.List)) e.Delete("/api/sessions", m.OAuth2(sessions.Logoff)) /** * HISTORY */ e.Get("/api/histories", m.OAuth2(histories.List)) e.Post("/api/histories", m.OAuth2(histories.Add)) //m.OAuth2( /** * USERS */ e.Patch("/api/users/:id", m.OAuth2(m.Admin(users.Update))) e.Get("/api/users", m.OAuth2(users.Get)) e.Post("/api/users", m.OAuth2(m.Admin(users.Post))) e.Delete("/api/users/:id", m.OAuth2(m.Admin(users.Delete))) e.Put("/api/users/:id", m.OAuth2(m.Admin(users.UpdatePassword))) e.Get("/api/users/:id", m.OAuth2(users.GetUser)) /** * MACHINES */ e.Get("/api/machines", m.OAuth2(m.Admin(machines.Machines))) e.Get("/api/machines/:id", m.OAuth2(m.Admin(machines.GetMachine))) e.Patch("/api/machines/:id", m.OAuth2(m.Admin(machines.PatchMachine))) e.Post("/api/machines", m.OAuth2(m.Admin(machines.CreateMachine))) e.Delete("/api/machines/:id", m.OAuth2(m.Admin(machines.DeleteMachine))) /** * MACHINES DRIVERS */ e.Get("/api/machine-drivers", m.OAuth2(m.Admin(machinedrivers.FindAll))) /** * Files */ e.Get("/api/files", files.Get) e.Get("/api/files/token", m.OAuth2(files.GetDownloadToken)) /** * FRONT */ e.Static("/", front.StaticDirectory) /** * OAUTH */ e.Any("/oauth/*", oauth.Handler) /** * TOKENS */ e.Get("/api/tokens", m.OAuth2(tokens.Get)) e.Delete("/api/tokens/:id", m.OAuth2(tokens.Delete)) /** * UPLOAD */ e.Post("/upload", upload.Post) e.Get("/upload", upload.Get) addr := ":" + utils.Env("BACKEND_PORT", "8080") log.Info("Server running at ", addr) e.Run(addr) }
func Migrate() error { rows, err := db.Query( `SELECT table_name FROM information_schema.tables WHERE table_name = 'users'`) if err != nil { return err } defer rows.Close() if rows.Next() { return nil } rows, err = db.Query( `CREATE TABLE users ( id varchar(36) PRIMARY KEY, first_name varchar(36) NOT NULL DEFAULT '', last_name varchar(36) NOT NULL DEFAULT '', email varchar(36) NOT NULL DEFAULT '' UNIQUE, password varchar(60) NOT NULL DEFAULT '', is_admin boolean, activated boolean, sam varchar(35) NOT NULL DEFAULT '', windows_password varchar(36) NOT NULL DEFAULT '' );`) if err != nil { return err } rows.Close() admin, err := users.CreateUser( true, "*****@*****.**", "John", "Doe", "admin", true, ) if err != nil { return err } password := utils.Env("WIN_PASSWORD", "") sam := utils.Env("WIN_USER", "") result, err := db.Exec( `UPDATE users SET sam = $1::varchar, windows_password = $2::varchar WHERE id = $3::varchar;`, sam, password, admin.Id, ) if err != nil { log.Error("Failed to update admin account: ", err) return err } updated, err := result.RowsAffected() if err != nil { log.Error(err) return err } if updated != 1 { return errors.New("Unable to set admin password") } return nil }