mirror of
https://github.com/bitechdev/ResolveSpec.git
synced 2025-11-13 09:53:53 +00:00
Fixed linting issues
This commit is contained in:
parent
7b8216b71c
commit
ecd7b31910
@ -1,5 +1,7 @@
|
|||||||
# 📜 ResolveSpec 📜
|
# 📜 ResolveSpec 📜
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
ResolveSpec is a flexible and powerful REST API specification and implementation that provides GraphQL-like capabilities while maintaining REST simplicity. It offers **two complementary approaches**:
|
ResolveSpec is a flexible and powerful REST API specification and implementation that provides GraphQL-like capabilities while maintaining REST simplicity. It offers **two complementary approaches**:
|
||||||
|
|
||||||
1. **ResolveSpec** - Body-based API with JSON request options
|
1. **ResolveSpec** - Body-based API with JSON request options
|
||||||
|
|||||||
@ -100,6 +100,10 @@ func (b *BunSelectQuery) Model(model interface{}) common.SelectQuery {
|
|||||||
b.schema, b.tableName = parseTableName(fullTableName)
|
b.schema, b.tableName = parseTableName(fullTableName)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if provider, ok := model.(common.TableAliasProvider); ok {
|
||||||
|
b.tableAlias = provider.TableAlias()
|
||||||
|
}
|
||||||
|
|
||||||
return b
|
return b
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -86,6 +86,10 @@ func (g *GormSelectQuery) Model(model interface{}) common.SelectQuery {
|
|||||||
g.schema, g.tableName = parseTableName(fullTableName)
|
g.schema, g.tableName = parseTableName(fullTableName)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if provider, ok := model.(common.TableAliasProvider); ok {
|
||||||
|
g.tableAlias = provider.TableAlias()
|
||||||
|
}
|
||||||
|
|
||||||
return g
|
return g
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -267,11 +271,12 @@ func (g *GormInsertQuery) Returning(columns ...string) common.InsertQuery {
|
|||||||
|
|
||||||
func (g *GormInsertQuery) Exec(ctx context.Context) (common.Result, error) {
|
func (g *GormInsertQuery) Exec(ctx context.Context) (common.Result, error) {
|
||||||
var result *gorm.DB
|
var result *gorm.DB
|
||||||
if g.model != nil {
|
switch {
|
||||||
|
case g.model != nil:
|
||||||
result = g.db.WithContext(ctx).Create(g.model)
|
result = g.db.WithContext(ctx).Create(g.model)
|
||||||
} else if g.values != nil {
|
case g.values != nil:
|
||||||
result = g.db.WithContext(ctx).Create(g.values)
|
result = g.db.WithContext(ctx).Create(g.values)
|
||||||
} else {
|
default:
|
||||||
result = g.db.WithContext(ctx).Create(map[string]interface{}{})
|
result = g.db.WithContext(ctx).Create(map[string]interface{}{})
|
||||||
}
|
}
|
||||||
return &GormResult{result: result}, result.Error
|
return &GormResult{result: result}, result.Error
|
||||||
|
|||||||
@ -130,7 +130,7 @@ func (h *HTTPRequest) AllHeaders() map[string]string {
|
|||||||
// HTTPResponseWriter adapts our ResponseWriter interface to standard http.ResponseWriter
|
// HTTPResponseWriter adapts our ResponseWriter interface to standard http.ResponseWriter
|
||||||
type HTTPResponseWriter struct {
|
type HTTPResponseWriter struct {
|
||||||
resp http.ResponseWriter
|
resp http.ResponseWriter
|
||||||
w common.ResponseWriter
|
w common.ResponseWriter //nolint:unused
|
||||||
status int
|
status int
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -131,6 +131,10 @@ type TableNameProvider interface {
|
|||||||
TableName() string
|
TableName() string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type TableAliasProvider interface {
|
||||||
|
TableAlias() string
|
||||||
|
}
|
||||||
|
|
||||||
// PrimaryKeyNameProvider interface for models that provide primary key column names
|
// PrimaryKeyNameProvider interface for models that provide primary key column names
|
||||||
type PrimaryKeyNameProvider interface {
|
type PrimaryKeyNameProvider interface {
|
||||||
GetIDName() string
|
GetIDName() string
|
||||||
|
|||||||
@ -49,12 +49,13 @@ func GetModelColumnDetail(record reflect.Value) []ModelFieldDetail {
|
|||||||
fielddetail.DataType = fieldtype.Type.Name()
|
fielddetail.DataType = fieldtype.Type.Name()
|
||||||
fielddetail.SQLName = fnFindKeyVal(gormdetail, "column:")
|
fielddetail.SQLName = fnFindKeyVal(gormdetail, "column:")
|
||||||
fielddetail.SQLDataType = fnFindKeyVal(gormdetail, "type:")
|
fielddetail.SQLDataType = fnFindKeyVal(gormdetail, "type:")
|
||||||
if strings.Index(strings.ToLower(gormdetail), "identity") > 0 ||
|
gormdetailLower := strings.ToLower(gormdetail)
|
||||||
strings.Index(strings.ToLower(gormdetail), "primary_key") > 0 {
|
switch {
|
||||||
|
case strings.Index(gormdetailLower, "identity") > 0 || strings.Index(gormdetailLower, "primary_key") > 0:
|
||||||
fielddetail.SQLKey = "primary_key"
|
fielddetail.SQLKey = "primary_key"
|
||||||
} else if strings.Contains(strings.ToLower(gormdetail), "unique") {
|
case strings.Contains(gormdetailLower, "unique"):
|
||||||
fielddetail.SQLKey = "unique"
|
fielddetail.SQLKey = "unique"
|
||||||
} else if strings.Contains(strings.ToLower(gormdetail), "uniqueindex") {
|
case strings.Contains(gormdetailLower, "uniqueindex"):
|
||||||
fielddetail.SQLKey = "uniqueindex"
|
fielddetail.SQLKey = "uniqueindex"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -481,11 +481,12 @@ func (h *Handler) handleUpdate(ctx context.Context, w common.ResponseWriter, url
|
|||||||
case map[string]interface{}:
|
case map[string]interface{}:
|
||||||
// Determine the ID to use
|
// Determine the ID to use
|
||||||
var targetID interface{}
|
var targetID interface{}
|
||||||
if urlID != "" {
|
switch {
|
||||||
|
case urlID != "":
|
||||||
targetID = urlID
|
targetID = urlID
|
||||||
} else if reqID != nil {
|
case reqID != nil:
|
||||||
targetID = reqID
|
targetID = reqID
|
||||||
} else if updates["id"] != nil {
|
case updates["id"] != nil:
|
||||||
targetID = updates["id"]
|
targetID = updates["id"]
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -723,11 +724,12 @@ func (h *Handler) handleDelete(ctx context.Context, w common.ResponseWriter, id
|
|||||||
var itemID interface{}
|
var itemID interface{}
|
||||||
|
|
||||||
// Check if item is a string ID or object with id field
|
// Check if item is a string ID or object with id field
|
||||||
if idStr, ok := item.(string); ok {
|
switch v := item.(type) {
|
||||||
itemID = idStr
|
case string:
|
||||||
} else if itemMap, ok := item.(map[string]interface{}); ok {
|
itemID = v
|
||||||
itemID = itemMap["id"]
|
case map[string]interface{}:
|
||||||
} else {
|
itemID = v["id"]
|
||||||
|
default:
|
||||||
// Try to use the item directly as ID
|
// Try to use the item directly as ID
|
||||||
itemID = item
|
itemID = item
|
||||||
}
|
}
|
||||||
|
|||||||
@ -781,11 +781,12 @@ func (h *Handler) handleUpdate(ctx context.Context, w common.ResponseWriter, id
|
|||||||
query := h.db.NewUpdate().Table(tableName).SetMap(dataMap)
|
query := h.db.NewUpdate().Table(tableName).SetMap(dataMap)
|
||||||
|
|
||||||
// Apply ID filter
|
// Apply ID filter
|
||||||
if id != "" {
|
switch {
|
||||||
|
case id != "":
|
||||||
query = query.Where("id = ?", id)
|
query = query.Where("id = ?", id)
|
||||||
} else if idPtr != nil {
|
case idPtr != nil:
|
||||||
query = query.Where("id = ?", *idPtr)
|
query = query.Where("id = ?", *idPtr)
|
||||||
} else {
|
default:
|
||||||
h.sendError(w, http.StatusBadRequest, "missing_id", "ID is required for update", nil)
|
h.sendError(w, http.StatusBadRequest, "missing_id", "ID is required for update", nil)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -902,11 +903,12 @@ func (h *Handler) handleDelete(ctx context.Context, w common.ResponseWriter, id
|
|||||||
var itemID interface{}
|
var itemID interface{}
|
||||||
|
|
||||||
// Check if item is a string ID or object with id field
|
// Check if item is a string ID or object with id field
|
||||||
if idStr, ok := item.(string); ok {
|
switch v := item.(type) {
|
||||||
itemID = idStr
|
case string:
|
||||||
} else if itemMap, ok := item.(map[string]interface{}); ok {
|
itemID = v
|
||||||
itemID = itemMap["id"]
|
case map[string]interface{}:
|
||||||
} else {
|
itemID = v["id"]
|
||||||
|
default:
|
||||||
itemID = item
|
itemID = item
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1330,7 +1332,9 @@ func (h *Handler) sendResponse(w common.ResponseWriter, data interface{}, metada
|
|||||||
Metadata: metadata,
|
Metadata: metadata,
|
||||||
}
|
}
|
||||||
w.WriteHeader(http.StatusOK)
|
w.WriteHeader(http.StatusOK)
|
||||||
w.WriteJSON(response)
|
if err := w.WriteJSON(response); err != nil {
|
||||||
|
logger.Error("Failed to write JSON response: %v", err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// sendFormattedResponse sends response with formatting options
|
// sendFormattedResponse sends response with formatting options
|
||||||
@ -1350,7 +1354,9 @@ func (h *Handler) sendFormattedResponse(w common.ResponseWriter, data interface{
|
|||||||
case "simple":
|
case "simple":
|
||||||
// Simple format: just return the data array
|
// Simple format: just return the data array
|
||||||
w.WriteHeader(http.StatusOK)
|
w.WriteHeader(http.StatusOK)
|
||||||
w.WriteJSON(data)
|
if err := w.WriteJSON(data); err != nil {
|
||||||
|
logger.Error("Failed to write JSON response: %v", err)
|
||||||
|
}
|
||||||
case "syncfusion":
|
case "syncfusion":
|
||||||
// Syncfusion format: { result: data, count: total }
|
// Syncfusion format: { result: data, count: total }
|
||||||
response := map[string]interface{}{
|
response := map[string]interface{}{
|
||||||
@ -1360,7 +1366,9 @@ func (h *Handler) sendFormattedResponse(w common.ResponseWriter, data interface{
|
|||||||
response["count"] = metadata.Total
|
response["count"] = metadata.Total
|
||||||
}
|
}
|
||||||
w.WriteHeader(http.StatusOK)
|
w.WriteHeader(http.StatusOK)
|
||||||
w.WriteJSON(response)
|
if err := w.WriteJSON(response); err != nil {
|
||||||
|
logger.Error("Failed to write JSON response: %v", err)
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
// Default/detail format: standard response with metadata
|
// Default/detail format: standard response with metadata
|
||||||
response := common.Response{
|
response := common.Response{
|
||||||
@ -1369,7 +1377,9 @@ func (h *Handler) sendFormattedResponse(w common.ResponseWriter, data interface{
|
|||||||
Metadata: metadata,
|
Metadata: metadata,
|
||||||
}
|
}
|
||||||
w.WriteHeader(http.StatusOK)
|
w.WriteHeader(http.StatusOK)
|
||||||
w.WriteJSON(response)
|
if err := w.WriteJSON(response); err != nil {
|
||||||
|
logger.Error("Failed to write JSON response: %v", err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1397,7 +1407,9 @@ func (h *Handler) sendError(w common.ResponseWriter, statusCode int, code, messa
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
w.WriteHeader(statusCode)
|
w.WriteHeader(statusCode)
|
||||||
w.WriteJSON(response)
|
if err := w.WriteJSON(response); err != nil {
|
||||||
|
logger.Error("Failed to write JSON error response: %v", err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// FetchRowNumber calculates the row number of a specific record based on sorting and filtering
|
// FetchRowNumber calculates the row number of a specific record based on sorting and filtering
|
||||||
|
|||||||
@ -416,16 +416,17 @@ func (h *Handler) parseSorting(options *ExtendedRequestOptions, value string) {
|
|||||||
direction := "ASC"
|
direction := "ASC"
|
||||||
colName := field
|
colName := field
|
||||||
|
|
||||||
if strings.HasPrefix(field, "-") {
|
switch {
|
||||||
|
case strings.HasPrefix(field, "-"):
|
||||||
direction = "DESC"
|
direction = "DESC"
|
||||||
colName = strings.TrimPrefix(field, "-")
|
colName = strings.TrimPrefix(field, "-")
|
||||||
} else if strings.HasPrefix(field, "+") {
|
case strings.HasPrefix(field, "+"):
|
||||||
direction = "ASC"
|
direction = "ASC"
|
||||||
colName = strings.TrimPrefix(field, "+")
|
colName = strings.TrimPrefix(field, "+")
|
||||||
} else if strings.HasSuffix(field, " desc") {
|
case strings.HasSuffix(field, " desc"):
|
||||||
direction = "DESC"
|
direction = "DESC"
|
||||||
colName = strings.TrimSuffix(field, "desc")
|
colName = strings.TrimSuffix(field, "desc")
|
||||||
} else if strings.HasSuffix(field, " asc") {
|
case strings.HasSuffix(field, " asc"):
|
||||||
direction = "ASC"
|
direction = "ASC"
|
||||||
colName = strings.TrimSuffix(field, "asc")
|
colName = strings.TrimSuffix(field, "asc")
|
||||||
}
|
}
|
||||||
|
|||||||
@ -62,6 +62,7 @@ import (
|
|||||||
|
|
||||||
"github.com/bitechdev/ResolveSpec/pkg/common/adapters/database"
|
"github.com/bitechdev/ResolveSpec/pkg/common/adapters/database"
|
||||||
"github.com/bitechdev/ResolveSpec/pkg/common/adapters/router"
|
"github.com/bitechdev/ResolveSpec/pkg/common/adapters/router"
|
||||||
|
"github.com/bitechdev/ResolveSpec/pkg/logger"
|
||||||
"github.com/bitechdev/ResolveSpec/pkg/modelregistry"
|
"github.com/bitechdev/ResolveSpec/pkg/modelregistry"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -252,5 +253,7 @@ func ExampleBunRouterWithBunDB(bunDB *bun.DB) {
|
|||||||
r := routerAdapter.GetBunRouter()
|
r := routerAdapter.GetBunRouter()
|
||||||
|
|
||||||
// Start server
|
// Start server
|
||||||
http.ListenAndServe(":8080", r)
|
if err := http.ListenAndServe(":8080", r); err != nil {
|
||||||
|
logger.Error("Server failed to start: %v", err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -5,7 +5,6 @@ import (
|
|||||||
"net/http"
|
"net/http"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
// DBM "github.com/bitechdev/GoCore/pkg/models"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// This file provides example implementations of the required security callbacks.
|
// This file provides example implementations of the required security callbacks.
|
||||||
|
|||||||
@ -27,9 +27,7 @@ func RegisterSecurityHooks(handler *restheadspec.Handler, securityList *Security
|
|||||||
})
|
})
|
||||||
|
|
||||||
// Hook 4 (Optional): Audit logging
|
// Hook 4 (Optional): Audit logging
|
||||||
handler.Hooks().Register(restheadspec.AfterRead, func(hookCtx *restheadspec.HookContext) error {
|
handler.Hooks().Register(restheadspec.AfterRead, logDataAccess)
|
||||||
return logDataAccess(hookCtx)
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// loadSecurityRules loads security configuration for the user and entity
|
// loadSecurityRules loads security configuration for the user and entity
|
||||||
@ -162,7 +160,7 @@ func applyColumnSecurity(hookCtx *restheadspec.HookContext, securityList *Securi
|
|||||||
resultValue = resultValue.Elem()
|
resultValue = resultValue.Elem()
|
||||||
}
|
}
|
||||||
|
|
||||||
err, maskedResult := securityList.ApplyColumnSecurity(resultValue, modelType, userID, schema, tablename)
|
maskedResult, err := securityList.ApplyColumnSecurity(resultValue, modelType, userID, schema, tablename)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Warn("Column security error: %v", err)
|
logger.Warn("Column security error: %v", err)
|
||||||
// Don't fail the request, just log the issue
|
// Don't fail the request, just log the issue
|
||||||
|
|||||||
@ -5,11 +5,14 @@ import (
|
|||||||
"net/http"
|
"net/http"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// contextKey is a custom type for context keys to avoid collisions
|
||||||
|
type contextKey string
|
||||||
|
|
||||||
const (
|
const (
|
||||||
// Context keys for user information
|
// Context keys for user information
|
||||||
UserIDKey = "user_id"
|
UserIDKey contextKey = "user_id"
|
||||||
UserRolesKey = "user_roles"
|
UserRolesKey contextKey = "user_roles"
|
||||||
UserTokenKey = "user_token"
|
UserTokenKey contextKey = "user_token"
|
||||||
)
|
)
|
||||||
|
|
||||||
// AuthMiddleware extracts user authentication from request and adds to context
|
// AuthMiddleware extracts user authentication from request and adds to context
|
||||||
|
|||||||
@ -73,8 +73,9 @@ type SecurityList struct {
|
|||||||
LoadColumnSecurityCallback LoadColumnSecurityFunc
|
LoadColumnSecurityCallback LoadColumnSecurityFunc
|
||||||
LoadRowSecurityCallback LoadRowSecurityFunc
|
LoadRowSecurityCallback LoadRowSecurityFunc
|
||||||
}
|
}
|
||||||
|
type CONTEXT_KEY string
|
||||||
|
|
||||||
const SECURITY_CONTEXT_KEY = "SecurityList"
|
const SECURITY_CONTEXT_KEY CONTEXT_KEY = "SecurityList"
|
||||||
|
|
||||||
var GlobalSecurity SecurityList
|
var GlobalSecurity SecurityList
|
||||||
|
|
||||||
@ -105,22 +106,22 @@ func maskString(pString string, maskStart, maskEnd int, maskChar string, invert
|
|||||||
}
|
}
|
||||||
for index, char := range pString {
|
for index, char := range pString {
|
||||||
if invert && index >= middleIndex-maskStart && index <= middleIndex {
|
if invert && index >= middleIndex-maskStart && index <= middleIndex {
|
||||||
newStr = newStr + maskChar
|
newStr += maskChar
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if invert && index <= middleIndex+maskEnd && index >= middleIndex {
|
if invert && index <= middleIndex+maskEnd && index >= middleIndex {
|
||||||
newStr = newStr + maskChar
|
newStr += maskChar
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if !invert && index <= maskStart {
|
if !invert && index <= maskStart {
|
||||||
newStr = newStr + maskChar
|
newStr += maskChar
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if !invert && index >= strLen-1-maskEnd {
|
if !invert && index >= strLen-1-maskEnd {
|
||||||
newStr = newStr + maskChar
|
newStr += maskChar
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
newStr = newStr + string(char)
|
newStr += string(char)
|
||||||
}
|
}
|
||||||
|
|
||||||
return newStr
|
return newStr
|
||||||
@ -145,7 +146,8 @@ func (m *SecurityList) ColumSecurityApplyOnRecord(prevRecord reflect.Value, newR
|
|||||||
return cols, fmt.Errorf("no security data")
|
return cols, fmt.Errorf("no security data")
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, colsec := range colsecList {
|
for i := range colsecList {
|
||||||
|
colsec := &colsecList[i]
|
||||||
if !strings.EqualFold(colsec.Accesstype, "mask") && !strings.EqualFold(colsec.Accesstype, "hide") {
|
if !strings.EqualFold(colsec.Accesstype, "mask") && !strings.EqualFold(colsec.Accesstype, "hide") {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
@ -262,24 +264,25 @@ func setColSecValue(fieldsrc reflect.Value, colsec ColumnSecurity, fieldTypeName
|
|||||||
fieldval = fieldval.Elem()
|
fieldval = fieldval.Elem()
|
||||||
}
|
}
|
||||||
|
|
||||||
if strings.Contains(strings.ToLower(fieldval.Kind().String()), "int") &&
|
fieldKindLower := strings.ToLower(fieldval.Kind().String())
|
||||||
(strings.EqualFold(colsec.Accesstype, "mask") || strings.EqualFold(colsec.Accesstype, "hide")) {
|
switch {
|
||||||
|
case strings.Contains(fieldKindLower, "int") &&
|
||||||
|
(strings.EqualFold(colsec.Accesstype, "mask") || strings.EqualFold(colsec.Accesstype, "hide")):
|
||||||
if fieldval.CanInt() && fieldval.CanSet() {
|
if fieldval.CanInt() && fieldval.CanSet() {
|
||||||
fieldval.SetInt(0)
|
fieldval.SetInt(0)
|
||||||
}
|
}
|
||||||
} else if (strings.Contains(strings.ToLower(fieldval.Kind().String()), "time") ||
|
case (strings.Contains(fieldKindLower, "time") || strings.Contains(fieldKindLower, "date")) &&
|
||||||
strings.Contains(strings.ToLower(fieldval.Kind().String()), "date")) &&
|
(strings.EqualFold(colsec.Accesstype, "mask") || strings.EqualFold(colsec.Accesstype, "hide")):
|
||||||
(strings.EqualFold(colsec.Accesstype, "mask") || strings.EqualFold(colsec.Accesstype, "hide")) {
|
|
||||||
fieldval.SetZero()
|
fieldval.SetZero()
|
||||||
} else if strings.Contains(strings.ToLower(fieldval.Kind().String()), "string") {
|
case strings.Contains(fieldKindLower, "string"):
|
||||||
strVal := fieldval.String()
|
strVal := fieldval.String()
|
||||||
if strings.EqualFold(colsec.Accesstype, "mask") {
|
if strings.EqualFold(colsec.Accesstype, "mask") {
|
||||||
fieldval.SetString(maskString(strVal, colsec.MaskStart, colsec.MaskEnd, colsec.MaskChar, colsec.MaskInvert))
|
fieldval.SetString(maskString(strVal, colsec.MaskStart, colsec.MaskEnd, colsec.MaskChar, colsec.MaskInvert))
|
||||||
} else if strings.EqualFold(colsec.Accesstype, "hide") {
|
} else if strings.EqualFold(colsec.Accesstype, "hide") {
|
||||||
fieldval.SetString("")
|
fieldval.SetString("")
|
||||||
}
|
}
|
||||||
} else if strings.Contains(fieldTypeName, "json") &&
|
case strings.Contains(fieldTypeName, "json") &&
|
||||||
(strings.EqualFold(colsec.Accesstype, "mask") || strings.EqualFold(colsec.Accesstype, "hide")) {
|
(strings.EqualFold(colsec.Accesstype, "mask") || strings.EqualFold(colsec.Accesstype, "hide")):
|
||||||
if len(colsec.Path) < 2 {
|
if len(colsec.Path) < 2 {
|
||||||
return 1, fieldval
|
return 1, fieldval
|
||||||
}
|
}
|
||||||
@ -300,11 +303,11 @@ func setColSecValue(fieldsrc reflect.Value, colsec ColumnSecurity, fieldTypeName
|
|||||||
return 0, fieldsrc
|
return 0, fieldsrc
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *SecurityList) ApplyColumnSecurity(records reflect.Value, modelType reflect.Type, pUserID int, pSchema, pTablename string) (error, reflect.Value) {
|
func (m *SecurityList) ApplyColumnSecurity(records reflect.Value, modelType reflect.Type, pUserID int, pSchema, pTablename string) (reflect.Value, error) {
|
||||||
defer logger.CatchPanic("ApplyColumnSecurity")
|
defer logger.CatchPanic("ApplyColumnSecurity")
|
||||||
|
|
||||||
if m.ColumnSecurity == nil {
|
if m.ColumnSecurity == nil {
|
||||||
return fmt.Errorf("security not initialized"), records
|
return records, fmt.Errorf("security not initialized")
|
||||||
}
|
}
|
||||||
|
|
||||||
m.ColumnSecurityMutex.RLock()
|
m.ColumnSecurityMutex.RLock()
|
||||||
@ -312,10 +315,11 @@ func (m *SecurityList) ApplyColumnSecurity(records reflect.Value, modelType refl
|
|||||||
|
|
||||||
colsecList, ok := m.ColumnSecurity[fmt.Sprintf("%s.%s@%d", pSchema, pTablename, pUserID)]
|
colsecList, ok := m.ColumnSecurity[fmt.Sprintf("%s.%s@%d", pSchema, pTablename, pUserID)]
|
||||||
if !ok || colsecList == nil {
|
if !ok || colsecList == nil {
|
||||||
return fmt.Errorf("no security data"), records
|
return records, fmt.Errorf("no security data")
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, colsec := range colsecList {
|
for i := range colsecList {
|
||||||
|
colsec := &colsecList[i]
|
||||||
if !strings.EqualFold(colsec.Accesstype, "mask") && !strings.EqualFold(colsec.Accesstype, "hide") {
|
if !strings.EqualFold(colsec.Accesstype, "mask") && !strings.EqualFold(colsec.Accesstype, "hide") {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
@ -353,7 +357,7 @@ func (m *SecurityList) ApplyColumnSecurity(records reflect.Value, modelType refl
|
|||||||
|
|
||||||
if i == pathLen-1 {
|
if i == pathLen-1 {
|
||||||
if nameType == "sql" || nameType == "struct" {
|
if nameType == "sql" || nameType == "struct" {
|
||||||
setColSecValue(field, colsec, fieldName)
|
setColSecValue(field, *colsec, fieldName)
|
||||||
}
|
}
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
@ -365,7 +369,7 @@ func (m *SecurityList) ApplyColumnSecurity(records reflect.Value, modelType refl
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil, records
|
return records, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *SecurityList) LoadColumnSecurity(pUserID int, pSchema, pTablename string, pOverwrite bool) error {
|
func (m *SecurityList) LoadColumnSecurity(pUserID int, pSchema, pTablename string, pOverwrite bool) error {
|
||||||
@ -407,9 +411,10 @@ func (m *SecurityList) ClearSecurity(pUserID int, pSchema, pTablename string) er
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, cs := range list {
|
for i := range list {
|
||||||
|
cs := &list[i]
|
||||||
if cs.Schema != pSchema && cs.Tablename != pTablename && cs.UserID != pUserID {
|
if cs.Schema != pSchema && cs.Tablename != pTablename && cs.UserID != pUserID {
|
||||||
filtered = append(filtered, cs)
|
filtered = append(filtered, *cs)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user