Skip to content

Commit cf3ebc1

Browse files
authored
Merge pull request #16 from pdsinterop/origin-grants
Fix for origin grants, allow registered clients
2 parents 9b828f3 + 61db092 commit cf3ebc1

1 file changed

Lines changed: 80 additions & 81 deletions

File tree

src/WAC.php

Lines changed: 80 additions & 81 deletions
Original file line numberDiff line numberDiff line change
@@ -22,12 +22,9 @@ public function setBaseUrl($url) {
2222
}
2323

2424
public function addWACHeaders($request, $response, $webId) {
25-
$path = $request->getUri()->getPath();
26-
if ($this->basePath) {
27-
$path = str_replace($this->basePath, '', $path);
28-
}
29-
$userGrants = $this->getWACGrants($this->getUserGrants($path, $webId), $request->getUri());
30-
$publicGrants = $this->getWACGrants($this->getPublicGrants($path), $request->getUri());
25+
$uri = $request->getUri();
26+
$userGrants = $this->getWACGrants($this->getUserGrants($uri, $webId), $uri);
27+
$publicGrants = $this->getWACGrants($this->getPublicGrants($uri), $uri);
3128

3229
$wacHeaders = array();
3330
if ($userGrants) {
@@ -49,26 +46,32 @@ public function addWACHeaders($request, $response, $webId) {
4946
* see: https://github.com/solid/web-access-control-spec
5047
*/
5148

52-
public function isAllowed($request, $webId, $origin=false) {
49+
public function isAllowed($request, $webId, $origin=false, $allowedOrigins=[]) {
5350
$requestedGrants = $this->getRequestedGrants($request);
5451
$uri = $request->getUri();
5552
$parentUri = $this->getParentUri($uri);
5653

5754
foreach ($requestedGrants as $requestedGrant) {
5855
switch ($requestedGrant['type']) {
5956
case "resource":
57+
if ($this->isPublicGranted($requestedGrant['grants'], $uri)) {
58+
return true;
59+
}
6060
if (!$this->isUserGranted($requestedGrant['grants'], $uri, $webId)) {
6161
return false;
6262
}
63-
if (!$this->isOriginGranted($requestedGrant['grants'], $uri, $origin)) {
63+
if (!$this->isOriginGranted($requestedGrant['grants'], $uri, $origin, $allowedOrigins)) {
6464
return false;
6565
}
6666
break;
6767
case "parent":
68+
if ($this->isPublicGranted($requestedGrant['grants'], $uri)) {
69+
return true;
70+
}
6871
if (!$this->isUserGranted($requestedGrant['grants'], $parentUri, $webId)) {
6972
return false;
7073
}
71-
if (!$this->isOriginGranted($requestedGrant['grants'], $parentUri, $origin)) {
74+
if (!$this->isOriginGranted($requestedGrant['grants'], $parentUri, $origin, $allowedOrigins)) {
7275
return false;
7376
}
7477
break;
@@ -77,19 +80,17 @@ public function isAllowed($request, $webId, $origin=false) {
7780
return true;
7881
}
7982

80-
private function isUserGranted($requestedGrants, $uri, $webId) {
81-
if (!$requestedGrants) {
82-
return true;
83-
}
84-
83+
private function getPathFromUri($uri) {
8584
$path = $uri->getPath();
8685
if ($this->basePath) {
8786
$path = str_replace($this->basePath, '', $path);
8887
}
89-
90-
// error_log("REQUESTED GRANT: " . join(" or ", $requestedGrants) . " on $uri");
91-
$grants = $this->getUserGrants($path, $webId);
92-
// error_log("GRANTED GRANTS for $webId: " . json_encode($grants));
88+
return $path;
89+
}
90+
private function checkGrants($requestedGrants, $uri, $grants) {
91+
if (!$requestedGrants) {
92+
return true;
93+
}
9394
if (is_array($grants)) {
9495
foreach ($requestedGrants as $requestedGrant) {
9596
if ($grants['accessTo'] && $grants['accessTo'][$requestedGrant] && $this->arePathsEqual($grants['accessTo'][$requestedGrant], $uri)) {
@@ -104,39 +105,76 @@ private function isUserGranted($requestedGrants, $uri, $webId) {
104105
}
105106
return false;
106107
}
108+
109+
private function isPublicGranted($requestedGrants, $uri) {
110+
// error_log("REQUESTED GRANT: " . join(" or ", $requestedGrants) . " on $uri");
111+
$grants = $this->getPublicGrants($uri);
112+
// error_log("GRANTED GRANTS for public: " . json_encode($grants));
113+
return $this->checkGrants($requestedGrants, $uri, $grants);
114+
}
115+
116+
private function isUserGranted($requestedGrants, $uri, $webId) {
117+
// error_log("REQUESTED GRANT: " . join(" or ", $requestedGrants) . " on $uri");
118+
$grants = $this->getUserGrants($uri, $webId);
119+
// error_log("GRANTED GRANTS for user $webId: " . json_encode($grants));
120+
return $this->checkGrants($requestedGrants, $uri, $grants);
121+
}
107122

108-
private function isOriginGranted($requestedGrants, $uri, $origin) {
109-
if (!$requestedGrants) {
123+
private function isOriginGranted($requestedGrants, $uri, $origin, $allowedOrigins) {
124+
if (!$origin) {
110125
return true;
111126
}
112-
if (!$origin) {
127+
$parsedOrigin = parse_url($origin)['host'];
128+
if (in_array($parsedOrigin, $allowedOrigins)) {
113129
return true;
114130
}
131+
//error_log("REQUESTED GRANT: " . join(" or ", $requestedGrants) . " on $uri");
132+
$grants = $this->getOriginGrants($uri, $origin);
133+
//error_log("GRANTED GRANTS for origin $origin: " . json_encode($grants));
134+
return $this->checkGrants($requestedGrants, $uri, $grants);
135+
}
115136

116-
$path = $uri->getPath();
117-
if ($this->basePath) {
118-
$path = str_replace($this->basePath, '', $path);
137+
private function getPublicGrants($resourceUri) {
138+
$resourcePath = $this->getPathFromUri($resourceUri);
139+
$aclPath = $this->getAclPath($resourcePath);
140+
if (!$aclPath) {
141+
return array();
119142
}
143+
144+
$acl = $this->filesystem->read($aclPath);
120145

121-
//error_log("REQUESTED GRANT: " . join(" or ", $requestedGrants) . " on $uri");
122-
$grants = $this->getOriginGrants($path, $origin);
123-
//error_log("GRANTED GRANTS for $origin: " . json_encode($grants));
124-
if (is_array($grants)) {
125-
foreach ($requestedGrants as $requestedGrant) {
126-
if ($grants['accessTo'] && $grants['accessTo'][$requestedGrant] && $this->arePathsEqual($grants['accessTo'][$requestedGrant], $uri)) {
127-
return true;
128-
} else if ($grants['default'][$requestedGrant]) {
129-
if ($this->arePathsEqual($grants['default'][$requestedGrant], $uri)) {
130-
return false; // only use default for children, not for an exact match;
146+
$graph = new \EasyRdf_Graph();
147+
148+
// error_log("PARSE ACL from $aclPath with base " . $this->getAclBase($aclPath));
149+
$graph->parse($acl, Format::TURTLE, $this->getAclBase($aclPath));
150+
151+
$grants = array();
152+
153+
$foafAgent = "http://xmlns.com/foaf/0.1/Agent";
154+
$matching = $graph->resourcesMatching('http://www.w3.org/ns/auth/acl#agentClass');
155+
foreach ($matching as $match) {
156+
$agentClass = $match->get("<http://www.w3.org/ns/auth/acl#agentClass>");
157+
if ($agentClass == $foafAgent) {
158+
$accessTo = $match->get("<http://www.w3.org/ns/auth/acl#accessTo>");
159+
$default = $match->get("<http://www.w3.org/ns/auth/acl#default>");
160+
$modes = $match->all("<http://www.w3.org/ns/auth/acl#mode>");
161+
if ($default) {
162+
foreach ($modes as $mode) {
163+
$grants["default"][$mode->getUri()] = $default->getUri();
164+
}
165+
}
166+
if ($accessTo) {
167+
foreach ($modes as $mode) {
168+
$grants["accessTo"][$mode->getUri()] = $accessTo->getUri();
131169
}
132-
return true;
133170
}
134171
}
135172
}
136-
return false;
137-
}
173+
return $grants;
174+
}
138175

139-
private function getUserGrants($resourcePath, $webId) {
176+
private function getUserGrants($resourceUri, $webId) {
177+
$resourcePath = $this->getPathFromUri($resourceUri);
140178
$aclPath = $this->getAclPath($resourcePath);
141179
if (!$aclPath) {
142180
return array();
@@ -148,9 +186,7 @@ private function getUserGrants($resourcePath, $webId) {
148186

149187
// error_log("GET GRANTS for $webId");
150188

151-
// Start with grants that everyone has
152-
$grants = $this->getPublicGrants($resourcePath);
153-
189+
$grants = array();
154190
// Then get grants that are valid for any authenticated agent;
155191
$authenticatedAgent = "http://www.w3.org/ns/auth/acl#AuthenticatedAgent";
156192
$matching = $graph->resourcesMatching('http://www.w3.org/ns/auth/acl#agentClass');
@@ -200,7 +236,8 @@ private function getUserGrants($resourcePath, $webId) {
200236
return $grants;
201237
}
202238

203-
private function getOriginGrants($resourcePath, $origin) {
239+
private function getOriginGrants($resourceUri, $origin) {
240+
$resourcePath = $this->getPathFromUri($resourceUri);
204241
$aclPath = $this->getAclPath($resourcePath);
205242
if (!$aclPath) {
206243
return array();
@@ -212,8 +249,7 @@ private function getOriginGrants($resourcePath, $origin) {
212249

213250
// error_log("GET GRANTS for $origin");
214251

215-
$grants = $this->getPublicGrants($resourcePath);
216-
252+
$grants = array();
217253
$matching = $graph->resourcesMatching('http://www.w3.org/ns/auth/acl#origin');
218254
//error_log("MATCHING " . sizeof($matching));
219255
// Find all grants machting our origin;
@@ -474,41 +510,4 @@ private function grantToWac($grant) {
474510
private function getAclBase($aclPath) {
475511
return $this->baseUrl . $this->normalizePath(dirname($aclPath) . "/");
476512
}
477-
private function getPublicGrants($resourcePath) {
478-
$aclPath = $this->getAclPath($resourcePath);
479-
if (!$aclPath) {
480-
return array();
481-
}
482-
483-
$acl = $this->filesystem->read($aclPath);
484-
485-
$graph = new \EasyRdf_Graph();
486-
487-
// error_log("PARSE ACL from $aclPath with base " . $this->getAclBase($aclPath));
488-
$graph->parse($acl, Format::TURTLE, $this->getAclBase($aclPath));
489-
490-
$grants = array();
491-
492-
$foafAgent = "http://xmlns.com/foaf/0.1/Agent";
493-
$matching = $graph->resourcesMatching('http://www.w3.org/ns/auth/acl#agentClass');
494-
foreach ($matching as $match) {
495-
$agentClass = $match->get("<http://www.w3.org/ns/auth/acl#agentClass>");
496-
if ($agentClass == $foafAgent) {
497-
$accessTo = $match->get("<http://www.w3.org/ns/auth/acl#accessTo>");
498-
$default = $match->get("<http://www.w3.org/ns/auth/acl#default>");
499-
$modes = $match->all("<http://www.w3.org/ns/auth/acl#mode>");
500-
if ($default) {
501-
foreach ($modes as $mode) {
502-
$grants["default"][$mode->getUri()] = $default->getUri();
503-
}
504-
}
505-
if ($accessTo) {
506-
foreach ($modes as $mode) {
507-
$grants["accessTo"][$mode->getUri()] = $accessTo->getUri();
508-
}
509-
}
510-
}
511-
}
512-
return $grants;
513-
}
514513
}

0 commit comments

Comments
 (0)