-
-
Save Fi1osof/0983698e48a892e65b8c to your computer and use it in GitHub Desktop.
modZilla
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/* | |
* To change this template, choose Tools | Templates | |
* and open the template in the editor. | |
*/ | |
/** | |
* Description of modzilla | |
* | |
* @author Fi1osof | |
*/ | |
class modzillaCacheManager{ | |
public $modx = null; | |
protected $cachePath = "ModzillaCache/"; | |
function __construct(MODx $modx) { | |
$this->modx = & $modx; | |
} | |
public function setPolicyCache($key, $var, $expire= 0, $options= array()){ | |
$key = "PolicyCache/{$key}"; | |
return $this->set($key, $var, $expire, $options); | |
} | |
public function getPolicyCache($key, $options= array()){ | |
$key = "PolicyCache/{$key}"; | |
return $this->get($key, $options); | |
} | |
public function set($key, $var, $expire= 0, $options= array()){ | |
return true; | |
switch($key){ | |
case "AccessesCache": | |
$key = "{$key}/{$this->modx->user->get('id')}"; | |
break; | |
} | |
$key = "{$this->cachePath}{$key}"; | |
return $this->modx->cacheManager->set($key, $var, $expire, $options); | |
} | |
public function get($key, $options= array()){ | |
return null; | |
switch($key){ | |
case "AccessesCache": | |
$key = "{$key}/{$this->modx->user->get('id')}"; | |
break; | |
} | |
$key = "{$this->cachePath}{$key}"; | |
return $this->modx->cacheManager->get($key, $options); | |
} | |
} | |
class modzilla { | |
public $modx = null; | |
public $cacheManager = null; | |
function __construct(MODx $modx) { | |
$this->modx = & $modx; | |
$this->cacheManager = new modzillaCacheManager($modx); | |
} | |
} | |
?> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
class ModzillaAccess extends modAccess { | |
public static function addCheckListConditions(xPDO & $xpdo, xPDOCriteria $criteria){ | |
if(empty($criteria->hasCheckListConditions)){ | |
if($definitions = $xpdo->getFKDefinition($criteria->getClass(), 'Accesses') | |
AND $class = $definitions['class'] | |
){ | |
$user_id = $xpdo->user->get('id'); | |
if(!$xpdo->user->get('sudo')){ | |
$criteria->leftJoin($class, 'Accesses'); | |
$criteria->leftJoin('modUserGroupMember', 'membergroup', | |
"Accesses.principal_class='modUserGroup' | |
AND Accesses.principal = membergroup.user_group"); | |
$criteria->where(array( | |
'Accesses.id' => null, | |
)); | |
$criteria->orCondition(array( | |
'owner' => $user_id, | |
)); | |
$criteria->orCondition(array( | |
"Accesses.principal_class" => "modUser", | |
"AND:Accesses.principal:=" => $user_id, | |
)); | |
$criteria->orCondition(array( | |
"Accesses.principal_class" => "modUserGroup", | |
"AND:membergroup.member:=" => $user_id, | |
)); | |
} | |
$criteria->hasCheckListConditions = true; | |
} | |
} | |
return $criteria; | |
} | |
public static function loadAttributes(modX &$modx, $context = '', $userId = 0) { | |
$class = __CLASS__; | |
return self::__loadAttributes($modx, $context, $userId, $class); | |
} | |
protected static function __loadAttributes(modX &$modx, $context = '', $userId = 0, $class) { | |
$cacheKey = "AccessesCache/{$class}/{$userId}"; | |
if(!$attributes = $modx->modzilla->cacheManager->get($cacheKey)){ | |
$attributes = array(); | |
$accessTable = $modx->getTableName($class); | |
$policyTable = $modx->getTableName('modAccessPolicy'); | |
$memberTable = $modx->getTableName('modUserGroupMember'); | |
$memberRoleTable = $modx->getTableName('modUserGroupRole'); | |
// $legacyDocGroups = array(); | |
$query = null; | |
if ($userId > 0) { | |
$sql = "SELECT acl.target, acl.principal_class, acl.principal, mr.authority, acl.policy, p.data | |
FROM {$accessTable} acl " . | |
"JOIN {$policyTable} p ON p.id = acl.policy " . | |
"LEFT JOIN {$memberTable} mug ON acl.principal_class = 'modUserGroup' AND acl.principal = mug.user_group " . | |
"LEFT JOIN {$memberRoleTable} mr ON mr.id = mug.role " . | |
"WHERE | |
( acl.principal_class = 'modUser' | |
AND acl.principal = :principal ) | |
OR (acl.principal_class = 'modUserGroup' | |
AND mug.member = :principal)". | |
"AND mug.user_group = acl.principal " . | |
"AND mr.authority <= acl.authority " . | |
"ORDER BY acl.target, acl.principal, mr.authority, acl.policy"; | |
$bindings = array( | |
':principal' => $userId, | |
); | |
$query = new xPDOCriteria($modx, $sql, $bindings); | |
} else { | |
$sql = "SELECT acl.target, acl.principal_class, acl.principal, 0 AS authority, acl.policy, p.data FROM {$accessTable} acl " . | |
"LEFT JOIN {$policyTable} p ON p.id = acl.policy " . | |
"WHERE acl.principal_class = 'modUserGroup' " . | |
"AND acl.principal = 0 " . | |
"ORDER BY acl.target, acl.principal, acl.authority, acl.policy"; | |
$query = new xPDOCriteria($modx, $sql, $bindings); | |
} | |
if ($query && $query->stmt && $query->stmt->execute()) { | |
while ($row = $query->stmt->fetch(PDO::FETCH_ASSOC)) { | |
$attributes[$row['target']][] = array( | |
'principal' => $row['principal'], | |
'authority' => $row['authority'], | |
'principal_class' => $row['principal_class'], | |
'policy' => $row['data'] ? $modx->fromJSON($row['data'], true) : array(), | |
); | |
} | |
} | |
// print $query->toSQL(); | |
//exit; | |
if($attributes){ | |
$modx->modzilla->cacheManager->set($cacheKey, $attributes); | |
} | |
} | |
return $attributes; | |
} | |
public static function getAccessesTable(){ | |
print __CLASS__; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
$this->loadClass('ModzillaAccess'); | |
class ModzillaAccessProjects extends ModzillaAccess { | |
public static function loadAttributes(modX &$modx, $context = '', $userId = 0) { | |
$class = __CLASS__; | |
return self::__loadAttributes($modx, $context, $userId, $class); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
$this->loadClass('ModzillaAccess'); | |
$this->loadClass('ModzillaAccessTasks'); | |
class ModzillaProject extends modAccessibleSimpleObject { | |
protected $policyFinded = false; | |
public function checkPolicy($criteria, $targets = null) { | |
if ($criteria && $this->xpdo instanceof modX && $this->xpdo->getSessionState() == modX::SESSION_STATE_INITIALIZED) { | |
if ($this->xpdo->user->get('sudo') OR $this->xpdo->user->get('id') == $this->get('owner')){ | |
return true; | |
} | |
if (!is_array($criteria) && is_scalar($criteria)) { | |
$criteria = array("{$criteria}" => true); | |
} | |
$policy = $this->findPolicy(); | |
if (!empty($policy)) { | |
$class = $this->getAccessClass(); | |
$principal = $class::loadAttributes($this->xpdo, '', $this->xpdo->user->get('id')); | |
/*print '<pre>'; | |
print_r($principal); | |
print_r($policy); | |
print $this->get('owner'); | |
print '</pre>'; | |
exit;*/ | |
if (!empty($principal) AND $userPerms = $principal[$this->get('id')]) { | |
foreach ($policy as $policyAccess => $access) { | |
foreach ($access as $targetId => $targetPolicy) { | |
foreach ($targetPolicy as $policyIndex => $applicablePolicy) { | |
if ($this->xpdo->getDebug() === true) | |
$this->xpdo->log(xPDO::LOG_LEVEL_DEBUG, 'target pk='. $this->getPrimaryKey() .'; evaluating policy: ' . print_r($applicablePolicy, 1) . ' against principal for user id=' . $this->xpdo->getLoginUserID() .': ' . print_r($principal[$policyAccess], 1)); | |
$principalPolicyData = array(); | |
$principalAuthority = 9999; | |
foreach ($userPerms as $acl) { | |
$principalAuthority = intval($acl['authority']); | |
$principalPolicyData = $acl['policy']; | |
$principalId = $acl['principal']; | |
$principalClass = $acl['principal_class']; | |
if ($applicablePolicy['principal'] == $principalId AND $applicablePolicy['principal_class'] == $principalClass){ | |
if ($principalAuthority <= $applicablePolicy['authority']) { | |
if (!$applicablePolicy['policy']) { | |
return true; | |
} | |
if (empty($principalPolicyData)) $principalPolicyData = array(); | |
$matches = array_intersect_assoc($principalPolicyData, $applicablePolicy['policy']); | |
if ($matches) { | |
if ($this->xpdo->getDebug() === true) | |
$this->xpdo->log(modX::LOG_LEVEL_DEBUG, 'Evaluating policy matches: ' . print_r($matches, 1)); | |
$matched = array_diff_assoc($criteria, $matches); | |
if (empty($matched)) { | |
return true; | |
} | |
} | |
} | |
} | |
} | |
} | |
} | |
} | |
} | |
return false; | |
} | |
} | |
else{ | |
return false; | |
} | |
return true; | |
} | |
protected function getPolicyCacheKey(){ | |
return $this->_class."/".$this->get('id'); | |
} | |
public function findPolicy($context = '') { | |
if (empty($this->_policies) && $this->policyFinded == false) { | |
$this->policyFinded = true; | |
$cacheKey = $this->getPolicyCacheKey(); | |
$class = $this->getAccessClass(); | |
if(!$policy = $this->xpdo->modzilla->cacheManager->getPolicyCache($cacheKey)){ | |
$policy = array(); | |
if($this->xpdo->user->get('sudo')){ | |
return $policy; | |
} | |
$q = $this->xpdo->newQuery($class); | |
$q->leftJoin('modUserGroupMember', 'membergroup', "{$class}.principal_class='modUserGroup' | |
AND {$class}.principal = membergroup.user_group"); | |
$q->leftJoin('modAccessPolicy', 'policy', "{$class}.policy=policy.id"); | |
$q->select(array( | |
"{$class}.*", | |
"policy.data", | |
)); | |
$q->where(array( | |
"target" => $this->get('id'), | |
// "policy.id:!=" => null, | |
)); | |
$q->groupby('target'); | |
$q->groupby('principal_class'); | |
$q->groupby('principal'); | |
$q->groupby('authority'); | |
$q->groupby('policy'); | |
if ($q->prepare() AND $q->stmt AND $q->stmt->execute()) { | |
while ($row = $q->stmt->fetch(PDO::FETCH_ASSOC)) { | |
$policy[$class][$row['target']][] = array( | |
'principal' => $row['principal'], | |
'principal_class' => $row['principal_class'], | |
'authority' => $row['authority'], | |
'policy' => $row['data'] ? $this->xpdo->fromJSON($row['data'], true) : array(), | |
); | |
} | |
} | |
// print $q->toSQL(); | |
$this->xpdo->modzilla->cacheManager->setPolicyCache($cacheKey, $policy); | |
$this->_policies = $policy; | |
} | |
} else { | |
$policy = $this->_policies; | |
} | |
return $policy; | |
} | |
protected function getAccessClass(){ | |
$class = 'ModzillaAccess'; | |
if($definitions = $this->getFKDefinition('Accesses') | |
AND !empty($definitions['class']) | |
){ | |
$class = $definitions['class']; | |
} | |
return $class; | |
} | |
public function save($cacheFlag = null) { | |
if(!$this->get('owner')){ | |
$this->set('owner', $this->xpdo->user->get('id')); | |
} | |
return parent::save($cacheFlag); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment