Skip to content

Commit a4c5144

Browse files
Hasura permissions
1 parent e1a4725 commit a4c5144

File tree

5 files changed

+44
-12
lines changed

5 files changed

+44
-12
lines changed

config/config.go

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,8 +53,10 @@ type Database struct {
5353

5454
// Hasura -
5555
type Hasura struct {
56-
URL string `yaml:"url"`
57-
Secret string `yaml:"admin_secret"`
56+
URL string `yaml:"url"`
57+
Secret string `yaml:"admin_secret"`
58+
RowsLimit uint64 `yaml:"select_limit"`
59+
EnableAggregations bool `yaml:"allow_aggregation"`
5860
}
5961

6062
// Validate -

hasura/api.go

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,3 +148,16 @@ func (api *API) TrackTable(schema, name string) error {
148148
}
149149
return api.post("/v1/query", nil, req, nil)
150150
}
151+
152+
// CreateSelectPermissions - A select permission is used to restrict access to only the specified columns and rows.
153+
func (api *API) CreateSelectPermissions(table, role string, perm Permission) error {
154+
req := request{
155+
Type: "create_select_permission",
156+
Args: map[string]interface{}{
157+
"table": table,
158+
"role": role,
159+
"permission": perm,
160+
},
161+
}
162+
return api.post("/v1/query", nil, req, nil)
163+
}

hasura/hasura.go

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ func Create(hasura config.Hasura, cfg config.Database, views []string, models ..
2121
time.Sleep(time.Second * 10)
2222
}
2323

24-
metadata, err := Generate(cfg, models...)
24+
metadata, err := Generate(hasura, cfg, models...)
2525
if err != nil {
2626
return err
2727
}
@@ -80,11 +80,11 @@ func Create(hasura config.Hasura, cfg config.Database, views []string, models ..
8080
}
8181

8282
// Generate - creates hasura table structure in JSON from `models`. `models` should be pointer to your table models. `cfg` is DB config from YAML.
83-
func Generate(cfg config.Database, models ...interface{}) (map[string]interface{}, error) {
83+
func Generate(hasura config.Hasura, cfg config.Database, models ...interface{}) (map[string]interface{}, error) {
8484
tables := make([]interface{}, 0)
8585
schema := getSchema(cfg)
8686
for _, model := range models {
87-
table, err := generateOne(schema, model)
87+
table, err := generateOne(hasura, schema, model)
8888
if err != nil {
8989
return nil, err
9090
}
@@ -108,7 +108,7 @@ func newTable(schema, name string) table {
108108
Name: name,
109109
}
110110
}
111-
func generateOne(schema string, model interface{}) (table, error) {
111+
func generateOne(hasura config.Hasura, schema string, model interface{}) (table, error) {
112112
value := reflect.ValueOf(model)
113113
if value.Kind() != reflect.Ptr {
114114
return table{}, errors.Errorf("Model has to be pointer")
@@ -123,10 +123,10 @@ func generateOne(schema string, model interface{}) (table, error) {
123123
t.Columns = getColumns(typ)
124124

125125
if p, ok := t.HasuraSchema["select_permissions"]; ok {
126-
t.HasuraSchema["select_permissions"] = append(p.([]interface{}), formatSelectPermissions(t.Columns...))
126+
t.HasuraSchema["select_permissions"] = append(p.([]interface{}), formatSelectPermissions(hasura.RowsLimit, hasura.EnableAggregations, t.Columns...))
127127
} else {
128128
t.HasuraSchema["select_permissions"] = []interface{}{
129-
formatSelectPermissions(t.Columns...),
129+
formatSelectPermissions(hasura.RowsLimit, hasura.EnableAggregations, t.Columns...),
130130
}
131131
}
132132
t.HasuraSchema["object_relationships"] = []interface{}{}
@@ -135,13 +135,17 @@ func generateOne(schema string, model interface{}) (table, error) {
135135
return t, nil
136136
}
137137

138-
func formatSelectPermissions(columns ...string) map[string]interface{} {
138+
func formatSelectPermissions(limit uint64, allowAggs bool, columns ...string) map[string]interface{} {
139+
if limit == 0 {
140+
limit = 10
141+
}
139142
return map[string]interface{}{
140143
"role": "user",
141144
"permission": map[string]interface{}{
142145
"columns": columns,
143146
"filter": map[string]interface{}{},
144-
"allow_aggregations": true,
147+
"allow_aggregations": allowAggs,
148+
"limit": limit,
145149
},
146150
}
147151
}

hasura/hasura_test.go

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,7 @@ func Test_getColumns(t *testing.T) {
124124
func TestGenerate(t *testing.T) {
125125
type args struct {
126126
cfg config.Database
127+
hasura config.Hasura
127128
models []interface{}
128129
}
129130
tests := []struct {
@@ -138,16 +139,20 @@ func TestGenerate(t *testing.T) {
138139
cfg: config.Database{
139140
Kind: "mysql",
140141
},
142+
hasura: config.Hasura{
143+
EnableAggregations: true,
144+
RowsLimit: 5,
145+
},
141146
models: []interface{}{
142147
&testTable{}, &testTable2{}, &testTable3{}, &testTable4{},
143148
},
144149
},
145-
want: `{"tables":[{"array_relationships":[],"object_relationships":[],"select_permissions":[{"permission":{"allow_aggregations":true,"columns":["field_1","field_2"],"filter":{}},"role":"user"}],"table":{"name":"test_table","schema":"public"}},{"array_relationships":[],"object_relationships":[],"select_permissions":[{"permission":{"allow_aggregations":true,"columns":["field_1","field_2"],"filter":{}},"role":"user"}],"table":{"name":"fake_name","schema":"public"}},{"array_relationships":[],"object_relationships":[],"select_permissions":[{"permission":{"allow_aggregations":true,"columns":["field_2"],"filter":{}},"role":"user"}],"table":{"name":"test_table_3","schema":"public"}},{"array_relationships":[],"object_relationships":[],"select_permissions":[{"permission":{"allow_aggregations":true,"columns":["field_2","field_3"],"filter":{}},"role":"user"}],"table":{"name":"test_table_4","schema":"public"}}],"version":2}`,
150+
want: `{"tables":[{"array_relationships":[],"object_relationships":[],"select_permissions":[{"permission":{"limit":5,"allow_aggregations":true,"columns":["field_1","field_2"],"filter":{}},"role":"user"}],"table":{"name":"test_table","schema":"public"}},{"array_relationships":[],"object_relationships":[],"select_permissions":[{"permission":{"limit":5,"allow_aggregations":true,"columns":["field_1","field_2"],"filter":{}},"role":"user"}],"table":{"name":"fake_name","schema":"public"}},{"array_relationships":[],"object_relationships":[],"select_permissions":[{"permission":{"limit":5,"allow_aggregations":true,"columns":["field_2"],"filter":{}},"role":"user"}],"table":{"name":"test_table_3","schema":"public"}},{"array_relationships":[],"object_relationships":[],"select_permissions":[{"permission":{"limit":5,"allow_aggregations":true,"columns":["field_2","field_3"],"filter":{}},"role":"user"}],"table":{"name":"test_table_4","schema":"public"}}],"version":2}`,
146151
},
147152
}
148153
for _, tt := range tests {
149154
t.Run(tt.name, func(t *testing.T) {
150-
got, err := Generate(tt.args.cfg, tt.args.models...)
155+
got, err := Generate(tt.args.hasura, tt.args.cfg, tt.args.models...)
151156
if (err != nil) != tt.wantErr {
152157
t.Errorf("Generate() error = %v, wantErr %v", err, tt.wantErr)
153158
return

hasura/requests.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,11 @@ type request struct {
44
Type string `json:"type"`
55
Args interface{} `json:"args"`
66
}
7+
8+
// Permission -
9+
type Permission struct {
10+
Columns string `json:"columns"`
11+
Limit uint64 `json:"limit"`
12+
AllowAggs bool `json:"allow_aggregations"`
13+
Filter interface{} `json:"filter,omitempty"`
14+
}

0 commit comments

Comments
 (0)