Explorar el Código

TableAjax send file content, secure file access

Piotr Labudda hace 11 años
padre
commit
a913bc49e3
Se han modificado 3 ficheros con 176 adiciones y 5 borrados
  1. 8 0
      SE/.htaccess
  2. 86 0
      SE/index-file.php
  3. 82 5
      SE/se-lib/TableAjax.php

+ 8 - 0
SE/.htaccess

@@ -0,0 +1,8 @@
+<IfModule mod_rewrite.c>
+RewriteEngine On
+RewriteBase /
+RewriteRule ^index\.php$ - [L]
+RewriteCond %{REQUEST_FILENAME} !-f
+RewriteCond %{REQUEST_FILENAME} !-d
+RewriteRule ^PLIKI/([0-9-]+)/([0-9-]+)/(.*)$ /SE/se-dev-pl-rsync/index-file.php?zasobID=$1&id=$2&file=$3 [L]
+</IfModule>

+ 86 - 0
SE/index-file.php

@@ -0,0 +1,86 @@
+<?php
+
+define('DS', DIRECTORY_SEPARATOR);
+define('APP_PATH_ROOT', dirname(__FILE__));
+define('APP_PATH_LIB', APP_PATH_ROOT . '/se-lib');
+define('APP_PATH_WWW', APP_PATH_ROOT);
+define('APP_PATH_CONFIG', APP_PATH_ROOT . DS . 'config');
+
+session_start();
+
+date_default_timezone_set('Europe/Warsaw');// PHP 5 >= 5.1.0 required by date functions
+
+error_reporting(1);
+ini_set('error_reporting', 1);
+ini_set('display_startup_errors','1'); 
+//display_startup_errors(0);
+
+#TEST $_SESSION['DEBUG'] = 3;// TODO: TEST
+if (!isset($_SESSION['DEBUG'])) $_SESSION['DEBUG'] = 0;// set default value
+
+
+if (file_exists(APP_PATH_ROOT . "/config/.config_{$_SERVER['SERVER_NAME']}.php")) {
+	require APP_PATH_ROOT . "/config/.config_{$_SERVER['SERVER_NAME']}.php";
+}
+
+if (file_exists(APP_PATH_ROOT . "/.config.php")) include APP_PATH_ROOT . "/.config.php";
+
+
+require_once APP_PATH_ROOT . "/superedit-SEF.php";
+SEF('DEBUG_S');
+
+require_once APP_PATH_LIB . '/' . 'Lib.php';
+Lib::loadClass('V');
+Lib::loadClass('DB');
+Lib::loadClass('User');
+Lib::loadClass('S');
+
+User::auth();// die if not logged in
+
+/* example:
+    [zasobID] => 636
+    [id] => 2773
+    [file] => 2014-07-11_wizytowki_michal_zaleski_wzor_bn2.bcard/Screen Shot 2014-07-11 at 15.58.15.png
+*/
+
+$zasobID = V::get('zasobID', 0, $_GET, 'int');
+$recordID = V::get('id', 0, $_GET, 'int');
+$fileName = V::get('file', '', $_GET);
+
+if (!$zasobID || !$recordID || empty($fileName)) {
+	header('HTTP/1.0 406 Not Acceptable');
+	exit;
+}
+if (false !== strpos($fileName, '../')) {
+	header('HTTP/1.0 403 Forbidden');
+	echo '..';
+	exit;
+}
+
+$userAcl = User::getAcl();
+$tblAcl = $userAcl->getTableAcl($zasobID);
+
+if (!$tblAcl->isInitialized()) {
+	echo'<p class="red">'."Brak konfiguracji dla ".$tblAcl->getName()."!".'</p>';
+	return;
+}
+
+Lib::loadClass('TableAjax');
+if (!class_exists('TableAjax')) {
+	die('Error: cls not exists TableAjax');
+}
+
+$tblObj = new TableAjax($tblAcl);
+try {
+	$tblObj->sendFileContent($recordID, $fileName);
+}
+catch (Exception $e) {
+	switch ($e->getCode()) {
+		case 404: header('HTTP/1.0 404 Not Found'); break;
+		case 403: header('HTTP/1.0 403 Forbidden'); break;
+		case 4033: header('HTTP/1.0 403.3 - Write access forbidden'); break;
+		default:
+	}
+	header('Content-Type: text/html; charset=utf-8');
+	echo $e->getMessage();
+}

+ 82 - 5
SE/se-lib/TableAjax.php

@@ -3736,7 +3736,7 @@ jQuery(document).ready(function(){
 		$files = $uploader->getFilesFromFolder($mainFolder, false, true);
 		$localPath = $uploader->getLocalPath();
 		$folderWeb = $uploader->getFolderWeb();
-		$jsonFiles = $this->convertFileListToJson($files, $folderWeb, $localPath, $mainFolder);
+		$jsonFiles = $this->convertFileListToJson($files, $folderWeb, $localPath, $mainFolder, $record->ID);
 		echo json_encode($jsonFiles);
 		exit;
 	}
@@ -3810,12 +3810,12 @@ jQuery(document).ready(function(){
 		$files = $uploader->getFilesFromFolder($mainFolder, false, true);
 		$localPath = $uploader->getLocalPath();
 		$folderWeb = $uploader->getFolderWeb();
-		$jsonFiles = $this->convertFileListToJson($files, $folderWeb, $localPath, $mainFolder);
+		$jsonFiles = $this->convertFileListToJson($files, $folderWeb, $localPath, $mainFolder, $record->ID);
 		echo json_encode($jsonFiles);
 		exit;
 	}
 
-	public function convertFileListToJson($files, $folderWeb, $localPath, $mainFolder) {
+	public function convertFileListToJson($files, $folderWeb, $localPath, $mainFolder, $recordID) {
 		sort($files);
 		$jsonFiles = array();
 		foreach ($files as $vFilePath) {
@@ -3832,7 +3832,7 @@ jQuery(document).ready(function(){
 			}
 			$file->type = '';
 			$file->created = date("Y-m-d H:i:s", filectime($vFilePath));
-			$file->web = str_replace($localPath, $folderWeb, $vFilePath);
+			$file->web = "PLIKI/{$this->_zasobID}/{$recordID}/{$file->name}";
 			$jsonFiles[] = $file;
 		}
 		return $jsonFiles;
@@ -3900,6 +3900,13 @@ jQuery(document).ready(function(){
 			exit;
 		}
 
+		if (!$this->_acl->canWriteRecord($record) && !$this->_acl->hasPermSuperWrite()) {
+			echo '<div class="alert alert-error">';
+				echo "Brak dostępu do rekordu";// TODO: more info - reason
+			echo '</div>';
+			return;
+		}
+
 		$tblName = $this->_acl->getName();
 		$confTblName = "{$tblName}_COLUMN";
 		Lib::loadClass('FoldersConfig');
@@ -3937,7 +3944,7 @@ jQuery(document).ready(function(){
 		}
 		$localPath = $uploader->getLocalPath();
 		$folderWeb = $uploader->getFolderWeb();
-		$jsonFiles = $this->convertFileListToJson($files, $folderWeb, $localPath, $mainFolder);
+		$jsonFiles = $this->convertFileListToJson($files, $folderWeb, $localPath, $mainFolder, $record->ID);
 		if($DBG){ echo'<pre style="max-height:200px;overflow:auto;border:1px solid red;text-align:left;">jsonFiles (' . __CLASS__ . '::' . __FUNCTION__ . ':' . __LINE__ . '): ';print_r($jsonFiles);echo'</pre>'; }
 
 		$folderSkanyConf = FoldersConfig::getAll('SCANS_COLUMN');
@@ -4797,4 +4804,74 @@ jQuery(document).ready(function(){
 		return $response;
 	}
 
+	// TODO: check read access
+	public function sendFileContent($id, $fileName) {
+		$DBG = ('1' == V::get('DBG', '', $_REQUEST));
+
+		$dbID = $this->_acl->getDB();
+		$db = DB::getDB($dbID);
+		if (!$db) {
+			throw new Exception('No DB', 406);
+		}
+
+		$record = $this->_dataSource->getItem($id);
+		if (!$record) {
+			throw new Exception("No item ID({$rowID})", 404);
+		}
+
+		if (!$this->_acl->canReadRecord($record)) {
+			throw new Exception("Brak dostępu do rekordu", 406);
+		}
+
+		$tblName = $this->_acl->getName();
+		$confTblName = "{$tblName}_COLUMN";
+		Lib::loadClass('FoldersConfig');
+		$folderConfAll = FoldersConfig::getRawData();
+		if (!FoldersConfig::hasConfig($confTblName)) {
+			throw new Exception("Brak danych konfiguracyjnych", 404);
+		}
+
+		$folderConf = FoldersConfig::getAll($confTblName);
+		if($DBG){ echo'<pre style="max-height:200px;overflow:auto;border:1px solid red;text-align:left;">$folderConf (' . __CLASS__ . '::' . __FUNCTION__ . ':' . __LINE__ . '): ';print_r($folderConf);echo'</pre>'; }
+
+		Lib::loadClass('FileUploader');
+		$uploader = new FileUploader($confTblName, $record);
+		$errMsg = '';
+		if (!$uploader->setConfig($folderConf, $errMsg)) {
+			throw new Exception("Błąd danych konfiguracyjnych ({$tblName})\n". $errMsg, 404);
+		}
+		$uploader->findFolder();
+		if($DBG){ echo'<pre style="max-height:200px;overflow:auto;border:1px solid red;text-align:left;">uploader (F.' . __FUNCTION__ . ':' . __LINE__ . '): ';print_r($uploader);echo'</pre>'; }
+
+		$mainFolder = $uploader->getDestFolder();
+		if($DBG){ echo'<pre style="max-height:200px;overflow:auto;border:1px solid red;text-align:left;">mainFolder (F.' . __FUNCTION__ . ':' . __LINE__ . '): ';print_r($mainFolder);echo'</pre>'; }
+
+		$localPath = $uploader->getLocalPath();
+		$filePath = "{$localPath}/{$mainFolder}/{$fileName}";
+		if (!file_exists($filePath)) {
+			throw new Exception("Plik nie istnieje", 404);
+		}
+
+		if (function_exists('http_send_file')) {
+			http_send_file($filePath);
+		} else {
+			header('Content-Description: File Transfer');
+			header('Content-Type: application/octet-stream');
+			header('Content-Disposition: attachment; filename='.basename($filePath));
+			header('Content-Transfer-Encoding: binary');
+			header('Expires: 0');
+			header('Cache-Control: must-revalidate');
+			header('Pragma: public');
+			header('Content-Length: ' . filesize($filePath));
+
+			set_time_limit(0);
+			$file = @fopen($filePath, "rb");
+			while (!feof($file)) {
+				print(@fread($file, 1024*8));
+				ob_flush();
+				flush();
+			}
+		}
+	}
+
 }