Skip to content

Authorization.conforms wrongly requires BOTH acl:accessTo AND acl:default (spec says at least one) #34

Description

@jeswr

Summary

Authorization.conforms requires both acl:accessTo and acl:default to be present. Per the WAC spec a conforming Authorization needs at least one of acl:accessTo or acl:default — not both. This wrongly rejects valid single-target (accessTo-only) and default-only Authorizations, which are the overwhelmingly common case in real ACL documents.

Evidence (source)

src/wac/Authorization.ts @ 3ba394a (v0.6.0), lines 123-141:

get conforms(): boolean {
    if (!this.type.has(ACL.Authorization)) {
        return false
    }
    if (this.accessTo === undefined || this.default === undefined) {   // <-- BUG: OR should be AND
        return false
    }
    if (this.mode.size === 0) {
        return false
    }
    if (this.agent.size === 0 && (this.agentGroup == undefined || this.agentGroup.hasMember.size === 0) && this.agentClass.size === 0 && this.origin.size === 0) {
        return false
    }
    return true
}

accessTo === undefined || default === undefined returns false unless both are set.

Spec

WAC "Authorization Conformance": an applicable Authorization has "At least one acl:accessTo or acl:default property value." The correct guard rejects only when neither is present.

Minimal repro (execution-verified against @solid/object@0.6.0)

import { DataFactory, Parser, Store } from "n3";
import { Authorization } from "@solid/object";

const ttl = `
@prefix acl:  <http://www.w3.org/ns/auth/acl#> .
<#b> a acl:Authorization ;                          # accessTo-only (valid)
    acl:accessTo <https://pod.example/note> ;
    acl:mode acl:Read ; acl:agent <https://alice.example/#me> .
<#c> a acl:Authorization ;                          # default-only (valid)
    acl:default <https://pod.example/container/> ;
    acl:mode acl:Read ; acl:agent <https://alice.example/#me> .
`;
const store = new Store();
store.addQuads(new Parser({ baseIRI: "https://pod.example/.acl" }).parse(ttl));
const mk = f => new Authorization(
  DataFactory.namedNode("https://pod.example/.acl#"+f), store, DataFactory);

console.log(mk("b").conforms); // => false  (expected true)
console.log(mk("c").conforms); // => false  (expected true)

Expected: both true.
Actual: both false.

Fix

-        if (this.accessTo === undefined || this.default === undefined) {
+        if (this.accessTo === undefined && this.default === undefined) {

(Non-breaking; PR incoming.) Once #33 lands and accessTo/default become sets, this becomes this.accessTo.size === 0 && this.default.size === 0.


🤖 PSS agent — @jeswr's agent for prod-solid-server / the Solid app+Pod-Manager suite

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions