正在显示
12 个修改的文件
包含
193 行增加
和
4 行删除
| @@ -2,10 +2,11 @@ package command | @@ -2,10 +2,11 @@ package command | ||
| 2 | 2 | ||
| 3 | import ( | 3 | import ( |
| 4 | "fmt" | 4 | "fmt" |
| 5 | - "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/domain" | ||
| 6 | "reflect" | 5 | "reflect" |
| 7 | "strings" | 6 | "strings" |
| 8 | 7 | ||
| 8 | + "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/domain" | ||
| 9 | + | ||
| 9 | "github.com/beego/beego/v2/core/validation" | 10 | "github.com/beego/beego/v2/core/validation" |
| 10 | ) | 11 | ) |
| 11 | 12 | ||
| @@ -16,6 +17,7 @@ type FieldOptionalValuesCommand struct { | @@ -16,6 +17,7 @@ type FieldOptionalValuesCommand struct { | ||
| 16 | Match string `cname:"匹配内容" json:"match"` | 17 | Match string `cname:"匹配内容" json:"match"` |
| 17 | PageNumber int `json:"pageNumber"` | 18 | PageNumber int `json:"pageNumber"` |
| 18 | PageSize int `json:"pageSize"` | 19 | PageSize int `json:"pageSize"` |
| 20 | + Condition *domain.Condition `json:"condition"` | ||
| 19 | } | 21 | } |
| 20 | 22 | ||
| 21 | func (cmd *FieldOptionalValuesCommand) Valid(validation *validation.Validation) { | 23 | func (cmd *FieldOptionalValuesCommand) Valid(validation *validation.Validation) { |
| @@ -23,6 +23,9 @@ func (cmd *TablePreviewCommand) Valid(validation *validation.Validation) { | @@ -23,6 +23,9 @@ func (cmd *TablePreviewCommand) Valid(validation *validation.Validation) { | ||
| 23 | cmd.Where.PageNumber = cmd.PageNumber | 23 | cmd.Where.PageNumber = cmd.PageNumber |
| 24 | cmd.Where.PageSize = cmd.PageSize | 24 | cmd.Where.PageSize = cmd.PageSize |
| 25 | } | 25 | } |
| 26 | + if err := cmd.Where.ValidSql(); err != nil { | ||
| 27 | + validation.Error(err.Error()) | ||
| 28 | + } | ||
| 26 | } | 29 | } |
| 27 | 30 | ||
| 28 | func (cmd *TablePreviewCommand) ValidateCommand() error { | 31 | func (cmd *TablePreviewCommand) ValidateCommand() error { |
| @@ -24,6 +24,9 @@ func (cmd *DBTablePreviewCommand) Valid(validation *validation.Validation) { | @@ -24,6 +24,9 @@ func (cmd *DBTablePreviewCommand) Valid(validation *validation.Validation) { | ||
| 24 | cmd.Where.PageNumber = cmd.PageNumber | 24 | cmd.Where.PageNumber = cmd.PageNumber |
| 25 | cmd.Where.PageSize = cmd.PageSize | 25 | cmd.Where.PageSize = cmd.PageSize |
| 26 | } | 26 | } |
| 27 | + if err := cmd.Where.ValidSql(); err != nil { | ||
| 28 | + validation.Error(err.Error()) | ||
| 29 | + } | ||
| 27 | } | 30 | } |
| 28 | 31 | ||
| 29 | func (cmd *DBTablePreviewCommand) ValidateCommand() error { | 32 | func (cmd *DBTablePreviewCommand) ValidateCommand() error { |
| 1 | package dto | 1 | package dto |
| 2 | 2 | ||
| 3 | -import "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/domain" | 3 | +import ( |
| 4 | + "strings" | ||
| 5 | + | ||
| 6 | + "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/domain" | ||
| 7 | +) | ||
| 4 | 8 | ||
| 5 | type TableDto struct { | 9 | type TableDto struct { |
| 6 | // 表Id | 10 | // 表Id |
| @@ -19,3 +23,38 @@ func (d *TableDto) Load(m *domain.Table) { | @@ -19,3 +23,38 @@ func (d *TableDto) Load(m *domain.Table) { | ||
| 19 | d.Name = m.Name | 23 | d.Name = m.Name |
| 20 | d.ParentId = m.ParentId | 24 | d.ParentId = m.ParentId |
| 21 | } | 25 | } |
| 26 | + | ||
| 27 | +func SuitTableByView(tables []*TableDto, view string, name string) []*TableDto { | ||
| 28 | + var mainTables = make(map[int]*TableDto) | ||
| 29 | + var res = make([]*TableDto, 0) | ||
| 30 | + if view == "main" { | ||
| 31 | + for i := range tables { | ||
| 32 | + t := tables[i] | ||
| 33 | + if t.ParentId == 0 && t.TableType == domain.MainTable.ToString() { | ||
| 34 | + mainTables[t.TableId] = t | ||
| 35 | + res = append(res, t) | ||
| 36 | + } | ||
| 37 | + } | ||
| 38 | + for i := range tables { | ||
| 39 | + t := tables[i] | ||
| 40 | + if t.TableType == domain.SubTable.ToString() { | ||
| 41 | + if _, ok := mainTables[t.ParentId]; ok { | ||
| 42 | + res = append(res, t) | ||
| 43 | + } | ||
| 44 | + } | ||
| 45 | + } | ||
| 46 | + } else { | ||
| 47 | + res = tables | ||
| 48 | + } | ||
| 49 | + var matchName = make([]*TableDto, 0) | ||
| 50 | + if len(name) > 0 { | ||
| 51 | + for i := range res { | ||
| 52 | + t := res[i] | ||
| 53 | + if strings.Contains(t.Name, name) { | ||
| 54 | + matchName = append(matchName, t) | ||
| 55 | + } | ||
| 56 | + } | ||
| 57 | + res = matchName | ||
| 58 | + } | ||
| 59 | + return res | ||
| 60 | +} |
| @@ -12,6 +12,7 @@ import ( | @@ -12,6 +12,7 @@ import ( | ||
| 12 | type SearchTableQuery struct { | 12 | type SearchTableQuery struct { |
| 13 | // 表名称 | 13 | // 表名称 |
| 14 | Name string `cname:"表名称" json:"name"` | 14 | Name string `cname:"表名称" json:"name"` |
| 15 | + ViewType string `cname:"视图类型 full:完整 main:主表关系" json:"viewType"` | ||
| 15 | // 表类型 MainTable:主表 SideTable:副表 SubTable:分表 ExcelTable:Excel表 | 16 | // 表类型 MainTable:主表 SideTable:副表 SubTable:分表 ExcelTable:Excel表 |
| 16 | TableTypes []string `cname:"表类型 MainTable:主表 SideTable:副表 SubTable:分表 ExcelTable:Excel表" json:"tableTypes"` | 17 | TableTypes []string `cname:"表类型 MainTable:主表 SideTable:副表 SubTable:分表 ExcelTable:Excel表" json:"tableTypes"` |
| 17 | // 父级ID | 18 | // 父级ID |
| @@ -2,6 +2,7 @@ package service | @@ -2,6 +2,7 @@ package service | ||
| 2 | 2 | ||
| 3 | import ( | 3 | import ( |
| 4 | "fmt" | 4 | "fmt" |
| 5 | + | ||
| 5 | "github.com/linmadan/egglib-go/core/application" | 6 | "github.com/linmadan/egglib-go/core/application" |
| 6 | "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/application/factory" | 7 | "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/application/factory" |
| 7 | "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/application/table/command" | 8 | "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/application/table/command" |
| @@ -85,6 +86,11 @@ func (tableService *TableService) FieldOptionalValues(ctx *domain.Context, cmd * | @@ -85,6 +86,11 @@ func (tableService *TableService) FieldOptionalValues(ctx *domain.Context, cmd * | ||
| 85 | }, | 86 | }, |
| 86 | }, | 87 | }, |
| 87 | } | 88 | } |
| 89 | + if cmd.Condition != nil { | ||
| 90 | + options.Where = append(options.Where, starrocks.Condition{ | ||
| 91 | + Condition: *cmd.Condition, | ||
| 92 | + }) | ||
| 93 | + } | ||
| 88 | options.SetOffsetLimit(cmd.PageNumber, cmd.PageSize) | 94 | options.SetOffsetLimit(cmd.PageNumber, cmd.PageSize) |
| 89 | 95 | ||
| 90 | dataTable, err = starrocks.Query(*options, starrocks.WrapQueryFuncWithDB(db)) | 96 | dataTable, err = starrocks.Query(*options, starrocks.WrapQueryFuncWithDB(db)) |
| @@ -241,6 +241,47 @@ func (tableService *TableService) Search(searchQuery *query.SearchTableQuery) (i | @@ -241,6 +241,47 @@ func (tableService *TableService) Search(searchQuery *query.SearchTableQuery) (i | ||
| 241 | }, nil | 241 | }, nil |
| 242 | } | 242 | } |
| 243 | 243 | ||
| 244 | +// 表搜索 | ||
| 245 | +func (tableService *TableService) RelationGraph(searchQuery *query.SearchTableQuery) (interface{}, error) { | ||
| 246 | + if err := searchQuery.ValidateQuery(); err != nil { | ||
| 247 | + return nil, application.ThrowError(application.ARG_ERROR, err.Error()) | ||
| 248 | + } | ||
| 249 | + transactionContext, err := factory.CreateTransactionContext(nil) | ||
| 250 | + if err != nil { | ||
| 251 | + return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error()) | ||
| 252 | + } | ||
| 253 | + if err := transactionContext.StartTransaction(); err != nil { | ||
| 254 | + return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error()) | ||
| 255 | + } | ||
| 256 | + defer func() { | ||
| 257 | + transactionContext.RollbackTransaction() | ||
| 258 | + }() | ||
| 259 | + | ||
| 260 | + tableRepository, _, _ := factory.FastPgTable(transactionContext, 0) | ||
| 261 | + name :=searchQuery.Name | ||
| 262 | + searchQuery.Name = "" | ||
| 263 | + _, tables, err := tableRepository.Find(utils.ObjectToMap(searchQuery)) | ||
| 264 | + if err != nil { | ||
| 265 | + return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error()) | ||
| 266 | + } | ||
| 267 | + | ||
| 268 | + var result = make([]*dto.TableDto, 0) | ||
| 269 | + for _, table := range tables { | ||
| 270 | + var item = &dto.TableDto{} | ||
| 271 | + item.Load(table) | ||
| 272 | + result = append(result, item) | ||
| 273 | + } | ||
| 274 | + | ||
| 275 | + if err := transactionContext.CommitTransaction(); err != nil { | ||
| 276 | + return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error()) | ||
| 277 | + } | ||
| 278 | + result = dto.SuitTableByView(result,searchQuery.ViewType,name) | ||
| 279 | + return map[string]interface{}{ | ||
| 280 | + "count": len(result), | ||
| 281 | + "tables":result, | ||
| 282 | + }, nil | ||
| 283 | +} | ||
| 284 | + | ||
| 244 | // 更新表服务 | 285 | // 更新表服务 |
| 245 | func (tableService *TableService) UpdateTable(updateTableCommand *command.UpdateTableCommand) (interface{}, error) { | 286 | func (tableService *TableService) UpdateTable(updateTableCommand *command.UpdateTableCommand) (interface{}, error) { |
| 246 | if err := updateTableCommand.ValidateCommand(); err != nil { | 287 | if err := updateTableCommand.ValidateCommand(); err != nil { |
| @@ -19,6 +19,29 @@ func (w Where) Offset() int { | @@ -19,6 +19,29 @@ func (w Where) Offset() int { | ||
| 19 | return (w.PageNumber - 1) * w.PageSize | 19 | return (w.PageNumber - 1) * w.PageSize |
| 20 | } | 20 | } |
| 21 | 21 | ||
| 22 | +func (w Where) ValidSql() (err error) { | ||
| 23 | + for _, c := range w.Conditions { | ||
| 24 | + if err = SqlDetections(c.Like); err != nil { | ||
| 25 | + return err | ||
| 26 | + } | ||
| 27 | + //if err = SqlDetections(c.In...); err != nil { | ||
| 28 | + // return err | ||
| 29 | + //} | ||
| 30 | + //if err = SqlDetections(c.Ex...); err != nil { | ||
| 31 | + // return err | ||
| 32 | + //} | ||
| 33 | + if err = SqlDetections(c.Order); err != nil { | ||
| 34 | + return err | ||
| 35 | + } | ||
| 36 | + for _, r := range c.Range { | ||
| 37 | + if err = SqlDetections(r.Val); err != nil { | ||
| 38 | + return err | ||
| 39 | + } | ||
| 40 | + } | ||
| 41 | + } | ||
| 42 | + return | ||
| 43 | +} | ||
| 44 | + | ||
| 22 | type Condition struct { | 45 | type Condition struct { |
| 23 | Field *Field `json:"field"` | 46 | Field *Field `json:"field"` |
| 24 | Like string `json:"like"` | 47 | Like string `json:"like"` |
pkg/domain/sql_inject_detector.go
0 → 100644
| 1 | +package domain | ||
| 2 | + | ||
| 3 | +import ( | ||
| 4 | + "fmt" | ||
| 5 | + "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/infrastructure/utils" | ||
| 6 | + "strings" | ||
| 7 | +) | ||
| 8 | + | ||
| 9 | +var sqlKeys = []string{ | ||
| 10 | + "'", | ||
| 11 | + "`", | ||
| 12 | + //",", | ||
| 13 | + "--", | ||
| 14 | + "/*", | ||
| 15 | + //";", | ||
| 16 | + "(", | ||
| 17 | + ")", | ||
| 18 | + "#", | ||
| 19 | + "*", | ||
| 20 | + "or", | ||
| 21 | + "=", | ||
| 22 | + "having ", | ||
| 23 | + "union", | ||
| 24 | + "sleep", | ||
| 25 | + "as ", | ||
| 26 | + "from", | ||
| 27 | + "where", | ||
| 28 | + "exists", | ||
| 29 | + "and", | ||
| 30 | + "&&", | ||
| 31 | + "or", | ||
| 32 | + "||", | ||
| 33 | + "not", | ||
| 34 | + "in", | ||
| 35 | + "like", | ||
| 36 | + "is", | ||
| 37 | + "between", | ||
| 38 | + "union", | ||
| 39 | + "all", | ||
| 40 | + "having", | ||
| 41 | + "order", | ||
| 42 | + "group", | ||
| 43 | + "by", | ||
| 44 | + "print", | ||
| 45 | + "sleep", | ||
| 46 | +} | ||
| 47 | + | ||
| 48 | +var ErrorSqlInject = fmt.Errorf("!!! 请检查输入的内容,存在注入风险") | ||
| 49 | + | ||
| 50 | +func SqlDetections(args ...interface{}) error { | ||
| 51 | + for _, item := range args { | ||
| 52 | + if err := sqlDetection(item); err != nil { | ||
| 53 | + return err | ||
| 54 | + } | ||
| 55 | + } | ||
| 56 | + return nil | ||
| 57 | +} | ||
| 58 | + | ||
| 59 | +func sqlDetection(val interface{}) error { | ||
| 60 | + sVal := strings.ToLower(utils.AssertString(val)) | ||
| 61 | + for _, kw := range sqlKeys { | ||
| 62 | + if strings.Contains(sVal, kw) { | ||
| 63 | + return ErrorSqlInject | ||
| 64 | + } | ||
| 65 | + } | ||
| 66 | + return nil | ||
| 67 | +} |
| @@ -24,7 +24,8 @@ func (ptr *GenerateMainTableService) GenerateTable(ctx *domain.Context, fileId i | @@ -24,7 +24,8 @@ func (ptr *GenerateMainTableService) GenerateTable(ctx *domain.Context, fileId i | ||
| 24 | if err != nil { | 24 | if err != nil { |
| 25 | return nil, fmt.Errorf("文件未校验") | 25 | return nil, fmt.Errorf("文件未校验") |
| 26 | } | 26 | } |
| 27 | - duplicateTable, err := tableRepository.FindOne(map[string]interface{}{"context": ctx, "tableName": tableName}) | 27 | + duplicateTable, err := tableRepository.FindOne(map[string]interface{}{"context": ctx, "tableName": tableName, |
| 28 | + "tableTypes":[]string{string(domain.MainTable),string(domain.SubTable),string(domain.SideTable)}}) | ||
| 28 | if err == nil && duplicateTable != nil { | 29 | if err == nil && duplicateTable != nil { |
| 29 | return nil, fmt.Errorf("表名称重复") | 30 | return nil, fmt.Errorf("表名称重复") |
| 30 | } | 31 | } |
| @@ -136,6 +136,9 @@ func (repository *TableRepository) FindOne(queryOptions map[string]interface{}) | @@ -136,6 +136,9 @@ func (repository *TableRepository) FindOne(queryOptions map[string]interface{}) | ||
| 136 | query.SetWhereByQueryOption(`table_type = ?`, "tableType") | 136 | query.SetWhereByQueryOption(`table_type = ?`, "tableType") |
| 137 | query.SetWhereByQueryOption("name = ?", "tableName") | 137 | query.SetWhereByQueryOption("name = ?", "tableName") |
| 138 | query.SetWhereByQueryOption("parent_id = ?", "parentId") | 138 | query.SetWhereByQueryOption("parent_id = ?", "parentId") |
| 139 | + if v, ok := queryOptions["tableTypes"]; ok && len(v.([]string)) > 0 { | ||
| 140 | + query.Where(`table_type in (?)`, pg.In(v.([]string))) | ||
| 141 | + } | ||
| 139 | if err := query.First(); err != nil { | 142 | if err := query.First(); err != nil { |
| 140 | if err.Error() == "pg: no rows in result set" { | 143 | if err.Error() == "pg: no rows in result set" { |
| 141 | return nil, domain.ErrorNotFound | 144 | return nil, domain.ErrorNotFound |
| @@ -111,7 +111,7 @@ func (controller *TableController) RelationGraph() { | @@ -111,7 +111,7 @@ func (controller *TableController) RelationGraph() { | ||
| 111 | Must(controller.Unmarshal(cmd)) | 111 | Must(controller.Unmarshal(cmd)) |
| 112 | cmd.TableTypes = []string{domain.MainTable.ToString(), domain.SideTable.ToString(), domain.SubTable.ToString()} | 112 | cmd.TableTypes = []string{domain.MainTable.ToString(), domain.SideTable.ToString(), domain.SubTable.ToString()} |
| 113 | cmd.Context = ParseContext(controller.BaseController) | 113 | cmd.Context = ParseContext(controller.BaseController) |
| 114 | - data, err := tableService.Search(cmd) | 114 | + data, err := tableService.RelationGraph(cmd) |
| 115 | controller.Response(data, err) | 115 | controller.Response(data, err) |
| 116 | } | 116 | } |
| 117 | 117 |
-
请 注册 或 登录 后发表评论