Skip to content

Commit 76e069e

Browse files
pindersarekkas
authored andcommitted
Add custom metadata to policies (#115)
Signed-off-by: Erik Pinders <[email protected]>
1 parent d963cb9 commit 76e069e

File tree

5 files changed

+81
-9
lines changed

5 files changed

+81
-9
lines changed

manager/sql/databases.go

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -136,9 +136,18 @@ var Migrations = map[string]Statements{
136136
"DROP INDEX ladon_resource_compiled_idx",
137137
},
138138
},
139+
{
140+
Id: "4",
141+
Up: []string{
142+
"ALTER TABLE ladon_policy ADD COLUMN meta json",
143+
},
144+
Down: []string{
145+
"ALTER TABLE ladon_policy DROP COLUMN IF EXISTS meta",
146+
},
147+
},
139148
},
140149
},
141-
QueryInsertPolicy: `INSERT INTO ladon_policy(id, description, effect, conditions) SELECT $1::varchar, $2, $3, $4 WHERE NOT EXISTS (SELECT 1 FROM ladon_policy WHERE id = $1)`,
150+
QueryInsertPolicy: `INSERT INTO ladon_policy(id, description, effect, conditions, meta) SELECT $1::varchar, $2, $3, $4, $5 WHERE NOT EXISTS (SELECT 1 FROM ladon_policy WHERE id = $1)`,
142151
QueryInsertPolicyActions: `INSERT INTO ladon_action (id, template, compiled, has_regex) SELECT $1::varchar, $2, $3, $4 WHERE NOT EXISTS (SELECT 1 FROM ladon_action WHERE id = $1)`,
143152
QueryInsertPolicyActionsRel: `INSERT INTO ladon_policy_action_rel (policy, action) SELECT $1::varchar, $2::varchar WHERE NOT EXISTS (SELECT 1 FROM ladon_policy_action_rel WHERE policy = $1 AND action = $2)`,
144153
QueryInsertPolicyResources: `INSERT INTO ladon_resource (id, template, compiled, has_regex) SELECT $1::varchar, $2, $3, $4 WHERE NOT EXISTS (SELECT 1 FROM ladon_resource WHERE id = $1)`,
@@ -151,6 +160,7 @@ var Migrations = map[string]Statements{
151160
p.effect,
152161
p.conditions,
153162
p.description,
163+
p.meta,
154164
subject.template AS subject,
155165
resource.template AS resource,
156166
action.template AS action
@@ -187,9 +197,18 @@ var Migrations = map[string]Statements{
187197
"DROP INDEX ladon_resource_compiled_idx",
188198
},
189199
},
200+
{
201+
Id: "4",
202+
Up: []string{
203+
"ALTER TABLE ladon_policy ADD COLUMN meta text",
204+
},
205+
Down: []string{
206+
"ALTER TABLE ladon_policy DROP COLUMN meta",
207+
},
208+
},
190209
},
191210
},
192-
QueryInsertPolicy: `INSERT IGNORE INTO ladon_policy (id, description, effect, conditions) VALUES(?,?,?,?)`,
211+
QueryInsertPolicy: `INSERT IGNORE INTO ladon_policy (id, description, effect, conditions, meta) VALUES(?,?,?,?,?)`,
193212
QueryInsertPolicyActions: `INSERT IGNORE INTO ladon_action (id, template, compiled, has_regex) VALUES(?,?,?,?)`,
194213
QueryInsertPolicyActionsRel: `INSERT IGNORE INTO ladon_policy_action_rel (policy, action) VALUES(?,?)`,
195214
QueryInsertPolicyResources: `INSERT IGNORE INTO ladon_resource (id, template, compiled, has_regex) VALUES(?,?,?,?)`,
@@ -202,6 +221,7 @@ var Migrations = map[string]Statements{
202221
p.effect,
203222
p.conditions,
204223
p.description,
224+
p.meta,
205225
subject.template AS subject,
206226
resource.template AS resource,
207227
action.template AS action

manager/sql/manager_sql.go

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -136,11 +136,16 @@ func (s *SQLManager) create(policy Policy, tx *sqlx.Tx) (err error) {
136136
}
137137
}
138138

139+
meta := []byte("{}")
140+
if policy.GetMeta() != nil {
141+
meta = policy.GetMeta()
142+
}
143+
139144
if _, ok := Migrations[s.database]; !ok {
140145
return errors.Errorf("Database %s is not supported", s.database)
141146
}
142147

143-
if _, err = tx.Exec(s.db.Rebind(Migrations[s.database].QueryInsertPolicy), policy.GetID(), policy.GetDescription(), policy.GetEffect(), conditions); err != nil {
148+
if _, err = tx.Exec(s.db.Rebind(Migrations[s.database].QueryInsertPolicy), policy.GetID(), policy.GetDescription(), policy.GetEffect(), conditions, meta); err != nil {
144149
return errors.WithStack(err)
145150
}
146151

@@ -217,7 +222,7 @@ func scanRows(rows *sql.Rows) (Policies, error) {
217222
p.Subjects = []string{}
218223
p.Resources = []string{}
219224

220-
if err := rows.Scan(&p.ID, &p.Effect, &conditions, &p.Description, &subject, &resource, &action); err == sql.ErrNoRows {
225+
if err := rows.Scan(&p.ID, &p.Effect, &conditions, &p.Description, &p.Meta, &subject, &resource, &action); err == sql.ErrNoRows {
221226
return nil, NewErrResourceNotFound(err)
222227
} else if err != nil {
223228
return nil, errors.WithStack(err)
@@ -271,7 +276,7 @@ func scanRows(rows *sql.Rows) (Policies, error) {
271276
}
272277

273278
var getQuery = `SELECT
274-
p.id, p.effect, p.conditions, p.description,
279+
p.id, p.effect, p.conditions, p.description, p.meta,
275280
subject.template as subject, resource.template as resource, action.template as action
276281
FROM
277282
ladon_policy as p
@@ -287,7 +292,7 @@ LEFT JOIN ladon_resource as resource ON rr.resource = resource.id
287292
WHERE p.id=?`
288293

289294
var getAllQuery = `SELECT
290-
p.id, p.effect, p.conditions, p.description,
295+
p.id, p.effect, p.conditions, p.description, p.meta,
291296
subject.template as subject, resource.template as resource, action.template as action
292297
FROM
293298
(SELECT * from ladon_policy ORDER BY id LIMIT ? OFFSET ?) as p

manager/sql/manager_sql_migration_0_5_to_0_6.go

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ func (s *SQLManagerMigrateFromMajor0Minor6ToMajor0Minor7) GetManager() ladon.Man
4444

4545
// Get retrieves a policy.
4646
func (s *SQLManagerMigrateFromMajor0Minor6ToMajor0Minor7) Migrate() error {
47-
rows, err := s.DB.Query(s.DB.Rebind("SELECT id, description, effect, conditions FROM ladon_policy"))
47+
rows, err := s.DB.Query(s.DB.Rebind("SELECT id, description, effect, conditions, meta FROM ladon_policy"))
4848
if err != nil {
4949
return errors.WithStack(err)
5050
}
@@ -55,7 +55,7 @@ func (s *SQLManagerMigrateFromMajor0Minor6ToMajor0Minor7) Migrate() error {
5555
var p DefaultPolicy
5656
var conditions []byte
5757

58-
if err := rows.Scan(&p.ID, &p.Description, &p.Effect, &conditions); err != nil {
58+
if err := rows.Scan(&p.ID, &p.Description, &p.Effect, &conditions, &p.Meta); err != nil {
5959
return errors.WithStack(err)
6060
}
6161

@@ -131,9 +131,14 @@ func (s *SQLManagerMigrateFromMajor0Minor6ToMajor0Minor7) Create(policy Policy)
131131
}
132132
}
133133

134+
meta := []byte("{}")
135+
if policy.GetMeta() != nil {
136+
meta = policy.GetMeta()
137+
}
138+
134139
if tx, err := s.DB.Begin(); err != nil {
135140
return errors.WithStack(err)
136-
} else if _, err = tx.Exec(s.DB.Rebind("INSERT INTO ladon_policy (id, description, effect, conditions) VALUES (?, ?, ?, ?)"), policy.GetID(), policy.GetDescription(), policy.GetEffect(), conditions); err != nil {
141+
} else if _, err = tx.Exec(s.DB.Rebind("INSERT INTO ladon_policy (id, description, effect, conditions, meta) VALUES (?, ?, ?, ?, ?)"), policy.GetID(), policy.GetDescription(), policy.GetEffect(), conditions, meta); err != nil {
137142
if err := tx.Rollback(); err != nil {
138143
return errors.WithStack(err)
139144
}

policy.go

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,9 @@ type Policy interface {
5555
// GetConditions returns the policies conditions.
5656
GetConditions() Conditions
5757

58+
// GetMeta returns the policies arbitrary metadata set by the user.
59+
GetMeta() []byte
60+
5861
// GetStartDelimiter returns the delimiter which identifies the beginning of a regular expression.
5962
GetStartDelimiter() byte
6063

@@ -71,6 +74,7 @@ type DefaultPolicy struct {
7174
Resources []string `json:"resources" gorethink:"resources"`
7275
Actions []string `json:"actions" gorethink:"actions"`
7376
Conditions Conditions `json:"conditions" gorethink:"conditions"`
77+
Meta []byte `json:"meta" gorethink:"meta"`
7478
}
7579

7680
// UnmarshalJSON overwrite own policy with values of the given in policy in JSON format
@@ -83,6 +87,7 @@ func (p *DefaultPolicy) UnmarshalJSON(data []byte) error {
8387
Resources []string `json:"resources" gorethink:"resources"`
8488
Actions []string `json:"actions" gorethink:"actions"`
8589
Conditions Conditions `json:"conditions" gorethink:"conditions"`
90+
Meta []byte `json:"meta" gorethink:"meta"`
8691
}{
8792
Conditions: Conditions{},
8893
}
@@ -99,10 +104,20 @@ func (p *DefaultPolicy) UnmarshalJSON(data []byte) error {
99104
Resources: pol.Resources,
100105
Actions: pol.Actions,
101106
Conditions: pol.Conditions,
107+
Meta: pol.Meta,
102108
}
103109
return nil
104110
}
105111

112+
// UnmarshalMeta parses the policies []byte encoded metadata and stores the result in the value pointed to by v.
113+
func (p *DefaultPolicy) UnmarshalMeta(v interface{}) error {
114+
if err := json.Unmarshal(p.Meta, &v); err != nil {
115+
return errors.WithStack(err)
116+
}
117+
118+
return nil
119+
}
120+
106121
// GetID returns the policies id.
107122
func (p *DefaultPolicy) GetID() string {
108123
return p.ID
@@ -143,6 +158,11 @@ func (p *DefaultPolicy) GetConditions() Conditions {
143158
return p.Conditions
144159
}
145160

161+
// GetMeta returns the policies arbitrary metadata set by the user.
162+
func (p *DefaultPolicy) GetMeta() []byte {
163+
return p.Meta
164+
}
165+
146166
// GetEndDelimiter returns the delimiter which identifies the end of a regular expression.
147167
func (p *DefaultPolicy) GetEndDelimiter() byte {
148168
return '>'

policy_test.go

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,10 @@ var policyCases = []*DefaultPolicy{
5050
},
5151
}
5252

53+
type TestMeta struct {
54+
Key string `json:"key"`
55+
}
56+
5357
func TestHasAccess(t *testing.T) {
5458
assert.True(t, policyCases[0].AllowAccess())
5559
assert.False(t, policyCases[1].AllowAccess())
@@ -71,6 +75,24 @@ func TestMarshalling(t *testing.T) {
7175
}
7276
}
7377

78+
func TestMetaUnmarshalling(t *testing.T) {
79+
var m = TestMeta{
80+
Key: "test",
81+
}
82+
var mm TestMeta
83+
var p = DefaultPolicy{}
84+
85+
data, err := json.Marshal(&m)
86+
RequireError(t, false, err)
87+
88+
p.Meta = data
89+
90+
err = p.UnmarshalMeta(&mm)
91+
RequireError(t, false, err)
92+
93+
assert.Equal(t, &m, &mm)
94+
}
95+
7496
func TestGetters(t *testing.T) {
7597
for _, c := range policyCases {
7698
assert.Equal(t, c.ID, c.GetID())

0 commit comments

Comments
 (0)