home

Menu
  • ripgrep search

datasette-permissions-sql/datasette_permissions_sql/__init__.py

from datasette import hookimpl
import json
 
 
@hookimpl
def permission_allowed(datasette, actor, action, resource):
    actor = actor or {}
 
    async def inner():
        params = {"action": action}
        if resource:
            if len(resource) == 2:
                resource_1, resource_2 = resource
            else:
                resource_1, resource_2 = resource, None
            params["resource_1"] = resource_1
            params["resource_2"] = resource_2
        for key, value in actor.items():
            if isinstance(value, (dict, list, tuple)):
                value = json.dumps(value, default=repr)
            params["actor_{}".format(key)] = value
        for rule in datasette.plugin_config("datasette-permissions-sql") or []:
            sql = rule["sql"]
            rule_action = rule.get("action")
            rule_resource = rule.get("resource")
            if isinstance(rule_resource, list):
                rule_resource = tuple(rule_resource)
            fallback = rule.get("fallback")
            # Optionally match on action/resource
            if rule_action is not None and rule_action != action:
                continue
            if rule_resource is not None and rule_resource != resource:
                continue
            # Execute the SQL
            if actor:
                db = datasette.get_database(rule.get("database"))
                result = await db.execute(sql, params)
                row = result.first()
            else:
                row = None
            if row is None:
                if not fallback:
                    # Explicit deny
                    return False
                else:
                    # Fallback mode: try next rule in the loop
                    continue
            if len(row) == 1 and str(row[0]) == "-1":
                # Explicit deny
                return False
            else:
                return True
 
    return inner
 
Powered by Datasette