add some audit log
This commit is contained in:
parent
d89eaec596
commit
184c39d311
|
@ -247,7 +247,7 @@ CREATE TABLE `role`
|
||||||
`note` varchar(255) not null default '',
|
`note` varchar(255) not null default '',
|
||||||
`cate` char(6) not null default '' comment 'category: global or local',
|
`cate` char(6) not null default '' comment 'category: global or local',
|
||||||
PRIMARY KEY (`id`),
|
PRIMARY KEY (`id`),
|
||||||
UNIQUE KEY (`name`)
|
UNIQUE KEY (`name`,`cate`)
|
||||||
) ENGINE = InnoDB
|
) ENGINE = InnoDB
|
||||||
DEFAULT CHARSET = utf8;
|
DEFAULT CHARSET = utf8;
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,7 @@ package models
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"regexp"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
@ -39,3 +40,124 @@ func Paths(longPath string) []string {
|
||||||
|
|
||||||
return paths
|
return paths
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func parseConditions(conditions string) (string, []interface{}) {
|
||||||
|
conditions = strings.TrimSpace(conditions)
|
||||||
|
if conditions == "" {
|
||||||
|
return "", []interface{}{}
|
||||||
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
where []string
|
||||||
|
args []interface{}
|
||||||
|
)
|
||||||
|
|
||||||
|
arr := strings.Split(conditions, ",")
|
||||||
|
cnt := len(arr)
|
||||||
|
for i := 0; i < cnt; i++ {
|
||||||
|
if strings.Contains(arr[i], "~=") {
|
||||||
|
pair := strings.Split(arr[i], "~=")
|
||||||
|
if WarningStr(pair[0]) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if strings.Contains(pair[0], "|") {
|
||||||
|
keys := strings.Split(pair[0], "|")
|
||||||
|
str := "("
|
||||||
|
for i, k := range keys {
|
||||||
|
if i < len(keys)-1 {
|
||||||
|
str += fmt.Sprintf("%s like ? OR ", k)
|
||||||
|
} else {
|
||||||
|
str += fmt.Sprintf("%s like ?)", k)
|
||||||
|
}
|
||||||
|
args = append(args, "%"+pair[1]+"%")
|
||||||
|
}
|
||||||
|
where = append(where, str)
|
||||||
|
} else {
|
||||||
|
where = append(where, pair[0]+" like ?")
|
||||||
|
args = append(args, "%"+pair[1]+"%")
|
||||||
|
}
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if strings.Contains(arr[i], "!=") {
|
||||||
|
pair := strings.Split(arr[i], "!=")
|
||||||
|
if WarningStr(pair[0]) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
where = append(where, pair[0]+" != ?")
|
||||||
|
args = append(args, pair[1])
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if strings.Contains(arr[i], ">=") {
|
||||||
|
pair := strings.Split(arr[i], ">=")
|
||||||
|
if WarningStr(pair[0]) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
where = append(where, pair[0]+" >= ?")
|
||||||
|
args = append(args, pair[1])
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if strings.Contains(arr[i], "<=") {
|
||||||
|
pair := strings.Split(arr[i], "<=")
|
||||||
|
if WarningStr(pair[0]) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
where = append(where, pair[0]+" <= ?")
|
||||||
|
args = append(args, pair[1])
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if strings.Contains(arr[i], "=") {
|
||||||
|
pair := strings.Split(arr[i], "=")
|
||||||
|
if WarningStr(pair[0]) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
where = append(where, pair[0]+" = ?")
|
||||||
|
args = append(args, pair[1])
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if strings.Contains(arr[i], ">") {
|
||||||
|
pair := strings.Split(arr[i], ">")
|
||||||
|
if WarningStr(pair[0]) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
where = append(where, pair[0]+" > ?")
|
||||||
|
args = append(args, pair[1])
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if strings.Contains(arr[i], "<") {
|
||||||
|
pair := strings.Split(arr[i], "<")
|
||||||
|
if WarningStr(pair[0]) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
where = append(where, pair[0]+" < ?")
|
||||||
|
args = append(args, pair[1])
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if strings.Contains(arr[i], "^^") {
|
||||||
|
pair := strings.Split(arr[i], "^^")
|
||||||
|
if WarningStr(pair[0]) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
where = append(where, pair[0]+" in ("+strings.Join(strings.Split(pair[1], "|"), ",")+")")
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return strings.Join(where, " and "), args
|
||||||
|
}
|
||||||
|
|
||||||
|
var dbfieldPattern = regexp.MustCompile("^[a-z][a-z0-9\\|_A-Z]*$")
|
||||||
|
|
||||||
|
func WarningStr(s string) bool {
|
||||||
|
if dbfieldPattern.MatchString(s) || s == "" {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
|
@ -141,9 +141,13 @@ func UsernameCandoNodeOp(username, operation string, nodeId int64) (bool, error)
|
||||||
return user.HasPermByNode(node, operation)
|
return user.HasPermByNode(node, operation)
|
||||||
}
|
}
|
||||||
|
|
||||||
func UserAndTotalGets(query, org string, limit, offset int, ids []int64) ([]User, int64, error) {
|
func UserAndTotalGets(query, org string, conditions string, limit, offset int, ids []int64) ([]User, int64, error) {
|
||||||
where := "1 = 1"
|
where := ""
|
||||||
param := []interface{}{}
|
param := []interface{}{}
|
||||||
|
where, param = parseConditions(conditions)
|
||||||
|
if where == "" {
|
||||||
|
where = "1 = 1"
|
||||||
|
}
|
||||||
|
|
||||||
if query != "" {
|
if query != "" {
|
||||||
q := "%" + query + "%"
|
q := "%" + query + "%"
|
||||||
|
|
|
@ -183,6 +183,7 @@ func Config(r *gin.Engine) {
|
||||||
|
|
||||||
v1.GET("/nodes", nodeGets)
|
v1.GET("/nodes", nodeGets)
|
||||||
v1.GET("/node/:id", nodeGet)
|
v1.GET("/node/:id", nodeGet)
|
||||||
|
v1.GET("/node-include-trash/:id", nodeIncludeTrashGet)
|
||||||
v1.GET("/node/:id/projs", v1treeUntilProjectGetsByNid)
|
v1.GET("/node/:id/projs", v1treeUntilProjectGetsByNid)
|
||||||
v1.GET("/tree/projs", v1TreeUntilProjectGets)
|
v1.GET("/tree/projs", v1TreeUntilProjectGets)
|
||||||
v1.GET("/tree", v1TreeUntilTypGets)
|
v1.GET("/tree", v1TreeUntilTypGets)
|
||||||
|
|
|
@ -15,6 +15,42 @@ func nodeGet(c *gin.Context) {
|
||||||
renderData(c, node, nil)
|
renderData(c, node, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//使用场景:节点被删除了,但还是需要查询节点来补全信息
|
||||||
|
func nodeIncludeTrashGet(c *gin.Context) {
|
||||||
|
nid := urlParamInt64(c, "id")
|
||||||
|
realNode, err := models.NodeGet("id=?", nid)
|
||||||
|
dangerous(err)
|
||||||
|
if realNode != nil {
|
||||||
|
realNode.FillAdmins()
|
||||||
|
renderData(c, realNode, nil)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
var node *models.Node
|
||||||
|
nodesInTrash, err := models.NodeTrashGetByIds([]int64{nid})
|
||||||
|
dangerous(err)
|
||||||
|
if len(nodesInTrash) == 1 {
|
||||||
|
nodeInTrash := nodesInTrash[0]
|
||||||
|
node = &models.Node{
|
||||||
|
Id: nid,
|
||||||
|
Pid: nodeInTrash.Pid,
|
||||||
|
Ident: nodeInTrash.Ident,
|
||||||
|
Name: nodeInTrash.Name,
|
||||||
|
Note: nodeInTrash.Note,
|
||||||
|
Path: nodeInTrash.Path,
|
||||||
|
Leaf: nodeInTrash.Leaf,
|
||||||
|
Cate: nodeInTrash.Cate,
|
||||||
|
IconColor: nodeInTrash.IconColor,
|
||||||
|
IconChar: nodeInTrash.IconChar,
|
||||||
|
Proxy: nodeInTrash.Proxy,
|
||||||
|
Creator: nodeInTrash.Creator,
|
||||||
|
LastUpdated: nodeInTrash.LastUpdated,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
renderData(c, node, nil)
|
||||||
|
}
|
||||||
|
|
||||||
func nodeGets(c *gin.Context) {
|
func nodeGets(c *gin.Context) {
|
||||||
cate := queryStr(c, "cate", "")
|
cate := queryStr(c, "cate", "")
|
||||||
withInner := queryInt(c, "inner", 0)
|
withInner := queryInt(c, "inner", 0)
|
||||||
|
@ -151,7 +187,8 @@ func nodePut(c *gin.Context) {
|
||||||
id := urlParamInt64(c, "id")
|
id := urlParamInt64(c, "id")
|
||||||
node := Node(id)
|
node := Node(id)
|
||||||
|
|
||||||
loginUser(c).CheckPermByNode(node, "rdb_node_modify")
|
me := loginUser(c)
|
||||||
|
me.CheckPermByNode(node, "rdb_node_modify")
|
||||||
|
|
||||||
// 即使是第三方系统创建的节点,也可以修改,只是改个名字、备注、类别、管理员,没啥大不了的
|
// 即使是第三方系统创建的节点,也可以修改,只是改个名字、备注、类别、管理员,没啥大不了的
|
||||||
// 第三方系统主要是管理下面的资源的挂载
|
// 第三方系统主要是管理下面的资源的挂载
|
||||||
|
@ -168,14 +205,17 @@ func nodePut(c *gin.Context) {
|
||||||
}
|
}
|
||||||
|
|
||||||
err := node.Modify(f.Name, f.Cate, f.Note, f.AdminIds)
|
err := node.Modify(f.Name, f.Cate, f.Note, f.AdminIds)
|
||||||
|
go models.OperationLogNew(me.Username, "node", node.Id, fmt.Sprintf("NodeModify path: %s, name: %s clientIP: %s", node.Path, node.Name, c.ClientIP()))
|
||||||
renderData(c, node, err)
|
renderData(c, node, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
func nodeDel(c *gin.Context) {
|
func nodeDel(c *gin.Context) {
|
||||||
id := urlParamInt64(c, "id")
|
id := urlParamInt64(c, "id")
|
||||||
node := Node(id)
|
node := Node(id)
|
||||||
|
me := loginUser(c)
|
||||||
|
me.CheckPermByNode(node, "rdb_node_delete")
|
||||||
|
|
||||||
loginUser(c).CheckPermByNode(node, "rdb_node_delete")
|
dangerous(node.Del())
|
||||||
|
go models.OperationLogNew(me.Username, "node", node.Id, fmt.Sprintf("NodeDelete path: %s, name: %s clientIP: %s", node.Path, node.Name, c.ClientIP()))
|
||||||
renderMessage(c, node.Del())
|
renderMessage(c, nil)
|
||||||
}
|
}
|
||||||
|
|
|
@ -380,9 +380,17 @@ func resourceBindNode(c *gin.Context) {
|
||||||
bomb("field[%s] not supported", f.Field)
|
bomb("field[%s] not supported", f.Field)
|
||||||
}
|
}
|
||||||
|
|
||||||
loginUser(c).CheckPermByNode(node, "rdb_resource_bind")
|
me := loginUser(c)
|
||||||
|
me.CheckPermByNode(node, "rdb_resource_bind")
|
||||||
|
dangerous(node.Bind(ids))
|
||||||
|
|
||||||
renderMessage(c, node.Bind(ids))
|
sql := "id in (" + str.IdsString(ids) + ")"
|
||||||
|
resources, _ := models.ResourceGets(sql)
|
||||||
|
for _, resource := range resources {
|
||||||
|
go models.OperationLogNew(me.Username, "node", node.Id, fmt.Sprintf("NodeBind path: %s, name: %s resource:%s clientIP: %s", node.Path, node.Name, resource.Ident, c.ClientIP()))
|
||||||
|
}
|
||||||
|
|
||||||
|
renderMessage(c, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
func resourceUnbindNode(c *gin.Context) {
|
func resourceUnbindNode(c *gin.Context) {
|
||||||
|
@ -395,9 +403,17 @@ func resourceUnbindNode(c *gin.Context) {
|
||||||
var f idsForm
|
var f idsForm
|
||||||
bind(c, &f)
|
bind(c, &f)
|
||||||
|
|
||||||
loginUser(c).CheckPermByNode(node, "rdb_resource_unbind")
|
me := loginUser(c)
|
||||||
|
me.CheckPermByNode(node, "rdb_resource_unbind")
|
||||||
|
dangerous(node.Unbind(f.Ids))
|
||||||
|
|
||||||
renderMessage(c, node.Unbind(f.Ids))
|
sql := "id in (" + str.IdsString(f.Ids) + ")"
|
||||||
|
resources, _ := models.ResourceGets(sql)
|
||||||
|
for _, resource := range resources {
|
||||||
|
go models.OperationLogNew(me.Username, "node", node.Id, fmt.Sprintf("NodeUnbind path: %s, name: %s resource:%s clientIP: %s", node.Path, node.Name, resource.Ident, c.ClientIP()))
|
||||||
|
}
|
||||||
|
|
||||||
|
renderMessage(c, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 这个修改备注信息是在节点下挂载的资源页面,非游离资源页面
|
// 这个修改备注信息是在节点下挂载的资源页面,非游离资源页面
|
||||||
|
|
|
@ -17,10 +17,11 @@ import (
|
||||||
func userListGet(c *gin.Context) {
|
func userListGet(c *gin.Context) {
|
||||||
limit := queryInt(c, "limit", 20)
|
limit := queryInt(c, "limit", 20)
|
||||||
query := queryStr(c, "query", "")
|
query := queryStr(c, "query", "")
|
||||||
|
conditions := queryStr(c, "conditions", "")
|
||||||
org := queryStr(c, "org", "")
|
org := queryStr(c, "org", "")
|
||||||
ids := str.IdsInt64(queryStr(c, "ids", ""))
|
ids := str.IdsInt64(queryStr(c, "ids", ""))
|
||||||
|
|
||||||
list, total, err := models.UserAndTotalGets(query, org, limit, offset(c, limit), ids)
|
list, total, err := models.UserAndTotalGets(query, org, conditions, limit, offset(c, limit), ids)
|
||||||
dangerous(err)
|
dangerous(err)
|
||||||
|
|
||||||
for i := 0; i < len(list); i++ {
|
for i := 0; i < len(list); i++ {
|
||||||
|
@ -40,7 +41,7 @@ func v1UserListGet(c *gin.Context) {
|
||||||
org := queryStr(c, "org", "")
|
org := queryStr(c, "org", "")
|
||||||
ids := str.IdsInt64(queryStr(c, "ids", ""))
|
ids := str.IdsInt64(queryStr(c, "ids", ""))
|
||||||
|
|
||||||
list, total, err := models.UserAndTotalGets(query, org, limit, offset(c, limit), ids)
|
list, total, err := models.UserAndTotalGets(query, org, "", limit, offset(c, limit), ids)
|
||||||
|
|
||||||
renderData(c, gin.H{
|
renderData(c, gin.H{
|
||||||
"list": list,
|
"list": list,
|
||||||
|
|
Loading…
Reference in New Issue