Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add hasPaid(agent) function to ACL check #38

Open
wants to merge 5 commits into
base: main
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 23 additions & 7 deletions src/acl-check.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,9 @@ function publisherTrustedApp (kb, doc, aclDoc, modesRequired, origin, docAuths)
// modesRequired.every(mode => appAuths.some(auth => kb.holds(auth, ACL('mode'), mode, aclDoc)))
}

function accessDenied (kb, doc, directory, aclDoc, agent, modesRequired, origin, trustedOrigins, originTrustedModes = []) {
function accessDenied (kb, doc, directory, aclDoc, agent, modesRequired, origin, trustedOrigins, originTrustedModes = [], hasPaid) {
log(`accessDenied: checking access to ${doc} by ${agent} and origin ${origin}`)
const modeURIorReasons = modesAllowed(kb, doc, directory, aclDoc, agent, origin, trustedOrigins, originTrustedModes)
const modeURIorReasons = modesAllowed(kb, doc, directory, aclDoc, agent, origin, trustedOrigins, originTrustedModes, hasPaid)
let ok = false
log('accessDenied: modeURIorReasons: ' + JSON.stringify(Array.from(modeURIorReasons)))
modesRequired.forEach(mode => {
Expand Down Expand Up @@ -111,7 +111,7 @@ function checkAccess (kb, doc, directory, aclDoc, agent, modesRequired, origin,
return !accessDenied(kb, doc, directory, aclDoc, agent, modesRequired, origin, trustedOrigins, originTrustedModes)
}

function modesAllowed (kb, doc, directory, aclDoc, agent, origin, trustedOrigins, originTrustedModes = []) {
function modesAllowed (kb, doc, directory, aclDoc, agent, origin, trustedOrigins, originTrustedModes = [], hasPaid) {
let auths
if (!directory) { // Normal case, ACL for a file
auths = kb.each(null, ACL('accessTo'), doc, aclDoc)
Expand All @@ -127,7 +127,7 @@ function modesAllowed (kb, doc, directory, aclDoc, agent, origin, trustedOrigins
log(` modesAllowed: Origin ${origin} is trusted.`)
}

function agentOrGroupOK (auth, agent) {
function agentOrGroupOK (auth, agent, hasPaid) {
log(` Checking auth ${auth} with agent ${agent}`)
if (!agent) {
log(' Agent or group: Fail: not public and not logged on.')
Expand All @@ -146,6 +146,21 @@ function modesAllowed (kb, doc, directory, aclDoc, agent, origin, trustedOrigins
log(' Agent is member of group which has access.')
return true
}
// See https://github.com/solid/monetization-tests/issues/2
if (kb.holds(auth, ACL('agentClass'), ACL('PayingAgent'), aclDoc)) {
if (hasPaid && hasPaid(agent)) {
log(' PayingAgent: logged in and has paid, looks good')
return true
} else {
// FIXME: this will be logged if an Authorization exists for
// which paying would help it apply, but even then we don't know
// if that Authorization would give all the required modes and origins,
// and also maybe the agent already gets sufficient access through one
// of the other Authorizations in the ACL doc.
log(` PayingAgent: logged in but has not paid, and paying would make <${auth.value}> apply.`)
return false
}
}
log(' Agent or group access fails for this authentication.')
return false
} // Agent or group
Expand All @@ -154,15 +169,16 @@ function modesAllowed (kb, doc, directory, aclDoc, agent, origin, trustedOrigins
return kb.holds(auth, ACL('origin'), origin, aclDoc)
}

function agentAndAppFail (auth) {
function agentAndAppFail (auth, hasPaid) {
if (kb.holds(auth, ACL('agentClass'), FOAF('Agent'), aclDoc)) {
log(' Agent or group: Ok, its public.')
return false
}
if (!agentOrGroupOK(auth, agent)) {
if (!agentOrGroupOK(auth, agent, hasPaid)) {
log(' The agent/group check fails')
return 'User Unauthorized'
}

if (!origin) {
log(' Origin check not needed: no origin.')
return false
Expand All @@ -182,7 +198,7 @@ function modesAllowed (kb, doc, directory, aclDoc, agent, origin, trustedOrigins
const modeURIorReasons = new Set()

auths.forEach(auth => {
const agentAndAppStatus = agentAndAppFail(auth)
const agentAndAppStatus = agentAndAppFail(auth, hasPaid)
if (agentAndAppStatus) {
log(' Check failed: ' + agentAndAppStatus)
modeURIorReasons.add(agentAndAppStatus)
Expand Down