diff --git a/datasette/templates/debug_allowed.html b/datasette/templates/debug_allowed.html
index b06e1faf..f63fdc63 100644
--- a/datasette/templates/debug_allowed.html
+++ b/datasette/templates/debug_allowed.html
@@ -80,6 +80,7 @@ const resultsContent = document.getElementById('results-content');
const resultsCount = document.getElementById('results-count');
const pagination = document.getElementById('pagination');
const submitBtn = document.getElementById('submit-btn');
+const hasDebugPermission = {{ 'true' if has_debug_permission else 'false' }};
let currentData = null;
form.addEventListener('submit', async (ev) => {
@@ -164,7 +165,9 @@ function displayResults(data) {
html += '
Resource Path | ';
html += 'Parent | ';
html += 'Child | ';
- html += 'Reason | ';
+ if (hasDebugPermission) {
+ html += 'Reason | ';
+ }
html += '';
html += '';
@@ -173,7 +176,9 @@ function displayResults(data) {
html += `${escapeHtml(item.resource || '/')} | `;
html += `${escapeHtml(item.parent || '—')} | `;
html += `${escapeHtml(item.child || '—')} | `;
- html += `${escapeHtml(item.reason || '—')} | `;
+ if (hasDebugPermission) {
+ html += `${escapeHtml(item.reason || '—')} | `;
+ }
html += '';
}
diff --git a/datasette/views/special.py b/datasette/views/special.py
index e896becc..2e658d05 100644
--- a/datasette/views/special.py
+++ b/datasette/views/special.py
@@ -225,6 +225,7 @@ class AllowedResourcesView(BaseView):
request,
{
"supported_actions": sorted_actions,
+ "has_debug_permission": has_debug_permission,
},
)
@@ -262,12 +263,19 @@ class AllowedResourcesView(BaseView):
offset = (page - 1) * page_size
# Use the simplified allowed_resources method
+ # If user has debug permission, use the with_reasons variant
try:
- allowed_resources = await self.ds.allowed_resources(
- action=action,
- actor=actor,
- parent=parent_filter,
- )
+ if has_debug_permission:
+ allowed_resources = await self.ds.allowed_resources_with_reasons(
+ action=action,
+ actor=actor,
+ )
+ else:
+ allowed_resources = await self.ds.allowed_resources(
+ action=action,
+ actor=actor,
+ parent=parent_filter,
+ )
except Exception:
# If catalog tables don't exist yet, return empty results
headers = {}
@@ -287,10 +295,24 @@ class AllowedResourcesView(BaseView):
# Convert to list of dicts with resource path
allowed_rows = []
- for resource in allowed_resources:
+ for item in allowed_resources:
+ # Extract resource and reason depending on what we got back
+ if has_debug_permission:
+ # allowed_resources_with_reasons returns AllowedResource(resource, reason)
+ resource = item.resource
+ reason = item.reason
+ else:
+ # allowed_resources returns plain Resource objects
+ resource = item
+ reason = None
+
parent_val = resource.parent
child_val = resource.child
+ # Apply parent filter if needed (when using with_reasons, we need to filter manually)
+ if parent_filter is not None and parent_val != parent_filter:
+ continue
+
# Build resource path
if parent_val is None:
resource_path = "/"
@@ -305,9 +327,9 @@ class AllowedResourcesView(BaseView):
"resource": resource_path,
}
- # Add debug fields if available
- if has_debug_permission and hasattr(resource, "_reason"):
- row["reason"] = resource._reason
+ # Add reason if we have it
+ if reason is not None:
+ row["reason"] = reason
allowed_rows.append(row)