mirror of
https://github.com/veops/oneterm.git
synced 2025-10-19 05:34:46 +08:00
feat(api): share
This commit is contained in:
@@ -136,6 +136,13 @@ func RunApi() error {
|
|||||||
share.GET("", c.GetShare, authAdmin())
|
share.GET("", c.GetShare, authAdmin())
|
||||||
}
|
}
|
||||||
r.GET("/api/oneterm/v1/share/connect/:uuid", Error2Resp(), c.ConnectShare)
|
r.GET("/api/oneterm/v1/share/connect/:uuid", Error2Resp(), c.ConnectShare)
|
||||||
|
|
||||||
|
authorization := v1.Group("/authorization")
|
||||||
|
{
|
||||||
|
authorization.POST("", c.CreateAuthorization)
|
||||||
|
authorization.DELETE("/:id", c.DeleteAccount)
|
||||||
|
authorization.PUT("/:id", c.UpdateAuthorization)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
srv.Addr = fmt.Sprintf("%s:%d", conf.Cfg.Http.Host, conf.Cfg.Http.Port)
|
srv.Addr = fmt.Sprintf("%s:%d", conf.Cfg.Http.Host, conf.Cfg.Http.Port)
|
||||||
|
@@ -145,23 +145,10 @@ func (c *Controller) GetAccounts(ctx *gin.Context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if info && !acl.IsAdmin(currentUser) {
|
if info && !acl.IsAdmin(currentUser) {
|
||||||
//rs := make([]*acl.Resource, 0)
|
ids, err := getAccountIdsByAuthorization(ctx)
|
||||||
rs, err := acl.GetRoleResources(ctx, currentUser.Acl.Rid, acl.GetResourceTypeName(conf.RESOURCE_AUTHORIZATION))
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
handleRemoteErr(ctx, err)
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
ids := make([]int, 0)
|
|
||||||
if err = mysql.DB.
|
|
||||||
Model(&model.Authorization{}).
|
|
||||||
Where("resource_id IN ?", lo.Map(rs, func(r *acl.Resource, _ int) int { return r.ResourceId })).
|
|
||||||
Distinct().
|
|
||||||
Pluck("account_id", &ids).
|
|
||||||
Error; err != nil {
|
|
||||||
ctx.AbortWithError(http.StatusInternalServerError, &ApiError{Code: ErrInternal, Data: map[string]any{"err": err}})
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
db = db.Where("id IN ?", ids)
|
db = db.Where("id IN ?", ids)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -169,3 +156,30 @@ func (c *Controller) GetAccounts(ctx *gin.Context) {
|
|||||||
|
|
||||||
doGet[*model.Account](ctx, !info, db, acl.GetResourceTypeName(conf.RESOURCE_ACCOUNT), accountPostHooks...)
|
doGet[*model.Account](ctx, !info, db, acl.GetResourceTypeName(conf.RESOURCE_ACCOUNT), accountPostHooks...)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func getAccountIdsByAuthorization(ctx *gin.Context) (ids []int, err error) {
|
||||||
|
assetIds, err := getAssertIdsByAuthorization(ctx)
|
||||||
|
if err != nil {
|
||||||
|
ctx.AbortWithError(http.StatusInternalServerError, &ApiError{Code: ErrInternal, Data: map[string]any{"err": err}})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
assets := make([]*model.Asset, 0)
|
||||||
|
if err = mysql.DB.Model(&model.Asset{}).Where("id IN ?", assetIds).Find(&assets).Error; err != nil {
|
||||||
|
ctx.AbortWithError(http.StatusInternalServerError, &ApiError{Code: ErrInternal, Data: map[string]any{"err": err}})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
authorizationIds, _ := ctx.Value("authorizationIds").([]*model.AuthorizationIds)
|
||||||
|
parentNodeIds, _ := ctx.Value("parentNodeIds").([]int)
|
||||||
|
for _, a := range assets {
|
||||||
|
if lo.Contains(parentNodeIds, a.Id) {
|
||||||
|
ids = append(ids, lo.Keys(a.Authorization)...)
|
||||||
|
}
|
||||||
|
accountIds := lo.Uniq(
|
||||||
|
lo.Map(lo.Filter(authorizationIds, func(item *model.AuthorizationIds, _ int) bool {
|
||||||
|
return item.AssetId != nil && *item.AssetId == a.Id && item.AccountId != nil
|
||||||
|
}),
|
||||||
|
func(item *model.AuthorizationIds, _ int) int { return *item.AccountId }))
|
||||||
|
ids = append(ids, accountIds...)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
@@ -101,25 +101,11 @@ func (c *Controller) GetAssets(ctx *gin.Context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if info && !acl.IsAdmin(currentUser) {
|
if info && !acl.IsAdmin(currentUser) {
|
||||||
//rs := make([]*acl.Resource, 0)
|
ids, err := getAssertIdsByAuthorization(ctx)
|
||||||
authorizationResourceIds, err := GetAutorizationResourceIds(ctx)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
handleRemoteErr(ctx, err)
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
ids := make([]*model.AuthorizationIds, 0)
|
db = db.Where("id IN ?", ids)
|
||||||
if err = mysql.DB.
|
|
||||||
Model(&model.Authorization{}).
|
|
||||||
Where("resource_id IN ?", authorizationResourceIds).
|
|
||||||
Find(&ids).
|
|
||||||
Error; err != nil {
|
|
||||||
ctx.AbortWithError(http.StatusInternalServerError, &ApiError{Code: ErrInternal, Data: map[string]any{"err": err}})
|
|
||||||
return
|
|
||||||
}
|
|
||||||
assetIds := lo.Uniq(lo.Map(ids, func(item *model.AuthorizationIds, _ int) int { return item.AssetId }))
|
|
||||||
db = db.Where("id IN ?", assetIds)
|
|
||||||
|
|
||||||
ctx.Set("authorizationIds", ids)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
db = db.Order("name")
|
db = db.Order("name")
|
||||||
@@ -161,10 +147,16 @@ func assetPostHookAuth(ctx *gin.Context, data []*model.Asset) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
authorizationIds, _ := ctx.Value("authorizationIds").([]*model.AuthorizationIds)
|
authorizationIds, _ := ctx.Value("authorizationIds").([]*model.AuthorizationIds)
|
||||||
|
parentNodeIds, _ := ctx.Value("parentNodeIds").([]int)
|
||||||
for _, a := range data {
|
for _, a := range data {
|
||||||
|
if lo.Contains(parentNodeIds, a.Id) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
accountIds := lo.Uniq(
|
accountIds := lo.Uniq(
|
||||||
lo.Map(lo.Filter(authorizationIds, func(item *model.AuthorizationIds, _ int) bool { return item.AssetId == a.Id }),
|
lo.Map(lo.Filter(authorizationIds, func(item *model.AuthorizationIds, _ int) bool {
|
||||||
func(item *model.AuthorizationIds, _ int) int { return item.AccountId }))
|
return item.AssetId != nil && *item.AssetId == a.Id && item.AccountId != nil
|
||||||
|
}),
|
||||||
|
func(item *model.AuthorizationIds, _ int) int { return *item.AccountId }))
|
||||||
for k := range a.Authorization {
|
for k := range a.Authorization {
|
||||||
if !lo.Contains(accountIds, k) {
|
if !lo.Contains(accountIds, k) {
|
||||||
delete(a.Authorization, k)
|
delete(a.Authorization, k)
|
||||||
@@ -193,3 +185,34 @@ func handleParentId(parentId int) (pids []int, err error) {
|
|||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func getAssertIdsByAuthorization(ctx *gin.Context) (ids []int, err error) {
|
||||||
|
authorizationResourceIds, err := getAutorizationResourceIds(ctx)
|
||||||
|
if err != nil {
|
||||||
|
handleRemoteErr(ctx, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
authIds := make([]*model.AuthorizationIds, 0)
|
||||||
|
if err = mysql.DB.Model(authIds).Where("resource_id IN ?", authorizationResourceIds).Find(&ids).Error; err != nil {
|
||||||
|
ctx.AbortWithError(http.StatusInternalServerError, &ApiError{Code: ErrInternal, Data: map[string]any{"err": err}})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
ctx.Set("authorizationIds", authIds)
|
||||||
|
|
||||||
|
parentNodeIds := make([]int, 0)
|
||||||
|
for _, a := range authIds {
|
||||||
|
if a.NodeId != nil {
|
||||||
|
parentNodeIds = append(parentNodeIds, *a.NodeId)
|
||||||
|
} else if a.AssetId != nil {
|
||||||
|
ids = append(ids, *a.AssetId)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ctx.Set("parentNodeIds", parentNodeIds)
|
||||||
|
tmp := make([]int, 0)
|
||||||
|
if err = mysql.DB.Model(&model.Asset{}).Where("parent_id IN?", parentNodeIds).Pluck("id", &tmp).Error; err != nil {
|
||||||
|
ctx.AbortWithError(http.StatusInternalServerError, &ApiError{Code: ErrInternal, Data: map[string]any{"err": err}})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
ids = append(ids, tmp...)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
@@ -1,15 +1,13 @@
|
|||||||
package controller
|
package controller
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"net/http"
|
||||||
"errors"
|
|
||||||
"fmt"
|
|
||||||
"reflect"
|
"reflect"
|
||||||
"sort"
|
"sort"
|
||||||
"sync"
|
|
||||||
|
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
"github.com/samber/lo"
|
"github.com/samber/lo"
|
||||||
|
"github.com/spf13/cast"
|
||||||
"go.uber.org/zap"
|
"go.uber.org/zap"
|
||||||
"golang.org/x/sync/errgroup"
|
"golang.org/x/sync/errgroup"
|
||||||
"gorm.io/gorm"
|
"gorm.io/gorm"
|
||||||
@@ -21,100 +19,84 @@ import (
|
|||||||
"github.com/veops/oneterm/model"
|
"github.com/veops/oneterm/model"
|
||||||
)
|
)
|
||||||
|
|
||||||
func HandleAuthorization(currentUser *acl.Session, tx *gorm.DB, action int, old, new *model.Asset) (err error) {
|
func getAuthsByAsset(t *model.Asset) (data []*model.Authorization, err error) {
|
||||||
ctx := context.Background()
|
db := mysql.DB.Model(data)
|
||||||
assetId := lo.TernaryF(new == nil, func() int { return old.Id }, func() int { return new.Id })
|
for accountId := range t.Authorization {
|
||||||
mtx := &sync.Mutex{}
|
db = db.Or("asset_id=? AND account_id=? AND node_id=NULL", t.Id, accountId)
|
||||||
|
}
|
||||||
|
err = db.Find(&data).Error
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func handleAuthorization(ctx *gin.Context, tx *gorm.DB, action int, asset *model.Asset, auths ...*model.Authorization) (err error) {
|
||||||
|
currentUser, _ := acl.GetSessionFromCtx(ctx)
|
||||||
|
|
||||||
eg := &errgroup.Group{}
|
eg := &errgroup.Group{}
|
||||||
|
|
||||||
|
if asset != nil {
|
||||||
if action == model.ACTION_UPDATE {
|
if action == model.ACTION_UPDATE {
|
||||||
if sameAuthorization(old.Authorization, new.Authorization) {
|
var pres []*model.Authorization
|
||||||
return
|
pres, err = getAuthsByAsset(asset)
|
||||||
}
|
|
||||||
for id := range old.Authorization {
|
|
||||||
if _, ok := new.Authorization[id]; ok {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
accountId := id
|
|
||||||
eg.Go(func() (err error) {
|
|
||||||
a := &model.Authorization{}
|
|
||||||
if err = mysql.DB.
|
|
||||||
Model(a).
|
|
||||||
Select("id", "resource_id").
|
|
||||||
Where("asset_id = ? AND account_id = ?", assetId, accountId).
|
|
||||||
First(a).
|
|
||||||
Error; err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if err = acl.DeleteResource(ctx, currentUser.GetUid(), a.ResourceId); err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
mtx.Lock()
|
|
||||||
defer mtx.Unlock()
|
|
||||||
err = tx.Delete(a, a.Id).Error
|
|
||||||
return
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
as := lo.TernaryF(action == model.ACTION_DELETE,
|
|
||||||
func() model.Map[int, model.Slice[int]] { return old.Authorization },
|
|
||||||
func() model.Map[int, model.Slice[int]] { return new.Authorization })
|
|
||||||
for k, v := range as {
|
|
||||||
accountId := k
|
|
||||||
curRids := lo.Uniq(v)
|
|
||||||
eg.Go(func() (err error) {
|
|
||||||
resourceId := 0
|
|
||||||
if err = mysql.DB.
|
|
||||||
Model(&model.Authorization{}).
|
|
||||||
Select("resource_id").
|
|
||||||
Where("asset_id = ? AND account_id = ?", assetId, accountId).
|
|
||||||
First(&resourceId).
|
|
||||||
Error; err != nil {
|
|
||||||
notFount := errors.Is(err, gorm.ErrRecordNotFound)
|
|
||||||
if !notFount || (notFount && action == model.ACTION_DELETE) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if resourceId, err = acl.CreateGrantAcl(ctx, currentUser, conf.GetResourceTypeName(conf.RESOURCE_AUTHORIZATION),
|
|
||||||
fmt.Sprintf("%d-%d", assetId, accountId)); err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
mtx.Lock()
|
|
||||||
if err = tx.Create(&model.Authorization{AssetId: assetId, AccountId: accountId, ResourceId: resourceId,
|
|
||||||
CreatorId: currentUser.GetUid(), UpdaterId: currentUser.GetUid()}).Error; err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
mtx.Unlock()
|
|
||||||
}
|
|
||||||
switch action {
|
|
||||||
case model.ACTION_CREATE:
|
|
||||||
err = acl.BatchGrantRoleResource(ctx, currentUser.GetUid(), curRids, resourceId, []string{acl.READ})
|
|
||||||
case model.ACTION_DELETE:
|
|
||||||
err = acl.DeleteResource(ctx, currentUser.GetUid(), resourceId)
|
|
||||||
case model.ACTION_UPDATE:
|
|
||||||
var res map[string]*acl.ResourcePermissionsRespItem
|
|
||||||
res, err = acl.GetResourcePermissions(ctx, resourceId)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
perms := make([]*acl.Perm, 0)
|
for _, p := range pres {
|
||||||
for _, v := range res {
|
if _, ok := asset.Authorization[*p.AccountId]; ok {
|
||||||
perms = append(perms, v.Perms...)
|
auths = append(auths, p)
|
||||||
|
} else {
|
||||||
|
eg.Go(func() error {
|
||||||
|
return acl.DeleteResource(ctx, currentUser.GetUid(), p.ResourceId)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
preRids := lo.Map(lo.Filter(perms, func(p *acl.Perm, _ int) bool { return p.Name == acl.READ }), func(p *acl.Perm, _ int) int { return p.Rid })
|
}
|
||||||
revokeRids := lo.Without(preRids, curRids...)
|
} else {
|
||||||
|
auths = lo.Map(lo.Keys(asset.Authorization), func(id int, _ int) *model.Authorization {
|
||||||
|
return &model.Authorization{AssetId: &asset.Id, AccountId: &id, Rids: asset.Authorization[id]}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, auth := range lo.Filter(auths, func(item *model.Authorization, _ int) bool { return item != nil }) {
|
||||||
|
switch action {
|
||||||
|
case model.ACTION_CREATE:
|
||||||
|
eg.Go(func() (err error) {
|
||||||
|
resourceId := 0
|
||||||
|
if resourceId, err = acl.CreateGrantAcl(ctx, currentUser, conf.GetResourceTypeName(conf.RESOURCE_AUTHORIZATION), auth.GetName()); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if err = acl.BatchGrantRoleResource(ctx, currentUser.GetUid(), auth.Rids, resourceId, []string{acl.READ}); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
auth.CreatorId = currentUser.GetUid()
|
||||||
|
auth.UpdaterId = currentUser.GetUid()
|
||||||
|
auth.ResourceId = resourceId
|
||||||
|
return tx.Create(auth).Error
|
||||||
|
})
|
||||||
|
case model.ACTION_DELETE:
|
||||||
|
eg.Go(func() (err error) {
|
||||||
|
return acl.DeleteResource(ctx, currentUser.GetUid(), auth.ResourceId)
|
||||||
|
})
|
||||||
|
case model.ACTION_UPDATE:
|
||||||
|
eg.Go(func() (err error) {
|
||||||
|
pre := &model.Authorization{}
|
||||||
|
if err = mysql.DB.First(pre, auth.GetId()).Error; err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
revokeRids := lo.Without(pre.Rids, auth.Rids...)
|
||||||
if len(revokeRids) > 0 {
|
if len(revokeRids) > 0 {
|
||||||
if err = acl.BatchRevokeRoleResource(ctx, currentUser.GetUid(), revokeRids, resourceId, []string{acl.READ}); err != nil {
|
if err = acl.BatchRevokeRoleResource(ctx, currentUser.GetUid(), revokeRids, auth.ResourceId, []string{acl.READ}); err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
grantRids := lo.Without(curRids, preRids...)
|
grantRids := lo.Without(auth.Rids, pre.Rids...)
|
||||||
if len(grantRids) > 0 {
|
if len(grantRids) > 0 {
|
||||||
err = acl.BatchGrantRoleResource(ctx, currentUser.GetUid(), grantRids, resourceId, []string{acl.READ})
|
err = acl.BatchGrantRoleResource(ctx, currentUser.GetUid(), grantRids, auth.ResourceId, []string{acl.READ})
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
err = eg.Wait()
|
err = eg.Wait()
|
||||||
|
|
||||||
@@ -142,7 +124,7 @@ func sameAuthorization(old, new model.Map[int, model.Slice[int]]) bool {
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetAutorizationResourceIds(ctx *gin.Context) (resourceIds []int, err error) {
|
func getAutorizationResourceIds(ctx *gin.Context) (resourceIds []int, err error) {
|
||||||
currentUser, _ := acl.GetSessionFromCtx(ctx)
|
currentUser, _ := acl.GetSessionFromCtx(ctx)
|
||||||
var rs []*acl.Resource
|
var rs []*acl.Resource
|
||||||
rs, err = acl.GetRoleResources(ctx, currentUser.Acl.Rid, conf.RESOURCE_AUTHORIZATION)
|
rs, err = acl.GetRoleResources(ctx, currentUser.Acl.Rid, conf.RESOURCE_AUTHORIZATION)
|
||||||
@@ -154,8 +136,11 @@ func GetAutorizationResourceIds(ctx *gin.Context) (resourceIds []int, err error)
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func HasAuthorization(ctx *gin.Context, assetId, accountId int) (ok bool) {
|
func hasAuthorization(ctx *gin.Context, assetId, accountId int) (ok bool) {
|
||||||
ids, err := GetAutorizationResourceIds(ctx)
|
if cast.ToString(ctx.Value("shareId")) != "" {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
ids, err := getAutorizationResourceIds(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.L().Error("", zap.Error(err))
|
logger.L().Error("", zap.Error(err))
|
||||||
return
|
return
|
||||||
@@ -171,3 +156,74 @@ func HasAuthorization(ctx *gin.Context, assetId, accountId int) (ok bool) {
|
|||||||
|
|
||||||
return cnt > 0
|
return cnt > 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// CreateAccount godoc
|
||||||
|
//
|
||||||
|
// @Tags authorization
|
||||||
|
// @Param authorization body model.Authorization true "authorization"
|
||||||
|
// @Success 200 {object} HttpResponse
|
||||||
|
// @Router /authorization [post]
|
||||||
|
func (c *Controller) CreateAuthorization(ctx *gin.Context) {
|
||||||
|
auth := &model.Authorization{}
|
||||||
|
err := ctx.ShouldBindBodyWithJSON(auth)
|
||||||
|
if err != nil {
|
||||||
|
ctx.AbortWithError(http.StatusBadRequest, &ApiError{Code: ErrInvalidArgument, Data: map[string]any{"err": err}})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if err := handleAuthorization(ctx, mysql.DB, model.ACTION_CREATE, nil, auth); err != nil {
|
||||||
|
ctx.AbortWithError(http.StatusInternalServerError, &ApiError{Code: ErrInternal, Data: map[string]any{"err": err}})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
ctx.JSON(http.StatusOK, HttpResponse{
|
||||||
|
Data: map[string]any{
|
||||||
|
"id": auth.GetId(),
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeleteAccount godoc
|
||||||
|
//
|
||||||
|
// @Tags authorization
|
||||||
|
// @Param id path int true "authorization id"
|
||||||
|
// @Success 200 {object} HttpResponse
|
||||||
|
// @Router /authorization/:id [delete]
|
||||||
|
func (c *Controller) DeleteAuthorization(ctx *gin.Context) {
|
||||||
|
auth := &model.Authorization{
|
||||||
|
Id: cast.ToInt(ctx.Param("id")),
|
||||||
|
}
|
||||||
|
if err := handleAuthorization(ctx, mysql.DB, model.ACTION_DELETE, nil, auth); err != nil {
|
||||||
|
ctx.AbortWithError(http.StatusInternalServerError, &ApiError{Code: ErrInternal, Data: map[string]any{"err": err}})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
ctx.JSON(http.StatusOK, HttpResponse{
|
||||||
|
Data: map[string]any{
|
||||||
|
"id": auth.GetId(),
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// UpdateAccount godoc
|
||||||
|
//
|
||||||
|
// @Tags authorization
|
||||||
|
// @Param id path int true "authorization id"
|
||||||
|
// @Param authorization body model.Authorization true "authorization"
|
||||||
|
// @Success 200 {object} HttpResponse
|
||||||
|
// @Router /authorization/:id [put]
|
||||||
|
func (c *Controller) UpdateAuthorization(ctx *gin.Context) {
|
||||||
|
auth := &model.Authorization{}
|
||||||
|
err := ctx.ShouldBindBodyWithJSON(auth)
|
||||||
|
if err != nil {
|
||||||
|
ctx.AbortWithError(http.StatusBadRequest, &ApiError{Code: ErrInvalidArgument, Data: map[string]any{"err": err}})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
auth.Id = cast.ToInt(ctx.Param("id"))
|
||||||
|
if err := handleAuthorization(ctx, mysql.DB, model.ACTION_UPDATE, nil, auth); err != nil {
|
||||||
|
ctx.AbortWithError(http.StatusInternalServerError, &ApiError{Code: ErrInternal, Data: map[string]any{"err": err}})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
ctx.JSON(http.StatusOK, HttpResponse{
|
||||||
|
Data: map[string]any{
|
||||||
|
"id": auth.GetId(),
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
@@ -255,10 +255,13 @@ func DoConnect(ctx *gin.Context, ws *websocket.Conn) (sess *gsession.Session, er
|
|||||||
currentUser, _ := acl.GetSessionFromCtx(ctx)
|
currentUser, _ := acl.GetSessionFromCtx(ctx)
|
||||||
|
|
||||||
assetId, accountId := cast.ToInt(ctx.Param("asset_id")), cast.ToInt(ctx.Param("account_id"))
|
assetId, accountId := cast.ToInt(ctx.Param("asset_id")), cast.ToInt(ctx.Param("account_id"))
|
||||||
|
fmt.Println("--------------------------------------", assetId, accountId)
|
||||||
asset, account, gateway, err := util.GetAAG(assetId, accountId)
|
asset, account, gateway, err := util.GetAAG(assetId, accountId)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
fmt.Println("--------------------------------------", *asset)
|
||||||
|
fmt.Println("--------------------------------------", *account)
|
||||||
|
|
||||||
sess = gsession.NewSession(ctx)
|
sess = gsession.NewSession(ctx)
|
||||||
sess.Ws = ws
|
sess.Ws = ws
|
||||||
@@ -277,6 +280,8 @@ func DoConnect(ctx *gin.Context, ws *websocket.Conn) (sess *gsession.Session, er
|
|||||||
Status: model.SESSIONSTATUS_ONLINE,
|
Status: model.SESSIONSTATUS_ONLINE,
|
||||||
ShareId: cast.ToInt(ctx.Value("shareId")),
|
ShareId: cast.ToInt(ctx.Value("shareId")),
|
||||||
}
|
}
|
||||||
|
fmt.Printf("==============%+v\n", *sess)
|
||||||
|
fmt.Printf("==============%+v\n", *sess.Session)
|
||||||
if sess.IsSsh() {
|
if sess.IsSsh() {
|
||||||
w, h := cast.ToInt(ctx.Query("w")), cast.ToInt(ctx.Query("h"))
|
w, h := cast.ToInt(ctx.Query("w")), cast.ToInt(ctx.Query("h"))
|
||||||
sess.SshParser = gsession.NewParser(sess.SessionId, w, h)
|
sess.SshParser = gsession.NewParser(sess.SessionId, w, h)
|
||||||
@@ -304,14 +309,16 @@ func DoConnect(ctx *gin.Context, ws *websocket.Conn) (sess *gsession.Session, er
|
|||||||
ctx.AbortWithError(http.StatusBadRequest, err)
|
ctx.AbortWithError(http.StatusBadRequest, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if !acl.IsAdmin(currentUser) && !HasAuthorization(ctx, assetId, accountId) {
|
if !acl.IsAdmin(currentUser) && !hasAuthorization(ctx, assetId, accountId) {
|
||||||
err = &ApiError{Code: ErrUnauthorized}
|
err = &ApiError{Code: ErrUnauthorized}
|
||||||
ctx.AbortWithError(http.StatusForbidden, err)
|
ctx.AbortWithError(http.StatusForbidden, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
switch strings.Split(sess.Protocol, ":")[0] {
|
switch strings.Split(sess.Protocol, ":")[0] {
|
||||||
case "ssh":
|
case "ssh":
|
||||||
|
fmt.Println("-----------------------------------------------fuckkkkkkkkkkkkkkkkkkkkkkkkkkk")
|
||||||
go connectSsh(ctx, sess, asset, account, gateway)
|
go connectSsh(ctx, sess, asset, account, gateway)
|
||||||
case "vnc", "rdp":
|
case "vnc", "rdp":
|
||||||
go connectGuacd(ctx, sess, asset, account, gateway)
|
go connectGuacd(ctx, sess, asset, account, gateway)
|
||||||
|
@@ -99,7 +99,7 @@ func doCreate[T model.Model](ctx *gin.Context, needAcl bool, md T, resourceType
|
|||||||
|
|
||||||
switch t := any(md).(type) {
|
switch t := any(md).(type) {
|
||||||
case *model.Asset:
|
case *model.Asset:
|
||||||
if err = HandleAuthorization(currentUser, tx, model.ACTION_CREATE, nil, t); err != nil {
|
if err = handleAuthorization(ctx, tx, model.ACTION_CREATE, t, nil); err != nil {
|
||||||
handleRemoteErr(ctx, err)
|
handleRemoteErr(ctx, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -178,7 +178,7 @@ func doDelete[T model.Model](ctx *gin.Context, needAcl bool, md T, dcs ...delete
|
|||||||
if err = mysql.DB.Transaction(func(tx *gorm.DB) (err error) {
|
if err = mysql.DB.Transaction(func(tx *gorm.DB) (err error) {
|
||||||
switch t := any(md).(type) {
|
switch t := any(md).(type) {
|
||||||
case *model.Asset:
|
case *model.Asset:
|
||||||
if err = HandleAuthorization(currentUser, tx, model.ACTION_DELETE, t, nil); err != nil {
|
if err = handleAuthorization(ctx, tx, model.ACTION_DELETE, t, nil, nil); err != nil {
|
||||||
handleRemoteErr(ctx, err)
|
handleRemoteErr(ctx, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -268,7 +268,7 @@ func doUpdate[T model.Model](ctx *gin.Context, needAcl bool, md T, preHooks ...p
|
|||||||
selects := []string{"*"}
|
selects := []string{"*"}
|
||||||
switch t := any(md).(type) {
|
switch t := any(md).(type) {
|
||||||
case *model.Asset:
|
case *model.Asset:
|
||||||
if err = HandleAuthorization(currentUser, tx, model.ACTION_UPDATE, any(old).(*model.Asset), t); err != nil {
|
if err = handleAuthorization(ctx, tx, model.ACTION_UPDATE, t, nil); err != nil {
|
||||||
handleRemoteErr(ctx, err)
|
handleRemoteErr(ctx, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@@ -61,7 +61,7 @@ func (c *Controller) GetFileHistory(ctx *gin.Context) {
|
|||||||
// @Router /file/ls/:asset_id/:account_id [post]
|
// @Router /file/ls/:asset_id/:account_id [post]
|
||||||
func (c *Controller) FileLS(ctx *gin.Context) {
|
func (c *Controller) FileLS(ctx *gin.Context) {
|
||||||
currentUser, _ := acl.GetSessionFromCtx(ctx)
|
currentUser, _ := acl.GetSessionFromCtx(ctx)
|
||||||
if !acl.IsAdmin(currentUser) && !HasAuthorization(ctx, cast.ToInt(ctx.Param("account_id")), cast.ToInt(ctx.Param("account_id"))) {
|
if !acl.IsAdmin(currentUser) && !hasAuthorization(ctx, cast.ToInt(ctx.Param("account_id")), cast.ToInt(ctx.Param("account_id"))) {
|
||||||
ctx.AbortWithError(http.StatusForbidden, &ApiError{Code: ErrNoPerm, Data: map[string]any{}})
|
ctx.AbortWithError(http.StatusForbidden, &ApiError{Code: ErrNoPerm, Data: map[string]any{}})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -101,7 +101,7 @@ func (c *Controller) FileLS(ctx *gin.Context) {
|
|||||||
// @Router /file/mkdir/:asset_id/:account_id [post]
|
// @Router /file/mkdir/:asset_id/:account_id [post]
|
||||||
func (c *Controller) FileMkdir(ctx *gin.Context) {
|
func (c *Controller) FileMkdir(ctx *gin.Context) {
|
||||||
currentUser, _ := acl.GetSessionFromCtx(ctx)
|
currentUser, _ := acl.GetSessionFromCtx(ctx)
|
||||||
if !acl.IsAdmin(currentUser) && !HasAuthorization(ctx, cast.ToInt(ctx.Param("account_id")), cast.ToInt(ctx.Param("account_id"))) {
|
if !acl.IsAdmin(currentUser) && !hasAuthorization(ctx, cast.ToInt(ctx.Param("account_id")), cast.ToInt(ctx.Param("account_id"))) {
|
||||||
ctx.AbortWithError(http.StatusForbidden, &ApiError{Code: ErrNoPerm, Data: map[string]any{}})
|
ctx.AbortWithError(http.StatusForbidden, &ApiError{Code: ErrNoPerm, Data: map[string]any{}})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -141,7 +141,7 @@ func (c *Controller) FileMkdir(ctx *gin.Context) {
|
|||||||
// @Router /file/upload/:asset_id/:account_id [post]
|
// @Router /file/upload/:asset_id/:account_id [post]
|
||||||
func (c *Controller) FileUpload(ctx *gin.Context) {
|
func (c *Controller) FileUpload(ctx *gin.Context) {
|
||||||
currentUser, _ := acl.GetSessionFromCtx(ctx)
|
currentUser, _ := acl.GetSessionFromCtx(ctx)
|
||||||
if !acl.IsAdmin(currentUser) && !HasAuthorization(ctx, cast.ToInt(ctx.Param("account_id")), cast.ToInt(ctx.Param("account_id"))) {
|
if !acl.IsAdmin(currentUser) && !hasAuthorization(ctx, cast.ToInt(ctx.Param("account_id")), cast.ToInt(ctx.Param("account_id"))) {
|
||||||
ctx.AbortWithError(http.StatusForbidden, &ApiError{Code: ErrNoPerm, Data: map[string]any{}})
|
ctx.AbortWithError(http.StatusForbidden, &ApiError{Code: ErrNoPerm, Data: map[string]any{}})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -202,7 +202,7 @@ func (c *Controller) FileUpload(ctx *gin.Context) {
|
|||||||
// @Router /file/download/:asset_id/:account_id [get]
|
// @Router /file/download/:asset_id/:account_id [get]
|
||||||
func (c *Controller) FileDownload(ctx *gin.Context) {
|
func (c *Controller) FileDownload(ctx *gin.Context) {
|
||||||
currentUser, _ := acl.GetSessionFromCtx(ctx)
|
currentUser, _ := acl.GetSessionFromCtx(ctx)
|
||||||
if !acl.IsAdmin(currentUser) && !HasAuthorization(ctx, cast.ToInt(ctx.Param("account_id")), cast.ToInt(ctx.Param("account_id"))) {
|
if !acl.IsAdmin(currentUser) && !hasAuthorization(ctx, cast.ToInt(ctx.Param("account_id")), cast.ToInt(ctx.Param("account_id"))) {
|
||||||
ctx.AbortWithError(http.StatusForbidden, &ApiError{Code: ErrNoPerm, Data: map[string]any{}})
|
ctx.AbortWithError(http.StatusForbidden, &ApiError{Code: ErrNoPerm, Data: map[string]any{}})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@@ -124,7 +124,7 @@ func nodePostHookCountAsset(ctx *gin.Context, data []*model.Node) {
|
|||||||
assets := make([]*model.AssetIdPid, 0)
|
assets := make([]*model.AssetIdPid, 0)
|
||||||
db := mysql.DB.Model(&model.Asset{})
|
db := mysql.DB.Model(&model.Asset{})
|
||||||
if !isAdmin {
|
if !isAdmin {
|
||||||
authorizationResourceIds, err := GetAutorizationResourceIds(ctx)
|
authorizationResourceIds, err := getAutorizationResourceIds(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ctx.AbortWithError(http.StatusInternalServerError, err)
|
ctx.AbortWithError(http.StatusInternalServerError, err)
|
||||||
return
|
return
|
||||||
@@ -243,3 +243,26 @@ func handleSelfParent(id int) (ids []int, err error) {
|
|||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func handleSelfChild(ins []int) (ids []int, err error) {
|
||||||
|
nodes := make([]*model.NodeIdPid, 0)
|
||||||
|
if err = mysql.DB.Model(&model.Node{}).Find(&nodes).Error; err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
g := make(map[int][]int)
|
||||||
|
for _, n := range nodes {
|
||||||
|
g[n.ParentId] = append(g[n.ParentId], n.Id)
|
||||||
|
}
|
||||||
|
var dfs func(int, bool)
|
||||||
|
dfs = func(x int, b bool) {
|
||||||
|
if b {
|
||||||
|
ids = append(ids, x)
|
||||||
|
}
|
||||||
|
for _, y := range g[x] {
|
||||||
|
dfs(y, b || lo.Contains(ins, x))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dfs(0, false)
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
@@ -18,11 +18,12 @@ import (
|
|||||||
// CreateShare godoc
|
// CreateShare godoc
|
||||||
//
|
//
|
||||||
// @Tags share
|
// @Tags share
|
||||||
// @Param share body model.Share true "share"
|
// @Param share body []model.Share true "share"
|
||||||
// @Success 200 {object} HttpResponse{data=ListData{list=[]string}}
|
// @Success 200 {object} HttpResponse{data=ListData{list=[]string}}
|
||||||
// @Router /share [post]
|
// @Router /share [post]
|
||||||
func (c *Controller) CreateShare(ctx *gin.Context) {
|
func (c *Controller) CreateShare(ctx *gin.Context) {
|
||||||
shares := make([]*model.Share, 0)
|
shares := make([]*model.Share, 0)
|
||||||
|
|
||||||
if err := ctx.ShouldBindBodyWithJSON(&shares); err != nil {
|
if err := ctx.ShouldBindBodyWithJSON(&shares); err != nil {
|
||||||
ctx.AbortWithError(http.StatusBadRequest, &ApiError{Code: ErrInvalidArgument, Data: map[string]any{"err": err}})
|
ctx.AbortWithError(http.StatusBadRequest, &ApiError{Code: ErrInvalidArgument, Data: map[string]any{"err": err}})
|
||||||
return
|
return
|
||||||
@@ -31,14 +32,14 @@ func (c *Controller) CreateShare(ctx *gin.Context) {
|
|||||||
s.Uuid = uuid.New().String()
|
s.Uuid = uuid.New().String()
|
||||||
return s.Uuid
|
return s.Uuid
|
||||||
})
|
})
|
||||||
if err := mysql.DB.Create(shares); err != nil {
|
if err := mysql.DB.Create(&shares).Error; err != nil {
|
||||||
ctx.AbortWithError(http.StatusInternalServerError, &ApiError{Code: ErrInternal, Data: map[string]any{"err": err}})
|
ctx.AbortWithError(http.StatusInternalServerError, &ApiError{Code: ErrInternal, Data: map[string]any{"err": err}})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
ctx.JSON(http.StatusOK, toListData(uuids))
|
ctx.JSON(http.StatusOK, toListData(uuids))
|
||||||
}
|
}
|
||||||
|
|
||||||
// DeleteAsset godoc
|
// DeleteShare godoc
|
||||||
//
|
//
|
||||||
// @Tags share
|
// @Tags share
|
||||||
// @Param id path int true "share id"
|
// @Param id path int true "share id"
|
||||||
@@ -48,7 +49,7 @@ func (c *Controller) DeleteShare(ctx *gin.Context) {
|
|||||||
doDelete(ctx, false, &model.Share{})
|
doDelete(ctx, false, &model.Share{})
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetAssets godoc
|
// GetShare godoc
|
||||||
//
|
//
|
||||||
// @Tags share
|
// @Tags share
|
||||||
// @Param page_index query int true "page_index"
|
// @Param page_index query int true "page_index"
|
||||||
@@ -72,9 +73,9 @@ func (c *Controller) GetShare(ctx *gin.Context) {
|
|||||||
doGet[*model.Share](ctx, false, db, "")
|
doGet[*model.Share](ctx, false, db, "")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Connect godoc
|
// ConnectShare godoc
|
||||||
//
|
//
|
||||||
// @Tags connect
|
// @Tags share
|
||||||
// @Success 200 {object} HttpResponse
|
// @Success 200 {object} HttpResponse
|
||||||
// @Param w query int false "width"
|
// @Param w query int false "width"
|
||||||
// @Param h query int false "height"
|
// @Param h query int false "height"
|
||||||
|
@@ -223,7 +223,7 @@ func (c *Controller) StatCountOfUser(ctx *gin.Context) {
|
|||||||
isAdmin := acl.IsAdmin(currentUser)
|
isAdmin := acl.IsAdmin(currentUser)
|
||||||
db := mysql.DB.Model(&model.Asset{})
|
db := mysql.DB.Model(&model.Asset{})
|
||||||
if !isAdmin {
|
if !isAdmin {
|
||||||
authorizationResourceIds, err := GetAutorizationResourceIds(ctx)
|
authorizationResourceIds, err := getAutorizationResourceIds(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@@ -2,6 +2,7 @@ package mysql
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
|
||||||
"go.uber.org/zap"
|
"go.uber.org/zap"
|
||||||
"gorm.io/driver/mysql"
|
"gorm.io/driver/mysql"
|
||||||
@@ -35,4 +36,8 @@ func init() {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
logger.L().Fatal("auto migrate mysql failed", zap.Error(err))
|
logger.L().Fatal("auto migrate mysql failed", zap.Error(err))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if err = DB.Migrator().DropIndex(&model.Authorization{}, "asset_account_id_del"); err != nil && !strings.Contains(err.Error(), "1091") {
|
||||||
|
logger.L().Fatal("drop index failed", zap.Error(err))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
// Package docs Code generated by swaggo/swag at 2024-09-11 13:36:52.1950431 +0800 CST m=+7.950178801. DO NOT EDIT
|
// Package docs Code generated by swaggo/swag at 2024-09-19 17:52:48.7357174 +0800 CST m=+7.810953701. DO NOT EDIT
|
||||||
package docs
|
package docs
|
||||||
|
|
||||||
import "github.com/swaggo/swag"
|
import "github.com/swaggo/swag"
|
||||||
@@ -367,6 +367,87 @@ const docTemplate = `{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"/authorization": {
|
||||||
|
"post": {
|
||||||
|
"tags": [
|
||||||
|
"authorization"
|
||||||
|
],
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"description": "authorization",
|
||||||
|
"name": "authorization",
|
||||||
|
"in": "body",
|
||||||
|
"required": true,
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/model.Authorization"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "OK",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/controller.HttpResponse"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"/authorization/:id": {
|
||||||
|
"put": {
|
||||||
|
"tags": [
|
||||||
|
"authorization"
|
||||||
|
],
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"type": "integer",
|
||||||
|
"description": "authorization id",
|
||||||
|
"name": "id",
|
||||||
|
"in": "path",
|
||||||
|
"required": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "authorization",
|
||||||
|
"name": "authorization",
|
||||||
|
"in": "body",
|
||||||
|
"required": true,
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/model.Authorization"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "OK",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/controller.HttpResponse"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"delete": {
|
||||||
|
"tags": [
|
||||||
|
"authorization"
|
||||||
|
],
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"type": "integer",
|
||||||
|
"description": "authorization id",
|
||||||
|
"name": "id",
|
||||||
|
"in": "path",
|
||||||
|
"required": true
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "OK",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/controller.HttpResponse"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"/command": {
|
"/command": {
|
||||||
"get": {
|
"get": {
|
||||||
"tags": [
|
"tags": [
|
||||||
@@ -1995,9 +2076,12 @@ const docTemplate = `{
|
|||||||
"in": "body",
|
"in": "body",
|
||||||
"required": true,
|
"required": true,
|
||||||
"schema": {
|
"schema": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
"$ref": "#/definitions/model.Share"
|
"$ref": "#/definitions/model.Share"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
],
|
],
|
||||||
"responses": {
|
"responses": {
|
||||||
"200": {
|
"200": {
|
||||||
@@ -2063,7 +2147,7 @@ const docTemplate = `{
|
|||||||
"/share/connect/:uuid": {
|
"/share/connect/:uuid": {
|
||||||
"get": {
|
"get": {
|
||||||
"tags": [
|
"tags": [
|
||||||
"connect"
|
"share"
|
||||||
],
|
],
|
||||||
"parameters": [
|
"parameters": [
|
||||||
{
|
{
|
||||||
@@ -2497,14 +2581,49 @@ const docTemplate = `{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"model.Authorization": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"account_id": {
|
||||||
|
"type": "integer"
|
||||||
|
},
|
||||||
|
"asset_id": {
|
||||||
|
"type": "integer"
|
||||||
|
},
|
||||||
|
"created_at": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"creator_id": {
|
||||||
|
"type": "integer"
|
||||||
|
},
|
||||||
|
"id": {
|
||||||
|
"type": "integer"
|
||||||
|
},
|
||||||
|
"node_id": {
|
||||||
|
"type": "integer"
|
||||||
|
},
|
||||||
|
"resource_id": {
|
||||||
|
"type": "integer"
|
||||||
|
},
|
||||||
|
"rids": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"type": "integer"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"updated_at": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"updater_id": {
|
||||||
|
"type": "integer"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"model.Command": {
|
"model.Command": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
"cmds": {
|
"cmd": {
|
||||||
"type": "array",
|
|
||||||
"items": {
|
|
||||||
"type": "string"
|
"type": "string"
|
||||||
}
|
|
||||||
},
|
},
|
||||||
"created_at": {
|
"created_at": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
@@ -2518,6 +2637,9 @@ const docTemplate = `{
|
|||||||
"id": {
|
"id": {
|
||||||
"type": "integer"
|
"type": "integer"
|
||||||
},
|
},
|
||||||
|
"is_re": {
|
||||||
|
"type": "boolean"
|
||||||
|
},
|
||||||
"name": {
|
"name": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
|
@@ -356,6 +356,87 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"/authorization": {
|
||||||
|
"post": {
|
||||||
|
"tags": [
|
||||||
|
"authorization"
|
||||||
|
],
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"description": "authorization",
|
||||||
|
"name": "authorization",
|
||||||
|
"in": "body",
|
||||||
|
"required": true,
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/model.Authorization"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "OK",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/controller.HttpResponse"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"/authorization/:id": {
|
||||||
|
"put": {
|
||||||
|
"tags": [
|
||||||
|
"authorization"
|
||||||
|
],
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"type": "integer",
|
||||||
|
"description": "authorization id",
|
||||||
|
"name": "id",
|
||||||
|
"in": "path",
|
||||||
|
"required": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "authorization",
|
||||||
|
"name": "authorization",
|
||||||
|
"in": "body",
|
||||||
|
"required": true,
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/model.Authorization"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "OK",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/controller.HttpResponse"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"delete": {
|
||||||
|
"tags": [
|
||||||
|
"authorization"
|
||||||
|
],
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"type": "integer",
|
||||||
|
"description": "authorization id",
|
||||||
|
"name": "id",
|
||||||
|
"in": "path",
|
||||||
|
"required": true
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "OK",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/controller.HttpResponse"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"/command": {
|
"/command": {
|
||||||
"get": {
|
"get": {
|
||||||
"tags": [
|
"tags": [
|
||||||
@@ -1984,9 +2065,12 @@
|
|||||||
"in": "body",
|
"in": "body",
|
||||||
"required": true,
|
"required": true,
|
||||||
"schema": {
|
"schema": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
"$ref": "#/definitions/model.Share"
|
"$ref": "#/definitions/model.Share"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
],
|
],
|
||||||
"responses": {
|
"responses": {
|
||||||
"200": {
|
"200": {
|
||||||
@@ -2052,7 +2136,7 @@
|
|||||||
"/share/connect/:uuid": {
|
"/share/connect/:uuid": {
|
||||||
"get": {
|
"get": {
|
||||||
"tags": [
|
"tags": [
|
||||||
"connect"
|
"share"
|
||||||
],
|
],
|
||||||
"parameters": [
|
"parameters": [
|
||||||
{
|
{
|
||||||
@@ -2486,14 +2570,49 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"model.Authorization": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"account_id": {
|
||||||
|
"type": "integer"
|
||||||
|
},
|
||||||
|
"asset_id": {
|
||||||
|
"type": "integer"
|
||||||
|
},
|
||||||
|
"created_at": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"creator_id": {
|
||||||
|
"type": "integer"
|
||||||
|
},
|
||||||
|
"id": {
|
||||||
|
"type": "integer"
|
||||||
|
},
|
||||||
|
"node_id": {
|
||||||
|
"type": "integer"
|
||||||
|
},
|
||||||
|
"resource_id": {
|
||||||
|
"type": "integer"
|
||||||
|
},
|
||||||
|
"rids": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"type": "integer"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"updated_at": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"updater_id": {
|
||||||
|
"type": "integer"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"model.Command": {
|
"model.Command": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
"cmds": {
|
"cmd": {
|
||||||
"type": "array",
|
|
||||||
"items": {
|
|
||||||
"type": "string"
|
"type": "string"
|
||||||
}
|
|
||||||
},
|
},
|
||||||
"created_at": {
|
"created_at": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
@@ -2507,6 +2626,9 @@
|
|||||||
"id": {
|
"id": {
|
||||||
"type": "integer"
|
"type": "integer"
|
||||||
},
|
},
|
||||||
|
"is_re": {
|
||||||
|
"type": "boolean"
|
||||||
|
},
|
||||||
"name": {
|
"name": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
|
@@ -98,12 +98,35 @@ definitions:
|
|||||||
updater_id:
|
updater_id:
|
||||||
type: integer
|
type: integer
|
||||||
type: object
|
type: object
|
||||||
|
model.Authorization:
|
||||||
|
properties:
|
||||||
|
account_id:
|
||||||
|
type: integer
|
||||||
|
asset_id:
|
||||||
|
type: integer
|
||||||
|
created_at:
|
||||||
|
type: string
|
||||||
|
creator_id:
|
||||||
|
type: integer
|
||||||
|
id:
|
||||||
|
type: integer
|
||||||
|
node_id:
|
||||||
|
type: integer
|
||||||
|
resource_id:
|
||||||
|
type: integer
|
||||||
|
rids:
|
||||||
|
items:
|
||||||
|
type: integer
|
||||||
|
type: array
|
||||||
|
updated_at:
|
||||||
|
type: string
|
||||||
|
updater_id:
|
||||||
|
type: integer
|
||||||
|
type: object
|
||||||
model.Command:
|
model.Command:
|
||||||
properties:
|
properties:
|
||||||
cmds:
|
cmd:
|
||||||
items:
|
|
||||||
type: string
|
type: string
|
||||||
type: array
|
|
||||||
created_at:
|
created_at:
|
||||||
type: string
|
type: string
|
||||||
creator_id:
|
creator_id:
|
||||||
@@ -112,6 +135,8 @@ definitions:
|
|||||||
type: boolean
|
type: boolean
|
||||||
id:
|
id:
|
||||||
type: integer
|
type: integer
|
||||||
|
is_re:
|
||||||
|
type: boolean
|
||||||
name:
|
name:
|
||||||
type: string
|
type: string
|
||||||
resource_id:
|
resource_id:
|
||||||
@@ -662,6 +687,57 @@ paths:
|
|||||||
$ref: '#/definitions/controller.HttpResponse'
|
$ref: '#/definitions/controller.HttpResponse'
|
||||||
tags:
|
tags:
|
||||||
- asset
|
- asset
|
||||||
|
/authorization:
|
||||||
|
post:
|
||||||
|
parameters:
|
||||||
|
- description: authorization
|
||||||
|
in: body
|
||||||
|
name: authorization
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/model.Authorization'
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: OK
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/controller.HttpResponse'
|
||||||
|
tags:
|
||||||
|
- authorization
|
||||||
|
/authorization/:id:
|
||||||
|
delete:
|
||||||
|
parameters:
|
||||||
|
- description: authorization id
|
||||||
|
in: path
|
||||||
|
name: id
|
||||||
|
required: true
|
||||||
|
type: integer
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: OK
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/controller.HttpResponse'
|
||||||
|
tags:
|
||||||
|
- authorization
|
||||||
|
put:
|
||||||
|
parameters:
|
||||||
|
- description: authorization id
|
||||||
|
in: path
|
||||||
|
name: id
|
||||||
|
required: true
|
||||||
|
type: integer
|
||||||
|
- description: authorization
|
||||||
|
in: body
|
||||||
|
name: authorization
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/model.Authorization'
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: OK
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/controller.HttpResponse'
|
||||||
|
tags:
|
||||||
|
- authorization
|
||||||
/command:
|
/command:
|
||||||
get:
|
get:
|
||||||
parameters:
|
parameters:
|
||||||
@@ -1652,7 +1728,9 @@ paths:
|
|||||||
name: share
|
name: share
|
||||||
required: true
|
required: true
|
||||||
schema:
|
schema:
|
||||||
|
items:
|
||||||
$ref: '#/definitions/model.Share'
|
$ref: '#/definitions/model.Share'
|
||||||
|
type: array
|
||||||
responses:
|
responses:
|
||||||
"200":
|
"200":
|
||||||
description: OK
|
description: OK
|
||||||
@@ -1708,7 +1786,7 @@ paths:
|
|||||||
schema:
|
schema:
|
||||||
$ref: '#/definitions/controller.HttpResponse'
|
$ref: '#/definitions/controller.HttpResponse'
|
||||||
tags:
|
tags:
|
||||||
- connect
|
- share
|
||||||
/stat/account:
|
/stat/account:
|
||||||
get:
|
get:
|
||||||
parameters:
|
parameters:
|
||||||
|
@@ -1,6 +1,7 @@
|
|||||||
package model
|
package model
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"gorm.io/plugin/soft_delete"
|
"gorm.io/plugin/soft_delete"
|
||||||
@@ -8,28 +9,39 @@ import (
|
|||||||
|
|
||||||
type Authorization struct {
|
type Authorization struct {
|
||||||
Id int `json:"id" gorm:"column:id;primarykey;autoIncrement"`
|
Id int `json:"id" gorm:"column:id;primarykey;autoIncrement"`
|
||||||
AssetId int `json:"asset_id" gorm:"column:asset_id;uniqueIndex:asset_account_id_del"`
|
AssetId *int `json:"asset_id" gorm:"column:asset_id"`
|
||||||
AccountId int `json:"account_id" gorm:"column:account_id;uniqueIndex:asset_account_id_del"`
|
AccountId *int `json:"account_id" gorm:"column:account_id"`
|
||||||
|
NodeId *int `json:"node_id" gorm:"column:node_id"`
|
||||||
|
Rids Slice[int] `json:"rids" gorm:"column:rids"`
|
||||||
|
|
||||||
ResourceId int `json:"resource_id" gorm:"column:resource_id"`
|
ResourceId int `json:"resource_id" gorm:"column:resource_id"`
|
||||||
CreatorId int `json:"creator_id" gorm:"column:creator_id"`
|
CreatorId int `json:"creator_id" gorm:"column:creator_id"`
|
||||||
UpdaterId int `json:"updater_id" gorm:"column:updater_id"`
|
UpdaterId int `json:"updater_id" gorm:"column:updater_id"`
|
||||||
CreatedAt time.Time `json:"created_at" gorm:"column:created_at"`
|
CreatedAt time.Time `json:"created_at" gorm:"column:created_at"`
|
||||||
UpdatedAt time.Time `json:"updated_at" gorm:"column:updated_at"`
|
UpdatedAt time.Time `json:"updated_at" gorm:"column:updated_at"`
|
||||||
DeletedAt soft_delete.DeletedAt `json:"-" gorm:"column:deleted_at;uniqueIndex:asset_account_id_del"`
|
DeletedAt soft_delete.DeletedAt `json:"-" gorm:"column:deleted_at"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *Authorization) TableName() string {
|
func (m *Authorization) TableName() string {
|
||||||
return "authorization"
|
return "authorization"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (m *Authorization) GetName() string {
|
||||||
|
return fmt.Sprintf("%s-%s-%s", m.AssetId, m.AccountId, m.NodeId)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *Authorization) GetId() int {
|
||||||
|
return m.Id
|
||||||
|
}
|
||||||
|
|
||||||
type InfoModel interface {
|
type InfoModel interface {
|
||||||
GetId() int
|
GetId() int
|
||||||
}
|
}
|
||||||
|
|
||||||
type AuthorizationIds struct {
|
type AuthorizationIds struct {
|
||||||
AssetId int `json:"asset_id" gorm:"column:asset_id"`
|
AssetId *int `json:"asset_id" gorm:"column:asset_id"`
|
||||||
AccountId int `json:"account_id" gorm:"column:account_id"`
|
AccountId *int `json:"account_id" gorm:"column:account_id"`
|
||||||
|
NodeId *int `json:"node_id" gorm:"column:node_id"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *AuthorizationIds) TableName() string {
|
func (m *AuthorizationIds) TableName() string {
|
||||||
|
@@ -66,10 +66,14 @@ type Parser struct {
|
|||||||
|
|
||||||
func (p *Parser) AddInput(bs []byte) (cmd string, forbidden bool) {
|
func (p *Parser) AddInput(bs []byte) (cmd string, forbidden bool) {
|
||||||
if p.isPrompt && !p.isEdit {
|
if p.isPrompt && !p.isEdit {
|
||||||
p.prompt = p.GetOutput()
|
//TODO: may someone has empty ps1?
|
||||||
|
if ps1 := p.GetOutput(); ps1 != "" {
|
||||||
|
p.prompt = ps1
|
||||||
|
}
|
||||||
p.isPrompt = false
|
p.isPrompt = false
|
||||||
p.WriteDb()
|
p.WriteDb()
|
||||||
p.lastCmd = ""
|
p.lastCmd = ""
|
||||||
|
p.lastRes = ""
|
||||||
}
|
}
|
||||||
p.Input = append(p.Input, bs...)
|
p.Input = append(p.Input, bs...)
|
||||||
if !bytes.HasSuffix(p.Input, []byte("\r")) {
|
if !bytes.HasSuffix(p.Input, []byte("\r")) {
|
||||||
@@ -88,7 +92,7 @@ func (p *Parser) AddInput(bs []byte) (cmd string, forbidden bool) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (p *Parser) IsForbidden(cmd string) (string, bool) {
|
func (p *Parser) IsForbidden(cmd string) (string, bool) {
|
||||||
if p.isEdit {
|
if p.isEdit || cmd == "" {
|
||||||
return "", false
|
return "", false
|
||||||
}
|
}
|
||||||
for _, c := range p.Cmds {
|
for _, c := range p.Cmds {
|
||||||
|
@@ -242,8 +242,8 @@ func (m *view) refresh() {
|
|||||||
logger.L().Error("auths", zap.Error(err))
|
logger.L().Error("auths", zap.Error(err))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
dbAccount = dbAccount.Where("id IN ?", lo.Map(auths, func(a *model.Authorization, _ int) int { return a.AccountId }))
|
dbAccount = dbAccount.Where("id IN ?", lo.Map(auths, func(a *model.Authorization, _ int) int { return *a.AccountId }))
|
||||||
dbAsset = dbAsset.Where("id IN ?", lo.Map(auths, func(a *model.Authorization, _ int) int { return a.AssetId }))
|
dbAsset = dbAsset.Where("id IN ?", lo.Map(auths, func(a *model.Authorization, _ int) int { return *a.AssetId }))
|
||||||
|
|
||||||
eg := &errgroup.Group{}
|
eg := &errgroup.Group{}
|
||||||
eg.Go(func() error {
|
eg.Go(func() error {
|
||||||
@@ -262,11 +262,11 @@ func (m *view) refresh() {
|
|||||||
|
|
||||||
m.combines = make(map[string][3]int)
|
m.combines = make(map[string][3]int)
|
||||||
for _, auth := range auths {
|
for _, auth := range auths {
|
||||||
asset, ok := assetMap[auth.AssetId]
|
asset, ok := assetMap[*auth.AssetId]
|
||||||
if !ok {
|
if !ok {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
account, ok := accountMap[auth.AccountId]
|
account, ok := accountMap[*auth.AccountId]
|
||||||
if !ok {
|
if !ok {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user