Skip to content

Commit cb696d5

Browse files
authored
Merge pull request #44 from SolidOS/discovery
Discovery
2 parents 6a574cd + af110ec commit cb696d5

35 files changed

Lines changed: 2430 additions & 2387 deletions

src/acl/aclLogic.ts

Lines changed: 137 additions & 118 deletions
Original file line numberDiff line numberDiff line change
@@ -1,137 +1,156 @@
1-
/**
2-
* Simple Access Control
3-
*
4-
* This function sets up a simple default ACL for a resource, with
5-
* RWC for the owner, and a specified access (default none) for the public.
6-
* In all cases owner has read write control.
7-
* Parameter lists modes allowed to public
8-
*
9-
* @param options
10-
* @param options.public eg ['Read', 'Write']
11-
*
12-
* @returns Resolves with aclDoc uri on successful write
13-
*/
1+
import { graph, NamedNode, Namespace, serialize, sym } from "rdflib"
2+
import { AclLogic } from "../types";
3+
import { ns as namespace } from '../util/ns'
144

15-
import { graph, NamedNode, Namespace, serialize } from "rdflib"
16-
import solidNamespace from 'solid-namespace'
17-
import * as $rdf from 'rdflib'
18-
import { solidLogicSingleton } from "../logic/solidLogicSingleton"
19-
import { ACL_LINK } from "../util/UtilityLogic"
205

21-
export const ns = solidNamespace($rdf)
6+
export const ACL_LINK = sym(
7+
"http://www.iana.org/assignments/link-relations/acl"
8+
);
229

23-
export function setACLUserPublic (
24-
docURI: string,
25-
me: NamedNode,
26-
options: {
27-
defaultForNew?: boolean,
28-
public?: []
29-
}
30-
): Promise<NamedNode> {
31-
const aclDoc = solidLogicSingleton.store.any(
32-
solidLogicSingleton.store.sym(docURI),
33-
ACL_LINK
34-
)
10+
export function createAclLogic(store): AclLogic {
3511

36-
return Promise.resolve()
37-
.then(() => {
38-
if (aclDoc) {
39-
return aclDoc as NamedNode
12+
const ns = namespace
13+
14+
async function findAclDocUrl(url: string) {
15+
const doc = store.sym(url);
16+
await store.fetcher.load(doc);
17+
const docNode = store.any(doc, ACL_LINK);
18+
if (!docNode) {
19+
throw new Error(`No ACL link discovered for ${url}`);
20+
}
21+
return docNode.value;
4022
}
41-
42-
return fetchACLRel(docURI).catch(err => {
43-
throw new Error(`Error fetching rel=ACL header for ${docURI}: ${err}`)
44-
})
45-
})
46-
.then(aclDoc => {
47-
const aclText = genACLText(docURI, me, aclDoc.uri, options)
48-
if (!solidLogicSingleton.store.fetcher) {
49-
throw new Error('Cannot PUT this, store has no fetcher')
23+
/**
24+
* Simple Access Control
25+
*
26+
* This function sets up a simple default ACL for a resource, with
27+
* RWC for the owner, and a specified access (default none) for the public.
28+
* In all cases owner has read write control.
29+
* Parameter lists modes allowed to public
30+
*
31+
* @param options
32+
* @param options.public eg ['Read', 'Write']
33+
*
34+
* @returns Resolves with aclDoc uri on successful write
35+
*/
36+
function setACLUserPublic (
37+
docURI: string,
38+
me: NamedNode,
39+
options: {
40+
defaultForNew?: boolean,
41+
public?: []
5042
}
51-
return solidLogicSingleton.store.fetcher
52-
.webOperation('PUT', aclDoc.uri, {
53-
data: aclText,
54-
contentType: 'text/turtle'
55-
})
56-
.then(result => {
57-
if (!result.ok) {
58-
throw new Error('Error writing ACL text: ' + result.error)
43+
): Promise<NamedNode> {
44+
const aclDoc = store.any(
45+
store.sym(docURI),
46+
ACL_LINK
47+
)
48+
49+
return Promise.resolve()
50+
.then(() => {
51+
if (aclDoc) {
52+
return aclDoc as NamedNode
5953
}
6054

61-
return aclDoc
55+
return fetchACLRel(docURI).catch(err => {
56+
throw new Error(`Error fetching rel=ACL header for ${docURI}: ${err}`)
57+
})
6258
})
63-
})
64-
}
59+
.then(aclDoc => {
60+
const aclText = genACLText(docURI, me, aclDoc.uri, options)
61+
if (!store.fetcher) {
62+
throw new Error('Cannot PUT this, store has no fetcher')
63+
}
64+
return store.fetcher
65+
.webOperation('PUT', aclDoc.uri, {
66+
data: aclText,
67+
contentType: 'text/turtle'
68+
})
69+
.then(result => {
70+
if (!result.ok) {
71+
throw new Error('Error writing ACL text: ' + result.error)
72+
}
6573

66-
/**
67-
* @param docURI
68-
* @returns
69-
*/
70-
function fetchACLRel (docURI: string): Promise<NamedNode> {
71-
const fetcher = solidLogicSingleton.store.fetcher
72-
if (!fetcher) {
73-
throw new Error('Cannot fetch ACL rel, store has no fetcher')
74+
return aclDoc
75+
})
76+
})
7477
}
7578

76-
return fetcher.load(docURI).then(result => {
77-
if (!result.ok) {
78-
throw new Error('fetchACLRel: While loading:' + (result as any).error)
79+
/**
80+
* @param docURI
81+
* @returns
82+
*/
83+
function fetchACLRel (docURI: string): Promise<NamedNode> {
84+
const fetcher = store.fetcher
85+
if (!fetcher) {
86+
throw new Error('Cannot fetch ACL rel, store has no fetcher')
7987
}
8088

81-
const aclDoc = solidLogicSingleton.store.any(
82-
solidLogicSingleton.store.sym(docURI),
83-
ACL_LINK
84-
)
89+
return fetcher.load(docURI).then(result => {
90+
if (!result.ok) {
91+
throw new Error('fetchACLRel: While loading:' + (result as any).error)
92+
}
8593

86-
if (!aclDoc) {
87-
throw new Error('fetchACLRel: No Link rel=ACL header for ' + docURI)
88-
}
94+
const aclDoc = store.any(
95+
store.sym(docURI),
96+
ACL_LINK
97+
)
8998

90-
return aclDoc as NamedNode
91-
})
92-
}
99+
if (!aclDoc) {
100+
throw new Error('fetchACLRel: No Link rel=ACL header for ' + docURI)
101+
}
102+
103+
return aclDoc as NamedNode
104+
})
105+
}
93106

94-
/**
95-
* @param docURI
96-
* @param me
97-
* @param aclURI
98-
* @param options
99-
*
100-
* @returns Serialized ACL
101-
*/
102-
export function genACLText (
103-
docURI: string,
104-
me: NamedNode,
105-
aclURI: string,
106-
options: {
107-
defaultForNew?: boolean,
108-
public?: []
109-
} = {}
110-
): string | undefined {
111-
const optPublic = options.public || []
112-
const g = graph()
113-
const auth = Namespace('http://www.w3.org/ns/auth/acl#')
114-
let a = g.sym(`${aclURI}#a1`)
115-
const acl = g.sym(aclURI)
116-
const doc = g.sym(docURI)
117-
g.add(a, ns.rdf('type'), auth('Authorization'), acl)
118-
g.add(a, auth('accessTo'), doc, acl)
119-
if (options.defaultForNew) {
120-
g.add(a, auth('default'), doc, acl)
121-
}
122-
g.add(a, auth('agent'), me, acl)
123-
g.add(a, auth('mode'), auth('Read'), acl)
124-
g.add(a, auth('mode'), auth('Write'), acl)
125-
g.add(a, auth('mode'), auth('Control'), acl)
107+
/**
108+
* @param docURI
109+
* @param me
110+
* @param aclURI
111+
* @param options
112+
*
113+
* @returns Serialized ACL
114+
*/
115+
function genACLText (
116+
docURI: string,
117+
me: NamedNode,
118+
aclURI: string,
119+
options: {
120+
defaultForNew?: boolean,
121+
public?: []
122+
} = {}
123+
): string | undefined {
124+
const optPublic = options.public || []
125+
const g = graph()
126+
const auth = Namespace('http://www.w3.org/ns/auth/acl#')
127+
let a = g.sym(`${aclURI}#a1`)
128+
const acl = g.sym(aclURI)
129+
const doc = g.sym(docURI)
130+
g.add(a, ns.rdf('type'), auth('Authorization'), acl)
131+
g.add(a, auth('accessTo'), doc, acl)
132+
if (options.defaultForNew) {
133+
g.add(a, auth('default'), doc, acl)
134+
}
135+
g.add(a, auth('agent'), me, acl)
136+
g.add(a, auth('mode'), auth('Read'), acl)
137+
g.add(a, auth('mode'), auth('Write'), acl)
138+
g.add(a, auth('mode'), auth('Control'), acl)
126139

127-
if (optPublic.length) {
128-
a = g.sym(`${aclURI}#a2`)
129-
g.add(a, ns.rdf('type'), auth('Authorization'), acl)
130-
g.add(a, auth('accessTo'), doc, acl)
131-
g.add(a, auth('agentClass'), ns.foaf('Agent'), acl)
132-
for (let p = 0; p < optPublic.length; p++) {
133-
g.add(a, auth('mode'), auth(optPublic[p]), acl) // Like 'Read' etc
140+
if (optPublic.length) {
141+
a = g.sym(`${aclURI}#a2`)
142+
g.add(a, ns.rdf('type'), auth('Authorization'), acl)
143+
g.add(a, auth('accessTo'), doc, acl)
144+
g.add(a, auth('agentClass'), ns.foaf('Agent'), acl)
145+
for (let p = 0; p < optPublic.length; p++) {
146+
g.add(a, auth('mode'), auth(optPublic[p]), acl) // Like 'Read' etc
147+
}
148+
}
149+
return serialize(acl, g, aclURI)
150+
}
151+
return {
152+
findAclDocUrl,
153+
setACLUserPublic,
154+
genACLText
134155
}
135-
}
136-
return serialize(acl, g, aclURI)
137-
}
156+
}

src/authn/SolidAuthnLogic.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { appContext, offlineTestID } from "./authUtil";
33
import * as debug from '../util/debug'
44
import { Session } from "@inrupt/solid-client-authn-browser";
55
import { AuthenticationContext, AuthnLogic } from "../types";
6+
67
export class SolidAuthnLogic implements AuthnLogic {
78
private session: Session;
89

@@ -58,10 +59,10 @@ export class SolidAuthnLogic implements AuthnLogic {
5859
const curUrl = new URL(window.location.href)
5960
if (curUrl.hash !== postLoginRedirectHash) {
6061
if (history.pushState) {
61-
// console.log('Setting window.location.has using pushState')
62+
// debug.log('Setting window.location.has using pushState')
6263
history.pushState(null, document.title, postLoginRedirectHash)
6364
} else {
64-
// console.warn('Setting window.location.has using location.hash')
65+
// debug.warn('Setting window.location.has using location.hash')
6566
location.hash = postLoginRedirectHash
6667
}
6768
curUrl.hash = postLoginRedirectHash

0 commit comments

Comments
 (0)