Answer prose round 1: 1 🔴, 4 🟡 (0 misread); correct the older changelog entries, keep each fact in one home, rewrap the Keto header
CI / full-gate (push) Successful in 4m37s
CI / full-gate (push) Successful in 4m37s
This commit is contained in:
+8
-10
@@ -16,18 +16,17 @@ The host's contract version is now 0.5.0, so discovery refuses a plugin whose `a
|
|||||||
|
|
||||||
`transactTuples({ delete, insert })` sends both lists to Keto in one `PATCH /admin/relation-tuples`,
|
`transactTuples({ delete, insert })` sends both lists to Keto in one `PATCH /admin/relation-tuples`,
|
||||||
so all of them apply or none does. A `KetoClient` you build by hand, such as a test stub, must add the
|
so all of them apply or none does. A `KetoClient` you build by hand, such as a test stub, must add the
|
||||||
method. The admin example saves a user's or group's permissions through it: a Keto failure now
|
method. The admin example saves a user's or group's permissions through it, so a Keto failure leaves
|
||||||
changes nothing and answers with the error page, instead of a "stopped part-way" report. Its
|
every grant as it was and answers with the error page.
|
||||||
catalogs lose `admin.grants.partial`.
|
|
||||||
|
|
||||||
### The admin example lists a user's or group's grants that no installed plugin declares, with a Remove
|
### The admin example lists a user's or group's grants that no installed plugin declares, with a Remove
|
||||||
|
|
||||||
A direct grant of a name no installed plugin declares, such as one left by an uninstalled plugin,
|
A direct grant of a name no installed plugin declares, such as one left by an uninstalled plugin,
|
||||||
used to stay invisible and unchangeable, and reinstalling the plugin silently reactivated it. The
|
used to stay invisible and unchangeable, and reinstalling the plugin silently reactivated it. The
|
||||||
user and group pages now list these apart from the checkboxes, each with a Remove button (hidden from
|
user and group pages now list these apart from the checkboxes, each with a Remove button (hidden from
|
||||||
a `:read`-only holder). The example's catalogs gain `admin.grants.remove`, `admin.grants.undeclaredHint`
|
a `:read`-only holder). The example's catalogs gain `admin.grants.remove`, `admin.grants.removed`,
|
||||||
and `admin.grants.undeclaredLegend`, and its routes gain `POST /auth-admin/users/:id/permissions/remove`
|
`admin.grants.undeclaredHint` and `admin.grants.undeclaredLegend`, and its routes gain
|
||||||
and `POST /auth-admin/groups/:name/permissions/remove`.
|
`POST /auth-admin/users/:id/permissions/remove` and `POST /auth-admin/groups/:name/permissions/remove`.
|
||||||
|
|
||||||
### An operator can hide or rename a plugin's profile-menu entry
|
### An operator can hide or rename a plugin's profile-menu entry
|
||||||
|
|
||||||
@@ -174,14 +173,13 @@ page's `baseline` field.
|
|||||||
|
|
||||||
### The admin example confirms a permission save and reports a partial one
|
### The admin example confirms a permission save and reports a partial one
|
||||||
|
|
||||||
A save now lands on the page with "Permissions saved." If the permission service fails midway, the
|
A save now lands on the page with "Permissions saved." On a user, a changed grant reaches the user's
|
||||||
page says the save stopped part-way instead of showing the generic error page. On a user, the
|
live sessions at once when the revocation denylist is on.
|
||||||
changes that landed still reach the user's live sessions at once when the revocation denylist is on.
|
|
||||||
|
|
||||||
### A read-only holder sees View, not Edit, on the admin example's users list
|
### A read-only holder sees View, not Edit, on the admin example's users list
|
||||||
|
|
||||||
A holder of `users:read` without `users:write` gets a "View" row action with an eye icon. The admin
|
A holder of `users:read` without `users:write` gets a "View" row action with an eye icon. The admin
|
||||||
example's catalogs gain `admin.grants.partial`, `admin.grants.saved`, `admin.grants.stale` and
|
example's catalogs gain `admin.grants.saved`, `admin.grants.stale` and
|
||||||
`admin.users.view`, so a translated catalog mounted under `locales/plugins/auth-admin/` must add them.
|
`admin.users.view`, so a translated catalog mounted under `locales/plugins/auth-admin/` must add them.
|
||||||
|
|
||||||
### Every page carries a smaller icon sprite
|
### Every page carries a smaller icon sprite
|
||||||
|
|||||||
@@ -126,8 +126,6 @@ test("applyGrants sends the whole change as one Keto transaction, and a failure
|
|||||||
await assert.rejects(applyGrants(keto(true), userSubject("u1"), diff), /boom/);
|
await assert.rejects(applyGrants(keto(true), userSubject("u1"), diff), /boom/);
|
||||||
});
|
});
|
||||||
|
|
||||||
// grantDiff never touches a held name nobody declares, so the picker lists them apart and offers a
|
|
||||||
// Remove for each. A reader is told what is held but offered no button.
|
|
||||||
test("buildPermissionPicker lists direct grants no plugin declares, with a remove action only for a writer", () => {
|
test("buildPermissionPicker lists direct grants no plugin declares, with a remove action only for a writer", () => {
|
||||||
const direct = ["zed:read", "users:read", "old:write"];
|
const direct = ["zed:read", "users:read", "old:write"];
|
||||||
const picker = buildPermissionPicker({ action: "/auth-admin/users/u1/permissions", declared, direct });
|
const picker = buildPermissionPicker({ action: "/auth-admin/users/u1/permissions", declared, direct });
|
||||||
|
|||||||
@@ -9,8 +9,6 @@
|
|||||||
|
|
||||||
Locals: csrfToken, permissions ({ action, baseline, choices, empty, error, field, hint, inheritedNote, legend, notice, pending, readOnly, submit, undeclared }).
|
Locals: csrfToken, permissions ({ action, baseline, choices, empty, error, field, hint, inheritedNote, legend, notice, pending, readOnly, submit, undeclared }).
|
||||||
|
|
||||||
`undeclared` lists direct grants of names no plugin declares, outside the form above because grantDiff
|
|
||||||
never revokes one. Each has its own Remove form, and a reader gets the names without the button.
|
|
||||||
%>
|
%>
|
||||||
<section class="form-card" aria-labelledby="permissions-h">
|
<section class="form-card" aria-labelledby="permissions-h">
|
||||||
<h2 class="card-title" id="permissions-h"><%= permissions.legend %></h2>
|
<h2 class="card-title" id="permissions-h"><%= permissions.legend %></h2>
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
// Keto client: typed `fetch` wrappers over Ory Keto's relation-tuple APIs —
|
// Keto client: typed `fetch` wrappers over Ory Keto's relation-tuple APIs —
|
||||||
// `check` a permission, `listRelations`/`expand` to inspect them (read API), `writeTuple`/
|
// `check` a permission, `listRelations`/`expand` to inspect them (read API), `writeTuple`/
|
||||||
// `deleteTuple`/`transactTuples` to grant/revoke them (write API). Built-in `fetch` only, no SDK dep (AGENTS.md);
|
// `deleteTuple`/`transactTuples` to grant/revoke them (write API). Built-in `fetch` only, no SDK dep
|
||||||
// `fetchImpl`-injectable like the kratos clients. Read/write split onto the two ports config.ts
|
// (AGENTS.md); `fetchImpl`-injectable like the kratos clients. Read/write split onto the two ports config.ts
|
||||||
// targets (ketoReadUrl 4466 / ketoWriteUrl 4467).
|
// targets (ketoReadUrl 4466 / ketoWriteUrl 4467).
|
||||||
|
|
||||||
// A subject set: a relation on another object (e.g. Group:eng#members), resolved
|
// A subject set: a relation on another object (e.g. Group:eng#members), resolved
|
||||||
|
|||||||
Reference in New Issue
Block a user