Skip to content

Commit

Permalink
Fix #2339: getResourcePolicyAll returns unnamed policies (#2370)
Browse files Browse the repository at this point in the history
This fixes #2161.
 
With these changes, `getResourcePolicyAll` gets a new options argument, which can be set to `{ acceptBlankNodes: true }` in order for unnamed policies to be included in the result set. The default behavior of `getResourcePolicyAll` is unchanged, because otherwise this would be a breaking change, as the return type of the function would change.

Instead of being discovered in bulk by type, policies are now discovered following a chain of links from the ACR, and then its access control(s).

---------

Co-authored-by: garciafdezpatricia <[email protected]>
  • Loading branch information
NSeydoux and garciafdezpatricia authored Apr 24, 2024
1 parent 5d35c2e commit f9e7ce0
Show file tree
Hide file tree
Showing 7 changed files with 438 additions and 72 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@ The following changes are pending, and will be applied on the next major release

### Patch changes

- Fixed #2339: Unnamed policies are now returned by `getResourcePolicyAll` if an optional argument
`{ acceptBlankNodes: true }` is specified. This additional argument makes this a non-breaking change,
as the current type signature isn't changed.
- `getThing` now supports Blank Node identifiers in addition to IRIs and skolems to refer to a subject.
- `getThingAll(dataset, { allowacceptBlankNodes: true })` now returns all Blank Nodes
subjects in the Dataset, in particular including those part of a single chain of
Expand Down
25 changes: 22 additions & 3 deletions src/acp/control.internal.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,16 @@ import type { ThingPersisted, Url, UrlString } from "../interfaces";
import { getSourceUrl } from "../resource/resource";
import { internal_cloneResource } from "../resource/resource.internal";
import { addIri } from "../thing/add";
import { getIriAll } from "../thing/get";
import { getIriAll, getUrlAll } from "../thing/get";
import { removeAll, removeIri } from "../thing/remove";
import { setIri } from "../thing/set";
import { createThing, getThing, getThingAll, setThing } from "../thing/thing";
import {
asIri,
createThing,
getThing,
getThingAll,
setThing,
} from "../thing/thing";
import type { WithAccessibleAcr, WithAcp } from "./acp";
import { hasAccessibleAcr } from "./acp";
import type { AccessControlResource, Control } from "./control";
Expand Down Expand Up @@ -156,7 +162,20 @@ export function internal_setControl<ResourceExt extends WithAccessibleAcr>(
control: Control,
): ResourceExt {
const acr = internal_getAcr(withAccessControlResource);
const updatedAcr = setThing(acr, control);
let updatedAcr = setThing(acr, control);
const acrSubj = getThing(updatedAcr, getSourceUrl(acr));
// If the ACR has an anchor node, link the Access Control.
if (
acrSubj !== null &&
getUrlAll(acrSubj, acp.accessControl).every(
(object) => object.toString() !== asIri(control, getSourceUrl(acr)),
)
) {
updatedAcr = setThing(
updatedAcr,
addIri(acrSubj, acp.accessControl, asIri(control, getSourceUrl(acr))),
);
}
const updatedResource = internal_setAcr(
withAccessControlResource,
updatedAcr,
Expand Down
Loading

0 comments on commit f9e7ce0

Please sign in to comment.