mirror of
https://github.com/veops/oneterm.git
synced 2025-10-09 01:00:09 +08:00
feat(api): permission
This commit is contained in:
@@ -134,15 +134,14 @@ func RunApi() error {
|
|||||||
share.POST("", authAdmin(), c.CreateShare)
|
share.POST("", authAdmin(), c.CreateShare)
|
||||||
share.DELETE("/:id", authAdmin(), c.DeleteShare)
|
share.DELETE("/:id", authAdmin(), c.DeleteShare)
|
||||||
share.GET("", authAdmin(), c.GetShare)
|
share.GET("", authAdmin(), c.GetShare)
|
||||||
share.GET("/connect/:uuid", c.ConnectShare)
|
|
||||||
}
|
}
|
||||||
// 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 := v1.Group("/authorization", authAdmin())
|
||||||
{
|
{
|
||||||
authorization.POST("", c.CreateAuthorization)
|
authorization.POST("", c.UpsertAuthorization)
|
||||||
authorization.DELETE("/:id", c.DeleteAccount)
|
authorization.DELETE("/:id", c.DeleteAccount)
|
||||||
authorization.PUT("/:id", c.UpdateAuthorization)
|
authorization.GET("", c.GetAuthorizations)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -2,8 +2,10 @@ package controller
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
"strings"
|
"strings"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
"github.com/samber/lo"
|
"github.com/samber/lo"
|
||||||
@@ -12,12 +14,17 @@ import (
|
|||||||
"gorm.io/gorm"
|
"gorm.io/gorm"
|
||||||
|
|
||||||
"github.com/veops/oneterm/acl"
|
"github.com/veops/oneterm/acl"
|
||||||
|
redis "github.com/veops/oneterm/cache"
|
||||||
"github.com/veops/oneterm/conf"
|
"github.com/veops/oneterm/conf"
|
||||||
mysql "github.com/veops/oneterm/db"
|
mysql "github.com/veops/oneterm/db"
|
||||||
"github.com/veops/oneterm/model"
|
"github.com/veops/oneterm/model"
|
||||||
"github.com/veops/oneterm/util"
|
"github.com/veops/oneterm/util"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
kFmtAccountIds = "accountIds-%d"
|
||||||
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
accountPreHooks = []preHook[*model.Account]{
|
accountPreHooks = []preHook[*model.Account]{
|
||||||
func(ctx *gin.Context, data *model.Account) {
|
func(ctx *gin.Context, data *model.Account) {
|
||||||
@@ -145,7 +152,7 @@ func (c *Controller) GetAccounts(ctx *gin.Context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if info && !acl.IsAdmin(currentUser) {
|
if info && !acl.IsAdmin(currentUser) {
|
||||||
ids, err := getAccountIdsByAuthorization(ctx)
|
ids, err := GetAccountIdsByAuthorization(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -157,29 +164,29 @@ 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) {
|
func GetAccountIdsByAuthorization(ctx *gin.Context) (ids []int, err error) {
|
||||||
assetIds, err := getAssertIdsByAuthorization(ctx)
|
currentUser, _ := acl.GetSessionFromCtx(ctx)
|
||||||
|
|
||||||
|
k := fmt.Sprintf(kFmtAccountIds, currentUser.GetUid())
|
||||||
|
if err = redis.Get(ctx, k, &ids); err == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
assetIds, err := GetAssetIdsByAuthorization(ctx)
|
||||||
if err != nil {
|
if 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
|
||||||
}
|
}
|
||||||
assets := make([]*model.Asset, 0)
|
ss := make([][]int, 0)
|
||||||
if err = mysql.DB.Model(&model.Asset{}).Where("id IN ?", assetIds).Find(&assets).Error; err != nil {
|
if err = mysql.DB.Model(&model.Asset{}).Where("id IN ?", assetIds).Pluck("JSON_KEYS(authorization)", &ss).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
|
||||||
}
|
}
|
||||||
authorizationIds, _ := ctx.Value("authorizationIds").([]*model.AuthorizationIds)
|
ids = lo.Uniq(lo.Flatten(ss))
|
||||||
parentNodeIds, _ := ctx.Value("parentNodeIds").([]int)
|
_, _, accountIds := getIdsByAuthorizationIds(ctx)
|
||||||
for _, a := range assets {
|
ids = lo.Uniq(append(ids, accountIds...))
|
||||||
if lo.Contains(parentNodeIds, a.Id) {
|
|
||||||
ids = append(ids, lo.Keys(a.Authorization)...)
|
redis.SetEx(ctx, k, ids, time.Minute)
|
||||||
}
|
|
||||||
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
|
return
|
||||||
}
|
}
|
||||||
|
@@ -1,9 +1,10 @@
|
|||||||
package controller
|
package controller
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"net/http"
|
|
||||||
"strings"
|
"strings"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
"github.com/samber/lo"
|
"github.com/samber/lo"
|
||||||
@@ -11,6 +12,7 @@ import (
|
|||||||
"go.uber.org/zap"
|
"go.uber.org/zap"
|
||||||
|
|
||||||
"github.com/veops/oneterm/acl"
|
"github.com/veops/oneterm/acl"
|
||||||
|
redis "github.com/veops/oneterm/cache"
|
||||||
"github.com/veops/oneterm/conf"
|
"github.com/veops/oneterm/conf"
|
||||||
mysql "github.com/veops/oneterm/db"
|
mysql "github.com/veops/oneterm/db"
|
||||||
"github.com/veops/oneterm/logger"
|
"github.com/veops/oneterm/logger"
|
||||||
@@ -18,6 +20,13 @@ import (
|
|||||||
"github.com/veops/oneterm/schedule"
|
"github.com/veops/oneterm/schedule"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
kFmtAssetIds = "assetIds-%d"
|
||||||
|
kAuthorizationIds = "authorizationIds"
|
||||||
|
kParentNodeIds = "parentNodeIds"
|
||||||
|
kAccountIds = "accountIds"
|
||||||
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
assetPreHooks = []preHook[*model.Asset]{
|
assetPreHooks = []preHook[*model.Asset]{
|
||||||
func(ctx *gin.Context, data *model.Asset) {
|
func(ctx *gin.Context, data *model.Asset) {
|
||||||
@@ -92,7 +101,7 @@ func (c *Controller) GetAssets(ctx *gin.Context) {
|
|||||||
db = db.Where("id IN ?", lo.Map(strings.Split(q, ","), func(s string, _ int) int { return cast.ToInt(s) }))
|
db = db.Where("id IN ?", lo.Map(strings.Split(q, ","), func(s string, _ int) int { return cast.ToInt(s) }))
|
||||||
}
|
}
|
||||||
if q, ok := ctx.GetQuery("parent_id"); ok {
|
if q, ok := ctx.GetQuery("parent_id"); ok {
|
||||||
parentIds, err := handleParentId(cast.ToInt(q))
|
parentIds, err := handleParentId(ctx, cast.ToInt(q))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.L().Error("parent id found failed", zap.Error(err))
|
logger.L().Error("parent id found failed", zap.Error(err))
|
||||||
return
|
return
|
||||||
@@ -101,7 +110,7 @@ func (c *Controller) GetAssets(ctx *gin.Context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if info && !acl.IsAdmin(currentUser) {
|
if info && !acl.IsAdmin(currentUser) {
|
||||||
ids, err := getAssertIdsByAuthorization(ctx)
|
ids, err := GetAssetIdsByAuthorization(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -147,29 +156,33 @@ 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)
|
parentNodeIds, _, accountIds := getIdsByAuthorizationIds(ctx)
|
||||||
for _, a := range data {
|
for _, a := range data {
|
||||||
if lo.Contains(parentNodeIds, a.Id) {
|
if lo.Contains(parentNodeIds, a.Id) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
accountIds := lo.Uniq(
|
ids := lo.Uniq(
|
||||||
lo.Map(lo.Filter(authorizationIds, func(item *model.AuthorizationIds, _ int) bool {
|
lo.Map(lo.Filter(authorizationIds, func(item *model.AuthorizationIds, _ int) bool {
|
||||||
return item.AssetId != nil && *item.AssetId == a.Id && item.AccountId != nil
|
return item.AssetId != nil && *item.AssetId == a.Id && item.AccountId != nil
|
||||||
}),
|
}),
|
||||||
func(item *model.AuthorizationIds, _ int) int { return *item.AccountId }))
|
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(ids, k) && !lo.Contains(accountIds, k) {
|
||||||
delete(a.Authorization, k)
|
delete(a.Authorization, k)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func handleParentId(parentId int) (pids []int, err error) {
|
func handleParentId(ctx context.Context, parentId int) (pids []int, err error) {
|
||||||
nodes := make([]*model.NodeIdPid, 0)
|
nodes := make([]*model.NodeIdPid, 0)
|
||||||
|
if err = redis.Get(ctx, kFmtAllNodes, &nodes); err != nil {
|
||||||
if err = mysql.DB.Model(&model.Node{}).Find(&nodes).Error; err != nil {
|
if err = mysql.DB.Model(&model.Node{}).Find(&nodes).Error; err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
redis.SetEx(ctx, kFmtAllNodes, nodes, time.Hour)
|
||||||
|
}
|
||||||
g := make(map[int][]int)
|
g := make(map[int][]int)
|
||||||
for _, n := range nodes {
|
for _, n := range nodes {
|
||||||
g[n.ParentId] = append(g[n.ParentId], n.Id)
|
g[n.ParentId] = append(g[n.ParentId], n.Id)
|
||||||
@@ -186,33 +199,69 @@ func handleParentId(parentId int) (pids []int, err error) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func getAssertIdsByAuthorization(ctx *gin.Context) (ids []int, err error) {
|
func GetAssetIdsByAuthorization(ctx *gin.Context) (ids []int, err error) {
|
||||||
authorizationResourceIds, err := getAutorizationResourceIds(ctx)
|
currentUser, _ := acl.GetSessionFromCtx(ctx)
|
||||||
|
|
||||||
|
authIds, err := getAuthorizationIds(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
ctx.Set(kAuthorizationIds, authIds)
|
||||||
|
|
||||||
|
k := fmt.Sprintf(kFmtAssetIds, currentUser.GetUid())
|
||||||
|
if err = redis.Get(ctx, k, &ids); err == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
parentNodeIds, ids, accountIds := getIdsByAuthorizationIds(ctx)
|
||||||
|
|
||||||
|
tmp, err := handleSelfChild(ctx, parentNodeIds)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
parentNodeIds = append(parentNodeIds, tmp...)
|
||||||
|
ctx.Set(kParentNodeIds, parentNodeIds)
|
||||||
|
ctx.Set(kAccountIds, accountIds)
|
||||||
|
tmp, err = getAssetIdsByNodeAccount(ctx, parentNodeIds, accountIds)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
ids = lo.Uniq(append(ids, tmp...))
|
||||||
|
|
||||||
|
redis.SetEx(ctx, k, ids, time.Minute)
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func getIdsByAuthorizationIds(ctx context.Context) (parentNodeIds, assetIds, accountIds []int) {
|
||||||
|
authIds, _ := ctx.Value(kAuthorizationIds).([]*model.AuthorizationIds)
|
||||||
|
|
||||||
|
for _, a := range authIds {
|
||||||
|
if a.NodeId != nil && a.AssetId == nil && a.AccountId == nil {
|
||||||
|
parentNodeIds = append(parentNodeIds, *a.NodeId)
|
||||||
|
}
|
||||||
|
if a.AssetId != nil && a.NodeId == nil && a.AccountId == nil {
|
||||||
|
assetIds = append(assetIds, *a.AssetId)
|
||||||
|
}
|
||||||
|
if a.AccountId != nil && a.AssetId == nil && a.NodeId == nil {
|
||||||
|
accountIds = append(accountIds, *a.AccountId)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func getAuthorizationIds(ctx *gin.Context) (authIds []*model.AuthorizationIds, err error) {
|
||||||
|
resourceIds, err := getAutorizationResourceIds(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
handleRemoteErr(ctx, err)
|
handleRemoteErr(ctx, err)
|
||||||
return
|
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)
|
err = mysql.DB.Model(authIds).Where("resource_id IN ?", resourceIds).Find(&authIds).Error
|
||||||
for _, a := range authIds {
|
return
|
||||||
if a.NodeId != nil {
|
}
|
||||||
parentNodeIds = append(parentNodeIds, *a.NodeId)
|
|
||||||
} else if a.AssetId != nil {
|
func getAssetIdsByNodeAccount(ctx context.Context, parentNodeIds, accountIds []int) (assetIds []int, err error) {
|
||||||
ids = append(ids, *a.AssetId)
|
err = mysql.DB.Model(&model.Asset{}).Where("parent_id IN?", parentNodeIds).Or("JSON_KEYS(authorization) IN ?", accountIds).Pluck("id", &assetIds).Error
|
||||||
}
|
|
||||||
}
|
|
||||||
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
|
return
|
||||||
}
|
}
|
||||||
|
@@ -1,9 +1,11 @@
|
|||||||
package controller
|
package controller
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
"reflect"
|
"strings"
|
||||||
"sort"
|
"time"
|
||||||
|
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
"github.com/samber/lo"
|
"github.com/samber/lo"
|
||||||
@@ -13,12 +15,104 @@ import (
|
|||||||
"gorm.io/gorm"
|
"gorm.io/gorm"
|
||||||
|
|
||||||
"github.com/veops/oneterm/acl"
|
"github.com/veops/oneterm/acl"
|
||||||
|
redis "github.com/veops/oneterm/cache"
|
||||||
"github.com/veops/oneterm/conf"
|
"github.com/veops/oneterm/conf"
|
||||||
mysql "github.com/veops/oneterm/db"
|
mysql "github.com/veops/oneterm/db"
|
||||||
"github.com/veops/oneterm/logger"
|
"github.com/veops/oneterm/logger"
|
||||||
"github.com/veops/oneterm/model"
|
"github.com/veops/oneterm/model"
|
||||||
|
gsession "github.com/veops/oneterm/session"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
kFmtAuthorizationIds = "AuthorizationIds-%d"
|
||||||
|
kFmtHasAuthorization = "HasAuthorization-%d-%d-%d"
|
||||||
|
)
|
||||||
|
|
||||||
|
// UpsertAuthorization godoc
|
||||||
|
//
|
||||||
|
// @Tags authorization
|
||||||
|
// @Param authorization body model.Authorization true "authorization"
|
||||||
|
// @Success 200 {object} HttpResponse
|
||||||
|
// @Router /authorization [post]
|
||||||
|
func (c *Controller) UpsertAuthorization(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 := mysql.DB.Transaction(func(tx *gorm.DB) error {
|
||||||
|
auth := &model.Authorization{}
|
||||||
|
if err = tx.Model(auth).
|
||||||
|
Where(fmt.Sprintf("node_id %s AND asset_id %s AND account_id %s",
|
||||||
|
lo.Ternary(auth.NodeId == nil, "IS NULL", fmt.Sprintf("=%d", auth.NodeId)),
|
||||||
|
lo.Ternary(auth.AssetId == nil, "IS NULL", fmt.Sprintf("=%d", auth.AssetId)),
|
||||||
|
lo.Ternary(auth.AccountId == nil, "IS NULL", fmt.Sprintf("=%d", auth.AccountId)),
|
||||||
|
)).
|
||||||
|
FirstOrCreate(auth).Error; err != nil {
|
||||||
|
if !errors.Is(err, gorm.ErrRecordNotFound) {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
action := lo.Ternary(auth.Id > 0, model.ACTION_UPDATE, model.ACTION_CREATE)
|
||||||
|
return handleAuthorization(ctx, tx, action, 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(),
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetAuthorizations godoc
|
||||||
|
//
|
||||||
|
// @Tags authorization
|
||||||
|
// @Param page_index query int true "page_index"
|
||||||
|
// @Param page_size query int true "page_size"
|
||||||
|
// @Param node_id query int false "node id"
|
||||||
|
// @Param asset_id query int false "asset id"
|
||||||
|
// @Param account_id query int false "account id"
|
||||||
|
// @Success 200 {object} HttpResponse{data=ListData{list=[]model.Account}}
|
||||||
|
// @Router /authorization [get]
|
||||||
|
func (c *Controller) GetAuthorizations(ctx *gin.Context) {
|
||||||
|
db := mysql.DB.Model(&model.Authorization{})
|
||||||
|
for _, k := range []string{"node_id", "asset_id", "account_id"} {
|
||||||
|
q, ok := ctx.GetQuery(k)
|
||||||
|
if ok {
|
||||||
|
db = db.Where(fmt.Sprintf("%s IN ?", k), lo.Map(strings.Split(q, ","), func(s string, _ int) int { return cast.ToInt(s) }))
|
||||||
|
} else {
|
||||||
|
db = db.Where(fmt.Sprintf("%s IS NULL", k))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
doGet[*model.Authorization](ctx, false, db, acl.GetResourceTypeName(conf.RESOURCE_AUTHORIZATION))
|
||||||
|
}
|
||||||
|
|
||||||
func getAuthsByAsset(t *model.Asset) (data []*model.Authorization, err error) {
|
func getAuthsByAsset(t *model.Asset) (data []*model.Authorization, err error) {
|
||||||
db := mysql.DB.Model(data)
|
db := mysql.DB.Model(data)
|
||||||
for accountId := range t.Authorization {
|
for accountId := range t.Authorization {
|
||||||
@@ -57,7 +151,8 @@ func handleAuthorization(ctx *gin.Context, tx *gorm.DB, action int, asset *model
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, auth := range lo.Filter(auths, func(item *model.Authorization, _ int) bool { return item != nil }) {
|
for _, a := range lo.Filter(auths, func(item *model.Authorization, _ int) bool { return item != nil }) {
|
||||||
|
auth := a
|
||||||
switch action {
|
switch action {
|
||||||
case model.ACTION_CREATE:
|
case model.ACTION_CREATE:
|
||||||
eg.Go(func() (err error) {
|
eg.Go(func() (err error) {
|
||||||
@@ -103,29 +198,14 @@ func handleAuthorization(ctx *gin.Context, tx *gorm.DB, action int, asset *model
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func sameAuthorization(old, new model.Map[int, model.Slice[int]]) bool {
|
|
||||||
if len(old) != len(new) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
ks := lo.Uniq(append(lo.Keys(old), lo.Keys(new)...))
|
|
||||||
for _, k := range ks {
|
|
||||||
if len(old[k]) != len(new[k]) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
o, n := make([]int, 0, len(old[k])), make([]int, 0, len(new[k]))
|
|
||||||
copy(o, old[k])
|
|
||||||
copy(n, new[k])
|
|
||||||
sort.Ints(o)
|
|
||||||
sort.Ints(n)
|
|
||||||
if !reflect.DeepEqual(o, n) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
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)
|
||||||
|
|
||||||
|
k := fmt.Sprintf(kFmtAuthorizationIds, currentUser.GetUid())
|
||||||
|
if err = redis.Get(ctx, k, &resourceIds); err == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
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)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -133,97 +213,63 @@ func getAutorizationResourceIds(ctx *gin.Context) (resourceIds []int, err error)
|
|||||||
}
|
}
|
||||||
resourceIds = lo.Map(rs, func(r *acl.Resource, _ int) int { return r.ResourceId })
|
resourceIds = lo.Map(rs, func(r *acl.Resource, _ int) int { return r.ResourceId })
|
||||||
|
|
||||||
|
redis.SetEx(ctx, k, resourceIds, time.Minute)
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func hasAuthorization(ctx *gin.Context, assetId, accountId int) (ok bool) {
|
func hasAuthorization(ctx *gin.Context, sess *gsession.Session) (ok bool) {
|
||||||
if cast.ToString(ctx.Value("shareId")) != "" {
|
currentUser, _ := acl.GetSessionFromCtx(ctx)
|
||||||
|
|
||||||
|
if sess.ShareId != 0 {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
ids, err := getAutorizationResourceIds(ctx)
|
|
||||||
|
k := fmt.Sprintf(kFmtHasAuthorization, currentUser.GetUid(), sess.AccountId, sess.AssetId)
|
||||||
|
if err := redis.Get(ctx, k, &ok); err == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
defer func() {
|
||||||
|
redis.SetEx(ctx, k, ok, time.Minute)
|
||||||
|
}()
|
||||||
|
|
||||||
|
if ok = acl.IsAdmin(currentUser); ok {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if sess.Session.Asset == nil {
|
||||||
|
if err := mysql.DB.Model(sess.Session.Asset).First(&sess.Session.Asset, sess.AssetId).Error; err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
authIds, err := getAuthorizationIds(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if _, ok = lo.Find(authIds, func(item *model.AuthorizationIds) bool {
|
||||||
|
return item.NodeId == nil && item.AssetId != nil && *item.AssetId == sess.AssetId && item.AccountId != nil && *item.AccountId == sess.AccountId
|
||||||
|
}); ok {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
ctx.Set(kAuthorizationIds, authIds)
|
||||||
|
|
||||||
|
parentNodeIds, assetIds, accountIds := getIdsByAuthorizationIds(ctx)
|
||||||
|
tmp, err := handleSelfChild(ctx, parentNodeIds)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.L().Error("", zap.Error(err))
|
logger.L().Error("", zap.Error(err))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
cnt := int64(0)
|
parentNodeIds = append(parentNodeIds, tmp...)
|
||||||
err = mysql.DB.Model(&model.Authorization{}).
|
if ok = lo.Contains(parentNodeIds, sess.Session.Asset.ParentId) || lo.Contains(assetIds, sess.AssetId) || lo.Contains(accountIds, sess.AccountId); ok {
|
||||||
Where("asset_id =? AND account_id =? AND resource_id IN (?)", assetId, accountId, ids).
|
return
|
||||||
Count(&cnt).Error
|
}
|
||||||
|
|
||||||
|
ids, err := getAssetIdsByNodeAccount(ctx, parentNodeIds, accountIds)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.L().Error("", zap.Error(err))
|
logger.L().Error("", zap.Error(err))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
return cnt > 0
|
return lo.Contains(ids, sess.AssetId)
|
||||||
}
|
|
||||||
|
|
||||||
// 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(),
|
|
||||||
},
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
@@ -269,6 +269,7 @@ func DoConnect(ctx *gin.Context, ws *websocket.Conn) (sess *gsession.Session, er
|
|||||||
Uid: currentUser.GetUid(),
|
Uid: currentUser.GetUid(),
|
||||||
UserName: currentUser.GetUserName(),
|
UserName: currentUser.GetUserName(),
|
||||||
AssetId: assetId,
|
AssetId: assetId,
|
||||||
|
Asset: asset,
|
||||||
AssetInfo: fmt.Sprintf("%s(%s)", asset.Name, asset.Ip),
|
AssetInfo: fmt.Sprintf("%s(%s)", asset.Name, asset.Ip),
|
||||||
AccountId: accountId,
|
AccountId: accountId,
|
||||||
AccountInfo: fmt.Sprintf("%s(%s)", account.Name, account.Account),
|
AccountInfo: fmt.Sprintf("%s(%s)", account.Name, account.Account),
|
||||||
@@ -305,7 +306,7 @@ 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 !hasAuthorization(ctx, sess) {
|
||||||
err = &ApiError{Code: ErrUnauthorized}
|
err = &ApiError{Code: ErrUnauthorized}
|
||||||
ctx.AbortWithError(http.StatusForbidden, err)
|
ctx.AbortWithError(http.StatusForbidden, err)
|
||||||
return
|
return
|
||||||
|
@@ -18,6 +18,7 @@ import (
|
|||||||
mysql "github.com/veops/oneterm/db"
|
mysql "github.com/veops/oneterm/db"
|
||||||
"github.com/veops/oneterm/logger"
|
"github.com/veops/oneterm/logger"
|
||||||
"github.com/veops/oneterm/model"
|
"github.com/veops/oneterm/model"
|
||||||
|
gsession "github.com/veops/oneterm/session"
|
||||||
)
|
)
|
||||||
|
|
||||||
// GetFileHistory godoc
|
// GetFileHistory godoc
|
||||||
@@ -60,8 +61,14 @@ func (c *Controller) GetFileHistory(ctx *gin.Context) {
|
|||||||
// @Success 200 {object} HttpResponse
|
// @Success 200 {object} HttpResponse
|
||||||
// @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)
|
sess := &gsession.Session{
|
||||||
if !acl.IsAdmin(currentUser) && !hasAuthorization(ctx, cast.ToInt(ctx.Param("account_id")), cast.ToInt(ctx.Param("account_id"))) {
|
Session: &model.Session{
|
||||||
|
AssetId: cast.ToInt(ctx.Param("asset_id")),
|
||||||
|
AccountId: cast.ToInt(ctx.Param("account_id")),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
if !hasAuthorization(ctx, sess) {
|
||||||
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 +108,15 @@ 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"))) {
|
|
||||||
|
sess := &gsession.Session{
|
||||||
|
Session: &model.Session{
|
||||||
|
AssetId: cast.ToInt(ctx.Param("asset_id")),
|
||||||
|
AccountId: cast.ToInt(ctx.Param("account_id")),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
if !hasAuthorization(ctx, sess) {
|
||||||
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 +156,15 @@ 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"))) {
|
|
||||||
|
sess := &gsession.Session{
|
||||||
|
Session: &model.Session{
|
||||||
|
AssetId: cast.ToInt(ctx.Param("asset_id")),
|
||||||
|
AccountId: cast.ToInt(ctx.Param("account_id")),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
if !hasAuthorization(ctx, sess) {
|
||||||
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 +225,15 @@ 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"))) {
|
|
||||||
|
sess := &gsession.Session{
|
||||||
|
Session: &model.Session{
|
||||||
|
AssetId: cast.ToInt(ctx.Param("asset_id")),
|
||||||
|
AccountId: cast.ToInt(ctx.Param("account_id")),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
if !hasAuthorization(ctx, sess) {
|
||||||
ctx.AbortWithError(http.StatusForbidden, &ApiError{Code: ErrNoPerm, Data: map[string]any{}})
|
ctx.AbortWithError(http.StatusForbidden, &ApiError{Code: ErrNoPerm, Data: map[string]any{}})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@@ -1,9 +1,11 @@
|
|||||||
package controller
|
package controller
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"errors"
|
"errors"
|
||||||
"net/http"
|
"net/http"
|
||||||
"strings"
|
"strings"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
"github.com/samber/lo"
|
"github.com/samber/lo"
|
||||||
@@ -12,11 +14,16 @@ import (
|
|||||||
"gorm.io/gorm"
|
"gorm.io/gorm"
|
||||||
|
|
||||||
"github.com/veops/oneterm/acl"
|
"github.com/veops/oneterm/acl"
|
||||||
|
redis "github.com/veops/oneterm/cache"
|
||||||
mysql "github.com/veops/oneterm/db"
|
mysql "github.com/veops/oneterm/db"
|
||||||
"github.com/veops/oneterm/logger"
|
"github.com/veops/oneterm/logger"
|
||||||
"github.com/veops/oneterm/model"
|
"github.com/veops/oneterm/model"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
kFmtAllNodes = "allNodes"
|
||||||
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
nodePreHooks = []preHook[*model.Node]{nodePreHookCheckCycle}
|
nodePreHooks = []preHook[*model.Node]{nodePreHookCheckCycle}
|
||||||
nodePostHooks = []postHook[*model.Node]{nodePostHookCountAsset, nodePostHookHasChild}
|
nodePostHooks = []postHook[*model.Node]{nodePostHookCountAsset, nodePostHookHasChild}
|
||||||
@@ -30,6 +37,7 @@ var (
|
|||||||
// @Success 200 {object} HttpResponse
|
// @Success 200 {object} HttpResponse
|
||||||
// @Router /node [post]
|
// @Router /node [post]
|
||||||
func (c *Controller) CreateNode(ctx *gin.Context) {
|
func (c *Controller) CreateNode(ctx *gin.Context) {
|
||||||
|
redis.RC.Del(ctx, kFmtAllNodes)
|
||||||
doCreate(ctx, false, &model.Node{}, "")
|
doCreate(ctx, false, &model.Node{}, "")
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -40,6 +48,7 @@ func (c *Controller) CreateNode(ctx *gin.Context) {
|
|||||||
// @Success 200 {object} HttpResponse
|
// @Success 200 {object} HttpResponse
|
||||||
// @Router /node/:id [delete]
|
// @Router /node/:id [delete]
|
||||||
func (c *Controller) DeleteNode(ctx *gin.Context) {
|
func (c *Controller) DeleteNode(ctx *gin.Context) {
|
||||||
|
redis.RC.Del(ctx, kFmtAllNodes)
|
||||||
doDelete(ctx, false, &model.Node{}, nodeDcs...)
|
doDelete(ctx, false, &model.Node{}, nodeDcs...)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -51,6 +60,7 @@ func (c *Controller) DeleteNode(ctx *gin.Context) {
|
|||||||
// @Success 200 {object} HttpResponse
|
// @Success 200 {object} HttpResponse
|
||||||
// @Router /node/:id [put]
|
// @Router /node/:id [put]
|
||||||
func (c *Controller) UpdateNode(ctx *gin.Context) {
|
func (c *Controller) UpdateNode(ctx *gin.Context) {
|
||||||
|
redis.RC.Del(ctx, kFmtAllNodes)
|
||||||
doUpdate(ctx, false, &model.Node{}, nodePreHooks...)
|
doUpdate(ctx, false, &model.Node{}, nodePreHooks...)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -77,7 +87,7 @@ func (c *Controller) GetNodes(ctx *gin.Context) {
|
|||||||
db = db.Where("id IN ?", lo.Map(strings.Split(q, ","), func(s string, _ int) int { return cast.ToInt(s) }))
|
db = db.Where("id IN ?", lo.Map(strings.Split(q, ","), func(s string, _ int) int { return cast.ToInt(s) }))
|
||||||
}
|
}
|
||||||
if id, ok := ctx.GetQuery("no_self_child"); ok {
|
if id, ok := ctx.GetQuery("no_self_child"); ok {
|
||||||
ids, err := handleNoSelfChild(cast.ToInt(id))
|
ids, err := handleNoSelfChild(ctx, cast.ToInt(id))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -85,7 +95,7 @@ func (c *Controller) GetNodes(ctx *gin.Context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if id, ok := ctx.GetQuery("self_parent"); ok {
|
if id, ok := ctx.GetQuery("self_parent"); ok {
|
||||||
ids, err := handleSelfParent(cast.ToInt(id))
|
ids, err := handleSelfParent(ctx, cast.ToInt(id))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -200,11 +210,14 @@ func nodeDelHook(ctx *gin.Context, id int) {
|
|||||||
ctx.AbortWithError(http.StatusBadRequest, err)
|
ctx.AbortWithError(http.StatusBadRequest, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
func handleNoSelfChild(id int) (ids []int, err error) {
|
func handleNoSelfChild(ctx context.Context, id int) (ids []int, err error) {
|
||||||
nodes := make([]*model.NodeIdPid, 0)
|
nodes := make([]*model.NodeIdPid, 0)
|
||||||
|
if err = redis.Get(ctx, kFmtAllNodes, &nodes); err != nil {
|
||||||
if err = mysql.DB.Model(&model.Node{}).Find(&nodes).Error; err != nil {
|
if err = mysql.DB.Model(&model.Node{}).Find(&nodes).Error; err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
redis.SetEx(ctx, kFmtAllNodes, nodes, time.Hour)
|
||||||
|
}
|
||||||
g := make(map[int][]int)
|
g := make(map[int][]int)
|
||||||
for _, n := range nodes {
|
for _, n := range nodes {
|
||||||
g[n.ParentId] = append(g[n.ParentId], n.Id)
|
g[n.ParentId] = append(g[n.ParentId], n.Id)
|
||||||
@@ -221,11 +234,14 @@ func handleNoSelfChild(id int) (ids []int, err error) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func handleSelfParent(id int) (ids []int, err error) {
|
func handleSelfParent(ctx context.Context, id int) (ids []int, err error) {
|
||||||
nodes := make([]*model.NodeIdPid, 0)
|
nodes := make([]*model.NodeIdPid, 0)
|
||||||
|
if err = redis.Get(ctx, kFmtAllNodes, &nodes); err != nil {
|
||||||
if err = mysql.DB.Model(&model.Node{}).Find(&nodes).Error; err != nil {
|
if err = mysql.DB.Model(&model.Node{}).Find(&nodes).Error; err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
redis.SetEx(ctx, kFmtAllNodes, nodes, time.Hour)
|
||||||
|
}
|
||||||
g := make(map[int][]int)
|
g := make(map[int][]int)
|
||||||
for _, n := range nodes {
|
for _, n := range nodes {
|
||||||
g[n.ParentId] = append(g[n.ParentId], n.Id)
|
g[n.ParentId] = append(g[n.ParentId], n.Id)
|
||||||
@@ -244,11 +260,15 @@ func handleSelfParent(id int) (ids []int, err error) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func handleSelfChild(ins []int) (ids []int, err error) {
|
func handleSelfChild(ctx context.Context, parentIds []int) (ids []int, err error) {
|
||||||
|
// TODO: cache
|
||||||
nodes := make([]*model.NodeIdPid, 0)
|
nodes := make([]*model.NodeIdPid, 0)
|
||||||
|
if err = redis.Get(ctx, kFmtAllNodes, &nodes); err != nil {
|
||||||
if err = mysql.DB.Model(&model.Node{}).Find(&nodes).Error; err != nil {
|
if err = mysql.DB.Model(&model.Node{}).Find(&nodes).Error; err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
redis.SetEx(ctx, kFmtAllNodes, nodes, time.Hour)
|
||||||
|
}
|
||||||
g := make(map[int][]int)
|
g := make(map[int][]int)
|
||||||
for _, n := range nodes {
|
for _, n := range nodes {
|
||||||
g[n.ParentId] = append(g[n.ParentId], n.Id)
|
g[n.ParentId] = append(g[n.ParentId], n.Id)
|
||||||
@@ -259,7 +279,7 @@ func handleSelfChild(ins []int) (ids []int, err error) {
|
|||||||
ids = append(ids, x)
|
ids = append(ids, x)
|
||||||
}
|
}
|
||||||
for _, y := range g[x] {
|
for _, y := range g[x] {
|
||||||
dfs(y, b || lo.Contains(ins, x))
|
dfs(y, b || lo.Contains(parentIds, x))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
dfs(0, false)
|
dfs(0, false)
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
// 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 Code generated by swaggo/swag at 2024-09-20 17:24:49.219072 +0800 CST m=+7.114523601. DO NOT EDIT
|
||||||
package docs
|
package docs
|
||||||
|
|
||||||
import "github.com/swaggo/swag"
|
import "github.com/swaggo/swag"
|
||||||
@@ -368,6 +368,80 @@ const docTemplate = `{
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"/authorization": {
|
"/authorization": {
|
||||||
|
"get": {
|
||||||
|
"tags": [
|
||||||
|
"authorization"
|
||||||
|
],
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"type": "integer",
|
||||||
|
"description": "page_index",
|
||||||
|
"name": "page_index",
|
||||||
|
"in": "query",
|
||||||
|
"required": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "integer",
|
||||||
|
"description": "page_size",
|
||||||
|
"name": "page_size",
|
||||||
|
"in": "query",
|
||||||
|
"required": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "integer",
|
||||||
|
"description": "node id",
|
||||||
|
"name": "node_id",
|
||||||
|
"in": "query"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "integer",
|
||||||
|
"description": "asset id",
|
||||||
|
"name": "asset_id",
|
||||||
|
"in": "query"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "integer",
|
||||||
|
"description": "account id",
|
||||||
|
"name": "account_id",
|
||||||
|
"in": "query"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "OK",
|
||||||
|
"schema": {
|
||||||
|
"allOf": [
|
||||||
|
{
|
||||||
|
"$ref": "#/definitions/controller.HttpResponse"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"data": {
|
||||||
|
"allOf": [
|
||||||
|
{
|
||||||
|
"$ref": "#/definitions/controller.ListData"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"list": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"$ref": "#/definitions/model.Account"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"post": {
|
"post": {
|
||||||
"tags": [
|
"tags": [
|
||||||
"authorization"
|
"authorization"
|
||||||
@@ -394,37 +468,6 @@ const docTemplate = `{
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"/authorization/:id": {
|
"/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": {
|
"delete": {
|
||||||
"tags": [
|
"tags": [
|
||||||
"authorization"
|
"authorization"
|
||||||
|
@@ -357,6 +357,80 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"/authorization": {
|
"/authorization": {
|
||||||
|
"get": {
|
||||||
|
"tags": [
|
||||||
|
"authorization"
|
||||||
|
],
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"type": "integer",
|
||||||
|
"description": "page_index",
|
||||||
|
"name": "page_index",
|
||||||
|
"in": "query",
|
||||||
|
"required": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "integer",
|
||||||
|
"description": "page_size",
|
||||||
|
"name": "page_size",
|
||||||
|
"in": "query",
|
||||||
|
"required": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "integer",
|
||||||
|
"description": "node id",
|
||||||
|
"name": "node_id",
|
||||||
|
"in": "query"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "integer",
|
||||||
|
"description": "asset id",
|
||||||
|
"name": "asset_id",
|
||||||
|
"in": "query"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "integer",
|
||||||
|
"description": "account id",
|
||||||
|
"name": "account_id",
|
||||||
|
"in": "query"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "OK",
|
||||||
|
"schema": {
|
||||||
|
"allOf": [
|
||||||
|
{
|
||||||
|
"$ref": "#/definitions/controller.HttpResponse"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"data": {
|
||||||
|
"allOf": [
|
||||||
|
{
|
||||||
|
"$ref": "#/definitions/controller.ListData"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"list": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"$ref": "#/definitions/model.Account"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"post": {
|
"post": {
|
||||||
"tags": [
|
"tags": [
|
||||||
"authorization"
|
"authorization"
|
||||||
@@ -383,37 +457,6 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"/authorization/:id": {
|
"/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": {
|
"delete": {
|
||||||
"tags": [
|
"tags": [
|
||||||
"authorization"
|
"authorization"
|
||||||
|
@@ -688,6 +688,49 @@ paths:
|
|||||||
tags:
|
tags:
|
||||||
- asset
|
- asset
|
||||||
/authorization:
|
/authorization:
|
||||||
|
get:
|
||||||
|
parameters:
|
||||||
|
- description: page_index
|
||||||
|
in: query
|
||||||
|
name: page_index
|
||||||
|
required: true
|
||||||
|
type: integer
|
||||||
|
- description: page_size
|
||||||
|
in: query
|
||||||
|
name: page_size
|
||||||
|
required: true
|
||||||
|
type: integer
|
||||||
|
- description: node id
|
||||||
|
in: query
|
||||||
|
name: node_id
|
||||||
|
type: integer
|
||||||
|
- description: asset id
|
||||||
|
in: query
|
||||||
|
name: asset_id
|
||||||
|
type: integer
|
||||||
|
- description: account id
|
||||||
|
in: query
|
||||||
|
name: account_id
|
||||||
|
type: integer
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: OK
|
||||||
|
schema:
|
||||||
|
allOf:
|
||||||
|
- $ref: '#/definitions/controller.HttpResponse'
|
||||||
|
- properties:
|
||||||
|
data:
|
||||||
|
allOf:
|
||||||
|
- $ref: '#/definitions/controller.ListData'
|
||||||
|
- properties:
|
||||||
|
list:
|
||||||
|
items:
|
||||||
|
$ref: '#/definitions/model.Account'
|
||||||
|
type: array
|
||||||
|
type: object
|
||||||
|
type: object
|
||||||
|
tags:
|
||||||
|
- authorization
|
||||||
post:
|
post:
|
||||||
parameters:
|
parameters:
|
||||||
- description: authorization
|
- description: authorization
|
||||||
@@ -718,26 +761,6 @@ paths:
|
|||||||
$ref: '#/definitions/controller.HttpResponse'
|
$ref: '#/definitions/controller.HttpResponse'
|
||||||
tags:
|
tags:
|
||||||
- authorization
|
- 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:
|
||||||
|
@@ -16,9 +16,9 @@ type Asset struct {
|
|||||||
Comment string `json:"comment" gorm:"column:comment"`
|
Comment string `json:"comment" gorm:"column:comment"`
|
||||||
ParentId int `json:"parent_id" gorm:"column:parent_id"`
|
ParentId int `json:"parent_id" gorm:"column:parent_id"`
|
||||||
Ip string `json:"ip" gorm:"column:ip"`
|
Ip string `json:"ip" gorm:"column:ip"`
|
||||||
Protocols Slice[string] `json:"protocols" gorm:"column:protocols"`
|
Protocols Slice[string] `json:"protocols" gorm:"column:protocols;type:text"`
|
||||||
GatewayId int `json:"gateway_id" gorm:"column:gateway_id"`
|
GatewayId int `json:"gateway_id" gorm:"column:gateway_id"`
|
||||||
Authorization Map[int, Slice[int]] `json:"authorization" gorm:"column:authorization"`
|
Authorization Map[int, Slice[int]] `json:"authorization" gorm:"column:authorization;type:text"`
|
||||||
AccessAuth AccessAuth `json:"access_auth" gorm:"embedded;column:access_auth"`
|
AccessAuth AccessAuth `json:"access_auth" gorm:"embedded;column:access_auth"`
|
||||||
Connectable bool `json:"connectable" gorm:"column:connectable"`
|
Connectable bool `json:"connectable" gorm:"column:connectable"`
|
||||||
NodeChain string `json:"node_chain" gorm:"-"`
|
NodeChain string `json:"node_chain" gorm:"-"`
|
||||||
@@ -34,8 +34,8 @@ type Asset struct {
|
|||||||
type AccessAuth struct {
|
type AccessAuth struct {
|
||||||
Start *time.Time `json:"start,omitempty" gorm:"column:start"`
|
Start *time.Time `json:"start,omitempty" gorm:"column:start"`
|
||||||
End *time.Time `json:"end,omitempty" gorm:"column:end"`
|
End *time.Time `json:"end,omitempty" gorm:"column:end"`
|
||||||
CmdIds Slice[int] `json:"cmd_ids" gorm:"column:cmd_ids"`
|
CmdIds Slice[int] `json:"cmd_ids" gorm:"column:cmd_ids;type:text"`
|
||||||
Ranges Slice[Range] `json:"ranges" gorm:"column:ranges"`
|
Ranges Slice[Range] `json:"ranges" gorm:"column:ranges;type:text"`
|
||||||
Allow bool `json:"allow" gorm:"column:allow"`
|
Allow bool `json:"allow" gorm:"column:allow"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -15,9 +15,9 @@ type Node struct {
|
|||||||
Name string `json:"name" gorm:"column:name"`
|
Name string `json:"name" gorm:"column:name"`
|
||||||
Comment string `json:"comment" gorm:"column:comment"`
|
Comment string `json:"comment" gorm:"column:comment"`
|
||||||
ParentId int `json:"parent_id" gorm:"column:parent_id"`
|
ParentId int `json:"parent_id" gorm:"column:parent_id"`
|
||||||
Authorization Map[int, Slice[int]] `json:"authorization" gorm:"column:authorization"`
|
Authorization Map[int, Slice[int]] `json:"authorization" gorm:"column:authorization;type:text"`
|
||||||
AccessAuth AccessAuth `json:"access_auth" gorm:"embedded;column:access_auth"`
|
AccessAuth AccessAuth `json:"access_auth" gorm:"embedded;column:access_auth"`
|
||||||
Protocols Slice[string] `json:"protocols" gorm:"column:protocols"`
|
Protocols Slice[string] `json:"protocols" gorm:"column:protocols;type:text"`
|
||||||
GatewayId int `json:"gateway_id" gorm:"column:gateway_id"`
|
GatewayId int `json:"gateway_id" gorm:"column:gateway_id"`
|
||||||
|
|
||||||
// ResourceId int `json:"resource_id"`
|
// ResourceId int `json:"resource_id"`
|
||||||
|
@@ -28,6 +28,7 @@ type Session struct {
|
|||||||
Uid int `json:"uid" gorm:"column:uid"`
|
Uid int `json:"uid" gorm:"column:uid"`
|
||||||
UserName string `json:"user_name" gorm:"column:user_name"`
|
UserName string `json:"user_name" gorm:"column:user_name"`
|
||||||
AssetId int `json:"asset_id" gorm:"column:asset_id"`
|
AssetId int `json:"asset_id" gorm:"column:asset_id"`
|
||||||
|
Asset *Asset `json:"-" gorm:"-"`
|
||||||
AssetInfo string `json:"asset_info" gorm:"column:asset_info"`
|
AssetInfo string `json:"asset_info" gorm:"column:asset_info"`
|
||||||
AccountId int `json:"account_id" gorm:"column:account_id"`
|
AccountId int `json:"account_id" gorm:"column:account_id"`
|
||||||
AccountInfo string `json:"account_info" gorm:"column:account_info"`
|
AccountInfo string `json:"account_info" gorm:"column:account_info"`
|
||||||
|
@@ -30,7 +30,7 @@ func UpdateConnectables(ids ...int) (err error) {
|
|||||||
if len(ids) > 0 {
|
if len(ids) > 0 {
|
||||||
db = db.Where("id IN ?", ids)
|
db = db.Where("id IN ?", ids)
|
||||||
} else {
|
} else {
|
||||||
db = db.Where("updated_at <= ?", time.Now().Add(time.Hour).Unix())
|
db = db.Where("updated_at <= ?", time.Now().Add(-time.Hour))
|
||||||
}
|
}
|
||||||
if err = db.
|
if err = db.
|
||||||
Find(&assets).Error; err != nil {
|
Find(&assets).Error; err != nil {
|
||||||
|
@@ -23,7 +23,6 @@ import (
|
|||||||
"github.com/veops/oneterm/acl"
|
"github.com/veops/oneterm/acl"
|
||||||
"github.com/veops/oneterm/api/controller"
|
"github.com/veops/oneterm/api/controller"
|
||||||
redis "github.com/veops/oneterm/cache"
|
redis "github.com/veops/oneterm/cache"
|
||||||
"github.com/veops/oneterm/conf"
|
|
||||||
mysql "github.com/veops/oneterm/db"
|
mysql "github.com/veops/oneterm/db"
|
||||||
"github.com/veops/oneterm/logger"
|
"github.com/veops/oneterm/logger"
|
||||||
"github.com/veops/oneterm/model"
|
"github.com/veops/oneterm/model"
|
||||||
@@ -226,24 +225,22 @@ func (m *view) refresh() {
|
|||||||
auths := make([]*model.Authorization, 0)
|
auths := make([]*model.Authorization, 0)
|
||||||
assets := make([]*model.Asset, 0)
|
assets := make([]*model.Asset, 0)
|
||||||
accounts := make([]*model.Account, 0)
|
accounts := make([]*model.Account, 0)
|
||||||
dbAuth := mysql.DB.Model(auths)
|
|
||||||
dbAsset := mysql.DB.Model(assets)
|
dbAsset := mysql.DB.Model(assets)
|
||||||
dbAccount := mysql.DB.Model(accounts)
|
dbAccount := mysql.DB.Model(accounts)
|
||||||
|
|
||||||
if !acl.IsAdmin(m.currentUser) {
|
if !acl.IsAdmin(m.currentUser) {
|
||||||
rs, err := acl.GetRoleResources(ctx, m.currentUser.Acl.Rid, conf.GetResourceTypeName(conf.RESOURCE_AUTHORIZATION))
|
assetIds, err := controller.GetAssetIdsByAuthorization(m.Ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.L().Error("auths", zap.Error(err))
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
dbAuth = dbAuth.Where("resource_id IN ?", lo.Map(rs, func(r *acl.Resource, _ int) int { return r.ResourceId }))
|
dbAccount = dbAccount.Where("id IN ?", assetIds)
|
||||||
}
|
|
||||||
if err := dbAuth.Find(&auths).Error; err != nil {
|
accountIds, err := controller.GetAccountIdsByAuthorization(m.Ctx)
|
||||||
logger.L().Error("auths", zap.Error(err))
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
dbAccount = dbAccount.Where("id IN ?", lo.Map(auths, func(a *model.Authorization, _ int) int { return *a.AccountId }))
|
dbAsset = dbAsset.Where("id IN ?", accountIds)
|
||||||
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 {
|
||||||
|
Reference in New Issue
Block a user