mirror of
https://github.com/simonw/datasette.git
synced 2025-12-10 16:51:24 +01:00
Migrate views from ds.permissions to ds.actions, refs #2528
Updates all permission debugging views to use the new ds.actions dict instead of the old ds.permissions dict. Changes include: - Replace all ds.permissions references with ds.actions - Update field references: takes_database/takes_resource → takes_parent/takes_child - Remove default field from permission display - Rename sorted_permissions to sorted_actions in templates - Remove source_plugin from SQL queries and responses - Update test expectations to not check for source_plugin field This aligns the views with the new Action dataclass structure.
This commit is contained in:
parent
5feb5fcf5d
commit
5c6b76f2f0
5 changed files with 15 additions and 30 deletions
|
|
@ -110,7 +110,7 @@
|
||||||
<label for="action">Action (permission name):</label>
|
<label for="action">Action (permission name):</label>
|
||||||
<select id="action" name="action" required>
|
<select id="action" name="action" required>
|
||||||
<option value="">Select an action...</option>
|
<option value="">Select an action...</option>
|
||||||
{% for permission_name in sorted_permissions %}
|
{% for permission_name in sorted_actions %}
|
||||||
<option value="{{ permission_name }}">{{ permission_name }}</option>
|
<option value="{{ permission_name }}">{{ permission_name }}</option>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</select>
|
</select>
|
||||||
|
|
|
||||||
|
|
@ -26,7 +26,7 @@
|
||||||
<label for="action">Action (permission name):</label>
|
<label for="action">Action (permission name):</label>
|
||||||
<select id="action" name="action" required>
|
<select id="action" name="action" required>
|
||||||
<option value="">Select an action...</option>
|
<option value="">Select an action...</option>
|
||||||
{% for permission_name in sorted_permissions %}
|
{% for permission_name in sorted_actions %}
|
||||||
<option value="{{ permission_name }}">{{ permission_name }}</option>
|
<option value="{{ permission_name }}">{{ permission_name }}</option>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</select>
|
</select>
|
||||||
|
|
|
||||||
|
|
@ -57,7 +57,7 @@ textarea {
|
||||||
<p><label for="permission" style="display:block">Permission</label>
|
<p><label for="permission" style="display:block">Permission</label>
|
||||||
<select name="permission" id="permission">
|
<select name="permission" id="permission">
|
||||||
{% for permission in permissions %}
|
{% for permission in permissions %}
|
||||||
<option value="{{ permission.name }}">{{ permission.name }} (default {{ permission.default }})</option>
|
<option value="{{ permission.name }}">{{ permission.name }}</option>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</select>
|
</select>
|
||||||
<p><label for="resource_1">Database name</label><input type="text" id="resource_1" name="resource_1"></p>
|
<p><label for="resource_1">Database name</label><input type="text" id="resource_1" name="resource_1"></p>
|
||||||
|
|
@ -131,9 +131,6 @@ debugPost.addEventListener('submit', function(ev) {
|
||||||
{% else %}
|
{% else %}
|
||||||
<span class="check-result check-result-false">✗</span>
|
<span class="check-result check-result-false">✗</span>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% if check.used_default %}
|
|
||||||
<span class="check-used-default">(used default)</span>
|
|
||||||
{% endif %}
|
|
||||||
</h2>
|
</h2>
|
||||||
<p><strong>Actor:</strong> {{ check.actor|tojson }}</p>
|
<p><strong>Actor:</strong> {{ check.actor|tojson }}</p>
|
||||||
{% if check.resource %}
|
{% if check.resource %}
|
||||||
|
|
|
||||||
|
|
@ -144,11 +144,10 @@ class PermissionsDebugView(BaseView):
|
||||||
"name": p.name,
|
"name": p.name,
|
||||||
"abbr": p.abbr,
|
"abbr": p.abbr,
|
||||||
"description": p.description,
|
"description": p.description,
|
||||||
"takes_database": p.takes_database,
|
"takes_parent": p.takes_parent,
|
||||||
"takes_resource": p.takes_resource,
|
"takes_child": p.takes_child,
|
||||||
"default": p.default,
|
|
||||||
}
|
}
|
||||||
for p in self.ds.permissions.values()
|
for p in self.ds.actions.values()
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
@ -182,7 +181,6 @@ class PermissionsDebugView(BaseView):
|
||||||
"permission": permission,
|
"permission": permission,
|
||||||
"resource": resource_for_response,
|
"resource": resource_for_response,
|
||||||
"result": result,
|
"result": result,
|
||||||
"default": self.ds.permissions[permission].default,
|
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -232,7 +230,7 @@ class AllowedResourcesView(BaseView):
|
||||||
action = request.args.get("action")
|
action = request.args.get("action")
|
||||||
if not action:
|
if not action:
|
||||||
return Response.json({"error": "action parameter is required"}, status=400)
|
return Response.json({"error": "action parameter is required"}, status=400)
|
||||||
if action not in self.ds.permissions:
|
if action not in self.ds.actions:
|
||||||
return Response.json({"error": f"Unknown action: {action}"}, status=404)
|
return Response.json({"error": f"Unknown action: {action}"}, status=404)
|
||||||
if action not in self.CANDIDATE_SQL:
|
if action not in self.CANDIDATE_SQL:
|
||||||
return Response.json(
|
return Response.json(
|
||||||
|
|
@ -313,8 +311,6 @@ class AllowedResourcesView(BaseView):
|
||||||
# Add debug fields if available
|
# Add debug fields if available
|
||||||
if has_debug_permission and hasattr(resource, "_reason"):
|
if has_debug_permission and hasattr(resource, "_reason"):
|
||||||
row["reason"] = resource._reason
|
row["reason"] = resource._reason
|
||||||
if has_debug_permission and hasattr(resource, "_source_plugin"):
|
|
||||||
row["source_plugin"] = resource._source_plugin
|
|
||||||
|
|
||||||
allowed_rows.append(row)
|
allowed_rows.append(row)
|
||||||
|
|
||||||
|
|
@ -380,7 +376,7 @@ class PermissionRulesView(BaseView):
|
||||||
["debug_rules.html"],
|
["debug_rules.html"],
|
||||||
request,
|
request,
|
||||||
{
|
{
|
||||||
"sorted_permissions": sorted(self.ds.permissions.keys()),
|
"sorted_actions": sorted(self.ds.actions.keys()),
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -388,7 +384,7 @@ class PermissionRulesView(BaseView):
|
||||||
action = request.args.get("action")
|
action = request.args.get("action")
|
||||||
if not action:
|
if not action:
|
||||||
return Response.json({"error": "action parameter is required"}, status=400)
|
return Response.json({"error": "action parameter is required"}, status=400)
|
||||||
if action not in self.ds.permissions:
|
if action not in self.ds.actions:
|
||||||
return Response.json({"error": f"Unknown action: {action}"}, status=404)
|
return Response.json({"error": f"Unknown action: {action}"}, status=404)
|
||||||
|
|
||||||
actor = request.actor if isinstance(request.actor, dict) else None
|
actor = request.actor if isinstance(request.actor, dict) else None
|
||||||
|
|
@ -431,7 +427,7 @@ class PermissionRulesView(BaseView):
|
||||||
WITH rules AS (
|
WITH rules AS (
|
||||||
{union_sql}
|
{union_sql}
|
||||||
)
|
)
|
||||||
SELECT parent, child, allow, reason, source_plugin
|
SELECT parent, child, allow, reason
|
||||||
FROM rules
|
FROM rules
|
||||||
ORDER BY allow DESC, (parent IS NOT NULL), parent, child
|
ORDER BY allow DESC, (parent IS NOT NULL), parent, child
|
||||||
LIMIT :limit OFFSET :offset
|
LIMIT :limit OFFSET :offset
|
||||||
|
|
@ -450,7 +446,6 @@ class PermissionRulesView(BaseView):
|
||||||
"resource": _resource_path(parent, child),
|
"resource": _resource_path(parent, child),
|
||||||
"allow": row["allow"],
|
"allow": row["allow"],
|
||||||
"reason": row["reason"],
|
"reason": row["reason"],
|
||||||
"source_plugin": row["source_plugin"],
|
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -505,7 +500,7 @@ class PermissionCheckView(BaseView):
|
||||||
["debug_check.html"],
|
["debug_check.html"],
|
||||||
request,
|
request,
|
||||||
{
|
{
|
||||||
"sorted_permissions": sorted(self.ds.permissions.keys()),
|
"sorted_actions": sorted(self.ds.actions.keys()),
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -513,7 +508,7 @@ class PermissionCheckView(BaseView):
|
||||||
action = request.args.get("action")
|
action = request.args.get("action")
|
||||||
if not action:
|
if not action:
|
||||||
return Response.json({"error": "action parameter is required"}, status=400)
|
return Response.json({"error": "action parameter is required"}, status=400)
|
||||||
if action not in self.ds.permissions:
|
if action not in self.ds.actions:
|
||||||
return Response.json({"error": f"Unknown action: {action}"}, status=404)
|
return Response.json({"error": f"Unknown action: {action}"}, status=404)
|
||||||
|
|
||||||
parent = request.args.get("parent")
|
parent = request.args.get("parent")
|
||||||
|
|
@ -564,12 +559,10 @@ class PermissionCheckView(BaseView):
|
||||||
response["actor_id"] = request.actor["id"]
|
response["actor_id"] = request.actor["id"]
|
||||||
|
|
||||||
if info is not None:
|
if info is not None:
|
||||||
response["used_default"] = info.get("used_default")
|
|
||||||
response["depth"] = info.get("depth")
|
response["depth"] = info.get("depth")
|
||||||
# Only include sensitive fields if user has permissions-debug
|
# Only include sensitive fields if user has permissions-debug
|
||||||
if has_debug_permission:
|
if has_debug_permission:
|
||||||
response["reason"] = info.get("reason")
|
response["reason"] = info.get("reason")
|
||||||
response["source_plugin"] = info.get("source_plugin")
|
|
||||||
|
|
||||||
return Response.json(response)
|
return Response.json(response)
|
||||||
|
|
||||||
|
|
@ -687,16 +680,12 @@ class CreateTokenView(BaseView):
|
||||||
)
|
)
|
||||||
return {
|
return {
|
||||||
"actor": request.actor,
|
"actor": request.actor,
|
||||||
"all_permissions": self.ds.permissions.keys(),
|
"all_permissions": self.ds.actions.keys(),
|
||||||
"database_permissions": [
|
"database_permissions": [
|
||||||
key
|
key for key, value in self.ds.actions.items() if value.takes_database
|
||||||
for key, value in self.ds.permissions.items()
|
|
||||||
if value.takes_database
|
|
||||||
],
|
],
|
||||||
"resource_permissions": [
|
"resource_permissions": [
|
||||||
key
|
key for key, value in self.ds.actions.items() if value.takes_resource
|
||||||
for key, value in self.ds.permissions.items()
|
|
||||||
if value.takes_resource
|
|
||||||
],
|
],
|
||||||
"database_with_tables": database_with_tables,
|
"database_with_tables": database_with_tables,
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -247,7 +247,6 @@ async def test_rules_json_response_structure(ds_with_permissions):
|
||||||
assert "resource" in item
|
assert "resource" in item
|
||||||
assert "allow" in item
|
assert "allow" in item
|
||||||
assert "reason" in item
|
assert "reason" in item
|
||||||
assert "source_plugin" in item
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.asyncio
|
@pytest.mark.asyncio
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue