From 812eb9d0c12884cf2c7e77d1fb99f1c5b348fa5b Mon Sep 17 00:00:00 2001 From: Matthieu Patou Date: Thu, 17 Nov 2011 01:01:30 +0100 Subject: [PATCH 1/6] Add DB schema for Sqlite --- config/db/schema.sqlite.sql | 29 +++++++++++++++++++++++++++++ config/db/schema.user.sqlite.sql | 13 +++++++++++++ 2 files changed, 42 insertions(+) create mode 100644 config/db/schema.sqlite.sql create mode 100644 config/db/schema.user.sqlite.sql diff --git a/config/db/schema.sqlite.sql b/config/db/schema.sqlite.sql new file mode 100644 index 00000000..16b65e1b --- /dev/null +++ b/config/db/schema.sqlite.sql @@ -0,0 +1,29 @@ +-- SQLITE3 use UTF8 format by default SET NAMES 'utf8'; +CREATE TABLE IF NOT EXISTS `fz_file` ( + `id` BIGINT UNSIGNED NOT NULL, + `del_notif_sent` BOOLEAN DEFAULT 0, + `file_name` varchar(100) NOT NULL, + `file_size` INTEGER DEFAULT 0, + `available_from` DATE NOT NULL, + `available_until` DATE NOT NULL, + `created_at` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, + `comment` varchar(200), + `download_count` INTEGER DEFAULT 0, + `notify_uploader` BOOLEAN DEFAULT 0, + `uploader_uid` varchar(30) DEFAULT NULL, + `uploader_email` varchar(60) DEFAULT NULL, + `extends_count` INTEGER DEFAULT '0', + `password` varchar(40) DEFAULT NULL + +); +CREATE UNIQUE INDEX IF NOT EXISTS 'fz_file_id_idx' on 'fz_file' ('id'); + + +CREATE TABLE IF NOT EXISTS `fz_info` ( + `key` VARCHAR( 30 ) NOT NULL, + `value` VARCHAR( 50 ) NOT NULL +); + +CREATE UNIQUE INDEX IF NOT EXISTS 'fz_info_key_idx' on 'fz_info' ('key'); +INSERT INTO `fz_info` (`key`, `value`) VALUES ('db_version', '2.0.0-2'); + diff --git a/config/db/schema.user.sqlite.sql b/config/db/schema.user.sqlite.sql new file mode 100644 index 00000000..7a5a7be9 --- /dev/null +++ b/config/db/schema.user.sqlite.sql @@ -0,0 +1,13 @@ +CREATE TABLE IF NOT EXISTS `fz_user` ( + `id` INTEGER PRIMARY KEY, + `username` VARCHAR( 30 ) NOT NULL , + `password` VARCHAR( 40 ) NOT NULL , + `salt` VARCHAR( 40 ), + `firstname` VARCHAR( 50 ) NOT NULL , + `lastname` VARCHAR( 50 ) NOT NULL , + `email` VARCHAR( 50 ) NOT NULL , + `is_admin` BOOLEAN DEFAULT 0, + `created_at` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP +); + +--CREATE UNIQUE INDEX IF NOT EXISTS 'fz_user_id_idx' ON 'fz_user' ('id'); From 681b7ae0dc18ac2932a8fcf48edd5880a3d13d5a Mon Sep 17 00:00:00 2001 From: Matthieu Patou Date: Thu, 17 Nov 2011 01:02:14 +0100 Subject: [PATCH 2/6] Sqlite use UTF-8 by default --- index.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/index.php b/index.php index 038beb34..1b8793f8 100755 --- a/index.php +++ b/index.php @@ -131,7 +131,9 @@ function before () { $db = new PDO (fz_config_get ('db', 'dsn'), fz_config_get ('db', 'user'), fz_config_get ('db', 'password')); $db->setAttribute (PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); - $db->exec ('SET NAMES \'utf8\''); + if (fz_config_get ('db', 'db_dialect') != "Sqlite") { + $db->exec ('SET NAMES \'utf8\''); + } option ('db_conn', $db); } catch (Exception $e) { halt (SERVER_ERROR, 'Can\'t connect to the database'); From 6a3f458e5444a658c47da7de50a0c503f38282ba Mon Sep 17 00:00:00 2001 From: Matthieu Patou Date: Thu, 17 Nov 2011 01:03:22 +0100 Subject: [PATCH 3/6] Create a specialized class for Sqlite for the database as Date function are not the same in Mysql and Sqlite --- app/models/DbTable/FileSqlite.php | 85 +++++++++++++++++++++++++++++++ 1 file changed, 85 insertions(+) create mode 100644 app/models/DbTable/FileSqlite.php diff --git a/app/models/DbTable/FileSqlite.php b/app/models/DbTable/FileSqlite.php new file mode 100644 index 00000000..73d298b1 --- /dev/null +++ b/app/models/DbTable/FileSqlite.php @@ -0,0 +1,85 @@ + + * + * This file is part of Filez. + * + * Filez is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Filez 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Filez. If not, see . + */ + +class App_Model_DbTable_FileSqlite extends App_Model_DbTable_File { + /** + * Return all file owned by $uid which are available (not deleted) + * + * @param string $uid + * @return array of App_Model_File + */ + public function findByOwnerOrderByUploadDateDesc ($uid) { + $sql = 'SELECT * FROM '.$this->getTableName () + .' WHERE uploader_uid=:uid ' + .' AND available_until >= CURRENT_TIMESTAMP' + .' ORDER BY created_at DESC'; + return $this->findBySql ($sql, array (':uid' => $uid)); + } + + /** + * Delete files whose lifetime expired + */ + public function deleteExpiredFiles () { + $select = 'SELECT * FROM '.$this->getTableName (); + $where = ' WHERE available_untilfindBySql ($select.$where) as $file) { + if ($file->deleteFromDisk () === true) { + fz_log ('Deleted file "'.$file->getOnDiskLocation ().'"', + FZ_LOG_CRON); + } else { + fz_log ('Failed deleting file "'.$file->getOnDiskLocation ().'"', + FZ_LOG_CRON_ERROR); + } + } + option ('db_conn')->exec ('DELETE FROM '.$this->getTableName ().$where); + } + + /** + * Return files which will be deleted within X days and where uploader wants + * to be notified but hasn't been yet + * + * @param integer $days Number of days before being deleted + * @return App_Model_File + */ + public function findFilesToBeDeleted ($days = 2) { + $sql = 'SELECT * FROM '.$this->getTableName () + .' WHERE available_until BETWEEN CURRENT_TIMESTAMP' + .'AND DATE_ADD(\'now\',\'+'.$days.' day\') ' + .'AND del_notif_sent=0 AND notify_uploader=1'; + + return $this->findBySql ($sql); + } + + /** + * Return disk space used by someone + * + * @param array $user User data + * @return float Size in bytes + */ + public function getTotalDiskSpaceByUser ($user) { + $result = option ('db_conn') + ->prepare ('SELECT sum(file_size) FROM `' + .$this->getTableName () + .'` WHERE uploader_email = ?' + .' AND available_until >= CURRENT_TIMESTAMP'); + $result->execute (array ($user['email'])); + return (float) $result->fetchColumn (); + } +} From cafd85d1eef756cbe15a36a1ae31389304137a80 Mon Sep 17 00:00:00 2001 From: Matthieu Patou Date: Thu, 17 Nov 2011 01:04:09 +0100 Subject: [PATCH 4/6] Introduce the notion of dialect in the getTable function to be able to use the correct class --- lib/Fz/Db.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/Fz/Db.php b/lib/Fz/Db.php index 0bfdc48d..4b617069 100755 --- a/lib/Fz/Db.php +++ b/lib/Fz/Db.php @@ -97,9 +97,11 @@ public static function findAssocBySQL ($sql, $params = array (), $limit = 0) { */ public static function getTable ($table) { if (! array_key_exists($table, self::$_tables)) { + $dialect = fz_config_get('db', 'db_dialect', ''); $prefix = 'App_Model_DbTable_'; $tableClass = substr ($table, 0, strlen ($prefix)) == $prefix ? $table : ($prefix.$table); + $tableClass = "$tableClass$dialect"; self::$_tables [$table] = new $tableClass (); } From 489e5cf21b26ea42b588e2bb6a4d526da85ac2c7 Mon Sep 17 00:00:00 2001 From: Matthieu Patou Date: Thu, 17 Nov 2011 01:04:29 +0100 Subject: [PATCH 5/6] Add an example config just for sqlite --- config/filez.ini.example.sqlite | 143 ++++++++++++++++++++++++++++++++ 1 file changed, 143 insertions(+) create mode 100644 config/filez.ini.example.sqlite diff --git a/config/filez.ini.example.sqlite b/config/filez.ini.example.sqlite new file mode 100644 index 00000000..6369ce0b --- /dev/null +++ b/config/filez.ini.example.sqlite @@ -0,0 +1,143 @@ + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; General configuration +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +[app] +use_url_rewriting = true + +; Must be writtable by the web server +upload_dir = /var/fz_uploads + +; Must be writtable by the web server +log_dir = /var/log + +; Allow downloading file sent with filez 1.x +filez1_compat = true + +; Max and default lifetime of a file on the server +max_file_lifetime = 20 +default_file_lifetime = 10 + +; Maximum number of days the lifetime of a file can be extended +max_extend_count = 7 + +; Min/Max size of files hash codes +min_hash_size = 4 +max_hash_size = 6 + +; Default langage when no translation exists for the user locale +default_locale = fr + +; Name of the class used to authenticate the user. Built-in handler are : +; * Fz_Controller_Security_Cas Log the user against a CAS server +; * Fz_Controller_Security_Internal Log the user with a built-in Controller. +; This controller will check user/pass with +; 'login' method in the user factory. +auth_handler_class = Fz_Controller_Security_Internal + +; Name of the class used to identify the user. Built-in factories are : +; * Fz_User_Factory_Ldap +; * Fz_User_Factory_Database +user_factory_class = Fz_User_Factory_Database + +; Max disk spaced per user. Support shorthand format : M (Mega), G (Giga) +user_quota = 2G + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; Cron Job +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +[cron] +; Number of days before before sending the notification mail for deletion +days_before_expiration_mail = 2 + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; Look'n feel +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +[looknfeel] +; Logo image +your_logo = "resources/images/uapv-logo.gif" + +; Custom CSS +; custom_css = "resources/css/custom.css" + +; show filez credits at the bottom of the pages +show_credit = true + +; Url where the user will find Filez documentation +help_url = help ; Relative or absolute + +; Where does the user reports bug ? +bug_report_href = mailto:some-one@somewhere.com ; or http://your-bug-tracker.com + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; Database configuration +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +[db] +#dsn is not used with sqlite +#dsn = "mysql:host=localhost;dbname=filez" +db_dialect = "Sqlite" + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; Mail configuration +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +[email] +from_email=filez@univ-avignon.fr +from_name=Filez +host=smtp.univ-avignon.fr +; auth=login ; possible values = crammd5, login, plain +; port=25 +; username=user +; password=pwd + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; Authentication configuration +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +[auth_options] +; Parameters for the CAS authentication handler. +;cas_server_host = cas.univ-avignon.fr + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; Identification configuration +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +[user_factory_options] +; Parameters passed to the Ldap user factory. +; Available parameters : http://framework.zend.com/manual/en/zend.ldap.api.html +;host = ldap.univ-avignon.fr +;useSsl = false +;baseDn = "ou=people,dc=univ-avignon,dc=fr" +;bindRequiresDn = true + +; Parameters for the Database user factory +db_use_global_conf = false +db_server_dsn = "sqlite:/path_to_FileZ/config/db/filez.db" +db_table = user +db_password_field = password +db_username_field = username +db_password_algorithm = sha1; use the sha1 function of PHP +; Possible algorithm are : +; - MD5 (unsecure) +; - SHA1 (unsecure) +; - PHP Function name ex: "methodName" +; - PHP Static method ex: "ClassName::Method" +; - Plain SQL ex: "password=SHA1(CONCAT(salt, :password))" + +[user_attributes_translation] +; In order to make the application schema agnostic with differents user storage +; facilities, each user attributes is translated from its original name to the +; application name. The syntax is as follow : application_name = original_name. +; This attributes are required by filez : +; * firstname +; * lastname +; * email +; * id +; Exemple for a sqlite, the translation seems pointless but something +; in the code insists on having this otherwise it tries to do some +; field conversion +email = email +firstname = firstname +lastname = lastname +id = id From 293952fc6945b8e23c20165cda1c57e5bcee9694 Mon Sep 17 00:00:00 2001 From: Matthieu Patou Date: Wed, 15 Jul 2015 14:00:23 -0700 Subject: [PATCH 6/6] Add information about SHA1 not working in SQLite Signed-off-by: Matthieu Patou --- doc/INSTALL.markdown | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/INSTALL.markdown b/doc/INSTALL.markdown index 27ea7f5d..e8403a3e 100755 --- a/doc/INSTALL.markdown +++ b/doc/INSTALL.markdown @@ -172,7 +172,7 @@ is several possible values that should suit your needs : - "SHA1" - PHP Function name ex: "methodName" - PHP Static method ex: "ClassName::Method" -- Plain SQL ex: "SHA1(CONCAT(salt, :password))" +- Plain SQL ex: "SHA1(CONCAT(salt, :password))" (does not work with sqlite) If you use a PHP callback, just put the file containing your function under the 'lib/' directory.