Пример #1
0
func Update(c *echo.Context) error {
	u := users.User{}

	err := utils.ParseJSONBody(c, &u)
	if err != nil {
		return nil
	}

	user, err := users.GetUser(u.GetID())
	if err != nil {
		return apiErrors.UserNotFound
	}

	if u.Password == "" {
		return apiErrors.InvalidRequest.Detail("The password field is missing.")
	}

	err = users.UpdateUserPassword(user.GetID(), u.Password)
	if err != nil {
		log.Error(err)
		return apiErrors.InternalError.Detail("Unable to update the password.")
	}

	return utils.JSON(c, http.StatusOK, user)
}
Пример #2
0
func RetrieveConnections(user *users.User, users []*users.User) ([]Connection, error) {

	rand.Seed(time.Now().UTC().UnixNano())
	var connections []Connection

	rows, err := db.Query("SELECT alias FROM apps")
	if err != nil {
		log.Error("Unable to retrieve apps list from Postgres: ", err.Error())
		return nil, AppsListUnavailable
	}
	defer rows.Close()
	var execServ string
	for rows.Next() {
		appParam := Application{}
		rows.Scan(
			&appParam.Alias,
		)

		if count := len(kExecutionServers); count > 0 {
			execServ = kExecutionServers[rand.Intn(count)]
		} else {
			execServ = kServer
		}

		winUser, err := user.WindowsCredentials()
		if err != nil {
			return nil, err
		}

		username := winUser.Sam + "@" + winUser.Domain
		pwd := winUser.Password

		var conn Connection
		if appParam.Alias != "hapticDesktop" {
			conn = Connection{
				Hostname:  execServ,
				Port:      kRDPPort,
				Protocol:  kProtocol,
				Username:  username,
				Password:  pwd,
				RemoteApp: "||" + appParam.Alias,
				AppName:   appParam.Alias,
			}
		} else {
			conn = Connection{
				Hostname:  execServ,
				Port:      kRDPPort,
				Protocol:  kProtocol,
				Username:  username,
				Password:  pwd,
				RemoteApp: "",
				AppName:   "hapticDesktop",
			}
		}
		connections = append(connections, conn)
	}

	return connections, nil
}
Пример #3
0
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
}
Пример #4
0
// ========================================================================================================================
// 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
}
Пример #5
0
func Update(c *echo.Context) error {
	updatedUser := users.User{}
	user := c.Get("user").(*users.User)

	err := utils.ParseJSONBody(c, &updatedUser)
	if err != nil {
		return apiErrors.InvalidRequest
	}

	currentUser, err := users.GetUser(updatedUser.GetID())
	if err != nil {
		return apiErrors.UserNotFound
	}

	if !user.IsAdmin && (updatedUser.GetID() != user.GetID()) {
		return apiErrors.Unauthorized.Detail("You can only update your account")
	}

	if updatedUser.IsAdmin != currentUser.IsAdmin {
		if currentUser.Id == user.GetID() {
			return apiErrors.Unauthorized.Detail("You cannot grant administration rights")
		}
		err = users.UpdateUserPrivilege(updatedUser.GetID(), updatedUser.IsAdmin)
		if err != nil {
			log.Error(err)
			return apiErrors.InternalError.Detail("Unable to update the rank")
		}
	} else if updatedUser.Password != "" {
		err = users.UpdateUserPassword(updatedUser.GetID(), updatedUser.Password)
		if err != nil {
			log.Error(err)
			return apiErrors.InternalError.Detail("Unable to update the password")
		}
	} else if updatedUser.Email != currentUser.Email {
		err = users.UpdateUserEmail(updatedUser.GetID(), updatedUser.Email)
		if err != nil {
			log.Error(err)
			return apiErrors.InternalError.Detail("Unable to update the email")
		}
	} else if updatedUser.FirstName != currentUser.FirstName {
		err = users.UpdateUserFirstName(updatedUser.GetID(), updatedUser.FirstName)
		if err != nil {
			log.Error(err)
			return apiErrors.InternalError.Detail("Unable to update the first name")
		}
	} else if updatedUser.LastName != currentUser.LastName {
		err = users.UpdateUserLastName(updatedUser.GetID(), updatedUser.LastName)
		if err != nil {
			log.Error(err)
			return apiErrors.InternalError.Detail("Unable to update the last name")
		}
	} else {
		return apiErrors.InvalidRequest.Detail("No field sent")
	}

	return utils.JSON(c, http.StatusOK, &updatedUser)
}
Пример #6
0
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
}