From 84a73dcd0ef9e11654e9e18e6da91983688c090b Mon Sep 17 00:00:00 2001 From: Michiel de Jong Date: Wed, 3 Mar 2021 14:10:14 +0100 Subject: [PATCH 1/5] Add hasPaid(agent) function to ACL check --- src/acl-check.js | 28 +++++++++++++++++++++------- 1 file changed, 21 insertions(+), 7 deletions(-) diff --git a/src/acl-check.js b/src/acl-check.js index d1887b7..4378efc 100644 --- a/src/acl-check.js +++ b/src/acl-check.js @@ -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 => { @@ -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) @@ -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.') @@ -146,6 +146,20 @@ 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.`) + } + } log(' Agent or group access fails for this authentication.') return false } // Agent or group @@ -154,12 +168,12 @@ 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' } @@ -182,7 +196,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) From d16dd9e5e8c4030d4e957afc5e93791b378add5d Mon Sep 17 00:00:00 2001 From: Michiel de Jong Date: Wed, 3 Mar 2021 16:24:02 +0100 Subject: [PATCH 2/5] Return if paying would help --- src/acl-check.js | 27 +++++++++++++++++++-------- 1 file changed, 19 insertions(+), 8 deletions(-) diff --git a/src/acl-check.js b/src/acl-check.js index 4378efc..40858d1 100644 --- a/src/acl-check.js +++ b/src/acl-check.js @@ -127,30 +127,30 @@ function modesAllowed (kb, doc, directory, aclDoc, agent, origin, trustedOrigins log(` modesAllowed: Origin ${origin} is trusted.`) } - function agentOrGroupOK (auth, agent, hasPaid) { + function agentOrGroupCheck (auth, agent, hasPaid) { log(` Checking auth ${auth} with agent ${agent}`) if (!agent) { log(' Agent or group: Fail: not public and not logged on.') - return false + return 'User Unauthorized' } if (kb.holds(auth, ACL('agentClass'), ACL('AuthenticatedAgent'), aclDoc)) { log(' AuthenticatedAgent: logged in, looks good') - return true + return 'OK' } if (kb.holds(auth, ACL('agent'), agent, aclDoc)) { log(' Agent explicitly authenticated.') - return true + return 'OK' } if (kb.each(auth, ACL('agentGroup'), null, aclDoc).some( group => kb.holds(group, VCARD('hasMember'), agent, group.doc()))) { log(' Agent is member of group which has access.') - return true + return 'OK' } // 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 + return 'OK' } else { // FIXME: this will be logged if an Authorization exists for // which paying would help it apply, but even then we don't know @@ -158,10 +158,11 @@ function modesAllowed (kb, doc, directory, aclDoc, agent, origin, trustedOrigins // 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 'Paying Would Help' } } log(' Agent or group access fails for this authentication.') - return false + return 'User Unauthorized' } // Agent or group function originOK (auth, origin) { @@ -173,10 +174,20 @@ function modesAllowed (kb, doc, directory, aclDoc, agent, origin, trustedOrigins log(' Agent or group: Ok, its public.') return false } - if (!agentOrGroupOK(auth, agent, hasPaid)) { + const agentOrGroupCheckResult = agentOrGroupCheck(auth, agent, hasPaid); + if (agentOrGroupCheckResult == 'User Unauthorized') { log(' The agent/group check fails') return 'User Unauthorized' } + if (agentOrGroupCheckResult == 'Paying Would Help') { + log(' Paying would help') + return 'Paying Would Help' + } + if (agentOrGroupCheckResult !== 'OK') { + log(' Unrecognized non-OK agentOrGroupCheckResult') + return 'User Unauthorized' + } + if (!origin) { log(' Origin check not needed: no origin.') return false From 2c585a1db0da526916ebc95256ed7bb64e639a49 Mon Sep 17 00:00:00 2001 From: Michiel de Jong Date: Wed, 3 Mar 2021 16:24:46 +0100 Subject: [PATCH 3/5] Return if paying would help --- src/acl-check.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/acl-check.js b/src/acl-check.js index 40858d1..acddfd7 100644 --- a/src/acl-check.js +++ b/src/acl-check.js @@ -174,12 +174,12 @@ function modesAllowed (kb, doc, directory, aclDoc, agent, origin, trustedOrigins log(' Agent or group: Ok, its public.') return false } - const agentOrGroupCheckResult = agentOrGroupCheck(auth, agent, hasPaid); - if (agentOrGroupCheckResult == 'User Unauthorized') { + const agentOrGroupCheckResult = agentOrGroupCheck(auth, agent, hasPaid) + if (agentOrGroupCheckResult === 'User Unauthorized') { log(' The agent/group check fails') return 'User Unauthorized' } - if (agentOrGroupCheckResult == 'Paying Would Help') { + if (agentOrGroupCheckResult === 'Paying Would Help') { log(' Paying would help') return 'Paying Would Help' } From db63e49d47b4446763625ae270b5757b75af6948 Mon Sep 17 00:00:00 2001 From: Michiel de Jong Date: Mon, 8 Mar 2021 13:31:50 +0100 Subject: [PATCH 4/5] Revert some of it --- src/acl-check.js | 25 ++++++++----------------- 1 file changed, 8 insertions(+), 17 deletions(-) diff --git a/src/acl-check.js b/src/acl-check.js index acddfd7..2d31e9e 100644 --- a/src/acl-check.js +++ b/src/acl-check.js @@ -127,11 +127,11 @@ function modesAllowed (kb, doc, directory, aclDoc, agent, origin, trustedOrigins log(` modesAllowed: Origin ${origin} is trusted.`) } - function agentOrGroupCheck (auth, agent, hasPaid) { + 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.') - return 'User Unauthorized' + return false } if (kb.holds(auth, ACL('agentClass'), ACL('AuthenticatedAgent'), aclDoc)) { log(' AuthenticatedAgent: logged in, looks good') @@ -139,18 +139,18 @@ function modesAllowed (kb, doc, directory, aclDoc, agent, origin, trustedOrigins } if (kb.holds(auth, ACL('agent'), agent, aclDoc)) { log(' Agent explicitly authenticated.') - return 'OK' + return true } if (kb.each(auth, ACL('agentGroup'), null, aclDoc).some( group => kb.holds(group, VCARD('hasMember'), agent, group.doc()))) { log(' Agent is member of group which has access.') - return 'OK' + 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 'OK' + 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 @@ -158,11 +158,11 @@ function modesAllowed (kb, doc, directory, aclDoc, agent, origin, trustedOrigins // 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 'Paying Would Help' + return false } } log(' Agent or group access fails for this authentication.') - return 'User Unauthorized' + return false } // Agent or group function originOK (auth, origin) { @@ -174,19 +174,10 @@ function modesAllowed (kb, doc, directory, aclDoc, agent, origin, trustedOrigins log(' Agent or group: Ok, its public.') return false } - const agentOrGroupCheckResult = agentOrGroupCheck(auth, agent, hasPaid) - if (agentOrGroupCheckResult === 'User Unauthorized') { + if (!agentOrGroupOK(auth, agent, hasPaid)) { log(' The agent/group check fails') return 'User Unauthorized' } - if (agentOrGroupCheckResult === 'Paying Would Help') { - log(' Paying would help') - return 'Paying Would Help' - } - if (agentOrGroupCheckResult !== 'OK') { - log(' Unrecognized non-OK agentOrGroupCheckResult') - return 'User Unauthorized' - } if (!origin) { log(' Origin check not needed: no origin.') From 350905eb973c46af2dc9404aad20e9da33c40b9d Mon Sep 17 00:00:00 2001 From: Michiel de Jong Date: Mon, 8 Mar 2021 13:38:00 +0100 Subject: [PATCH 5/5] One more --- src/acl-check.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/acl-check.js b/src/acl-check.js index 2d31e9e..4eb5695 100644 --- a/src/acl-check.js +++ b/src/acl-check.js @@ -135,7 +135,7 @@ function modesAllowed (kb, doc, directory, aclDoc, agent, origin, trustedOrigins } if (kb.holds(auth, ACL('agentClass'), ACL('AuthenticatedAgent'), aclDoc)) { log(' AuthenticatedAgent: logged in, looks good') - return 'OK' + return true } if (kb.holds(auth, ACL('agent'), agent, aclDoc)) { log(' Agent explicitly authenticated.')