mirror of
https://github.com/khairul169/vaulterm.git
synced 2025-04-29 00:59:40 +07:00
236 lines
5.2 KiB
Go
236 lines
5.2 KiB
Go
package hosts
|
|
|
|
import (
|
|
"errors"
|
|
"fmt"
|
|
"net/http"
|
|
"strings"
|
|
|
|
"github.com/gofiber/fiber/v2"
|
|
"rul.sh/vaulterm/server/lib"
|
|
"rul.sh/vaulterm/server/models"
|
|
"rul.sh/vaulterm/server/utils"
|
|
)
|
|
|
|
func Router(app fiber.Router) {
|
|
router := app.Group("/hosts")
|
|
|
|
router.Get("/", getAll)
|
|
router.Post("/", create)
|
|
router.Put("/:id", update)
|
|
router.Delete("/:id", delete)
|
|
router.Post("/move", move)
|
|
router.Get("/tags", getTags)
|
|
}
|
|
|
|
func getAll(c *fiber.Ctx) error {
|
|
teamId := c.Query("teamId")
|
|
parentId := c.Query("parentId")
|
|
|
|
user := lib.GetUser(c)
|
|
repo := NewRepository(&Hosts{User: user})
|
|
|
|
if teamId != "" && !user.IsInTeam(&teamId) {
|
|
return utils.ResponseError(c, errors.New("no access"), 403)
|
|
}
|
|
|
|
rows, err := repo.GetAll(GetAllOpt{TeamID: teamId, ParentID: &parentId})
|
|
if err != nil {
|
|
return utils.ResponseError(c, err, 500)
|
|
}
|
|
|
|
return c.JSON(fiber.Map{
|
|
"rows": rows,
|
|
})
|
|
}
|
|
|
|
func create(c *fiber.Ctx) error {
|
|
var body CreateHostSchema
|
|
if err := c.BodyParser(&body); err != nil {
|
|
return utils.ResponseError(c, err, 500)
|
|
}
|
|
|
|
user := lib.GetUser(c)
|
|
repo := NewRepository(&Hosts{User: user})
|
|
|
|
if body.TeamID != nil && !user.TeamCanWrite(body.TeamID) {
|
|
return utils.ResponseError(c, errors.New("no access"), 403)
|
|
}
|
|
|
|
item := &models.Host{
|
|
OwnerID: &user.ID,
|
|
TeamID: body.TeamID,
|
|
Type: body.Type,
|
|
Label: body.Label,
|
|
Host: body.Host,
|
|
Port: body.Port,
|
|
Metadata: body.Metadata,
|
|
ParentID: body.ParentID,
|
|
KeyID: body.KeyID,
|
|
AltKeyID: body.AltKeyID,
|
|
}
|
|
|
|
item.Tags = []*models.HostTag{}
|
|
for _, tag := range body.Tags {
|
|
item.Tags = append(item.Tags, &models.HostTag{Name: tag})
|
|
}
|
|
|
|
osName, err := tryConnect(c, item)
|
|
if err != nil {
|
|
return utils.ResponseError(c, fmt.Errorf("cannot connect to the host: %s", err), 500)
|
|
}
|
|
item.OS = osName
|
|
|
|
if err := repo.Create(item); err != nil {
|
|
return utils.ResponseError(c, err, 500)
|
|
}
|
|
|
|
return c.Status(http.StatusCreated).JSON(item)
|
|
}
|
|
|
|
func update(c *fiber.Ctx) error {
|
|
var body CreateHostSchema
|
|
if err := c.BodyParser(&body); err != nil {
|
|
return utils.ResponseError(c, err, 500)
|
|
}
|
|
|
|
user := lib.GetUser(c)
|
|
repo := NewRepository(&Hosts{User: user})
|
|
|
|
id := c.Params("id")
|
|
data, _ := repo.Get(id)
|
|
if data == nil {
|
|
return utils.ResponseError(c, errors.New("host not found"), 404)
|
|
}
|
|
if !data.CanWrite(&user.User) || !user.TeamCanWrite(body.TeamID) {
|
|
return utils.ResponseError(c, errors.New("no access"), 403)
|
|
}
|
|
|
|
item := &models.Host{
|
|
Model: models.Model{ID: id},
|
|
TeamID: body.TeamID,
|
|
Type: body.Type,
|
|
Label: body.Label,
|
|
Host: body.Host,
|
|
Port: body.Port,
|
|
Metadata: body.Metadata,
|
|
ParentID: body.ParentID,
|
|
KeyID: body.KeyID,
|
|
AltKeyID: body.AltKeyID,
|
|
}
|
|
|
|
// osName, err := tryConnect(c, item)
|
|
// if err != nil {
|
|
// return utils.ResponseError(c, fmt.Errorf("cannot connect to the host: %s", err), 500)
|
|
// }
|
|
// item.OS = osName
|
|
|
|
if err := repo.Update(id, item); err != nil {
|
|
return utils.ResponseError(c, err, 500)
|
|
}
|
|
|
|
tags := []models.HostTag{}
|
|
for _, tag := range body.Tags {
|
|
tags = append(tags, models.HostTag{
|
|
Name: tag,
|
|
})
|
|
}
|
|
|
|
if err := repo.db.Unscoped().Model(&item).
|
|
Association("Tags").Unscoped().Replace(&tags); err != nil {
|
|
return utils.ResponseError(c, err, 500)
|
|
}
|
|
|
|
return c.JSON(item)
|
|
}
|
|
|
|
func delete(c *fiber.Ctx) error {
|
|
user := lib.GetUser(c)
|
|
repo := NewRepository(&Hosts{User: user})
|
|
|
|
id := c.Params("id")
|
|
host, _ := repo.Get(id)
|
|
if host == nil {
|
|
return utils.ResponseError(c, errors.New("host not found"), 404)
|
|
}
|
|
if !host.CanWrite(&user.User) {
|
|
return utils.ResponseError(c, errors.New("no access"), 403)
|
|
}
|
|
|
|
if err := repo.Delete(id); err != nil {
|
|
return utils.ResponseError(c, err, 500)
|
|
}
|
|
|
|
return c.JSON(fiber.Map{
|
|
"status": "ok",
|
|
"message": "Successfully deleted",
|
|
})
|
|
}
|
|
|
|
func move(c *fiber.Ctx) error {
|
|
user := lib.GetUser(c)
|
|
repo := NewRepository(&Hosts{User: user})
|
|
|
|
// validate request
|
|
var body MoveHostSchema
|
|
if err := c.BodyParser(&body); err != nil {
|
|
return utils.ResponseError(c, err, 500)
|
|
}
|
|
if body.HostID == "" {
|
|
return utils.ResponseError(c, errors.New("invalid request"), 400)
|
|
}
|
|
|
|
// get parent
|
|
var parentId *string
|
|
|
|
if body.ParentID != "" {
|
|
parent, err := repo.Get(body.ParentID)
|
|
if err != nil {
|
|
return utils.ResponseError(c, err, 500)
|
|
}
|
|
if !parent.CanWrite(&user.User) {
|
|
return utils.ResponseError(c, errors.New("no access"), 403)
|
|
}
|
|
parentId = &body.ParentID
|
|
}
|
|
|
|
// get hosts
|
|
hostIds := strings.Split(body.HostID, ",")
|
|
hosts, err := repo.GetAll(GetAllOpt{TeamID: body.TeamID, ID: hostIds})
|
|
if err != nil {
|
|
return utils.ResponseError(c, err, 500)
|
|
}
|
|
|
|
if len(hosts) != len(hostIds) {
|
|
return utils.ResponseError(c, errors.New("one or more hosts not found"), 400)
|
|
}
|
|
|
|
for _, host := range hosts {
|
|
if !host.CanWrite(&user.User) {
|
|
return utils.ResponseError(c, errors.New("no access"), 403)
|
|
}
|
|
}
|
|
|
|
// move the hosts to new parent
|
|
if err := repo.SetParentId(parentId, hostIds); err != nil {
|
|
return utils.ResponseError(c, err, 500)
|
|
}
|
|
|
|
return c.JSON(true)
|
|
}
|
|
|
|
func getTags(c *fiber.Ctx) error {
|
|
teamId := c.Query("teamId")
|
|
user := lib.GetUser(c)
|
|
repo := NewRepository(&Hosts{User: user})
|
|
|
|
rows, err := repo.GetAvailableTags(teamId)
|
|
if err != nil {
|
|
return utils.ResponseError(c, err, 500)
|
|
}
|
|
|
|
return c.JSON(fiber.Map{
|
|
"rows": rows,
|
|
})
|
|
}
|