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 '',
|
||||
`cate` char(6) not null default '' comment 'category: global or local',
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY (`name`)
|
||||
UNIQUE KEY (`name`,`cate`)
|
||||
) ENGINE = InnoDB
|
||||
DEFAULT CHARSET = utf8;
|
||||
|
||||
|
|
|
@ -2,6 +2,7 @@ package models
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"regexp"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
|
@ -39,3 +40,124 @@ func Paths(longPath string) []string {
|
|||
|
||||
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)
|
||||
}
|
||||
|
||||
func UserAndTotalGets(query, org string, limit, offset int, ids []int64) ([]User, int64, error) {
|
||||
where := "1 = 1"
|
||||
func UserAndTotalGets(query, org string, conditions string, limit, offset int, ids []int64) ([]User, int64, error) {
|
||||
where := ""
|
||||
param := []interface{}{}
|
||||
where, param = parseConditions(conditions)
|
||||
if where == "" {
|
||||
where = "1 = 1"
|
||||
}
|
||||
|
||||
if query != "" {
|
||||
q := "%" + query + "%"
|
||||
|
|
|
@ -183,6 +183,7 @@ func Config(r *gin.Engine) {
|
|||
|
||||
v1.GET("/nodes", nodeGets)
|
||||
v1.GET("/node/:id", nodeGet)
|
||||
v1.GET("/node-include-trash/:id", nodeIncludeTrashGet)
|
||||
v1.GET("/node/:id/projs", v1treeUntilProjectGetsByNid)
|
||||
v1.GET("/tree/projs", v1TreeUntilProjectGets)
|
||||
v1.GET("/tree", v1TreeUntilTypGets)
|
||||
|
|
|
@ -15,6 +15,42 @@ func nodeGet(c *gin.Context) {
|
|||
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) {
|
||||
cate := queryStr(c, "cate", "")
|
||||
withInner := queryInt(c, "inner", 0)
|
||||
|
@ -151,7 +187,8 @@ func nodePut(c *gin.Context) {
|
|||
id := urlParamInt64(c, "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)
|
||||
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)
|
||||
}
|
||||
|
||||
func nodeDel(c *gin.Context) {
|
||||
id := urlParamInt64(c, "id")
|
||||
node := Node(id)
|
||||
me := loginUser(c)
|
||||
me.CheckPermByNode(node, "rdb_node_delete")
|
||||
|
||||
loginUser(c).CheckPermByNode(node, "rdb_node_delete")
|
||||
|
||||
renderMessage(c, node.Del())
|
||||
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, nil)
|
||||
}
|
||||
|
|
|
@ -380,9 +380,17 @@ func resourceBindNode(c *gin.Context) {
|
|||
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) {
|
||||
|
@ -395,9 +403,17 @@ func resourceUnbindNode(c *gin.Context) {
|
|||
var f idsForm
|
||||
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) {
|
||||
limit := queryInt(c, "limit", 20)
|
||||
query := queryStr(c, "query", "")
|
||||
conditions := queryStr(c, "conditions", "")
|
||||
org := queryStr(c, "org", "")
|
||||
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)
|
||||
|
||||
for i := 0; i < len(list); i++ {
|
||||
|
@ -40,7 +41,7 @@ func v1UserListGet(c *gin.Context) {
|
|||
org := queryStr(c, "org", "")
|
||||
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{
|
||||
"list": list,
|
||||
|
|
Loading…
Reference in New Issue