diff --git a/core/src/plugins/access.ajxp_conf/class.ajxp_confAccessDriver.php b/core/src/plugins/access.ajxp_conf/class.ajxp_confAccessDriver.php
index 6f508e14c4..d77371a5f2 100644
--- a/core/src/plugins/access.ajxp_conf/class.ajxp_confAccessDriver.php
+++ b/core/src/plugins/access.ajxp_conf/class.ajxp_confAccessDriver.php
@@ -1539,7 +1539,8 @@ public function switchAction($action, $httpVars, $fileVars)
case "clear_expired" :
- $deleted = ShareCenter::clearExpiredFiles(false); // $this->clearExpiredFiles();
+ $shareCenter = AJXP_PluginsService::getInstance()->findPluginById("action.share");
+ $deleted = $shareCenter->clearExpiredFiles(false); // $this->clearExpiredFiles();
AJXP_XMLWriter::header();
if (count($deleted)) {
AJXP_XMLWriter::sendMessage(sprintf($mess["ajxp_shared.23"], count($deleted).""), null);
@@ -2295,8 +2296,9 @@ public function listSharedFiles()
$downloadBase = str_replace("\\", "/", $fullUrl.rtrim(str_replace(AJXP_INSTALL_PATH, "", $dlFolder), "/"));
}
+ $shareCenter = AJXP_PluginsService::getInstance()->findPluginById("action.share");
foreach ($files as $file) {
- $publicletData = ShareCenter::loadPublicletData(array_shift(explode(".", basename($file))));
+ $publicletData = $shareCenter->loadPublicletData(array_shift(explode(".", basename($file))));
if (!is_a($publicletData["REPOSITORY"], "Repository")) {
continue;
}
diff --git a/core/src/plugins/access.ajxp_shared/class.ajxpSharedAccessDriver.php b/core/src/plugins/access.ajxp_shared/class.ajxpSharedAccessDriver.php
index 936f8e0af9..62bfe11ae4 100644
--- a/core/src/plugins/access.ajxp_shared/class.ajxpSharedAccessDriver.php
+++ b/core/src/plugins/access.ajxp_shared/class.ajxpSharedAccessDriver.php
@@ -98,11 +98,12 @@ public function switchAction($action, $httpVars, $fileVars)
$selection->initFromHttpVars($httpVars);
$files = $selection->getFiles();
AJXP_XMLWriter::header();
+ $shareCenter = AJXP_PluginsService::findPluginById("action.share");
foreach ($files as $index => $element) {
$element = basename($element);
$ar = explode("shared_", $mime);
$mime = array_pop($ar);
- ShareCenter::deleteSharedElement($mime, $element, $loggedUser);
+ $shareCenter->deleteSharedElement($mime, $element, $loggedUser);
if($mime == "repository") $out = $mess["ajxp_conf.59"];
else if($mime == "user") $out = $mess["ajxp_conf.60"];
else if($mime == "file") $out = $mess["ajxp_shared.13"];
diff --git a/core/src/plugins/access.ajxp_user/class.UserDashboardDriver.php b/core/src/plugins/access.ajxp_user/class.UserDashboardDriver.php
index 124f2d2662..9f8885751a 100644
--- a/core/src/plugins/access.ajxp_user/class.UserDashboardDriver.php
+++ b/core/src/plugins/access.ajxp_user/class.UserDashboardDriver.php
@@ -153,6 +153,7 @@ public function switchAction($action, $httpVars, $fileVars)
$files = $selection->getFiles();
AJXP_XMLWriter::header();
$minisites = $this->listSharedFiles("minisites");
+ $shareCenter = AJXP_PluginsService::findPluginById("action.share");
foreach ($files as $index => $element) {
$element = basename($element);
$ar = explode("shared_", $mime);
@@ -161,7 +162,7 @@ public function switchAction($action, $httpVars, $fileVars)
$mime = "minisite";
$element = $minisites[$element];
}
- ShareCenter::deleteSharedElement($mime, $element, $loggedUser);
+ $shareCenter->deleteSharedElement($mime, $element, $loggedUser);
if($mime == "repository" || $mime == "minisite") $out = $mess["ajxp_conf.59"];
else if($mime == "user") $out = $mess["ajxp_conf.60"];
else if($mime == "file") $out = $mess["user_dash.13"];
@@ -173,7 +174,8 @@ public function switchAction($action, $httpVars, $fileVars)
case "clear_expired" :
- $deleted = ShareCenter::clearExpiredFiles(true); // $this->clearExpiredFiles();
+ $shareCenter = AJXP_PluginsService::getInstance()->findPluginById("action.share");
+ $deleted = $shareCenter->clearExpiredFiles(true);
AJXP_XMLWriter::header();
if (count($deleted)) {
AJXP_XMLWriter::sendMessage(sprintf($mess["user_dash.23"], count($deleted).""), null);
@@ -237,12 +239,13 @@ public function listSharedFiles($mode = "files")
$downloadBase = str_replace("\\", "/", $fullUrl.rtrim(str_replace(AJXP_INSTALL_PATH, "", $dlFolder), "/"));
}
$minisites = array();
+ $shareCenter = AJXP_PluginsService::getInstance()->findPluginById("action.share");
foreach ($files as $file) {
$ar = explode(".", basename($file));
$id = array_shift($ar);
if($ar[0] != "php") continue;
//if(strlen($id) != 32) continue;
- $publicletData = ShareCenter::loadPublicletData($id);
+ $publicletData = $shareCenter->loadPublicletData($id);
if($mode == "files"){
if(isSet($publicletData["AJXP_APPLICATION_BASE"]) || isSet($publicletData["TRAVEL_PATH_TO_ROOT"])
|| (isset($publicletData["OWNER_ID"]) && $publicletData["OWNER_ID"] != $userId)
diff --git a/core/src/plugins/access.fs/class.fsAccessDriver.php b/core/src/plugins/access.fs/class.fsAccessDriver.php
index 84661efa30..afba38891d 100644
--- a/core/src/plugins/access.fs/class.fsAccessDriver.php
+++ b/core/src/plugins/access.fs/class.fsAccessDriver.php
@@ -1869,6 +1869,7 @@ public function makeZip ($src, $dest, $basedir)
public function recursivePurge($dirName, $hardPurgeTime, $softPurgeTime = 0)
{
$handle=opendir($dirName);
+ $shareCenter = AJXP_PluginsService::findPluginById("action.share");
while (false !== ($entry = readdir($handle))) {
if ($entry == "" || $entry == ".." || AJXP_Utils::isHidden($entry) ) {
continue;
@@ -1879,7 +1880,7 @@ public function recursivePurge($dirName, $hardPurgeTime, $softPurgeTime = 0)
if ($hardPurgeTime > 0 && $docAge > $hardPurgeTime) {
$this->purge($fileName);
} elseif ($softPurgeTime > 0 && $docAge > $softPurgeTime) {
- if(!ShareCenter::isShared(new AJXP_Node($fileName))) {
+ if($shareCenter !== false && $shareCenter->isShared(new AJXP_Node($fileName))) {
$this->purge($fileName);
}
}
diff --git a/core/src/plugins/action.share/class.ShareCenter.php b/core/src/plugins/action.share/class.ShareCenter.php
index 03270f07bc..d8688724c3 100644
--- a/core/src/plugins/action.share/class.ShareCenter.php
+++ b/core/src/plugins/action.share/class.ShareCenter.php
@@ -21,8 +21,6 @@
defined('AJXP_EXEC') or die( 'Access not allowed');
-require_once("class.PublicletCounter.php");
-
/**
* @package AjaXplorer_Plugins
* @subpackage Action
@@ -40,6 +38,10 @@ class ShareCenter extends AJXP_Plugin
private $urlBase;
private $baseProtocol;
+ /**
+ * @var ShareStore
+ */
+ private $shareStore;
/**
* @var MetaStoreProvider
*/
@@ -96,6 +98,30 @@ public function init($options)
}
}
+ /**
+ * @return ShareStore
+ */
+ private function getShareStore(){
+ if(!isSet($this->shareStore)){
+ require_once("class.ShareStore.php");
+ $hMin = 32;
+ if(isSet($this->repository)){
+ $hMin = $this->getFilteredOption("HASH_MIN_LENGTH", $this->repository->getId());
+ }
+ $this->shareStore = new ShareStore(
+ ConfService::getCoreConf("PUBLIC_DOWNLOAD_FOLDER"),
+ $hMin
+ );
+ }
+ return $this->shareStore;
+ }
+
+ public function preProcessDownload($action, &$httpVars, &$fileVars){
+ if(isSet($_SESSION["CURRENT_MINISITE"])){
+ $this->logDebug(__FUNCTION__, "Do something here!");
+ }
+ }
+
public function switchAction($action, $httpVars, $fileVars)
{
if (!isSet($this->accessDriver)) {
@@ -299,7 +325,7 @@ public function switchAction($action, $httpVars, $fileVars)
foreach ($elements as $element => $elementData) {
if(!is_array($elementData)) $elementData = array();
- $pData = self::loadPublicletData($element);
+ $pData = $this->getShareStore()->loadShare($element);
if (!count($pData)) {
continue;
}
@@ -326,7 +352,7 @@ public function switchAction($action, $httpVars, $fileVars)
$jsonData[] = array_merge(array(
"element_id" => $element,
"publiclet_link" => $link,
- "download_counter" => PublicletCounter::getCount($element),
+ "download_counter" => $this->getShareStore()->getCurrentDownloadCounter($element),
"download_limit" => $pData["DOWNLOAD_LIMIT"],
"expire_time" => ($pData["EXPIRE_TIME"]!=0?date($messages["date_format"], $pData["EXPIRE_TIME"]):0),
"has_password" => (!empty($pData["PASSWORD"])),
@@ -336,7 +362,7 @@ public function switchAction($action, $httpVars, $fileVars)
}
} else if ($elementType == "repository" || isSet($metadata["minisite"])) {
if (isSet($metadata["minisite"])) {
- $minisiteData = self::loadPublicletData($metadata["element"]);
+ $minisiteData = $this->getShareStore()->loadShare($metadata["element"]);
$repoId = $minisiteData["REPOSITORY"];
$minisiteIsPublic = isSet($minisiteData["PRELOG_USER"]);
$dlDisabled = isSet($minisiteData["DOWNLOAD_DISABLED"]);
@@ -415,7 +441,7 @@ public function switchAction($action, $httpVars, $fileVars)
if(count($metadata["element"]) > 0) $updateMeta = true;
}
}
- self::deleteSharedElement($eType, $elementId, AuthService::getLoggedUser());
+ $this->getShareStore()->deleteShare($eType, $elementId, AuthService::getLoggedUser());
if ($updateMeta) {
$ajxpNode->setMetadata("ajxp_shared", $metadata, true, AJXP_METADATA_SCOPE_REPOSITORY, true);
} else {
@@ -436,7 +462,7 @@ public function switchAction($action, $httpVars, $fileVars)
AJXP_METADATA_SCOPE_REPOSITORY
);
if (isSet($metadata["element"][$httpVars["element_id"]])) {
- PublicletCounter::reset($httpVars["element_id"]);
+ $this->getShareStore()->resetDownloadCounter($httpVars["element_id"]);
}
break;
@@ -487,7 +513,7 @@ public function nodeSharedMetadata(&$ajxpNode)
if (is_array($metadata["element"])) {
$updateMeta = false;
foreach ($metadata["element"] as $elementId => $elementData) {
- if (!self::sharedElementExists($eType, $elementId)) {
+ if (!$this->getShareStore()->shareExists($eType, $elementId)) {
unset($metadata["element"][$elementId]);
$updateMeta = true;
return;
@@ -505,7 +531,7 @@ public function nodeSharedMetadata(&$ajxpNode)
}
}
} else {
- if (!self::sharedElementExists($eType, $metadata["element"])) {
+ if (!$this->getShareStore()->shareExists($eType, $metadata["element"])) {
$ajxpNode->removeMetadata("ajxp_shared", true, AJXP_METADATA_SCOPE_REPOSITORY, true);
return;
}
@@ -524,14 +550,14 @@ public function nodeSharedMetadata(&$ajxpNode)
* @param AJXP_Node $ajxpNode
* @return boolean
*/
- public static function isShared($ajxpNode)
+ public function isShared($ajxpNode)
{
$metadata = $ajxpNode->retrieveMetadata("ajxp_shared",true);
if (is_array($metadata) && is_array($metadata["element"])) {
$eType = $ajxpNode->isLeaf()?"file":"repository";
if(isSet($metadata["minisite"])) $eType = "minisite";
foreach ($metadata["element"] as $elementId => $elementData) {
- if (self::sharedElementExists($eType, $elementId)) {
+ if ($this->getShareStore()->shareExists($eType, $elementId)) {
return true;
}
}
@@ -554,7 +580,7 @@ private function findMirrorNodesInShares($node, $direction){
if(is_string($metadata["element"])){
$wsId = $metadata["element"];
if(isSet($metadata["minisite"])){
- $minisiteData = self::loadPublicletData($metadata["element"]);
+ $minisiteData = $this->getShareStore()->loadShare($metadata["element"]);
$wsId = $minisiteData["REPOSITORY"];
}
$sharedNode = $metadata["SOURCE_NODE"];
@@ -712,7 +738,7 @@ public function updateNodeSharedData($oldNode/*, $newNode = null, $copy = false*
$elementIds[]= $metadata["element"];
}
foreach ($elementIds as $elementId) {
- self::deleteSharedElement(
+ $this->getShareStore()->deleteShare(
$type,
$elementId,
AuthService::getLoggedUser()
@@ -781,25 +807,14 @@ public function writePubliclet(&$data, $accessDriver, $repository)
if ($data["ACTION"] == "") $data["ACTION"] = "download";
// Create a random key
$data["FINAL_KEY"] = md5(mt_rand().time());
- // Cypher the data with a random key
- $outputData = serialize($data);
- // Hash the data to make sure it wasn't modified
- $hash = $this->computeHash($outputData, $downloadFolder); // md5($outputData);
-
- $outputData = base64_encode(mcrypt_encrypt(MCRYPT_RIJNDAEL_256, $hash, $outputData, MCRYPT_MODE_ECB));
- $fileData = "<"."?"."php \n".
- ' require_once("'.str_replace("\\", "/", AJXP_INSTALL_PATH).'/publicLet.inc.php"); '."\n".
- ' $id = str_replace(".php", "", basename(__FILE__)); '."\n". // Not using "" as php would replace $ inside
- ' $cypheredData = base64_decode("'.$outputData.'"); '."\n".
- ' $inputData = trim(mcrypt_decrypt(MCRYPT_RIJNDAEL_256, $id, $cypheredData, MCRYPT_MODE_ECB), "\0"); '."\n".
- ' if (!ShareCenter::checkHash($inputData, $id)) { header("HTTP/1.0 401 Not allowed, script was modified"); exit(); } '."\n".
- ' // Ok extract the data '."\n".
- ' $data = unserialize($inputData); ShareCenter::loadPubliclet($data); ';
- if (@file_put_contents($downloadFolder."/".$hash.".php", $fileData) === FALSE) {
- return "Can't write to PUBLIC URL";
- }
- @chmod($downloadFolder."/".$hash.".php", 0755);
- PublicletCounter::reset($hash);
+
+ try{
+ $hash = $this->getShareStore()->storeShare($data, "publiclet");
+ }catch(Exception $e){
+ return $e->getMessage();
+ }
+
+ $this->getShareStore()->resetDownloadCounter($hash);
$url = $this->buildPublicletLink($hash);
$this->logInfo("New Share", array(
"file" => "'".$copy->display.":/".$data['FILE_PATH']."'",
@@ -818,41 +833,6 @@ public function writePubliclet(&$data, $accessDriver, $repository)
return array($hash, $url);
}
- /**
- * Computes a short form of the hash, checking if it already exists in the folder,
- * in which case it increases the hashlength until there is no collision.
- * @static
- * @param String $outputData Serialized data
- * @param String|null $checkInFolder Path to folder
- * @return string
- */
- public function computeHash($outputData, $checkInFolder = null)
- {
- $length = $this->getFilteredOption("HASH_MIN_LENGTH", $this->repository->getId());
- $full = md5($outputData);
- $starter = substr($full, 0, $length);
- if ($checkInFolder != null) {
- while (file_exists($checkInFolder.DIRECTORY_SEPARATOR.$starter.".php")) {
- $length ++;
- $starter = substr($full, 0, $length);
- }
- }
- return $starter;
- }
-
- /**
- * Check if the hash seems to correspond to the serialized data.
- * @static
- * @param String $outputData serialized data
- * @param String $hash Id to check
- * @return bool
- */
- public static function checkHash($outputData, $hash)
- {
- $full = md5($outputData);
- return (!empty($hash) && strpos($full, $hash."") === 0);
- }
-
public function buildPublicDlURL()
{
$downloadFolder = ConfService::getCoreConf("PUBLIC_DOWNLOAD_FOLDER");
@@ -970,6 +950,7 @@ public static function loadMinisite($data)
$_SESSION["PENDING_FOLDER"] = "/";
$html = str_replace("AJXP_PRELOGED_USER", "", $html);
}
+ $_SESSION["CURRENT_MINISITE"] = true;
if (isSet($_GET["lang"])) {
$loggedUser = &AuthService::getLoggedUser();
if ($loggedUser != null) {
@@ -990,9 +971,13 @@ public static function loadMinisite($data)
echo($html);
}
- private static function deleteExpiredPubliclet($elementId, $data){
+ public static function loadShareByHash($hash){
+ AJXP_Logger::debug(__CLASS__, __FUNCTION__, "Do something");
+ }
- if(AuthService::getLoggedUser()->getId() != $data["OWNER_ID"]){
+ private function deleteExpiredPubliclet($elementId, $data){
+
+ if(AuthService::getLoggedUser() == null || AuthService::getLoggedUser()->getId() != $data["OWNER_ID"]){
AuthService::logUser($data["OWNER_ID"], "", true);
}
$repoObject = $data["REPOSITORY"];
@@ -1006,7 +991,7 @@ private static function deleteExpiredPubliclet($elementId, $data){
AJXP_METADATA_SCOPE_REPOSITORY,
true
);
- self::deleteSharedElement("file", $elementId, AuthService::getLoggedUser());
+ $this->getShareStore()->deleteShare("file", $elementId, AuthService::getLoggedUser());
if (count($metadata)) {
$updateMeta = false;
if (is_array($metadata["element"]) && isSet($metadata["element"][$elementId])) {
@@ -1035,20 +1020,6 @@ public static function loadPubliclet($data)
$u = parse_url($_SERVER["REQUEST_URI"]);
$shortHash = pathinfo(basename($u["path"]), PATHINFO_FILENAME);
- if ( ($data["EXPIRE_TIME"] && time() > $data["EXPIRE_TIME"]) ||
- ($data["DOWNLOAD_LIMIT"] && $data["DOWNLOAD_LIMIT"]> 0 && $data["DOWNLOAD_LIMIT"] <= PublicletCounter::getCount($shortHash)) )
- {
- // Remove the publiclet, it's done
- if (strstr(realpath($_SERVER["SCRIPT_FILENAME"]),realpath(ConfService::getCoreConf("PUBLIC_DOWNLOAD_FOLDER"))) !== FALSE) {
-
- self::deleteExpiredPubliclet($shortHash, $data);
- }
-
- //echo "Link is expired, sorry.";
- header("HTTP/1.0 404 Not Found");
- echo '404 File not found';
- exit();
- }
// Load language messages
$language = ConfService::getLanguage();
if (isSet($_GET["lang"])) {
@@ -1065,6 +1036,23 @@ public static function loadPubliclet($data)
$AJXP_LINK_HAS_PASSWORD = false;
$AJXP_LINK_BASENAME = SystemTextEncoding::toUTF8(basename($data["FILE_PATH"]));
AJXP_PluginsService::getInstance()->initActivePlugins();
+
+ $shareCenter = AJXP_PluginsService::findPluginById("action.share");
+
+ if ($shareCenter->getShareStore()->isShareExpired($shortHash, $data))
+ {
+ // Remove the publiclet, it's done
+ if (strstr(realpath($_SERVER["SCRIPT_FILENAME"]),realpath(ConfService::getCoreConf("PUBLIC_DOWNLOAD_FOLDER"))) !== FALSE) {
+ $shareCenter->deleteExpiredPubliclet($shortHash, $data);
+ }
+
+ //echo "Link is expired, sorry.";
+ header("HTTP/1.0 404 Not Found");
+ echo '404 File not found';
+ exit();
+ }
+
+
$customs = array("title", "legend", "legend_pass", "background_attributes_1", "background_attributes_2", "background_attributes_3", "text_color", "background_color", "textshadow_color");
$images = array("button", "background_1", "background_2", "background_3");
$shareCenter = AJXP_PluginsService::findPlugin("action", "share");
@@ -1125,7 +1113,7 @@ public static function loadPubliclet($data)
$driver->loadManifest();
//$hash = md5(serialize($data));
- PublicletCounter::increment($shortHash);
+ $shareCenter->getShareStore()->incrementDownloadCounter($shortHash);
//AuthService::logUser($data["OWNER_ID"], "", true);
AuthService::logTemporaryUser($data["OWNER_ID"], $shortHash);
@@ -1306,22 +1294,11 @@ public function createSharedMinisite($httpVars, $repository, $accessDriver)
$data["AJXP_TEMPLATE_NAME"] = $httpVars["minisite_layout"];
}
- $outputData = serialize($data);
- $hash = self::computeHash($outputData, $downloadFolder);
-
- $outputData = base64_encode(mcrypt_encrypt(MCRYPT_RIJNDAEL_256, $hash, $outputData, MCRYPT_MODE_ECB));
- $fileData = "<"."?"."php \n".
- ' require_once("'.str_replace("\\", "/", AJXP_INSTALL_PATH).'/publicLet.inc.php"); '."\n".
- ' $id = str_replace(".php", "", basename(__FILE__)); '."\n". // Not using "" as php would replace $ inside
- ' $cypheredData = base64_decode("'.$outputData.'"); '."\n".
- ' $inputData = trim(mcrypt_decrypt(MCRYPT_RIJNDAEL_256, $id, $cypheredData, MCRYPT_MODE_ECB), "\0"); '."\n".
- ' if (!ShareCenter::checkHash($inputData, $id)) { header("HTTP/1.0 401 Not allowed, script was modified"); exit(); } '."\n".
- ' // Ok extract the data '."\n".
- ' $data = unserialize($inputData); ShareCenter::loadMinisite($data); ';
- if (@file_put_contents($downloadFolder."/".$hash.".php", $fileData) === FALSE) {
- return "Can't write to PUBLIC URL";
+ try{
+ $hash = $this->getShareStore()->storeShare($data);
+ }catch(Exception $e){
+ return $e->getMessage();
}
- @chmod($downloadFolder."/".$hash.".php", 0755);
$url = $this->buildPublicletLink($hash);
AJXP_Controller::applyHook("node.share.create", array(
@@ -1635,100 +1612,22 @@ public function createSharedRepository($httpVars, $repository, $accessDriver, $u
/**
- * @static
* @param String $type
* @param String $element
* @param AbstractAjxpUser $loggedUser
* @throws Exception
*/
- public static function deleteSharedElement($type, $element, $loggedUser)
+ public function deleteSharedElement($type, $element, $loggedUser)
{
- $mess = ConfService::getMessages();
- AJXP_Logger::debug(__CLASS__, __FILE__, "Deleting shared element ".$type."-".$element);
- if ($type == "repository") {
- $repo = ConfService::getRepositoryById($element);
- if($repo == null) return;
- if (!$repo->hasOwner() || $repo->getOwner() != $loggedUser->getId()) {
- throw new Exception($mess["ajxp_shared.12"]);
- } else {
- $res = ConfService::deleteRepository($element);
- if ($res == -1) {
- throw new Exception($mess["ajxp_conf.51"]);
- }
- }
- } else if ($type == "minisite") {
- $minisiteData = self::loadPublicletData($element);
- $repoId = $minisiteData["REPOSITORY"];
- $repo = ConfService::getRepositoryById($repoId);
- if ($repo == null) {
- return false;
- }
- if (!$repo->hasOwner() || $repo->getOwner() != $loggedUser->getId()) {
- throw new Exception($mess["ajxp_shared.12"]);
- } else {
- $res = ConfService::deleteRepository($repoId);
- if ($res == -1) {
- throw new Exception($mess["ajxp_conf.51"]);
- }
- // Silently delete corresponding role if it exists
- AuthService::deleteRole("AJXP_SHARED-".$repoId);
- // If guest user created, remove it now.
- if (isSet($minisiteData["PRELOG_USER"])) {
- AuthService::deleteUser($minisiteData["PRELOG_USER"]);
- }
- unlink($minisiteData["PUBLICLET_PATH"]);
- }
- } else if ($type == "user") {
- $confDriver = ConfService::getConfStorageImpl();
- $object = $confDriver->createUserObject($element);
- if (!$object->hasParent() || $object->getParent() != $loggedUser->getId()) {
- throw new Exception($mess["ajxp_shared.12"]);
- } else {
- AuthService::deleteUser($element);
- }
- } else if ($type == "file") {
- $publicletData = self::loadPublicletData($element);
- if (isSet($publicletData["OWNER_ID"]) && $publicletData["OWNER_ID"] == $loggedUser->getId()) {
- PublicletCounter::delete($element);
- unlink($publicletData["PUBLICLET_PATH"]);
- } else {
- throw new Exception($mess["ajxp_shared.12"]);
- }
- }
- }
-
- public static function sharedElementExists($type, $element)
- {
- if ($type == "repository") {
- return (ConfService::getRepositoryById($element) != null);
- } else if ($type == "file" || $type == "minisite") {
- $dlFolder = ConfService::getCoreConf("PUBLIC_DOWNLOAD_FOLDER");
- return is_file($dlFolder."/".$element.".php");
- }
+ $this->getShareStore()->deleteShare($type, $element, $loggedUser);
}
-
- public static function loadPublicletData($id)
+ public function loadPublicletData($id)
{
- $dlFolder = ConfService::getCoreConf("PUBLIC_DOWNLOAD_FOLDER");
- $file = $dlFolder."/".$id.".php";
- if(!is_file($file)) return array();
- $lines = file($file);
- $inputData = '';
- $code = $lines[3] . $lines[4] . $lines[5];
- eval($code);
- if(empty($inputData)) return false;
- $dataModified = self::checkHash($inputData, $id); //(md5($inputData) != $id);
- $publicletData = unserialize($inputData);
- $publicletData["SECURITY_MODIFIED"] = $dataModified;
- if (!isSet($publicletData["REPOSITORY"])) {
- $publicletData["DOWNLOAD_COUNT"] = PublicletCounter::getCount($id);
- }
- $publicletData["PUBLICLET_PATH"] = $file;
- return $publicletData;
+ return $this->getShareStore()->loadShare($id);
}
- public static function clearExpiredFiles($currentUser = true)
+ public function clearExpiredFiles($currentUser = true)
{
$files = glob(ConfService::getCoreConf("PUBLIC_DOWNLOAD_FOLDER")."/*.php");
if($currentUser){
@@ -1740,9 +1639,10 @@ public static function clearExpiredFiles($currentUser = true)
$deleted = array();
$switchBackToOriginal = false;
foreach ($files as $file) {
+ if(basename($file) == "share.php") continue;
$ar = explode(".", basename($file));
$id = array_shift($ar);
- $publicletData = self::loadPublicletData($id);
+ $publicletData = $this->getShareStore()->loadShare($id);
if($publicletData === false) continue;
if ($currentUser && ( !isSet($publicletData["OWNER_ID"]) || $publicletData["OWNER_ID"] != $userId )) {
continue;
@@ -1750,7 +1650,7 @@ public static function clearExpiredFiles($currentUser = true)
if( (isSet($publicletData["EXPIRE_TIME"]) && is_numeric($publicletData["EXPIRE_TIME"]) && $publicletData["EXPIRE_TIME"] > 0 && $publicletData["EXPIRE_TIME"] < time()) ||
(isSet($publicletData["DOWNLOAD_LIMIT"]) && $publicletData["DOWNLOAD_LIMIT"] > 0 && $publicletData["DOWNLOAD_LIMIT"] <= $publicletData["DOWNLOAD_COUNT"]) ) {
if(!$currentUser) $switchBackToOriginal = true;
- self::deleteExpiredPubliclet($id, $publicletData);
+ $this->deleteExpiredPubliclet($id, $publicletData);
$deleted[] = $publicletData["FILE_PATH"];
}
@@ -1766,4 +1666,19 @@ public static function currentContextIsLinkDownload(){
return (isSet($_GET["dl"]) && isSet($_GET["dl"]) == "true");
}
+ /**
+ * Check if the hash seems to correspond to the serialized data.
+ * Kept there only for backward compatibility
+ * @static
+ * @param String $outputData serialized data
+ * @param String $hash Id to check
+ * @return bool
+ */
+ public static function checkHash($outputData, $hash)
+ {
+ $full = md5($outputData);
+ return (!empty($hash) && strpos($full, $hash."") === 0);
+ }
+
+
}
diff --git a/core/src/plugins/action.share/class.ShareStore.php b/core/src/plugins/action.share/class.ShareStore.php
new file mode 100644
index 0000000000..1731d41086
--- /dev/null
+++ b/core/src/plugins/action.share/class.ShareStore.php
@@ -0,0 +1,222 @@
+
+ * This file is part of Pydio.
+ *
+ * Pydio is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Pydio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with Pydio. If not, see .
+ *
+ * The latest code can be found at .
+ */
+
+defined('AJXP_EXEC') or die( 'Access not allowed');
+
+require_once("class.PublicletCounter.php");
+
+class ShareStore {
+
+ var $slqSupported = false;
+ var $downloadFolder;
+ var $hashMinLength;
+
+ public function __construct($downloadFolder, $hashMinLength = 32){
+ $this->downloadFolder = $downloadFolder;
+ $this->hashMinLength = $hashMinLength;
+ $storage = ConfService::getConfStorageImpl();
+ }
+
+ /**
+ * @param Array $shareData
+ * @param string $type
+ * @return string $hash
+ * @throws Exception
+ */
+ public function storeShare($shareData, $type="minisite"){
+
+ $data = serialize($shareData);
+ $hash = $this->computeHash($data, $this->downloadFolder);
+ $loader = 'ShareCenter::loadMinisite($data);';
+ if($type == "publiclet"){
+ $loader = 'ShareCenter::loadPubliclet($data);';
+ }
+
+ $outputData = base64_encode(mcrypt_encrypt(MCRYPT_RIJNDAEL_256, $hash, $data, MCRYPT_MODE_ECB));
+ $fileData = "<"."?"."php \n".
+ ' require_once("'.str_replace("\\", "/", AJXP_INSTALL_PATH).'/publicLet.inc.php"); '."\n".
+ ' $id = str_replace(".php", "", basename(__FILE__)); '."\n". // Not using "" as php would replace $ inside
+ ' $cypheredData = base64_decode("'.$outputData.'"); '."\n".
+ ' $inputData = trim(mcrypt_decrypt(MCRYPT_RIJNDAEL_256, $id, $cypheredData, MCRYPT_MODE_ECB), "\0"); '."\n".
+ ' if (!ShareCenter::checkHash($inputData, $id)) { header("HTTP/1.0 401 Not allowed, script was modified"); exit(); } '."\n".
+ ' // Ok extract the data '."\n".
+ ' $data = unserialize($inputData); '.$loader;
+ if (@file_put_contents($this->downloadFolder."/".$hash.".php", $fileData) === FALSE) {
+ throw new Exception("Can't write to PUBLIC URL");
+ }
+ @chmod($this->downloadFolder."/".$hash.".php", 0755);
+ return $hash;
+
+ }
+
+ public function loadShare($hash){
+
+ $dlFolder = $this->downloadFolder;
+ $file = $dlFolder."/".$hash.".php";
+ if(!is_file($file)) return array();
+ $lines = file($file);
+ $inputData = '';
+ // Necessary for the eval
+ $id = $hash;
+ $code = $lines[3] . $lines[4] . $lines[5];
+ eval($code);
+ if(empty($inputData)) return false;
+ $dataModified = $this->checkHash($inputData, $hash); //(md5($inputData) != $id);
+ $publicletData = unserialize($inputData);
+ $publicletData["SECURITY_MODIFIED"] = $dataModified;
+ if (!isSet($publicletData["REPOSITORY"])) {
+ $publicletData["DOWNLOAD_COUNT"] = PublicletCounter::getCount($hash);
+ }
+ $publicletData["PUBLICLET_PATH"] = $file;
+ return $publicletData;
+
+ }
+
+ /**
+ * @param String $type
+ * @param String $element
+ * @param AbstractAjxpUser $loggedUser
+ * @throws Exception
+ */
+ public function deleteShare($type, $element, $loggedUser)
+ {
+ $mess = ConfService::getMessages();
+ $shareCenter = AJXP_PluginsService::getInstance()->findPluginById("action.share");
+ AJXP_Logger::debug(__CLASS__, __FILE__, "Deleting shared element ".$type."-".$element);
+ if ($type == "repository") {
+ $repo = ConfService::getRepositoryById($element);
+ if($repo == null) return;
+ if (!$repo->hasOwner() || $repo->getOwner() != $loggedUser->getId()) {
+ throw new Exception($mess["ajxp_shared.12"]);
+ } else {
+ $res = ConfService::deleteRepository($element);
+ if ($res == -1) {
+ throw new Exception($mess["ajxp_conf.51"]);
+ }
+ }
+ } else if ($type == "minisite") {
+ $minisiteData = $this->loadShare($element);
+ $repoId = $minisiteData["REPOSITORY"];
+ $repo = ConfService::getRepositoryById($repoId);
+ if ($repo == null) {
+ return false;
+ }
+ if (!$repo->hasOwner() || $repo->getOwner() != $loggedUser->getId()) {
+ throw new Exception($mess["ajxp_shared.12"]);
+ } else {
+ $res = ConfService::deleteRepository($repoId);
+ if ($res == -1) {
+ throw new Exception($mess["ajxp_conf.51"]);
+ }
+ // Silently delete corresponding role if it exists
+ AuthService::deleteRole("AJXP_SHARED-".$repoId);
+ // If guest user created, remove it now.
+ if (isSet($minisiteData["PRELOG_USER"])) {
+ AuthService::deleteUser($minisiteData["PRELOG_USER"]);
+ }
+ unlink($minisiteData["PUBLICLET_PATH"]);
+ }
+ } else if ($type == "user") {
+ $confDriver = ConfService::getConfStorageImpl();
+ $object = $confDriver->createUserObject($element);
+ if (!$object->hasParent() || $object->getParent() != $loggedUser->getId()) {
+ throw new Exception($mess["ajxp_shared.12"]);
+ } else {
+ AuthService::deleteUser($element);
+ }
+ } else if ($type == "file") {
+ $publicletData = $this->loadShare($element);
+ if (isSet($publicletData["OWNER_ID"]) && $publicletData["OWNER_ID"] == $loggedUser->getId()) {
+ PublicletCounter::delete($element);
+ unlink($publicletData["PUBLICLET_PATH"]);
+ } else {
+ throw new Exception($mess["ajxp_shared.12"]);
+ }
+ }
+ }
+
+
+ public function shareExists($type, $element)
+ {
+ if ($type == "repository") {
+ return (ConfService::getRepositoryById($element) != null);
+ } else if ($type == "file" || $type == "minisite") {
+ return is_file($this->downloadFolder."/".$element.".php");
+ }
+ }
+
+
+ public function getCurrentDownloadCounter($hash){
+ return PublicletCounter::getCount($hash);
+ }
+
+ public function incrementDownloadCounter($hash){
+ PublicletCounter::increment($hash);
+ }
+
+ public function resetDownloadCounter($hash){
+ PublicletCounter::reset($hash);
+ }
+
+ public function isShareExpired($hash, $data){
+ return ($data["EXPIRE_TIME"] && time() > $data["EXPIRE_TIME"]) ||
+ ($data["DOWNLOAD_LIMIT"] && $data["DOWNLOAD_LIMIT"]> 0 && $data["DOWNLOAD_LIMIT"] <= $this->getCurrentDownloadCounter($hash));
+ }
+
+
+
+ /**
+ * Computes a short form of the hash, checking if it already exists in the folder,
+ * in which case it increases the hashlength until there is no collision.
+ * @static
+ * @param String $outputData Serialized data
+ * @param String|null $checkInFolder Path to folder
+ * @return string
+ */
+ private function computeHash($outputData, $checkInFolder = null)
+ {
+ $length = $this->hashMinLength;
+ $full = md5($outputData);
+ $starter = substr($full, 0, $length);
+ if ($checkInFolder != null) {
+ while (file_exists($checkInFolder.DIRECTORY_SEPARATOR.$starter.".php")) {
+ $length ++;
+ $starter = substr($full, 0, $length);
+ }
+ }
+ return $starter;
+ }
+
+ /**
+ * Check if the hash seems to correspond to the serialized data.
+ * @static
+ * @param String $outputData serialized data
+ * @param String $hash Id to check
+ * @return bool
+ */
+ private function checkHash($outputData, $hash)
+ {
+ $full = md5($outputData);
+ return (!empty($hash) && strpos($full, $hash."") === 0);
+ }
+
+
+}
\ No newline at end of file