74 lines
2.0 KiB
Go
74 lines
2.0 KiB
Go
|
package abac
|
||
|
|
||
|
type SQLPolicyEngine struct {
|
||
|
store *SQLiteStore
|
||
|
}
|
||
|
|
||
|
func NewSQLPolicyEngine(store *SQLiteStore) *SQLPolicyEngine {
|
||
|
return &SQLPolicyEngine{store: store}
|
||
|
}
|
||
|
|
||
|
func (e *SQLPolicyEngine) EvaluatePolicy(userID, resourceID, action string) (PolicyDecision, error) {
|
||
|
userAttributes, err := e.store.GetUserAttributes(userID)
|
||
|
if err != nil {
|
||
|
return Deny, err
|
||
|
}
|
||
|
|
||
|
resourceAttributes, err := e.store.GetResourceAttributes(resourceID)
|
||
|
if err != nil {
|
||
|
return Deny, err
|
||
|
}
|
||
|
|
||
|
rows, err := e.store.db.Query(`
|
||
|
SELECT effect, condition_attribute_key, condition_attribute_value, condition_attribute_type
|
||
|
FROM policies
|
||
|
WHERE action = ?;
|
||
|
`, action)
|
||
|
if err != nil {
|
||
|
return Deny, err
|
||
|
}
|
||
|
defer rows.Close()
|
||
|
|
||
|
var allowPolicyFound bool = false
|
||
|
for rows.Next() {
|
||
|
var effect string
|
||
|
var conditionAttributeKey string
|
||
|
var conditionAttributeValue string
|
||
|
var conditionAttributeType string
|
||
|
|
||
|
err = rows.Scan(&effect, &conditionAttributeKey, &conditionAttributeValue)
|
||
|
if err != nil {
|
||
|
return Deny, err
|
||
|
}
|
||
|
|
||
|
var hasAttribute bool = false
|
||
|
if conditionAttributeType == "user" {
|
||
|
hasAttribute = checkAttributes(userAttributes, conditionAttributeKey, conditionAttributeValue)
|
||
|
} else if conditionAttributeType == "resource" {
|
||
|
hasAttribute = checkAttributes(resourceAttributes, conditionAttributeKey, conditionAttributeValue)
|
||
|
}
|
||
|
|
||
|
if effect == "Deny" && hasAttribute {
|
||
|
return Deny, nil
|
||
|
} else if effect == "Allow" && hasAttribute {
|
||
|
allowPolicyFound = true
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if allowPolicyFound {
|
||
|
return Allow, nil
|
||
|
}
|
||
|
|
||
|
return Deny, nil
|
||
|
}
|
||
|
|
||
|
func checkAttributes(attributes []Attribute, key, value string) bool {
|
||
|
for _, attribute := range attributes {
|
||
|
if attribute.Key == key && attribute.Value == value {
|
||
|
return true
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return false
|
||
|
}
|