Linting fixes

This commit is contained in:
Hein 2025-11-11 11:03:02 +02:00
parent 412bbab560
commit 682716dd31
21 changed files with 302 additions and 290 deletions

129
.golangci.json Normal file
View File

@ -0,0 +1,129 @@
{
"formatters": {
"enable": [
"gofmt",
"goimports"
],
"exclusions": {
"generated": "lax",
"paths": [
"third_party$",
"builtin$",
"examples$"
]
},
"settings": {
"gofmt": {
"simplify": true
},
"goimports": {
"local-prefixes": [
"github.com/bitechdev/ResolveSpec"
]
}
}
},
"issues": {
"max-issues-per-linter": 0,
"max-same-issues": 0
},
"linters": {
"enable": [
"gocritic",
"misspell",
"revive"
],
"exclusions": {
"generated": "lax",
"paths": [
"third_party$",
"builtin$",
"examples$",
"mocks?",
"tests?"
],
"rules": [
{
"linters": [
"dupl",
"errcheck",
"gocritic",
"gosec"
],
"path": "_test\\.go"
},
{
"linters": [
"errcheck"
],
"text": "Error return value of .((os\\.)?std(out|err)\\..*|.*Close|.*Flush|os\\.Remove(All)?|.*print(f|ln)?|os\\.(Un)?Setenv). is not checked"
},
{
"path": "_test\\.go",
"text": "cognitive complexity|cyclomatic complexity"
}
]
},
"settings": {
"errcheck": {
"check-blank": false,
"check-type-assertions": false
},
"gocritic": {
"enabled-checks": [
"appendAssign",
"assignOp",
"boolExprSimplify",
"builtinShadow",
"captLocal",
"caseOrder",
"defaultCaseOrder",
"dupArg",
"dupBranchBody",
"dupCase",
"dupSubExpr",
"elseif",
"emptyFallthrough",
"equalFold",
"flagName",
"ifElseChain",
"indexAlloc",
"initClause",
"methodExprCall",
"nilValReturn",
"rangeExprCopy",
"rangeValCopy",
"regexpMust",
"singleCaseSwitch",
"sloppyLen",
"stringXbytes",
"switchTrue",
"typeAssertChain",
"typeSwitchVar",
"underef",
"unlabelStmt",
"unnamedResult",
"unnecessaryBlock",
"weakCond",
"yodaStyleExpr"
]
},
"revive": {
"rules": [
{
"disabled": true,
"name": "exported"
},
{
"disabled": true,
"name": "package-comments"
}
]
}
}
},
"run": {
"tests": true
},
"version": "2"
}

View File

@ -1,110 +0,0 @@
run:
timeout: 5m
tests: true
skip-dirs:
- vendor
- .github
linters:
enable:
- errcheck
- gosimple
- govet
- ineffassign
- staticcheck
- unused
- gofmt
- goimports
- misspell
- gocritic
- revive
- stylecheck
disable:
- typecheck # Can cause issues with generics in some cases
linters-settings:
errcheck:
check-type-assertions: false
check-blank: false
govet:
check-shadowing: false
gofmt:
simplify: true
goimports:
local-prefixes: github.com/bitechdev/ResolveSpec
gocritic:
enabled-checks:
- appendAssign
- assignOp
- boolExprSimplify
- builtinShadow
- captLocal
- caseOrder
- defaultCaseOrder
- dupArg
- dupBranchBody
- dupCase
- dupSubExpr
- elseif
- emptyFallthrough
- equalFold
- flagName
- ifElseChain
- indexAlloc
- initClause
- methodExprCall
- nilValReturn
- rangeExprCopy
- rangeValCopy
- regexpMust
- singleCaseSwitch
- sloppyLen
- stringXbytes
- switchTrue
- typeAssertChain
- typeSwitchVar
- underef
- unlabelStmt
- unnamedResult
- unnecessaryBlock
- weakCond
- yodaStyleExpr
revive:
rules:
- name: exported
disabled: true
- name: package-comments
disabled: true
issues:
exclude-use-default: false
max-issues-per-linter: 0
max-same-issues: 0
# Exclude some linters from running on tests files
exclude-rules:
- path: _test\.go
linters:
- errcheck
- dupl
- gosec
- gocritic
# Ignore "error return value not checked" for defer statements
- linters:
- errcheck
text: "Error return value of .((os\\.)?std(out|err)\\..*|.*Close|.*Flush|os\\.Remove(All)?|.*print(f|ln)?|os\\.(Un)?Setenv). is not checked"
# Ignore complexity in test files
- path: _test\.go
text: "cognitive complexity|cyclomatic complexity"
output:
format: colored-line-number
print-issued-lines: true
print-linter-name: true

View File

@ -6,8 +6,9 @@ import (
"fmt"
"strings"
"github.com/bitechdev/ResolveSpec/pkg/common"
"github.com/uptrace/bun"
"github.com/bitechdev/ResolveSpec/pkg/common"
)
// BunAdapter adapts Bun to work with our Database interface

View File

@ -5,8 +5,9 @@ import (
"fmt"
"strings"
"github.com/bitechdev/ResolveSpec/pkg/common"
"gorm.io/gorm"
"github.com/bitechdev/ResolveSpec/pkg/common"
)
// GormAdapter adapts GORM to work with our Database interface

View File

@ -3,8 +3,9 @@ package router
import (
"net/http"
"github.com/bitechdev/ResolveSpec/pkg/common"
"github.com/uptrace/bunrouter"
"github.com/bitechdev/ResolveSpec/pkg/common"
)
// BunRouterAdapter adapts uptrace/bunrouter to work with our Router interface

View File

@ -5,8 +5,9 @@ import (
"io"
"net/http"
"github.com/bitechdev/ResolveSpec/pkg/common"
"github.com/gorilla/mux"
"github.com/bitechdev/ResolveSpec/pkg/common"
)
// MuxAdapter adapts Gorilla Mux to work with our Router interface

View File

@ -75,7 +75,7 @@ func Debug(template string, args ...interface{}) {
// CatchPanic - Handle panic
func CatchPanicCallback(location string, cb func(err any)) {
if err := recover(); err != nil {
//callstack := debug.Stack()
// callstack := debug.Stack()
if Logger != nil {
Error("Panic in %s : %v", location, err)
@ -84,7 +84,7 @@ func CatchPanicCallback(location string, cb func(err any)) {
debug.PrintStack()
}
//push to sentry
// push to sentry
// hub := sentry.CurrentHub()
// if hub != nil {
// evtID := hub.Recover(err)

View File

@ -69,19 +69,19 @@ func (r *DefaultModelRegistry) RegisterModel(name string, model interface{}) err
func (r *DefaultModelRegistry) GetModel(name string) (interface{}, error) {
r.mutex.RLock()
defer r.mutex.RUnlock()
model, exists := r.models[name]
if !exists {
return nil, fmt.Errorf("model %s not found", name)
}
return model, nil
}
func (r *DefaultModelRegistry) GetAllModels() map[string]interface{} {
r.mutex.RLock()
defer r.mutex.RUnlock()
result := make(map[string]interface{})
for k, v := range r.models {
result[k] = v
@ -132,4 +132,4 @@ func GetModels() []interface{} {
models = append(models, model)
}
return models
}
}

View File

@ -73,11 +73,11 @@ func GetModelColumnDetail(record reflect.Value) []ModelFieldDetail {
ie := strings.Index(gormdetail[ik:], ";")
if ie > ik && ik > 0 {
fielddetail.SQLName = strings.ToLower(gormdetail)[ik+11 : ik+ie]
//fmt.Printf("\r\nforeignkey: %v", fielddetail)
// fmt.Printf("\r\nforeignkey: %v", fielddetail)
}
}
//";foreignkey:rid_parent;association_foreignkey:id_atevent;save_associations:false;association_autocreate:false;"
// ";foreignkey:rid_parent;association_foreignkey:id_atevent;save_associations:false;association_autocreate:false;"
lst = append(lst, fielddetail)

View File

@ -210,7 +210,7 @@ func (h *Handler) handleRead(ctx context.Context, w common.ResponseWriter, id st
// Apply sorting
for _, sort := range options.Sort {
direction := "ASC"
if strings.ToLower(sort.Direction) == "desc" {
if strings.EqualFold(sort.Direction, "desc") {
direction = "DESC"
}
logger.Debug("Applying sort: %s %s", sort.Column, direction)
@ -969,17 +969,20 @@ func (h *Handler) generateMetadata(schema, entity string, model interface{}) *co
func (h *Handler) sendResponse(w common.ResponseWriter, data interface{}, metadata *common.Metadata) {
w.SetHeader("Content-Type", "application/json")
w.WriteJSON(common.Response{
err := w.WriteJSON(common.Response{
Success: true,
Data: data,
Metadata: metadata,
})
if err != nil {
logger.Error("Error sending response: %v", err)
}
}
func (h *Handler) sendError(w common.ResponseWriter, status int, code, message string, details interface{}) {
w.SetHeader("Content-Type", "application/json")
w.WriteHeader(status)
w.WriteJSON(common.Response{
err := w.WriteJSON(common.Response{
Success: false,
Error: &common.APIError{
Code: code,
@ -988,6 +991,9 @@ func (h *Handler) sendError(w common.ResponseWriter, status int, code, message s
Detail: fmt.Sprintf("%v", details),
},
})
if err != nil {
logger.Error("Error sending response: %v", err)
}
}
// RegisterModel allows registering models at runtime

View File

@ -23,5 +23,5 @@ func (r GormTableCRUDRequest) GetRequest() string {
// New interfaces that replace the legacy ones above
// These are now defined in database.go:
// - TableNameProvider (replaces GormTableNameInterface)
// - TableNameProvider (replaces GormTableNameInterface)
// - SchemaProvider (replaces GormTableSchemaInterface)

View File

@ -3,13 +3,14 @@ package resolvespec
import (
"net/http"
"github.com/bitechdev/ResolveSpec/pkg/common/adapters/database"
"github.com/bitechdev/ResolveSpec/pkg/common/adapters/router"
"github.com/bitechdev/ResolveSpec/pkg/modelregistry"
"github.com/gorilla/mux"
"github.com/uptrace/bun"
"github.com/uptrace/bunrouter"
"gorm.io/gorm"
"github.com/bitechdev/ResolveSpec/pkg/common/adapters/database"
"github.com/bitechdev/ResolveSpec/pkg/common/adapters/router"
"github.com/bitechdev/ResolveSpec/pkg/modelregistry"
)
// NewHandlerWithGORM creates a new Handler with GORM adapter

View File

@ -140,19 +140,19 @@ func (opts *ExtendedRequestOptions) GetCursorFilter(
// ------------------------------------------------------------------------- //
// Helper: get active cursor (forward or backward)
func (opts *ExtendedRequestOptions) getActiveCursor() (id string, direction CursorDirection) {
if opts.RequestOptions.CursorForward != "" {
return opts.RequestOptions.CursorForward, CursorForward
if opts.CursorForward != "" {
return opts.CursorForward, CursorForward
}
if opts.RequestOptions.CursorBackward != "" {
return opts.RequestOptions.CursorBackward, CursorBackward
if opts.CursorBackward != "" {
return opts.CursorBackward, CursorBackward
}
return "", 0
}
// Helper: extract sort columns
func (opts *ExtendedRequestOptions) getSortColumns() []common.SortOption {
if opts.RequestOptions.Sort != nil {
return opts.RequestOptions.Sort
if opts.Sort != nil {
return opts.Sort
}
return nil
}

View File

@ -318,7 +318,7 @@ func (h *Handler) handleRead(ctx context.Context, w common.ResponseWriter, id st
// Apply sorting
for _, sort := range options.Sort {
direction := "ASC"
if strings.ToLower(sort.Direction) == "desc" {
if strings.EqualFold(sort.Direction, "desc") {
direction = "DESC"
}
logger.Debug("Applying sort: %s %s", sort.Column, direction)
@ -352,7 +352,7 @@ func (h *Handler) handleRead(ctx context.Context, w common.ResponseWriter, id st
}
// Apply cursor-based pagination
if len(options.RequestOptions.CursorForward) > 0 || len(options.RequestOptions.CursorBackward) > 0 {
if len(options.CursorForward) > 0 || len(options.CursorBackward) > 0 {
logger.Debug("Applying cursor pagination")
// Get primary key name
@ -425,9 +425,9 @@ func (h *Handler) handleRead(ctx context.Context, w common.ResponseWriter, id st
}
// Fetch row number for a specific record if requested
if options.RequestOptions.FetchRowNumber != nil && *options.RequestOptions.FetchRowNumber != "" {
if options.FetchRowNumber != nil && *options.FetchRowNumber != "" {
pkName := reflection.GetPrimaryKeyName(model)
pkValue := *options.RequestOptions.FetchRowNumber
pkValue := *options.FetchRowNumber
logger.Debug("Fetching row number for specific PK %s = %s", pkName, pkValue)
@ -1415,7 +1415,7 @@ func (h *Handler) FetchRowNumber(ctx context.Context, tableName string, pkName s
sortParts := make([]string, 0, len(options.Sort))
for _, sort := range options.Sort {
direction := "ASC"
if strings.ToLower(sort.Direction) == "desc" {
if strings.EqualFold(sort.Direction, "desc") {
direction = "DESC"
}
sortParts = append(sortParts, fmt.Sprintf("%s.%s %s", tableName, sort.Column, direction))

View File

@ -2,7 +2,6 @@ package restheadspec
import (
"encoding/base64"
"encoding/json"
"fmt"
"reflect"
"strconv"
@ -59,7 +58,7 @@ func decodeHeaderValue(value string) string {
// DecodeParam - Decodes parameter string and returns unencoded string
func DecodeParam(pStr string) (string, error) {
var code string = pStr
var code = pStr
if strings.HasPrefix(pStr, "ZIP_") {
code = strings.ReplaceAll(pStr, "ZIP_", "")
code = strings.ReplaceAll(code, "\n", "")
@ -125,7 +124,7 @@ func (h *Handler) parseOptionsFromHeaders(r common.Request) ExtendedRequestOptio
case strings.HasPrefix(normalizedKey, "x-not-select-fields"):
h.parseNotSelectFields(&options, decodedValue)
case strings.HasPrefix(normalizedKey, "x-clean-json"):
options.CleanJSON = strings.ToLower(decodedValue) == "true"
options.CleanJSON = strings.EqualFold(decodedValue, "true")
// Filtering & Search
case strings.HasPrefix(normalizedKey, "x-fieldfilter-"):
@ -166,9 +165,9 @@ func (h *Handler) parseOptionsFromHeaders(r common.Request) ExtendedRequestOptio
options.Offset = &offset
}
case strings.HasPrefix(normalizedKey, "x-cursor-forward"):
options.RequestOptions.CursorForward = decodedValue
options.CursorForward = decodedValue
case strings.HasPrefix(normalizedKey, "x-cursor-backward"):
options.RequestOptions.CursorBackward = decodedValue
options.CursorBackward = decodedValue
// Advanced Features
case strings.HasPrefix(normalizedKey, "x-advsql-"):
@ -178,13 +177,13 @@ func (h *Handler) parseOptionsFromHeaders(r common.Request) ExtendedRequestOptio
colName := strings.TrimPrefix(normalizedKey, "x-cql-sel-")
options.ComputedQL[colName] = decodedValue
case strings.HasPrefix(normalizedKey, "x-distinct"):
options.Distinct = strings.ToLower(decodedValue) == "true"
options.Distinct = strings.EqualFold(decodedValue, "true")
case strings.HasPrefix(normalizedKey, "x-skipcount"):
options.SkipCount = strings.ToLower(decodedValue) == "true"
options.SkipCount = strings.EqualFold(decodedValue, "true")
case strings.HasPrefix(normalizedKey, "x-skipcache"):
options.SkipCache = strings.ToLower(decodedValue) == "true"
options.SkipCache = strings.EqualFold(decodedValue, "true")
case strings.HasPrefix(normalizedKey, "x-fetch-rownumber"):
options.RequestOptions.FetchRowNumber = &decodedValue
options.FetchRowNumber = &decodedValue
case strings.HasPrefix(normalizedKey, "x-pkrow"):
options.PKRow = &decodedValue
@ -198,7 +197,7 @@ func (h *Handler) parseOptionsFromHeaders(r common.Request) ExtendedRequestOptio
// Transaction Control
case strings.HasPrefix(normalizedKey, "x-transaction-atomic"):
options.AtomicTransaction = strings.ToLower(decodedValue) == "true"
options.AtomicTransaction = strings.EqualFold(decodedValue, "true")
}
}
@ -455,16 +454,6 @@ func (h *Handler) parseCommaSeparated(value string) []string {
return result
}
// parseJSONHeader parses a header value as JSON
func (h *Handler) parseJSONHeader(value string) (map[string]interface{}, error) {
var result map[string]interface{}
err := json.Unmarshal([]byte(value), &result)
if err != nil {
return nil, fmt.Errorf("failed to parse JSON header: %w", err)
}
return result, nil
}
// getColumnTypeFromModel uses reflection to determine the Go type of a column in a model
func (h *Handler) getColumnTypeFromModel(model interface{}, colName string) reflect.Kind {
if model == nil {
@ -536,11 +525,6 @@ func isStringType(kind reflect.Kind) bool {
return kind == reflect.String
}
// isBoolType checks if a reflect.Kind is a boolean type
func isBoolType(kind reflect.Kind) bool {
return kind == reflect.Bool
}
// convertToNumericType converts a string value to the appropriate numeric type
func convertToNumericType(value string, kind reflect.Kind) (interface{}, error) {
value = strings.TrimSpace(value)

View File

@ -95,7 +95,7 @@ func (r *HookRegistry) RegisterMultiple(hookTypes []HookType, hook HookFunc) {
func (r *HookRegistry) Execute(hookType HookType, ctx *HookContext) error {
hooks, exists := r.hooks[hookType]
if !exists || len(hooks) == 0 {
//logger.Debug("No hooks registered for %s", hookType)
// logger.Debug("No hooks registered for %s", hookType)
return nil
}
@ -108,7 +108,7 @@ func (r *HookRegistry) Execute(hookType HookType, ctx *HookContext) error {
}
}
//logger.Debug("All hooks for %s executed successfully", hookType)
// logger.Debug("All hooks for %s executed successfully", hookType)
return nil
}

View File

@ -55,13 +55,14 @@ package restheadspec
import (
"net/http"
"github.com/bitechdev/ResolveSpec/pkg/common/adapters/database"
"github.com/bitechdev/ResolveSpec/pkg/common/adapters/router"
"github.com/bitechdev/ResolveSpec/pkg/modelregistry"
"github.com/gorilla/mux"
"github.com/uptrace/bun"
"github.com/uptrace/bunrouter"
"gorm.io/gorm"
"github.com/bitechdev/ResolveSpec/pkg/common/adapters/database"
"github.com/bitechdev/ResolveSpec/pkg/common/adapters/router"
"github.com/bitechdev/ResolveSpec/pkg/modelregistry"
)
// NewHandlerWithGORM creates a new Handler with GORM adapter

View File

@ -1,14 +1,11 @@
package security
import (
"encoding/json"
"fmt"
"net/http"
"strconv"
"strings"
DBM "github.com/bitechdev/GoCore/pkg/models"
"github.com/bitechdev/ResolveSpec/pkg/logger"
// DBM "github.com/bitechdev/GoCore/pkg/models"
)
// This file provides example implementations of the required security callbacks.
@ -121,104 +118,104 @@ func ExampleAuthenticateFromSession(r *http.Request) (userID int, roles string,
func ExampleLoadColumnSecurityFromDatabase(pUserID int, pSchema, pTablename string) ([]ColumnSecurity, error) {
colSecList := make([]ColumnSecurity, 0)
getExtraFilters := func(pStr string) map[string]string {
mp := make(map[string]string, 0)
for i, val := range strings.Split(pStr, ",") {
if i <= 1 {
continue
}
vals := strings.Split(val, ":")
if len(vals) > 1 {
mp[vals[0]] = vals[1]
}
}
return mp
}
// getExtraFilters := func(pStr string) map[string]string {
// mp := make(map[string]string, 0)
// for i, val := range strings.Split(pStr, ",") {
// if i <= 1 {
// continue
// }
// vals := strings.Split(val, ":")
// if len(vals) > 1 {
// mp[vals[0]] = vals[1]
// }
// }
// return mp
// }
rows, err := DBM.DBConn.Raw(fmt.Sprintf(`
SELECT a.rid_secacces, a.control, a.accesstype, a.jsonvalue
FROM core.secacces a
WHERE a.rid_hub IN (
SELECT l.rid_hub_parent
FROM core.hub_link l
WHERE l.parent_hubtype = 'secgroup'
AND l.rid_hub_child = ?
)
AND control ILIKE '%s.%s%%'
`, pSchema, pTablename), pUserID).Rows()
// rows, err := DBM.DBConn.Raw(fmt.Sprintf(`
// SELECT a.rid_secacces, a.control, a.accesstype, a.jsonvalue
// FROM core.secacces a
// WHERE a.rid_hub IN (
// SELECT l.rid_hub_parent
// FROM core.hub_link l
// WHERE l.parent_hubtype = 'secgroup'
// AND l.rid_hub_child = ?
// )
// AND control ILIKE '%s.%s%%'
// `, pSchema, pTablename), pUserID).Rows()
defer func() {
if rows != nil {
rows.Close()
}
}()
// defer func() {
// if rows != nil {
// rows.Close()
// }
// }()
if err != nil {
return colSecList, fmt.Errorf("failed to fetch column security from SQL: %v", err)
}
// if err != nil {
// return colSecList, fmt.Errorf("failed to fetch column security from SQL: %v", err)
// }
for rows.Next() {
var rid int
var jsondata []byte
var control, accesstype string
// for rows.Next() {
// var rid int
// var jsondata []byte
// var control, accesstype string
err = rows.Scan(&rid, &control, &accesstype, &jsondata)
if err != nil {
return colSecList, fmt.Errorf("failed to scan column security: %v", err)
}
// err = rows.Scan(&rid, &control, &accesstype, &jsondata)
// if err != nil {
// return colSecList, fmt.Errorf("failed to scan column security: %v", err)
// }
parts := strings.Split(control, ",")
ids := strings.Split(parts[0], ".")
if len(ids) < 3 {
continue
}
// parts := strings.Split(control, ",")
// ids := strings.Split(parts[0], ".")
// if len(ids) < 3 {
// continue
// }
jsonvalue := make(map[string]interface{})
if len(jsondata) > 1 {
err = json.Unmarshal(jsondata, &jsonvalue)
if err != nil {
logger.Error("Failed to parse json: %v", err)
}
}
// jsonvalue := make(map[string]interface{})
// if len(jsondata) > 1 {
// err = json.Unmarshal(jsondata, &jsonvalue)
// if err != nil {
// logger.Error("Failed to parse json: %v", err)
// }
// }
colsec := ColumnSecurity{
Schema: pSchema,
Tablename: pTablename,
UserID: pUserID,
Path: ids[2:],
ExtraFilters: getExtraFilters(control),
Accesstype: accesstype,
Control: control,
ID: int(rid),
}
// colsec := ColumnSecurity{
// Schema: pSchema,
// Tablename: pTablename,
// UserID: pUserID,
// Path: ids[2:],
// ExtraFilters: getExtraFilters(control),
// Accesstype: accesstype,
// Control: control,
// ID: int(rid),
// }
// Parse masking configuration from JSON
if v, ok := jsonvalue["start"]; ok {
if value, ok := v.(float64); ok {
colsec.MaskStart = int(value)
}
}
// // Parse masking configuration from JSON
// if v, ok := jsonvalue["start"]; ok {
// if value, ok := v.(float64); ok {
// colsec.MaskStart = int(value)
// }
// }
if v, ok := jsonvalue["end"]; ok {
if value, ok := v.(float64); ok {
colsec.MaskEnd = int(value)
}
}
// if v, ok := jsonvalue["end"]; ok {
// if value, ok := v.(float64); ok {
// colsec.MaskEnd = int(value)
// }
// }
if v, ok := jsonvalue["invert"]; ok {
if value, ok := v.(bool); ok {
colsec.MaskInvert = value
}
}
// if v, ok := jsonvalue["invert"]; ok {
// if value, ok := v.(bool); ok {
// colsec.MaskInvert = value
// }
// }
if v, ok := jsonvalue["char"]; ok {
if value, ok := v.(string); ok {
colsec.MaskChar = value
}
}
// if v, ok := jsonvalue["char"]; ok {
// if value, ok := v.(string); ok {
// colsec.MaskChar = value
// }
// }
colSecList = append(colSecList, colsec)
}
// colSecList = append(colSecList, colsec)
// }
return colSecList, nil
}
@ -296,34 +293,34 @@ func ExampleLoadRowSecurityFromDatabase(pUserID int, pSchema, pTablename string)
UserID: pUserID,
}
rows, err := DBM.DBConn.Raw(`
SELECT r.p_retval, r.p_errmsg, r.p_template, r.p_block
FROM core.api_sec_rowtemplate(?, ?, ?) r
`, pSchema, pTablename, pUserID).Rows()
// rows, err := DBM.DBConn.Raw(`
// SELECT r.p_retval, r.p_errmsg, r.p_template, r.p_block
// FROM core.api_sec_rowtemplate(?, ?, ?) r
// `, pSchema, pTablename, pUserID).Rows()
defer func() {
if rows != nil {
rows.Close()
}
}()
// defer func() {
// if rows != nil {
// rows.Close()
// }
// }()
if err != nil {
return record, fmt.Errorf("failed to fetch row security from SQL: %v", err)
}
// if err != nil {
// return record, fmt.Errorf("failed to fetch row security from SQL: %v", err)
// }
for rows.Next() {
var retval int
var errmsg string
// for rows.Next() {
// var retval int
// var errmsg string
err = rows.Scan(&retval, &errmsg, &record.Template, &record.HasBlock)
if err != nil {
return record, fmt.Errorf("failed to scan row security: %v", err)
}
// err = rows.Scan(&retval, &errmsg, &record.Template, &record.HasBlock)
// if err != nil {
// return record, fmt.Errorf("failed to scan row security: %v", err)
// }
if retval != 0 {
return RowSecurity{}, fmt.Errorf("api_sec_rowtemplate error: %s", errmsg)
}
}
// if retval != 0 {
// return RowSecurity{}, fmt.Errorf("api_sec_rowtemplate error: %s", errmsg)
// }
// }
return record, nil
}

View File

@ -7,9 +7,9 @@ import (
const (
// Context keys for user information
UserIDKey = "user_id"
UserRolesKey = "user_roles"
UserTokenKey = "user_token"
UserIDKey = "user_id"
UserRolesKey = "user_roles"
UserTokenKey = "user_token"
)
// AuthMiddleware extracts user authentication from request and adds to context

View File

@ -146,7 +146,7 @@ func (m *SecurityList) ColumSecurityApplyOnRecord(prevRecord reflect.Value, newR
}
for _, colsec := range colsecList {
if !(strings.EqualFold(colsec.Accesstype, "mask") || strings.EqualFold(colsec.Accesstype, "hide")) {
if !strings.EqualFold(colsec.Accesstype, "mask") && !strings.EqualFold(colsec.Accesstype, "hide") {
continue
}
lastRecords := interateStruct(prevRecord)
@ -316,7 +316,7 @@ func (m *SecurityList) ApplyColumnSecurity(records reflect.Value, modelType refl
}
for _, colsec := range colsecList {
if !(strings.EqualFold(colsec.Accesstype, "mask") || strings.EqualFold(colsec.Accesstype, "hide")) {
if !strings.EqualFold(colsec.Accesstype, "mask") && !strings.EqualFold(colsec.Accesstype, "hide") {
continue
}
@ -408,7 +408,7 @@ func (m *SecurityList) ClearSecurity(pUserID int, pSchema, pTablename string) er
}
for _, cs := range list {
if !(cs.Schema == pSchema && cs.Tablename == pTablename && cs.UserID == pUserID) {
if cs.Schema != pSchema && cs.Tablename != pTablename && cs.UserID != pUserID {
filtered = append(filtered, cs)
}
}

View File

@ -4,9 +4,10 @@ import (
"fmt"
"net/http"
"github.com/bitechdev/ResolveSpec/pkg/restheadspec"
"github.com/gorilla/mux"
"gorm.io/gorm"
"github.com/bitechdev/ResolveSpec/pkg/restheadspec"
)
// SetupSecurityProvider initializes and configures the security provider
@ -31,7 +32,6 @@ import (
// // Step 3: Apply middleware
// router.Use(mux.MiddlewareFunc(security.AuthMiddleware))
// router.Use(mux.MiddlewareFunc(security.SetSecurityMiddleware))
//
func SetupSecurityProvider(handler *restheadspec.Handler, securityList *SecurityList) error {
// Validate that required callbacks are configured
if securityList.AuthenticateCallback == nil {