Skip to content
This repository was archived by the owner on Nov 25, 2020. It is now read-only.

Commit f5b92ad

Browse files
committed
Massive refactoring introducing a MetaWrapper to avoid encapsulate all nodes url in the pydio:// form.
Wrappers specifics (getRealFSReference, getLastRealSize, isRemote, etc...) have been encapsulated as well and should not be called directly anymore. The MetaWrapper can register many subwrappers, once they are all used it will then translate the url to ajxp.XX SchemeTranslatorWrapper is an extendable wrapper simply translating URL to the next available wrapper from the MetaWrapper. Maybe could be simplified.
1 parent 09fa8a1 commit f5b92ad

File tree

53 files changed

+1540
-646
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

53 files changed

+1540
-646
lines changed

core/src/core/classes/class.AJXP_MetaStreamWrapper.php

Lines changed: 433 additions & 0 deletions
Large diffs are not rendered by default.

core/src/core/classes/class.AJXP_Node.php

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -414,8 +414,8 @@ public function loadNodeInfo($forceRefresh = false, $contextNode = false, $detai
414414
public function getRealFile()
415415
{
416416
if (!isset($this->realFilePointer)) {
417-
$this->realFilePointer = call_user_func(array($this->_wrapperClassName, "getRealFSReference"), $this->_url, true);
418-
$isRemote = call_user_func(array($this->_wrapperClassName, "isRemote"));
417+
$this->realFilePointer = AJXP_MetaStreamWrapper::getRealFSReference($this->_url, true);
418+
$isRemote = AJXP_MetaStreamWrapper::wrapperIsRemote($this->_url);
419419
if ($isRemote) {
420420
register_shutdown_function(array("AJXP_Utils", "silentUnlink"), $this->realFilePointer);
421421
}
@@ -564,6 +564,8 @@ protected function parseUrl()
564564
if (strstr($this->urlParts["scheme"], "ajxp.")!==false) {
565565
$pServ = AJXP_PluginsService::getInstance();
566566
$this->_wrapperClassName = $pServ->getWrapperClassName($this->urlParts["scheme"]);
567+
}else if($this->urlParts["scheme"] == "pydio"){
568+
$this->_wrapperClassName = "AJXP_PermissionWrapper";
567569
}
568570
}
569571

Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
<?php
2+
/*
3+
* Copyright 2007-2015 Abstrium <contact (at) pydio.com>
4+
* This file is part of Pydio.
5+
*
6+
* Pydio is free software: you can redistribute it and/or modify
7+
* it under the terms of the GNU Affero General Public License as published by
8+
* the Free Software Foundation, either version 3 of the License, or
9+
* (at your option) any later version.
10+
*
11+
* Pydio is distributed in the hope that it will be useful,
12+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14+
* GNU Affero General Public License for more details.
15+
*
16+
* You should have received a copy of the GNU Affero General Public License
17+
* along with Pydio. If not, see <http://www.gnu.org/licenses/>.
18+
*
19+
* The latest code can be found at <http://pyd.io/>.
20+
*/
21+
22+
defined('AJXP_EXEC') or die('Access not allowed');
23+
24+
25+
class AJXP_Permission
26+
{
27+
const READ = "r";
28+
const WRITE = "w";
29+
const DENY = "d";
30+
31+
private $value = array(
32+
self::WRITE => false,
33+
self::READ => false,
34+
self::DENY => false
35+
);
36+
37+
/**
38+
* @param array|null $value
39+
*/
40+
function __construct($value = null){
41+
if($value != null){
42+
if(is_array($value)) $this->value = $value;
43+
else if(is_string($value)){
44+
if(strpos($value, "r") !== false) $this->setRead();
45+
if(strpos($value, "w") !== false) $this->setWrite();
46+
if(strpos($value, "d") !== false) $this->setDeny();
47+
}
48+
}
49+
}
50+
51+
function getCopy(){
52+
return new AJXP_Permission($this->value);
53+
}
54+
55+
/**
56+
* @return bool
57+
*/
58+
function canRead(){
59+
return $this->value[self::READ];
60+
}
61+
62+
/**
63+
* @return bool
64+
*/
65+
function canWrite(){
66+
return $this->value[self::WRITE];
67+
}
68+
69+
/**
70+
* @return bool
71+
*/
72+
function denies(){
73+
if($this->value[self::DENY]) return true;
74+
if(!$this->value[self::DENY] && !$this->value[self::READ] && !$this->value[self::WRITE]){
75+
return true;
76+
}
77+
return false;
78+
}
79+
80+
function testPermission($stringPerm){
81+
if($stringPerm == self::READ) return $this->canRead();
82+
else if($stringPerm == self::WRITE) return $this->canWrite();
83+
else{
84+
throw new Exception("Unimplemented permission : " . $stringPerm);
85+
}
86+
}
87+
88+
function setRead($value = true){
89+
$this->value[self::READ] = $value;
90+
}
91+
function setWrite($value = true){
92+
$this->value[self::WRITE] = $value;
93+
}
94+
function setDeny($value = true){
95+
if($value){
96+
$this->value[self::WRITE] = $this->value[self::READ] = false;
97+
$this->value[self::DENY] = true;
98+
}else{
99+
$this->value[self::DENY] = false;
100+
}
101+
}
102+
103+
/**
104+
* @param AJXP_Permission $perm
105+
* @return AJXP_Permission
106+
*/
107+
function override($perm){
108+
$newPerm = $perm->getCopy();
109+
if($this->denies()){
110+
$newPerm->setDeny();
111+
}else{
112+
if($this->canRead()) $newPerm->setRead();
113+
if($this->canWrite()) $newPerm->setWrite();
114+
}
115+
return $newPerm;
116+
}
117+
118+
function __toString(){
119+
if($this->denies()) {
120+
return "DENY";
121+
}else if($this->canRead() && !$this->canWrite()) {
122+
return "READONLY";
123+
}else if(!$this->canRead() && $this->canWrite()) {
124+
return "WRITEONLY";
125+
}else{
126+
return "READ WRITE";
127+
}
128+
}
129+
130+
}
Lines changed: 189 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,189 @@
1+
<?php
2+
/*
3+
* Copyright 2007-2015 Abstrium <contact (at) pydio.com>
4+
* This file is part of Pydio.
5+
*
6+
* Pydio is free software: you can redistribute it and/or modify
7+
* it under the terms of the GNU Affero General Public License as published by
8+
* the Free Software Foundation, either version 3 of the License, or
9+
* (at your option) any later version.
10+
*
11+
* Pydio is distributed in the hope that it will be useful,
12+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14+
* GNU Affero General Public License for more details.
15+
*
16+
* You should have received a copy of the GNU Affero General Public License
17+
* along with Pydio. If not, see <http://www.gnu.org/licenses/>.
18+
*
19+
* The latest code can be found at <http://pyd.io/>.
20+
*/
21+
22+
defined('AJXP_EXEC') or die('Access not allowed');
23+
24+
25+
class AJXP_PermissionMask
26+
{
27+
/**
28+
* @var array
29+
*/
30+
private $permissionTree;
31+
32+
function __construct(){}
33+
34+
/**
35+
* @return array
36+
*/
37+
function getTree(){
38+
return $this->permissionTree;
39+
}
40+
41+
/**
42+
* @param array $tree
43+
* @return AJXP_PermissionMask;
44+
*/
45+
function updateTree($tree){
46+
$this->permissionTree = $tree;
47+
return $this;
48+
}
49+
50+
/**
51+
* @param string $path
52+
* @param AJXP_Permission $permission
53+
* @return AJXP_PermissionMask
54+
*/
55+
function updateBranch($path, $permission){
56+
// Update the tree
57+
$this->permissionTree = $this->mergeTrees($this->permissionTree, $this->pathToBranch($path, $permission));
58+
return $this;
59+
}
60+
61+
/**
62+
* @param string $path
63+
* @return AJXP_PermissionMask
64+
*/
65+
function deleteBranch($path){
66+
// Update the tree
67+
return $this;
68+
}
69+
70+
/**
71+
* @param AJXP_PermissionMask $mask
72+
* @return AJXP_PermissionMask
73+
*/
74+
function override($mask){
75+
// Return a new mask
76+
$this->permissionTree = $this->mergeTrees($this->permissionTree, $mask->getTree());
77+
return $this;
78+
}
79+
80+
/**
81+
* @param string $test
82+
* @param string $permission
83+
* @return bool
84+
*/
85+
function match($test, $permission){
86+
// Check if a path has the given permission
87+
88+
$pathes = $this->flattenTree();
89+
//var_dump($pathes);
90+
foreach($pathes as $path => $permObject){
91+
if(strpos($test, $path) === 0){
92+
var_dump("Test $test starts with existing path ".$path.":".$permObject);
93+
return $permObject->testPermission($permission);
94+
}
95+
}
96+
// test is not under a defined permission, check if it needs traversal
97+
foreach($pathes as $path => $permObject){
98+
if(strpos($path, $test) === 0 && !$permObject->denies()){
99+
var_dump("Existing path starts with test ($test) >> ".$path.":".$permObject);
100+
return $permObject->testPermission($permission);
101+
}
102+
}
103+
104+
// Not in any path
105+
return false;
106+
107+
}
108+
109+
/**
110+
* @param array $t1
111+
* @param array $t2
112+
* @return array
113+
*/
114+
private function mergeTrees($t1, $t2){
115+
$result = $t1;
116+
foreach($t2 as $key => $value2){
117+
if(!isset($t1[$key])){
118+
// Add branch
119+
$result[$key] = $value2;
120+
continue;
121+
}
122+
$value1 = $t1[$key];
123+
if(is_a($value1, "AJXP_Permission") && is_a($value2, "AJXP_Permission")){
124+
/**
125+
* @var AJXP_Permission $value2
126+
*/
127+
$result[$key] = $value2->override($value1);
128+
}else if(is_a($value1, "AJXP_Permission")){
129+
$result[$key] = $value2;
130+
}else if(is_a($value2, "AJXP_Permission")){
131+
/**
132+
* @var AJXP_Permission $value2
133+
*/
134+
//if($value2->denies()) {
135+
$result[$key] = $value2;
136+
//} else{
137+
// do nothing, keep original branch
138+
//}
139+
}else{
140+
// Two arrays
141+
$result[$key] = $this->mergeTrees($value1, $value2);
142+
}
143+
}
144+
return $result;
145+
}
146+
147+
/**
148+
* @param string $path
149+
* @param AJXP_Permission $permission
150+
* @return array
151+
*/
152+
private function pathToBranch($path, $permission){
153+
$parts = explode("/", trim($path, "/"));
154+
$l = count($parts);
155+
$br = array();
156+
$current = &$br;
157+
for($i=0;$i<$l; $i++){
158+
if($i < $l - 1){
159+
$current[$parts[$i]] = array();
160+
$current = &$current[$parts[$i]];
161+
}else{
162+
$current[$parts[$i]] = $permission;
163+
}
164+
}
165+
return $br;
166+
}
167+
168+
/**
169+
* @param array|null $tree
170+
* @param array|null $pathes
171+
* @param string $currentRoot
172+
* @return AJXP_Permission[]
173+
*/
174+
private function flattenTree($tree = null, &$pathes = null, $currentRoot=""){
175+
if($tree == null) $tree = $this->getTree();
176+
if($pathes == null) $pathes = array();
177+
178+
foreach($tree as $pathPart => $value){
179+
if(is_a($value, "AJXP_Permission")){
180+
$pathes[$currentRoot."/".$pathPart] = $value;
181+
}else{
182+
$this->flattenTree($value, $pathes, $currentRoot."/".$pathPart);
183+
}
184+
}
185+
186+
return $pathes;
187+
}
188+
189+
}

core/src/core/classes/class.AJXP_Plugin.php

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -809,10 +809,12 @@ public function detectStreamWrapper($register = false)
809809
}
810810
if ($register) {
811811
$pServ = AJXP_PluginsService::getInstance();
812-
if (!in_array($streamData["protocol"], stream_get_wrappers())) {
812+
$wrappers = stream_get_wrappers();
813+
if (!in_array($streamData["protocol"], $wrappers)) {
813814
stream_wrapper_register($streamData["protocol"], $streamData["classname"]);
814815
$pServ->registerWrapperClass($streamData["protocol"], $streamData["classname"]);
815816
}
817+
AJXP_MetaStreamWrapper::register($wrappers);
816818
}
817819
return $streamData;
818820
}

0 commit comments

Comments
 (0)