Skip to content

Commit

Permalink
Hasura permissions
Browse files Browse the repository at this point in the history
  • Loading branch information
aopoltorzhicky committed Jul 1, 2021
1 parent e1a4725 commit a4c5144
Show file tree
Hide file tree
Showing 5 changed files with 44 additions and 12 deletions.
6 changes: 4 additions & 2 deletions config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,10 @@ type Database struct {

// Hasura -
type Hasura struct {
URL string `yaml:"url"`
Secret string `yaml:"admin_secret"`
URL string `yaml:"url"`
Secret string `yaml:"admin_secret"`
RowsLimit uint64 `yaml:"select_limit"`
EnableAggregations bool `yaml:"allow_aggregation"`
}

// Validate -
Expand Down
13 changes: 13 additions & 0 deletions hasura/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -148,3 +148,16 @@ func (api *API) TrackTable(schema, name string) error {
}
return api.post("/v1/query", nil, req, nil)
}

// CreateSelectPermissions - A select permission is used to restrict access to only the specified columns and rows.
func (api *API) CreateSelectPermissions(table, role string, perm Permission) error {
req := request{
Type: "create_select_permission",
Args: map[string]interface{}{
"table": table,
"role": role,
"permission": perm,
},
}
return api.post("/v1/query", nil, req, nil)
}
20 changes: 12 additions & 8 deletions hasura/hasura.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ func Create(hasura config.Hasura, cfg config.Database, views []string, models ..
time.Sleep(time.Second * 10)
}

metadata, err := Generate(cfg, models...)
metadata, err := Generate(hasura, cfg, models...)
if err != nil {
return err
}
Expand Down Expand Up @@ -80,11 +80,11 @@ func Create(hasura config.Hasura, cfg config.Database, views []string, models ..
}

// Generate - creates hasura table structure in JSON from `models`. `models` should be pointer to your table models. `cfg` is DB config from YAML.
func Generate(cfg config.Database, models ...interface{}) (map[string]interface{}, error) {
func Generate(hasura config.Hasura, cfg config.Database, models ...interface{}) (map[string]interface{}, error) {
tables := make([]interface{}, 0)
schema := getSchema(cfg)
for _, model := range models {
table, err := generateOne(schema, model)
table, err := generateOne(hasura, schema, model)
if err != nil {
return nil, err
}
Expand All @@ -108,7 +108,7 @@ func newTable(schema, name string) table {
Name: name,
}
}
func generateOne(schema string, model interface{}) (table, error) {
func generateOne(hasura config.Hasura, schema string, model interface{}) (table, error) {
value := reflect.ValueOf(model)
if value.Kind() != reflect.Ptr {
return table{}, errors.Errorf("Model has to be pointer")
Expand All @@ -123,10 +123,10 @@ func generateOne(schema string, model interface{}) (table, error) {
t.Columns = getColumns(typ)

if p, ok := t.HasuraSchema["select_permissions"]; ok {
t.HasuraSchema["select_permissions"] = append(p.([]interface{}), formatSelectPermissions(t.Columns...))
t.HasuraSchema["select_permissions"] = append(p.([]interface{}), formatSelectPermissions(hasura.RowsLimit, hasura.EnableAggregations, t.Columns...))
} else {
t.HasuraSchema["select_permissions"] = []interface{}{
formatSelectPermissions(t.Columns...),
formatSelectPermissions(hasura.RowsLimit, hasura.EnableAggregations, t.Columns...),
}
}
t.HasuraSchema["object_relationships"] = []interface{}{}
Expand All @@ -135,13 +135,17 @@ func generateOne(schema string, model interface{}) (table, error) {
return t, nil
}

func formatSelectPermissions(columns ...string) map[string]interface{} {
func formatSelectPermissions(limit uint64, allowAggs bool, columns ...string) map[string]interface{} {
if limit == 0 {
limit = 10
}
return map[string]interface{}{
"role": "user",
"permission": map[string]interface{}{
"columns": columns,
"filter": map[string]interface{}{},
"allow_aggregations": true,
"allow_aggregations": allowAggs,
"limit": limit,
},
}
}
Expand Down
9 changes: 7 additions & 2 deletions hasura/hasura_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,7 @@ func Test_getColumns(t *testing.T) {
func TestGenerate(t *testing.T) {
type args struct {
cfg config.Database
hasura config.Hasura
models []interface{}
}
tests := []struct {
Expand All @@ -138,16 +139,20 @@ func TestGenerate(t *testing.T) {
cfg: config.Database{
Kind: "mysql",
},
hasura: config.Hasura{
EnableAggregations: true,
RowsLimit: 5,
},
models: []interface{}{
&testTable{}, &testTable2{}, &testTable3{}, &testTable4{},
},
},
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}`,
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}`,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got, err := Generate(tt.args.cfg, tt.args.models...)
got, err := Generate(tt.args.hasura, tt.args.cfg, tt.args.models...)
if (err != nil) != tt.wantErr {
t.Errorf("Generate() error = %v, wantErr %v", err, tt.wantErr)
return
Expand Down
8 changes: 8 additions & 0 deletions hasura/requests.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,11 @@ type request struct {
Type string `json:"type"`
Args interface{} `json:"args"`
}

// Permission -
type Permission struct {
Columns string `json:"columns"`
Limit uint64 `json:"limit"`
AllowAggs bool `json:"allow_aggregations"`
Filter interface{} `json:"filter,omitempty"`
}

0 comments on commit a4c5144

Please sign in to comment.