fix: add config for per role operation blocking by type
This commit is contained in:
parent
f7d3760af7
commit
448e6bb72a
|
@ -91,7 +91,6 @@ auth:
|
|||
# password: ""
|
||||
# max_idle: 80
|
||||
# max_active: 12000
|
||||
|
||||
# In most cases you don't need these
|
||||
# salt: "encrypted cookie"
|
||||
# sign_salt: "signed encrypted cookie"
|
||||
|
@ -165,7 +164,6 @@ tables:
|
|||
- name: email
|
||||
related_to: products.name
|
||||
|
||||
|
||||
roles_query: "SELECT * FROM users WHERE id = $user_id"
|
||||
|
||||
roles:
|
||||
|
@ -174,7 +172,7 @@ roles:
|
|||
- name: products
|
||||
query:
|
||||
limit: 10
|
||||
columns: ["id", "name", "description" ]
|
||||
columns: ["id", "name", "description"]
|
||||
aggregation: false
|
||||
|
||||
insert:
|
||||
|
|
|
@ -106,7 +106,8 @@ type Role struct {
|
|||
|
||||
// RoleTable struct contains role specific access control values for a database table
|
||||
type RoleTable struct {
|
||||
Name string
|
||||
Name string
|
||||
ReadOnly *bool `mapstructure:"read_only"`
|
||||
|
||||
Query Query
|
||||
Insert Insert
|
||||
|
@ -120,7 +121,7 @@ type Query struct {
|
|||
Filters []string
|
||||
Columns []string
|
||||
DisableFunctions bool `mapstructure:"disable_functions"`
|
||||
Block bool
|
||||
Block *bool
|
||||
}
|
||||
|
||||
// Insert struct contains access control values for insert operations
|
||||
|
@ -128,7 +129,7 @@ type Insert struct {
|
|||
Filters []string
|
||||
Columns []string
|
||||
Presets map[string]string
|
||||
Block bool
|
||||
Block *bool
|
||||
}
|
||||
|
||||
// Insert struct contains access control values for update operations
|
||||
|
@ -136,14 +137,14 @@ type Update struct {
|
|||
Filters []string
|
||||
Columns []string
|
||||
Presets map[string]string
|
||||
Block bool
|
||||
Block *bool
|
||||
}
|
||||
|
||||
// Delete struct contains access control values for delete operations
|
||||
type Delete struct {
|
||||
Filters []string
|
||||
Columns []string
|
||||
Block bool
|
||||
Block *bool
|
||||
}
|
||||
|
||||
// ReadInConfig function reads in the config file for the environment specified in the GO_ENV
|
||||
|
|
63
core/init.go
63
core/init.go
|
@ -216,53 +216,74 @@ func addRoles(c *Config, qc *qcode.Compiler) error {
|
|||
}
|
||||
|
||||
func addRole(qc *qcode.Compiler, r Role, t RoleTable) error {
|
||||
blockFilter := []string{"false"}
|
||||
blocked := struct {
|
||||
readOnly bool
|
||||
query bool
|
||||
insert bool
|
||||
update bool
|
||||
delete bool
|
||||
}{true, true, true, true, true}
|
||||
|
||||
if r.Name == "anon" {
|
||||
blocked.query = false
|
||||
} else {
|
||||
blocked.readOnly = false
|
||||
blocked.query = false
|
||||
blocked.insert = false
|
||||
blocked.update = false
|
||||
blocked.delete = false
|
||||
}
|
||||
|
||||
if t.ReadOnly != nil {
|
||||
blocked.readOnly = *t.ReadOnly
|
||||
}
|
||||
if t.Query.Block != nil {
|
||||
blocked.query = *t.Query.Block
|
||||
}
|
||||
if t.Insert.Block != nil {
|
||||
blocked.insert = *t.Insert.Block
|
||||
}
|
||||
if t.Update.Block != nil {
|
||||
blocked.update = *t.Update.Block
|
||||
}
|
||||
if t.Delete.Block != nil {
|
||||
blocked.delete = *t.Delete.Block
|
||||
}
|
||||
|
||||
query := qcode.QueryConfig{
|
||||
Limit: t.Query.Limit,
|
||||
Filters: t.Query.Filters,
|
||||
Columns: t.Query.Columns,
|
||||
DisableFunctions: t.Query.DisableFunctions,
|
||||
}
|
||||
|
||||
if t.Query.Block {
|
||||
query.Filters = blockFilter
|
||||
Block: blocked.query,
|
||||
}
|
||||
|
||||
insert := qcode.InsertConfig{
|
||||
Filters: t.Insert.Filters,
|
||||
Columns: t.Insert.Columns,
|
||||
Presets: t.Insert.Presets,
|
||||
}
|
||||
|
||||
if t.Insert.Block {
|
||||
insert.Filters = blockFilter
|
||||
Block: blocked.insert,
|
||||
}
|
||||
|
||||
update := qcode.UpdateConfig{
|
||||
Filters: t.Update.Filters,
|
||||
Columns: t.Update.Columns,
|
||||
Presets: t.Update.Presets,
|
||||
}
|
||||
|
||||
if t.Update.Block {
|
||||
update.Filters = blockFilter
|
||||
Block: blocked.update,
|
||||
}
|
||||
|
||||
delete := qcode.DeleteConfig{
|
||||
Filters: t.Delete.Filters,
|
||||
Columns: t.Delete.Columns,
|
||||
}
|
||||
|
||||
if t.Delete.Block {
|
||||
delete.Filters = blockFilter
|
||||
Block: blocked.delete,
|
||||
}
|
||||
|
||||
return qc.AddRole(r.Name, t.Name, qcode.TRConfig{
|
||||
Query: query,
|
||||
Insert: insert,
|
||||
Update: update,
|
||||
Delete: delete,
|
||||
ReadOnly: blocked.readOnly,
|
||||
Query: query,
|
||||
Insert: insert,
|
||||
Update: update,
|
||||
Delete: delete,
|
||||
})
|
||||
}
|
||||
|
||||
|
|
|
@ -16,41 +16,46 @@ type QueryConfig struct {
|
|||
Filters []string
|
||||
Columns []string
|
||||
DisableFunctions bool
|
||||
Block bool
|
||||
}
|
||||
|
||||
type InsertConfig struct {
|
||||
Filters []string
|
||||
Columns []string
|
||||
Presets map[string]string
|
||||
Block bool
|
||||
}
|
||||
|
||||
type UpdateConfig struct {
|
||||
Filters []string
|
||||
Columns []string
|
||||
Presets map[string]string
|
||||
Block bool
|
||||
}
|
||||
|
||||
type DeleteConfig struct {
|
||||
Filters []string
|
||||
Columns []string
|
||||
Block bool
|
||||
}
|
||||
|
||||
type TRConfig struct {
|
||||
Query QueryConfig
|
||||
Insert InsertConfig
|
||||
Update UpdateConfig
|
||||
Delete DeleteConfig
|
||||
ReadOnly bool
|
||||
Query QueryConfig
|
||||
Insert InsertConfig
|
||||
Update UpdateConfig
|
||||
Delete DeleteConfig
|
||||
}
|
||||
|
||||
type trval struct {
|
||||
query struct {
|
||||
readOnly bool
|
||||
query struct {
|
||||
limit string
|
||||
fil *Exp
|
||||
filNU bool
|
||||
cols map[string]struct{}
|
||||
disable struct {
|
||||
funcs bool
|
||||
}
|
||||
disable struct{ funcs bool }
|
||||
block bool
|
||||
}
|
||||
|
||||
insert struct {
|
||||
|
@ -59,6 +64,7 @@ type trval struct {
|
|||
cols map[string]struct{}
|
||||
psmap map[string]string
|
||||
pslist []string
|
||||
block bool
|
||||
}
|
||||
|
||||
update struct {
|
||||
|
@ -67,12 +73,14 @@ type trval struct {
|
|||
cols map[string]struct{}
|
||||
psmap map[string]string
|
||||
pslist []string
|
||||
block bool
|
||||
}
|
||||
|
||||
delete struct {
|
||||
fil *Exp
|
||||
filNU bool
|
||||
cols map[string]struct{}
|
||||
block bool
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -207,7 +207,7 @@ func NewFilter() *Exp {
|
|||
|
||||
func (com *Compiler) AddRole(role, table string, trc TRConfig) error {
|
||||
var err error
|
||||
trv := &trval{}
|
||||
trv := &trval{readOnly: trc.ReadOnly}
|
||||
|
||||
// query config
|
||||
trv.query.fil, trv.query.filNU, err = compileFilter(trc.Query.Filters)
|
||||
|
@ -219,6 +219,7 @@ func (com *Compiler) AddRole(role, table string, trc TRConfig) error {
|
|||
}
|
||||
trv.query.cols = listToMap(trc.Query.Columns)
|
||||
trv.query.disable.funcs = trc.Query.DisableFunctions
|
||||
trv.query.block = trc.Query.Block
|
||||
|
||||
// insert config
|
||||
trv.insert.fil, trv.insert.filNU, err = compileFilter(trc.Insert.Filters)
|
||||
|
@ -228,6 +229,7 @@ func (com *Compiler) AddRole(role, table string, trc TRConfig) error {
|
|||
trv.insert.cols = listToMap(trc.Insert.Columns)
|
||||
trv.insert.psmap = parsePresets(trc.Insert.Presets)
|
||||
trv.insert.pslist = mapToList(trv.insert.psmap)
|
||||
trv.insert.block = trc.Insert.Block
|
||||
|
||||
// update config
|
||||
trv.update.fil, trv.update.filNU, err = compileFilter(trc.Update.Filters)
|
||||
|
@ -237,6 +239,7 @@ func (com *Compiler) AddRole(role, table string, trc TRConfig) error {
|
|||
trv.update.cols = listToMap(trc.Update.Columns)
|
||||
trv.update.psmap = parsePresets(trc.Update.Presets)
|
||||
trv.update.pslist = mapToList(trv.update.psmap)
|
||||
trv.update.block = trc.Update.Block
|
||||
|
||||
// delete config
|
||||
trv.delete.fil, trv.delete.filNU, err = compileFilter(trc.Delete.Filters)
|
||||
|
@ -244,6 +247,7 @@ func (com *Compiler) AddRole(role, table string, trc TRConfig) error {
|
|||
return err
|
||||
}
|
||||
trv.delete.cols = listToMap(trc.Delete.Columns)
|
||||
trv.delete.block = trc.Delete.Block
|
||||
|
||||
singular := flect.Singularize(table)
|
||||
plural := flect.Pluralize(table)
|
||||
|
@ -330,6 +334,28 @@ func (com *Compiler) compileQuery(qc *QCode, op *Operation, role string) error {
|
|||
|
||||
trv := com.getRole(role, field.Name)
|
||||
|
||||
switch action {
|
||||
case QTQuery:
|
||||
if trv.query.block {
|
||||
continue
|
||||
}
|
||||
|
||||
case QTInsert:
|
||||
if trv.insert.block || trv.readOnly {
|
||||
return fmt.Errorf("insert blocked: %s", field.Name)
|
||||
}
|
||||
|
||||
case QTUpdate:
|
||||
if trv.update.block || trv.readOnly {
|
||||
return fmt.Errorf("update blocked: %s", field.Name)
|
||||
}
|
||||
|
||||
case QTDelete:
|
||||
if trv.delete.block || trv.readOnly {
|
||||
return fmt.Errorf("delete blocked: %s", field.Name)
|
||||
}
|
||||
}
|
||||
|
||||
selects = append(selects, Select{
|
||||
ID: id,
|
||||
ParentID: parentID,
|
||||
|
|
Loading…
Reference in New Issue