abac/sql_policy_engine.go

74 lines
2.0 KiB
Go
Raw Normal View History

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
}