From 297fb737ac1e8b5a50a3220cb0841457b042ac92 Mon Sep 17 00:00:00 2001 From: bharat Date: Mon, 1 Jun 2009 01:07:05 -0400 Subject: Convert %7E to ~ when proxying files to work around Firefox's overzealous security model. --- modules/gallery/controllers/file_proxy.php | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'modules/gallery/controllers') diff --git a/modules/gallery/controllers/file_proxy.php b/modules/gallery/controllers/file_proxy.php index 2037ad98..1901bd9f 100644 --- a/modules/gallery/controllers/file_proxy.php +++ b/modules/gallery/controllers/file_proxy.php @@ -32,9 +32,13 @@ class File_Proxy_Controller extends Controller { $request_uri = $this->input->server("REQUEST_URI"); $request_uri = preg_replace("/\?.*/", "", $request_uri); + // Firefox converts ~ to %7E breaking our url comparison, below. Convert that back here. + $request_uri = str_replace("%7E", "~", $request_uri); + // var_uri: http://example.com/gallery3/var/ $var_uri = url::file("var/"); + // Make sure that the request is for a file inside var $offset = strpos($request_uri, $var_uri); if ($offset === false) { -- cgit v1.2.3 From 54ae9fac88512f1bac05a5952fca9ade2eab0898 Mon Sep 17 00:00:00 2001 From: Bharat Mediratta Date: Sun, 31 May 2009 22:12:14 -0700 Subject: Remove extra blank line --- modules/gallery/controllers/file_proxy.php | 1 - 1 file changed, 1 deletion(-) (limited to 'modules/gallery/controllers') diff --git a/modules/gallery/controllers/file_proxy.php b/modules/gallery/controllers/file_proxy.php index 1901bd9f..dfdb4f34 100644 --- a/modules/gallery/controllers/file_proxy.php +++ b/modules/gallery/controllers/file_proxy.php @@ -38,7 +38,6 @@ class File_Proxy_Controller extends Controller { // var_uri: http://example.com/gallery3/var/ $var_uri = url::file("var/"); - // Make sure that the request is for a file inside var $offset = strpos($request_uri, $var_uri); if ($offset === false) { -- cgit v1.2.3 From 463b3454ae7633815e24cdf86e81c57409dd15a9 Mon Sep 17 00:00:00 2001 From: Tim Almdal Date: Sun, 31 May 2009 23:28:27 -0700 Subject: Move the sql packaging code from installer into the gallery module. It must be run from the command line and will throw a 404 if it is run as a web request. --- index.php | 15 +- installer/package.php | 239 -------------------------------- modules/gallery/controllers/package.php | 163 ++++++++++++++++++++++ 3 files changed, 173 insertions(+), 244 deletions(-) delete mode 100755 installer/package.php create mode 100644 modules/gallery/controllers/package.php (limited to 'modules/gallery/controllers') diff --git a/index.php b/index.php index a70053a8..fc6309b7 100644 --- a/index.php +++ b/index.php @@ -48,11 +48,16 @@ define('SYSPATH', strtr(realpath('system') . '/', DIRECTORY_SEPARATOR, '/')); // Force a test run if we're in command line mode. if (PHP_SAPI == 'cli') { - array_splice($_SERVER['argv'], 1, 0, 'gallery_unit_test'); - define('TEST_MODE', 1); - @mkdir('test/var/logs', 0777, true); - define('VARPATH', strtr(realpath('test/var') . '/', DIRECTORY_SEPARATOR, '/')); - @copy("var/database.php", VARPATH . "database.php"); + if ($_SERVER['argv'][1] != "package") { + array_splice($_SERVER['argv'], 1, 0, 'gallery_unit_test'); + define('TEST_MODE', 1); + @mkdir('test/var/logs', 0777, true); + define('VARPATH', strtr(realpath('test/var') . '/', DIRECTORY_SEPARATOR, '/')); + @copy("var/database.php", VARPATH . "database.php"); + } else { + define('TEST_MODE', 0); + define('VARPATH', strtr(realpath('var') . '/', DIRECTORY_SEPARATOR, '/')); + } } else { define('TEST_MODE', 0); define('VARPATH', strtr(realpath('var') . '/', DIRECTORY_SEPARATOR, '/')); diff --git a/installer/package.php b/installer/package.php deleted file mode 100755 index 591f12d0..00000000 --- a/installer/package.php +++ /dev/null @@ -1,239 +0,0 @@ -#!/usr/bin/php -f - tmp/dump.sql"); - - $db = Database::instance(); - // Drop all tables - foreach ($db->list_tables() as $table) { - $db->query("DROP TABLE IF EXISTS `$table`"); - } - - // Now the var directory - rename (VARPATH, realpath("tmp/var")); - mkdir(VARPATH); - copy(realpath("tmp/var/database.php"), VARPATH . "database.php"); - - $db->clear_cache(); - $modules_list = module::$modules; - $active_modules = module::$active; - - module::$modules = array(); - module::$active = array(); - - // Use a known random seed so that subsequent packaging runs will reuse the same random - // numbers, keeping our install.sql file more stable. - srand(0); -} - -function reset_install($config) { - // Reset the var path - system("rm -rf " . VARPATH); - rename (realpath("tmp/var"), VARPATH); - - $db = Database::instance(); - // Drop all tables - foreach ($db->list_tables() as $table) { - $db->query("DROP TABLE IF EXISTS `$table`"); - } - - // Lets restorep the database - $conn = $config["connection"]; - do_system("mysql -u{$conn['user']} -p{$conn['pass']} {$conn['database']} " . - " < tmp/dump.sql"); - - // Clear any database caching - $db->clear_cache(); - - module::$modules = $modules_list; - module::$active = $active_modules; -} - -function do_system($command) { - exec($command, $output, $status); - if ($status) { - throw new Exception("$command\nFailed to dump database\n" . implode("\n", $output)); - } -} - -function kohana_bootstrap() { - define('KOHANA_VERSION', '2.3.3'); - define('KOHANA_CODENAME', 'aegolius'); - - // Test of Kohana is running in Windows - define('KOHANA_IS_WIN', DIRECTORY_SEPARATOR === '\\'); - - // Kohana benchmarks are prefixed to prevent collisions - define('SYSTEM_BENCHMARK', 'system_benchmark'); - - // Load benchmarking support - require SYSPATH.'core/Benchmark'.EXT; - - // Start total_execution - Benchmark::start(SYSTEM_BENCHMARK.'_total_execution'); - - // Start kohana_loading - Benchmark::start(SYSTEM_BENCHMARK.'_kohana_loading'); - - // Load core files - require SYSPATH.'core/utf8'.EXT; - require SYSPATH.'core/Event'.EXT; - require SYSPATH.'core/Kohana'.EXT; - - // Prepare the environment - Kohana::setup(); - // End kohana_loading - Benchmark::stop(SYSTEM_BENCHMARK.'_kohana_loading'); - - // Prepare the system - Event::run('system.ready'); - - // Clean up and exit (this basically shuts down output buffering - Event::run('system.shutdown'); -} - -function install() { - gallery_installer::install(true); - module::load_modules(); - - foreach (array("user", "comment", "organize", "info", "rss", - "search", "slideshow", "tag") as $module_name) { - module::install($module_name); - module::activate($module_name); - } -} - -function dump_database() { - // We now have a clean install with just the packages that we want. Make sure that the - // database is clean too. - $db = Database::instance(); - $db->query("TRUNCATE {sessions}"); - $db->query("TRUNCATE {logs}"); - $db->query("DELETE FROM {vars} WHERE `module_name` = 'gallery' AND `name` = '_cache'"); - $db->update("users", array("password" => ""), array("id" => 1)); - $db->update("users", array("password" => ""), array("id" => 2)); - - $dbconfig = Kohana::config('database.default'); - $conn = $dbconfig["connection"]; - $pass = $conn["pass"] ? "-p{$conn['pass']}" : ""; - $sql_file = DOCROOT . "installer/install.sql"; - if (!is_writable($sql_file)) { - throw new Exception("$sql_file is not writeable"); - return; - } - do_system("mysqldump --compact --add-drop-table -h{$conn['host']} " . - "-u{$conn['user']} $pass {$conn['database']} > $sql_file"); - - // Post-process the sql file - $buf = ""; - $root = ORM::factory("item", 1); - $root_created_timestamp = $root->created; - $root_updated_timestamp = $root->updated; - foreach (file($sql_file) as $line) { - // Prefix tables - $line = preg_replace( - "/(CREATE TABLE|IF EXISTS|INSERT INTO) `{$dbconfig['table_prefix']}(\w+)`/", "\\1 {\\2}", - $line); - - // Normalize dates - $line = preg_replace("/,$root_created_timestamp,/", ",UNIX_TIMESTAMP(),", $line); - $line = preg_replace("/,$root_updated_timestamp,/", ",UNIX_TIMESTAMP(),", $line); - $buf .= $line; - } - $fd = fopen($sql_file, "wb"); - fwrite($fd, $buf); - fclose($fd); -} - -function dump_var() { - $objects = new RecursiveIteratorIterator( - new RecursiveDirectoryIterator(VARPATH), - RecursiveIteratorIterator::SELF_FIRST); - - $var_file = DOCROOT . "installer/init_var.php"; - if (!is_writable($var_file)) { - throw new Exception("$var_file is not writeable"); - return; - } - - $paths = array(); - foreach($objects as $name => $file) { - if ($file->getBasename() == "database.php") { - continue; - } else if (basename($file->getPath()) == "logs") { - continue; - } - - if ($file->isDir()) { - $paths[] = "VARPATH . \"" . substr($name, strlen(VARPATH)) . "\""; - } else { - // @todo: serialize non-directories - throw new Exception("Unknown file: $name"); - } - } - // Sort the paths so that the var file is stable - sort($paths); - - $fd = fopen($var_file, "w"); - fwrite($fd, "\n"); - fwrite($fd, "getTrace(); - return; -} - -try { - // Install the standard modules - install(); - - // Dump the empty gallery3 database and format it for the installer - dump_database(); - - // Dump the var directory - dump_var(); -} catch (Exception $e) { - print $e->getTrace(); -} - -try { - // Reset the Gallery3 installation - reset_install($config); -} catch (Exception $e) { - print $e->getTrace(); -} - -system("rm -rf tmp"); -?> \ No newline at end of file diff --git a/modules/gallery/controllers/package.php b/modules/gallery/controllers/package.php new file mode 100644 index 00000000..7b702498 --- /dev/null +++ b/modules/gallery/controllers/package.php @@ -0,0 +1,163 @@ +auto_render = false; + + $this->_reset(); // empty and reinstall the standard modules + + $this->_dump_database(); // Dump the database + + $this->_dump_var(); // Dump the var directory + print t("Successfully wrote install.sql and init_var.php\n"); + } + + private function _reset() { + $db = Database::instance(); + + // Drop all tables + foreach ($db->list_tables() as $table) { + $db->query("DROP TABLE IF EXISTS `$table`"); + } + + // Clean out data + dir::unlink(VARPATH . "uploads"); + dir::unlink(VARPATH . "albums"); + dir::unlink(VARPATH . "resizes"); + dir::unlink(VARPATH . "thumbs"); + dir::unlink(VARPATH . "modules"); + dir::unlink(VARPATH . "tmp"); + + $db->clear_cache(); + module::$modules = array(); + module::$active = array(); + + // Use a known random seed so that subsequent packaging runs will reuse the same random + // numbers, keeping our install.sql file more stable. + srand(0); + + try { + gallery_installer::install(true); + module::load_modules(); + + foreach (array("user", "comment", "organize", "info", "rss", + "search", "slideshow", "tag") as $module_name) { + module::install($module_name); + module::activate($module_name); + } + } catch (Exception $e) { + Kohana::log("error", $e->getTraceAsString()); + print $e->getTrace(); + throw $e; + } + } + + private function _dump_database() { + // We now have a clean install with just the packages that we want. Make sure that the + // database is clean too. + $db = Database::instance(); + $db->query("TRUNCATE {sessions}"); + $db->query("TRUNCATE {logs}"); + $db->query("DELETE FROM {vars} WHERE `module_name` = 'core' AND `name` = '_cache'"); + $db->update("users", array("password" => ""), array("id" => 1)); + $db->update("users", array("password" => ""), array("id" => 2)); + + $dbconfig = Kohana::config('database.default'); + $conn = $dbconfig["connection"]; + $pass = $conn["pass"] ? "-p{$conn['pass']}" : ""; + $sql_file = DOCROOT . "installer/install.sql"; + if (!is_writable($sql_file)) { + print "$sql_file is not writeable"; + return; + } + $command = "mysqldump --compact --add-drop-table -h{$conn['host']} " . + "-u{$conn['user']} $pass {$conn['database']} > $sql_file"; + exec($command, $output, $status); + if ($status) { + print "
";
+      print "$command\n";
+      print "Failed to dump database\n";
+      print implode("\n", $output);
+      return;
+    }
+
+    // Post-process the sql file
+    $buf = "";
+    $root_timestamp = ORM::factory("item", 1)->created;
+    foreach (file($sql_file) as $line) {
+      // Prefix tables
+      $line = preg_replace(
+        "/(CREATE TABLE|IF EXISTS|INSERT INTO) `{$dbconfig['table_prefix']}(\w+)`/", "\\1 {\\2}",
+        $line);
+
+      // Normalize dates
+      $line = preg_replace("/,$root_timestamp,/", ",UNIX_TIMESTAMP(),", $line);
+      $buf .= $line;
+    }
+    $fd = fopen($sql_file, "wb");
+    fwrite($fd, $buf);
+    fclose($fd);
+  }
+
+  private function _dump_var() {
+    $this->auto_render = false;
+
+    $objects = new RecursiveIteratorIterator(
+      new RecursiveDirectoryIterator(VARPATH),
+      RecursiveIteratorIterator::SELF_FIRST);
+
+    $var_file = DOCROOT . "installer/init_var.php";
+    if (!is_writable($var_file)) {
+      print "$var_file is not writeable";
+      return;
+    }
+
+    $paths = array();
+    foreach($objects as $name => $file){
+      if ($file->getBasename() == "database.php") {
+        continue;
+      } else if (basename($file->getPath()) == "logs") {
+        continue;
+      }
+
+      if ($file->isDir()) {
+        $paths[] = "VARPATH . \"" . substr($name, strlen(VARPATH)) . "\"";
+      } else {
+        // @todo: serialize non-directories
+        print "Unknown file: $name";
+        return;
+      }
+    }
+    // Sort the paths so that the var file is stable
+    sort($paths);
+
+    $fd = fopen($var_file, "w");
+    fwrite($fd, "\n");
+    fwrite($fd, "
Date: Mon, 1 Jun 2009 00:11:09 -0700
Subject: Do a little cleanup and get rid of code left-over from when this
 controller rendered HTML.  Also, catch all exceptions at the root level and
 restore the change in 84ce0cdefda162917c7b01722a7259ac52c4e30d which appears
 to have gotten lost in the shuffle.

---
 modules/gallery/controllers/package.php | 43 +++++++++++++++------------------
 1 file changed, 20 insertions(+), 23 deletions(-)

(limited to 'modules/gallery/controllers')

diff --git a/modules/gallery/controllers/package.php b/modules/gallery/controllers/package.php
index 7b702498..1b096cb5 100644
--- a/modules/gallery/controllers/package.php
+++ b/modules/gallery/controllers/package.php
@@ -23,14 +23,16 @@ class Package_Controller extends Controller {
       Kohana::show_404();
     }
 
-    $this->auto_render = false;
-
-    $this->_reset();                // empty and reinstall the standard modules
-
-    $this->_dump_database();        // Dump the database
+    try {
+      $this->_reset();                // empty and reinstall the standard modules
+      $this->_dump_database();        // Dump the database
+      $this->_dump_var();             // Dump the var directory
+    } catch (Exception $e) {
+      print $e->getTraceAsString();
+      return;
+    }
 
-    $this->_dump_var();             // Dump the var directory
-    print t("Successfully wrote install.sql and init_var.php\n");
+    print "Successfully wrote install.sql and init_var.php\n";
   }
 
   private function _reset() {
@@ -57,19 +59,13 @@ class Package_Controller extends Controller {
     // numbers, keeping our install.sql file more stable.
     srand(0);
 
-    try {
-      gallery_installer::install(true);
-      module::load_modules();
+    gallery_installer::install(true);
+    module::load_modules();
 
-      foreach (array("user", "comment", "organize", "info", "rss",
-                     "search", "slideshow", "tag") as $module_name) {
-        module::install($module_name);
-        module::activate($module_name);
-      }
-    } catch (Exception $e) {
-      Kohana::log("error", $e->getTraceAsString());
-      print $e->getTrace();
-      throw $e;
+    foreach (array("user", "comment", "organize", "info", "rss",
+                   "search", "slideshow", "tag") as $module_name) {
+      module::install($module_name);
+      module::activate($module_name);
     }
   }
 
@@ -104,7 +100,9 @@ class Package_Controller extends Controller {
 
     // Post-process the sql file
     $buf = "";
-    $root_timestamp = ORM::factory("item", 1)->created;
+    $root = ORM::factory("item", 1);
+    $root_created_timestamp = $root->created;
+    $root_updated_timestamp = $root->updated;
     foreach (file($sql_file) as $line) {
       // Prefix tables
       $line = preg_replace(
@@ -112,7 +110,8 @@ class Package_Controller extends Controller {
         $line);
 
       // Normalize dates
-      $line = preg_replace("/,$root_timestamp,/", ",UNIX_TIMESTAMP(),", $line);
+      $line = preg_replace("/,$root_created_timestamp,/", ",UNIX_TIMESTAMP(),", $line);
+      $line = preg_replace("/,$root_updated_timestamp,/", ",UNIX_TIMESTAMP(),", $line);
       $buf .= $line;
     }
     $fd = fopen($sql_file, "wb");
@@ -121,8 +120,6 @@ class Package_Controller extends Controller {
   }
 
   private function _dump_var() {
-    $this->auto_render = false;
-
     $objects = new RecursiveIteratorIterator(
       new RecursiveDirectoryIterator(VARPATH),
       RecursiveIteratorIterator::SELF_FIRST);
-- 
cgit v1.2.3


From c94c11eb3e4f48d2dbcc73ea6ca9358170733392 Mon Sep 17 00:00:00 2001
From: Bharat Mediratta 
Date: Mon, 1 Jun 2009 00:22:30 -0700
Subject: Normalize the random values used in the blocks_dashboard_xxx vars so
 that install.sql is more stable.

---
 installer/install.sql                   | 4 ++--
 modules/gallery/controllers/package.php | 9 +++++++++
 2 files changed, 11 insertions(+), 2 deletions(-)

(limited to 'modules/gallery/controllers')

diff --git a/installer/install.sql b/installer/install.sql
index 7109236f..0aaf8e79 100755
--- a/installer/install.sql
+++ b/installer/install.sql
@@ -333,6 +333,6 @@ CREATE TABLE {vars} (
   `value` text,
   PRIMARY KEY  (`id`),
   UNIQUE KEY `module_name` (`module_name`,`name`)
-) ENGINE=InnoDB AUTO_INCREMENT=22 DEFAULT CHARSET=utf8;
+) ENGINE=InnoDB AUTO_INCREMENT=24 DEFAULT CHARSET=utf8;
 SET character_set_client = @saved_cs_client;
-INSERT INTO {vars} VALUES (1,'gallery','active_site_theme','default'),(2,'gallery','active_admin_theme','admin_default'),(3,'gallery','page_size','9'),(4,'gallery','thumb_size','200'),(5,'gallery','resize_size','640'),(6,'gallery','default_locale','en_US'),(7,'gallery','image_quality','75'),(9,'gallery','blocks_dashboard_sidebar','a:4:{i:1804289383;a:2:{i:0;s:7:\"gallery\";i:1;s:11:\"block_adder\";}i:846930886;a:2:{i:0;s:7:\"gallery\";i:1;s:5:\"stats\";}i:1681692777;a:2:{i:0;s:7:\"gallery\";i:1;s:13:\"platform_info\";}i:1714636915;a:2:{i:0;s:7:\"gallery\";i:1;s:12:\"project_news\";}}'),(14,'gallery','blocks_dashboard_center','a:4:{i:1957747793;a:2:{i:0;s:7:\"gallery\";i:1;s:7:\"welcome\";}i:424238335;a:2:{i:0;s:7:\"gallery\";i:1;s:12:\"photo_stream\";}i:719885386;a:2:{i:0;s:7:\"gallery\";i:1;s:11:\"log_entries\";}i:1649760492;a:2:{i:0;s:7:\"comment\";i:1;s:15:\"recent_comments\";}}'),(17,'gallery','version','3.0 pre-beta git'),(18,'gallery','choose_default_tookit','1'),(19,'gallery','credits','Powered by Gallery %version'),(21,'comment','spam_caught','0');
+INSERT INTO {vars} VALUES (1,'gallery','active_site_theme','default'),(2,'gallery','active_admin_theme','admin_default'),(3,'gallery','page_size','9'),(4,'gallery','thumb_size','200'),(5,'gallery','resize_size','640'),(6,'gallery','default_locale','en_US'),(7,'gallery','image_quality','75'),(9,'gallery','blocks_dashboard_sidebar','a:4:{i:2;a:2:{i:0;s:7:\"gallery\";i:1;s:11:\"block_adder\";}i:3;a:2:{i:0;s:7:\"gallery\";i:1;s:5:\"stats\";}i:4;a:2:{i:0;s:7:\"gallery\";i:1;s:13:\"platform_info\";}i:5;a:2:{i:0;s:7:\"gallery\";i:1;s:12:\"project_news\";}}'),(14,'gallery','blocks_dashboard_center','a:4:{i:6;a:2:{i:0;s:7:\"gallery\";i:1;s:7:\"welcome\";}i:7;a:2:{i:0;s:7:\"gallery\";i:1;s:12:\"photo_stream\";}i:8;a:2:{i:0;s:7:\"gallery\";i:1;s:11:\"log_entries\";}i:9;a:2:{i:0;s:7:\"comment\";i:1;s:15:\"recent_comments\";}}'),(17,'gallery','version','3.0 pre-beta git'),(18,'gallery','choose_default_tookit','1'),(19,'gallery','credits','Powered by Gallery %version'),(21,'comment','spam_caught','0');
diff --git a/modules/gallery/controllers/package.php b/modules/gallery/controllers/package.php
index 1b096cb5..f5146fc8 100644
--- a/modules/gallery/controllers/package.php
+++ b/modules/gallery/controllers/package.php
@@ -72,6 +72,15 @@ class Package_Controller extends Controller {
   private function _dump_database() {
     // We now have a clean install with just the packages that we want.  Make sure that the
     // database is clean too.
+    $i = 1;
+    foreach (array("blocks_dashboard_sidebar", "blocks_dashboard_center") as $key) {
+      $blocks = array();
+      foreach (unserialize(module::get_var("gallery", $key)) as $rnd => $value) {
+        $blocks[++$i] = $value;
+      }
+      module::set_var("gallery", $key, serialize($blocks));
+    }
+
     $db = Database::instance();
     $db->query("TRUNCATE {sessions}");
     $db->query("TRUNCATE {logs}");
-- 
cgit v1.2.3


From 43abcd93867996e32890fa101ae09255ccc24847 Mon Sep 17 00:00:00 2001
From: Bharat Mediratta 
Date: Mon, 1 Jun 2009 22:40:22 -0700
Subject: Security pass over all controller code.  Mostly adding CSRF checking
 and verifying user permissions, but there are several above-the-bar changes:

1) Server add is now only available to admins.  This is a hard
   requirement because we have to limit server access (eg:
   server_add::children) to a user subset and the current permission
   model doesn't include that.  Easiest fix is to restrict to admins.
   Got rid of the server_add permission.

2) We now know check permissions at every level, which means in
   controllers AND in helpers.  This "belt and suspenders" approach will
   give us defense in depth in case we overlook it in one area.

3) We now do CSRF checking in every controller method that changes the
   code, in addition to the Forge auto-check.  Again, defense in depth
   and it makes scanning the code for security much simpler.

4) Moved Simple_Uploader_Controller::convert_filename_to_title to
   item:convert_filename_to_title

5) Fixed a bug in sending notification emails.

6) Fixed the Organize code to verify that you only have access to your
   own tasks.  In general, added permission checks to organize which had
   pretty much no validation code.

I did my best to verify every feature that I touched.
---
 modules/akismet/controllers/admin_akismet.php      |  3 +
 modules/comment/controllers/admin_comments.php     |  2 +
 modules/comment/controllers/comments.php           |  5 ++
 modules/g2_import/controllers/admin_g2_import.php  |  2 +
 modules/gallery/controllers/admin.php              |  3 +-
 modules/gallery/controllers/admin_dashboard.php    |  4 +
 modules/gallery/controllers/admin_graphics.php     |  1 +
 modules/gallery/controllers/admin_languages.php    |  4 +
 .../gallery/controllers/admin_theme_details.php    |  2 +
 modules/gallery/controllers/albums.php             | 14 +++-
 modules/gallery/controllers/l10n_client.php        | 11 ++-
 modules/gallery/controllers/move.php               |  9 +++
 modules/gallery/controllers/movies.php             |  3 +
 modules/gallery/controllers/permissions.php        |  4 +
 modules/gallery/controllers/photos.php             |  5 ++
 modules/gallery/controllers/quick.php              | 26 ++++---
 modules/gallery/controllers/rest.php               | 10 +--
 modules/gallery/controllers/simple_uploader.php    | 18 ++---
 modules/gallery/helpers/item.php                   | 17 +++++
 modules/gallery/libraries/MY_Forge.php             |  1 +
 modules/gallery/views/simple_uploader.html.php     |  2 +-
 modules/notification/helpers/notification.php      |  2 +-
 modules/organize/controllers/organize.php          | 85 ++++++++++++++++++----
 modules/organize/helpers/organize.php              |  8 ++
 modules/organize/helpers/organize_task.php         | 29 +++++++-
 modules/recaptcha/controllers/admin_recaptcha.php  |  8 +-
 modules/server_add/controllers/server_add.php      | 38 ++++++++--
 .../server_add/helpers/server_add_installer.php    |  5 --
 modules/server_add/helpers/server_add_menu.php     |  4 +-
 modules/server_add/helpers/server_add_task.php     |  1 -
 modules/tag/controllers/admin_tags.php             |  1 +
 modules/tag/controllers/tags.php                   |  2 +
 modules/user/controllers/admin_users.php           |  6 ++
 modules/user/controllers/login.php                 |  4 +
 modules/user/controllers/logout.php                |  2 +
 modules/user/controllers/password.php              |  4 +
 modules/user/views/login.html.php                  |  2 +-
 modules/watermark/controllers/admin_watermarks.php |  6 ++
 38 files changed, 281 insertions(+), 72 deletions(-)

(limited to 'modules/gallery/controllers')

diff --git a/modules/akismet/controllers/admin_akismet.php b/modules/akismet/controllers/admin_akismet.php
index 7485f283..9ba89bd4 100644
--- a/modules/akismet/controllers/admin_akismet.php
+++ b/modules/akismet/controllers/admin_akismet.php
@@ -22,6 +22,9 @@ class Admin_Akismet_Controller extends Admin_Controller {
     $form = akismet::get_configure_form();
 
     if (request::method() == "post") {
+      // @todo move the "post" handler part of this code into a separate function
+      access::verify_csrf();
+
       $valid = $form->validate();
 
       if ($valid) {
diff --git a/modules/comment/controllers/admin_comments.php b/modules/comment/controllers/admin_comments.php
index 50e35d23..3e8d3c46 100644
--- a/modules/comment/controllers/admin_comments.php
+++ b/modules/comment/controllers/admin_comments.php
@@ -107,6 +107,7 @@ class Admin_Comments_Controller extends Admin_Controller {
 
   public function set_state($id, $state) {
     access::verify_csrf();
+
     $comment = ORM::factory("comment", $id);
     $orig = clone $comment;
     if ($comment->loaded) {
@@ -121,6 +122,7 @@ class Admin_Comments_Controller extends Admin_Controller {
 
   public function delete_all_spam() {
     access::verify_csrf();
+
     ORM::factory("comment")
       ->where("state", "spam")
       ->delete_all();
diff --git a/modules/comment/controllers/comments.php b/modules/comment/controllers/comments.php
index 930579ac..c48bd380 100644
--- a/modules/comment/controllers/comments.php
+++ b/modules/comment/controllers/comments.php
@@ -134,6 +134,7 @@ class Comments_Controller extends REST_Controller {
    */
   public function _update($comment) {
     $item = ORM::factory("item", $comment->item_id);
+    access::required("view", $item);
     access::required("edit", $item);
 
     $form = comment::get_edit_form($comment);
@@ -161,6 +162,7 @@ class Comments_Controller extends REST_Controller {
    */
   public function _delete($comment) {
     $item = ORM::factory("item", $comment->item_id);
+    access::required("view", $item);
     access::required("edit", $item);
 
     $comment->delete();
@@ -183,6 +185,9 @@ class Comments_Controller extends REST_Controller {
    *  @see REST_Controller::form_edit($resource)
    */
   public function _form_edit($comment) {
+    if (!user::active()->admin) {
+      access::forbidden();
+    }
     print comment::get_edit_form($comment);
   }
 }
diff --git a/modules/g2_import/controllers/admin_g2_import.php b/modules/g2_import/controllers/admin_g2_import.php
index 25894291..f2969f49 100644
--- a/modules/g2_import/controllers/admin_g2_import.php
+++ b/modules/g2_import/controllers/admin_g2_import.php
@@ -39,6 +39,8 @@ class Admin_g2_import_Controller extends Admin_Controller {
   }
 
   public function save() {
+    access::verify_csrf();
+
     $form = $this->_get_import_form();
     if ($form->validate()) {
       $embed_path = $form->configure_g2_import->embed_path->value;
diff --git a/modules/gallery/controllers/admin.php b/modules/gallery/controllers/admin.php
index af0f387a..b92a32cd 100644
--- a/modules/gallery/controllers/admin.php
+++ b/modules/gallery/controllers/admin.php
@@ -22,8 +22,9 @@ class Admin_Controller extends Controller {
 
   public function __construct($theme=null) {
     if (!(user::active()->admin)) {
-      throw new Exception("@todo UNAUTHORIZED", 401);
+      access::forbidden();
     }
+
     parent::__construct();
   }
 
diff --git a/modules/gallery/controllers/admin_dashboard.php b/modules/gallery/controllers/admin_dashboard.php
index a1090a6d..3cb97b14 100644
--- a/modules/gallery/controllers/admin_dashboard.php
+++ b/modules/gallery/controllers/admin_dashboard.php
@@ -29,6 +29,8 @@ class Admin_Dashboard_Controller extends Admin_Controller {
   }
 
   public function add_block() {
+    access::verify_csrf();
+
     $form = gallery_block::get_add_block_form();
     if ($form->validate()) {
       list ($module_name, $id) = explode(":", $form->add_block->id->value);
@@ -51,6 +53,7 @@ class Admin_Dashboard_Controller extends Admin_Controller {
 
   public function remove_block($id) {
     access::verify_csrf();
+
     $blocks_center = block_manager::get_active("dashboard_center");
     $blocks_sidebar = block_manager::get_active("dashboard_sidebar");
 
@@ -73,6 +76,7 @@ class Admin_Dashboard_Controller extends Admin_Controller {
 
   public function reorder() {
     access::verify_csrf();
+
     $active_set = array();
     foreach (array("dashboard_sidebar", "dashboard_center") as $location) {
       foreach (block_manager::get_active($location) as $id => $info) {
diff --git a/modules/gallery/controllers/admin_graphics.php b/modules/gallery/controllers/admin_graphics.php
index 7e8ef47c..72f8d8e1 100644
--- a/modules/gallery/controllers/admin_graphics.php
+++ b/modules/gallery/controllers/admin_graphics.php
@@ -43,6 +43,7 @@ class Admin_Graphics_Controller extends Admin_Controller {
 
   public function choose($toolkit) {
     access::verify_csrf();
+
     if ($toolkit != module::get_var("gallery", "graphics_toolkit")) {
       module::set_var("gallery", "graphics_toolkit", $toolkit);
 
diff --git a/modules/gallery/controllers/admin_languages.php b/modules/gallery/controllers/admin_languages.php
index 1dea733c..4639de89 100644
--- a/modules/gallery/controllers/admin_languages.php
+++ b/modules/gallery/controllers/admin_languages.php
@@ -31,6 +31,8 @@ class Admin_Languages_Controller extends Admin_Controller {
   }
 
   public function save() {
+    access::verify_csrf();
+
     $form = $this->_languages_form();
     if ($form->validate()) {
       module::set_var("gallery", "default_locale", $form->choose_language->locale->value);
@@ -41,6 +43,8 @@ class Admin_Languages_Controller extends Admin_Controller {
   }
 
   public function share() {
+    access::verify_csrf();
+
     $form = $this->_share_translations_form();
     if (!$form->validate()) {
       // Show the page with form errors
diff --git a/modules/gallery/controllers/admin_theme_details.php b/modules/gallery/controllers/admin_theme_details.php
index fec1311b..97696df5 100644
--- a/modules/gallery/controllers/admin_theme_details.php
+++ b/modules/gallery/controllers/admin_theme_details.php
@@ -26,6 +26,8 @@ class Admin_Theme_Details_Controller extends Admin_Controller {
   }
 
   public function save() {
+    access::verify_csrf();
+
     $form = theme::get_edit_form_admin();
     if ($form->validate()) {
       module::set_var("gallery", "page_size", $form->edit_theme->page_size->value);
diff --git a/modules/gallery/controllers/albums.php b/modules/gallery/controllers/albums.php
index 5ccadb37..efde4f09 100644
--- a/modules/gallery/controllers/albums.php
+++ b/modules/gallery/controllers/albums.php
@@ -24,11 +24,11 @@ class Albums_Controller extends Items_Controller {
    */
   public function _show($album) {
     if (!access::can("view", $album)) {
-      if ($album->id != 1) {
-        access::forbidden();
-      } else {
+      if ($album->id == 1) {
         print new Theme_View("login_page.html", "album");
         return;
+      } else {
+        access::forbidden();
       }
     }
 
@@ -77,6 +77,8 @@ class Albums_Controller extends Items_Controller {
    * @see REST_Controller::_create($resource)
    */
   public function _create($album) {
+    access::verify_csrf();
+    access::required("view", $album);
     access::required("add", $album);
 
     switch ($this->input->post("type")) {
@@ -92,6 +94,7 @@ class Albums_Controller extends Items_Controller {
   }
 
   private function _create_album($album) {
+    access::required("view", $album);
     access::required("add", $album);
 
     $form = album::get_add_form($album);
@@ -120,6 +123,7 @@ class Albums_Controller extends Items_Controller {
   }
 
   private function _create_photo($album) {
+    access::required("view", $album);
     access::required("add", $album);
 
     // If we set the content type as JSON, it triggers saving the result as
@@ -153,6 +157,8 @@ class Albums_Controller extends Items_Controller {
    * @see REST_Controller::_update($resource)
    */
   public function _update($album) {
+    access::verify_csrf();
+    access::required("view", $album);
     access::required("edit", $album);
 
     $form = album::get_edit_form($album);
@@ -202,6 +208,7 @@ class Albums_Controller extends Items_Controller {
    */
   public function _form_add($album_id) {
     $album = ORM::factory("item", $album_id);
+    access::required("view", $album);
     access::required("add", $album);
 
     switch ($this->input->get("type")) {
@@ -223,6 +230,7 @@ class Albums_Controller extends Items_Controller {
    *  @see REST_Controller::_form_add($parameters)
    */
   public function _form_edit($album) {
+    access::required("view", $album);
     access::required("edit", $album);
 
     print album::get_edit_form($album);
diff --git a/modules/gallery/controllers/l10n_client.php b/modules/gallery/controllers/l10n_client.php
index 17520051..c3a76659 100644
--- a/modules/gallery/controllers/l10n_client.php
+++ b/modules/gallery/controllers/l10n_client.php
@@ -20,7 +20,9 @@
 class L10n_Client_Controller extends Controller {
   public function save() {
     access::verify_csrf();
-    user::active()->admin or access::forbidden();
+    if (!user::active()->admin) {
+      access::forbidden();
+    }
 
     $input = Input::instance();
     $message = $input->post("l10n-message-source");
@@ -58,6 +60,9 @@ class L10n_Client_Controller extends Controller {
 
   public function toggle_l10n_mode() {
     access::verify_csrf();
+    if (!user::active()->admin) {
+      access::forbidden();
+    }
 
     $session = Session::instance();
     $session->set("l10n_mode",
@@ -89,6 +94,10 @@ class L10n_Client_Controller extends Controller {
   }
 
   public static function l10n_form() {
+    if (!user::active()->admin) {
+      access::forbidden();
+    }
+
     $calls = I18n::instance()->call_log();
 
     if ($calls) {
diff --git a/modules/gallery/controllers/move.php b/modules/gallery/controllers/move.php
index 130c247f..93ef05a6 100644
--- a/modules/gallery/controllers/move.php
+++ b/modules/gallery/controllers/move.php
@@ -20,6 +20,7 @@
 class Move_Controller extends Controller {
   public function browse($source_id) {
     $source = ORM::factory("item", $source_id);
+    access::required("view", $source);
     access::required("edit", $source);
 
     $view = new View("move_browse.html");
@@ -33,6 +34,11 @@ class Move_Controller extends Controller {
     $source = ORM::factory("item", $source_id);
     $target = ORM::factory("item", $this->input->post("target_id"));
 
+    access::required("view", $source);
+    access::required("edit", $source);
+    access::required("view", $target);
+    access::required("edit", $target);
+
     item::move($source, $target);
 
     print json_encode(
@@ -43,8 +49,11 @@ class Move_Controller extends Controller {
   public function show_sub_tree($source_id, $target_id) {
     $source = ORM::factory("item", $source_id);
     $target = ORM::factory("item", $target_id);
+    access::required("view", $source);
     access::required("edit", $source);
     access::required("view", $target);
+    // show targets even if they're not editable because they may contain children which *are*
+    // editable
 
     print $this->_get_tree_html($source, $target);
   }
diff --git a/modules/gallery/controllers/movies.php b/modules/gallery/controllers/movies.php
index 55bbb0e5..86b0f177 100644
--- a/modules/gallery/controllers/movies.php
+++ b/modules/gallery/controllers/movies.php
@@ -66,6 +66,8 @@ class Movies_Controller extends Items_Controller {
    * @see REST_Controller::_update($resource)
    */
   public function _update($photo) {
+    access::verify_csrf();
+    access::required("view", $photo);
     access::required("edit", $photo);
 
     $form = photo::get_edit_form($photo);
@@ -108,6 +110,7 @@ class Movies_Controller extends Items_Controller {
    *  @see REST_Controller::_form_edit($resource)
    */
   public function _form_edit($photo) {
+    access::required("view", $photo);
     access::required("edit", $photo);
     print photo::get_edit_form($photo);
   }
diff --git a/modules/gallery/controllers/permissions.php b/modules/gallery/controllers/permissions.php
index b0cee303..c776a0fd 100644
--- a/modules/gallery/controllers/permissions.php
+++ b/modules/gallery/controllers/permissions.php
@@ -20,6 +20,7 @@
 class Permissions_Controller extends Controller {
   function browse($id) {
     $item = ORM::factory("item", $id);
+    access::required("view", $item);
     access::required("edit", $item);
 
     if (!$item->is_album()) {
@@ -37,6 +38,7 @@ class Permissions_Controller extends Controller {
 
   function form($id) {
     $item = ORM::factory("item", $id);
+    access::required("view", $item);
     access::required("edit", $item);
 
     if (!$item->is_album()) {
@@ -48,9 +50,11 @@ class Permissions_Controller extends Controller {
 
   function change($command, $group_id, $perm_id, $item_id) {
     access::verify_csrf();
+
     $group = ORM::factory("group", $group_id);
     $perm = ORM::factory("permission", $perm_id);
     $item = ORM::factory("item", $item_id);
+    access::required("view", $item);
     access::required("edit", $item);
 
     if ($group->loaded && $perm->loaded && $item->loaded) {
diff --git a/modules/gallery/controllers/photos.php b/modules/gallery/controllers/photos.php
index 5d4040cf..2de51bc7 100644
--- a/modules/gallery/controllers/photos.php
+++ b/modules/gallery/controllers/photos.php
@@ -62,10 +62,13 @@ class Photos_Controller extends Items_Controller {
     print $template;
   }
 
+
   /**
    * @see REST_Controller::_update($resource)
    */
   public function _update($photo) {
+    access::verify_csrf();
+    access::required("view", $photo);
     access::required("edit", $photo);
 
     $form = photo::get_edit_form($photo);
@@ -110,7 +113,9 @@ class Photos_Controller extends Items_Controller {
    *  @see REST_Controller::_form_edit($resource)
    */
   public function _form_edit($photo) {
+    access::required("view", $photo);
     access::required("edit", $photo);
+
     print photo::get_edit_form($photo);
   }
 }
diff --git a/modules/gallery/controllers/quick.php b/modules/gallery/controllers/quick.php
index 643dce30..6efcb9de 100644
--- a/modules/gallery/controllers/quick.php
+++ b/modules/gallery/controllers/quick.php
@@ -19,8 +19,8 @@
  */
 class Quick_Controller extends Controller {
   public function pane($id) {
-    $item = ORM::factory("item", $id);
-    if (!$item->loaded) {
+    $item = model_cache::get("item", $id);
+    if (!access::can("view", $item) || !access::can("edit", $item)) {
       return "";
     }
 
@@ -32,10 +32,9 @@ class Quick_Controller extends Controller {
 
   public function rotate($id, $dir) {
     access::verify_csrf();
-    $item = ORM::factory("item", $id);
-    if (!$item->loaded) {
-      return "";
-    }
+    $item = model_cache::get("item", $id);
+    access::required("view", $item);
+    access::required("edit", $item);
 
     $degrees = 0;
     switch($dir) {
@@ -82,14 +81,21 @@ class Quick_Controller extends Controller {
 
   public function make_album_cover($id) {
     access::verify_csrf();
-    item::make_album_cover(ORM::factory("item", $id));
+
+    $item = model_cache::get("item", $id);
+    access::required("view", $item);
+    access::required("view", $item->parent());
+    access::required("edit", $item->parent());
+
+    item::make_album_cover($item);
 
     print json_encode(array("result" => "success"));
   }
 
   public function delete($id) {
     access::verify_csrf();
-    $item = ORM::factory("item", $id);
+    $item = model_cache::get("item", $id);
+    access::required("view", $item);
     access::required("edit", $item);
 
     if ($item->is_album()) {
@@ -110,8 +116,10 @@ class Quick_Controller extends Controller {
   }
 
   public function form_edit($id) {
-    $item = ORM::factory("item", $id);
+    $item = model_cache::get("item", $id);
+    access::required("view", $item);
     access::required("edit", $item);
+
     if ($item->is_album()) {
       $form = album::get_edit_form($item);
     } else {
diff --git a/modules/gallery/controllers/rest.php b/modules/gallery/controllers/rest.php
index 11a6bbac..2edf079f 100644
--- a/modules/gallery/controllers/rest.php
+++ b/modules/gallery/controllers/rest.php
@@ -86,21 +86,20 @@ class REST_Controller extends Controller {
       return Kohana::show_404();
     }
 
-    if ($request_method != "get") {
-      access::verify_csrf();
-    }
-
     switch ($request_method) {
     case "get":
       return $this->_show($resource);
 
     case "put":
+      access::verify_csrf();
       return $this->_update($resource);
 
     case "delete":
+      access::verify_csrf();
       return $this->_delete($resource);
 
     case "post":
+      access::verify_csrf();
       return $this->_create($resource);
     }
   }
@@ -111,17 +110,18 @@ class REST_Controller extends Controller {
       throw new Exception("@todo ERROR_MISSING_RESOURCE_TYPE");
     }
 
-    // @todo this needs security checks
     $resource = ORM::factory($this->resource_type, $resource_id);
     if (!$resource->loaded) {
       return Kohana::show_404();
     }
 
+    // Security checks must be performed in _form_edit
     return $this->_form_edit($resource);
   }
 
   /* We're adding a new item, pass along any additional parameters. */
   public function form_add($parameters) {
+    // Security checks must be performed in _form_add
     return $this->_form_add($parameters);
   }
 
diff --git a/modules/gallery/controllers/simple_uploader.php b/modules/gallery/controllers/simple_uploader.php
index ec2a5ab9..dfbd4f17 100644
--- a/modules/gallery/controllers/simple_uploader.php
+++ b/modules/gallery/controllers/simple_uploader.php
@@ -20,6 +20,7 @@
 class Simple_Uploader_Controller extends Controller {
   public function app($id) {
     $item = ORM::factory("item", $id);
+    access::required("view", $item);
     access::required("add", $item);
 
     $v = new View("simple_uploader.html");
@@ -33,13 +34,13 @@ class Simple_Uploader_Controller extends Controller {
 
   public function add_photo($id) {
     $album = ORM::factory("item", $id);
+    access::required("view", $album);
     access::required("add", $album);
     access::verify_csrf();
 
     $file_validation = new Validation($_FILES);
     $file_validation->add_rules("Filedata", "upload::valid", "upload::type[gif,jpg,png,flv,mp4]");
     if ($file_validation->validate()) {
-
       // SimpleUploader.swf does not yet call /start directly, so simulate it here for now.
       if (!batch::in_progress()) {
         batch::start();
@@ -48,7 +49,7 @@ class Simple_Uploader_Controller extends Controller {
       $temp_filename = upload::save("Filedata");
       try {
         $name = substr(basename($temp_filename), 10);  // Skip unique identifier Kohana adds
-        $title = $this->convert_filename_to_title($name);
+        $title = item::convert_filename_to_title($name);
         $path_info = pathinfo($temp_filename);
         if (array_key_exists("extension", $path_info) &&
             in_array(strtolower($path_info["extension"]), array("flv", "mp4"))) {
@@ -69,18 +70,11 @@ class Simple_Uploader_Controller extends Controller {
     print "File Received";
   }
 
-  /**
-   * We should move this into a helper somewhere.. but where is appropriate?
-   */
-  private function convert_filename_to_title($filename) {
-    $title = strtr($filename, "_", " ");
-    $title = preg_replace("/\..*?$/", "", $title);
-    $title = preg_replace("/ +/", " ", $title);
-    return $title;
-  }
-
   public function finish() {
+    access::verify_csrf();
+
     batch::stop();
     print json_encode(array("result" => "success"));
   }
+
 }
diff --git a/modules/gallery/helpers/item.php b/modules/gallery/helpers/item.php
index 7daaf1e1..09870b45 100644
--- a/modules/gallery/helpers/item.php
+++ b/modules/gallery/helpers/item.php
@@ -19,6 +19,8 @@
  */
 class item_Core {
   static function move($source, $target) {
+    access::required("view", $source);
+    access::required("view", $target);
     access::required("edit", $source);
     access::required("edit", $target);
 
@@ -47,6 +49,8 @@ class item_Core {
 
   static function make_album_cover($item) {
     $parent = $item->parent();
+    access::required("view", $item);
+    access::required("view", $parent);
     access::required("edit", $parent);
 
     model_cache::clear("item", $parent->album_cover_item_id);
@@ -61,6 +65,7 @@ class item_Core {
   }
 
   static function remove_album_cover($album) {
+    access::required("view", $album);
     access::required("edit", $album);
     @unlink($album->thumb_path());
 
@@ -102,4 +107,16 @@ class item_Core {
       $input->add_error("conflict", 1);
     }
   }
+
+  /**
+   * Sanitize a filename into something presentable as an item title
+   * @param string $filename
+   * @return string title
+   */
+  static function convert_filename_to_title($filename) {
+    $title = strtr($filename, "_", " ");
+    $title = preg_replace("/\..*?$/", "", $title);
+    $title = preg_replace("/ +/", " ", $title);
+    return $title;
+  }
 }
\ No newline at end of file
diff --git a/modules/gallery/libraries/MY_Forge.php b/modules/gallery/libraries/MY_Forge.php
index 17d0465b..b40d067d 100644
--- a/modules/gallery/libraries/MY_Forge.php
+++ b/modules/gallery/libraries/MY_Forge.php
@@ -26,6 +26,7 @@ class Forge extends Forge_Core {
     parent::__construct($action, $title, $method, $attr);
     $this->hidden("csrf")->value("");
   }
+
   /**
    * Use our own template
    */
diff --git a/modules/gallery/views/simple_uploader.html.php b/modules/gallery/views/simple_uploader.html.php
index abda6d26..7b90c5be 100644
--- a/modules/gallery/views/simple_uploader.html.php
+++ b/modules/gallery/views/simple_uploader.html.php
@@ -3,7 +3,7 @@
 
 
 
-
"> +">
p::clean($item->title))) ?>
diff --git a/modules/notification/helpers/notification.php b/modules/notification/helpers/notification.php index 32301fe0..8ee0c6ba 100644 --- a/modules/notification/helpers/notification.php +++ b/modules/notification/helpers/notification.php @@ -149,7 +149,7 @@ class notification { $result = ORM::factory("pending_notification") ->where("email", $email) ->find_all(); - if ($result->count == 1) { + if ($result->count() == 1) { $pending = $result->get(); Sendmail::factory() ->to($email) diff --git a/modules/organize/controllers/organize.php b/modules/organize/controllers/organize.php index 1c4792b2..43d41357 100644 --- a/modules/organize/controllers/organize.php +++ b/modules/organize/controllers/organize.php @@ -24,19 +24,22 @@ class Organize_Controller extends Controller { function index($item_id=1) { $item = ORM::factory("item", $item_id); $root = ($item->id == 1) ? $item : ORM::factory("item", 1); + access::required("view", $item); + access::required("edit", $item); $v = new View("organize.html"); $v->root = $root; $v->item = $item; $v->album_tree = $this->tree($item, $root); - $v->button_pane = new View("organize_button_pane.html"); - print $v; } function content($item_id) { $item = ORM::factory("item", $item_id); + access::required("view", $item); + access::required("edit", $item); + $width = $this->input->get("width"); $height = $this->input->get("height"); $offset = $this->input->get("offset", 0); @@ -55,12 +58,17 @@ class Organize_Controller extends Controller { function header($item_id) { $item = ORM::factory("item", $item_id); + access::required("view", $item); + access::required("edit", $item); print json_encode(array("title" => $item->title, "description" => empty($item->description) ? "" : $item->description)); } function tree($item, $parent) { + access::required("view", $item); + access::required("edit", $item); + $albums = ORM::factory("item") ->where(array("parent_id" => $parent->id, "type" => "album")) ->orderby(array("title" => "ASC")) @@ -88,6 +96,8 @@ class Organize_Controller extends Controller { $items = $this->input->post("item"); $item = ORM::factory("item", $id); + access::required("view", $item); + access::required("edit", $item); $definition = $this->_getOperationDefinition($item, $operation); @@ -101,22 +111,26 @@ class Organize_Controller extends Controller { // @todo If there is only one item then call task_run($task->id); Maybe even change js so // we can call finish as well. batch::start(); - print json_encode(array("result" => "started", - "runningMsg" => $definition["runningMsg"], - "pauseMsg" => "
{$definition['pauseMsg']}
", - "resumeMsg" => "
{$definition['resumeMsg']}
", - "task" => array("id" => $task->id, - "percent_complete" => $task->percent_complete, - "type" => $task->get("type"), - "status" => $task->status, - "state" => $task->state, - "done" => $task->done))); + print json_encode( + array("result" => "started", + "runningMsg" => $definition["runningMsg"], + "pauseMsg" => "
{$definition['pauseMsg']}
", + "resumeMsg" => "
{$definition['resumeMsg']}
", + "task" => array("id" => $task->id, + "percent_complete" => $task->percent_complete, + "type" => $task->get("type"), + "status" => $task->status, + "state" => $task->state, + "done" => $task->done))); } function runTask($task_id) { access::verify_csrf(); $task = task::run($task_id); + if (!$task->loaded || $task->owner_id != user::active()->id) { + access::forbidden(); + } print json_encode(array("result" => $task->done ? $task->state : "in_progress", "task" => array("id" => $task->id, @@ -132,6 +146,9 @@ class Organize_Controller extends Controller { access::verify_csrf(); $task = ORM::factory("task", $task_id); + if (!$task->loaded || $task->owner_id != user::active()->id) { + access::forbidden(); + } if ($task->done) { $item = ORM::factory("item", (int)$task->get("target")); @@ -178,6 +195,9 @@ class Organize_Controller extends Controller { access::verify_csrf(); $task = ORM::factory("task", $task_id); + if (!$task->loaded || $task->owner_id != user::active()->id) { + access::forbidden(); + } if (!$task->done) { $task->done = 1; @@ -210,7 +230,7 @@ class Organize_Controller extends Controller { function editForm() { $event_parms = new stdClass(); $event_parms->panes = array(); - $event_parms->itemids = $this->input->get("item");; + $event_parms->itemids = $this->input->get("item"); // The following code should be done more dynamically i.e. use the event mechanism if (count($event_parms->itemids) == 1) { @@ -218,8 +238,12 @@ class Organize_Controller extends Controller { ->in("id", $event_parms->itemids[0]) ->find(); - $event_parms->panes[] = array("label" => $item->is_album() ? t("Edit Album") : t("Edit Photo"), - "content" => organize::get_general_edit_form($item)); + access::required("view", $item); + access::required("edit", $item); + + $event_parms->panes[] = array( + "label" => $item->is_album() ? t("Edit Album") : t("Edit Photo"), + "content" => organize::get_general_edit_form($item)); if ($item->is_album()) { $event_parms->panes[] = array("label" => t("Sort Order"), @@ -243,6 +267,7 @@ class Organize_Controller extends Controller { $item = ORM::factory("item") ->in("id", $itemids[0]) ->find(); + access::required("view", $item); access::required("edit", $item); $form = organize::get_general_edit_form($item); @@ -273,6 +298,7 @@ class Organize_Controller extends Controller { $item = ORM::factory("item") ->in("id", $itemids[0]) ->find(); + access::required("view", $item); access::required("edit", $item); print organize::get_general_edit_form($item); @@ -285,6 +311,7 @@ class Organize_Controller extends Controller { $item = ORM::factory("item") ->in("id", $itemids[0]) ->find(); + access::required("view", $item); access::required("edit", $item); $form = organize::get_sort_edit_form($item); @@ -309,6 +336,7 @@ class Organize_Controller extends Controller { $item = ORM::factory("item") ->in("id", $itemids[0]) ->find(); + access::required("view", $item); access::required("edit", $item); print organize::get_sort_edit_form($item); @@ -373,6 +401,13 @@ class Organize_Controller extends Controller { } private function _add_tag($new_tag, $itemids) { + // Super lame security stopgap. This code is going to get rewritten anyway. + foreach ($itemids as $item_id) { + $item = ORM::factory("item", $item_id); + access::required("view", $item); + access::required("edit", $item); + } + $tag = ORM::factory("tag") ->where("name", $new_tag) ->find(); @@ -391,6 +426,13 @@ class Organize_Controller extends Controller { } private function _delete_tag($new_tag, $itemids) { + // Super lame security stopgap. This code is going to get rewritten anyway. + foreach ($itemids as $item_id) { + $item = ORM::factory("item", $item_id); + access::required("view", $item); + access::required("edit", $item); + } + $tag = ORM::factory("tag") ->where("name", $new_tag) ->find(); @@ -407,6 +449,13 @@ class Organize_Controller extends Controller { } private function _update_tag($new_tag, $itemids) { + // Super lame security stopgap. This code is going to get rewritten anyway. + foreach ($itemids as $item_id) { + $item = ORM::factory("item", $item_id); + access::required("view", $item); + access::required("edit", $item); + } + $tag = ORM::factory("tag") ->where("name", $new_tag) ->find(); @@ -441,6 +490,7 @@ class Organize_Controller extends Controller { "pauseMsg" => t("The move operation was paused"), "resumeMsg" => t("The move operation was resumed")); break; + case "rearrange": return array("description" => t("Rearrange the order of albums and photos"), "name" => t("Rearrange: %name", array("name" => $item->title)), @@ -449,6 +499,7 @@ class Organize_Controller extends Controller { "pauseMsg" => t("The rearrange operation was paused"), "resumeMsg" => t("The rearrange operation was resumed")); break; + case "rotateCcw": return array("description" => t("Rotate the selected photos counter clockwise"), "name" => t("Rotate images in %name", array("name" => $item->title)), @@ -457,6 +508,7 @@ class Organize_Controller extends Controller { "pauseMsg" => t("The rotate operation was paused"), "resumeMsg" => t("The rotate operation was resumed")); break; + case "rotateCw": return array("description" => t("Rotate the selected photos clockwise"), "name" => t("Rotate images in %name", array("name" => $item->title)), @@ -465,6 +517,7 @@ class Organize_Controller extends Controller { "pauseMsg" => t("The rotate operation was paused"), "resumeMsg" => t("The rotate operation was resumed")); break; + case "delete": return array("description" => t("Delete selected photos and albums"), "name" => t("Delete images in %name", array("name" => $item->title)), @@ -473,6 +526,7 @@ class Organize_Controller extends Controller { "pauseMsg" => t("The delete operation was paused"), "resumeMsg" => t("The delete operation was resumed")); break; + case "albumCover": return array("description" => t("Reset Album Cover"), "name" => t("Reset Album cover for %name", array("name" => $item->title)), @@ -481,6 +535,7 @@ class Organize_Controller extends Controller { "pauseMsg" => t("Reset album cover was paused"), "resumeMsg" => t("Reset album cover was resumed")); break; + default: throw new Exception("Operation '$operation' is not implmented"); } diff --git a/modules/organize/helpers/organize.php b/modules/organize/helpers/organize.php index 3a207c95..9bf4e986 100644 --- a/modules/organize/helpers/organize.php +++ b/modules/organize/helpers/organize.php @@ -66,6 +66,14 @@ class organize_Core { $tagPane->hidden("item")->value(implode("|", $itemids)); $item_count = count($itemids); $ids = implode(", ", $itemids); + + // Lame stopgap security check. This code is going to get rewritten anyway. + foreach ($itemids as $id) { + $item = ORM::factory("item", $id); + access::required("view", $item); + access::required("edit", $item); + } + $tags = Database::instance()->query( "SELECT t.name, COUNT(it.item_id) as count FROM {items_tags} it, {tags} t diff --git a/modules/organize/helpers/organize_task.php b/modules/organize/helpers/organize_task.php index 0f0e4792..dc474818 100644 --- a/modules/organize/helpers/organize_task.php +++ b/modules/organize/helpers/organize_task.php @@ -38,30 +38,55 @@ class organize_task_Core { switch ($taskType) { case "move": $source = ORM::factory("item", $id); + access::required("view", $source); + access::required("view", $target); + access::required("edit", $source); + access::required("edit", $target); + item::move($source, $target); break; + case "rearrange": + $item = ORM::factory("item", $id); + access::required("view", $item); + access::required("edit", $item); + Database::instance() ->query("Update {items} set weight = {$context["position"]} where id=$id;"); break; + case "rotateCcw": case "rotateCw": $item = ORM::factory("item", $id); + access::required("view", $item); + access::required("edit", $item); + if ($item->is_photo()) { $context["post_process"]["reload"][] = self::_do_rotation($item, $taskType == "rotateCcw" ? -90 : 90); } break; + case "albumCover": - item::make_album_cover(ORM::factory("item", $id)); + $item = ORM::factory("item", $id); + access::required("view", $item); + access::required("view", $item->parent()); + access::required("edit", $item->parent()); + + item::make_album_cover($item); break; + case "delete": $item = ORM::factory("item", $id); + access::required("view", $item); + access::required("edit", $item); + $item->delete(); $context["post_process"]["remove"][] = array("id" => $id); break; + default: - throw new Exception("Task '$taskType' is not implmented"); + throw new Exception("Task '$taskType' is not implemented"); } } $context["position"] += $stop; diff --git a/modules/recaptcha/controllers/admin_recaptcha.php b/modules/recaptcha/controllers/admin_recaptcha.php index a8f85ed9..5813df8b 100644 --- a/modules/recaptcha/controllers/admin_recaptcha.php +++ b/modules/recaptcha/controllers/admin_recaptcha.php @@ -21,6 +21,8 @@ class Admin_Recaptcha_Controller extends Admin_Controller { public function index() { $form = recaptcha::get_configure_form(); if (request::method() == "post") { + // @todo move the "save" part of this into a separate controller function + access::verify_csrf(); $old_public_key = module::get_var("recaptcha", "public_key"); $old_private_key = module::get_var("recaptcha", "private_key"); if ($form->validate()) { @@ -55,10 +57,4 @@ class Admin_Recaptcha_Controller extends Admin_Controller { $view->content->form = $form; print $view; } - - public function test() { - $view = new View("admin_recaptcha_test.html"); - $view->public_key = module::get_var("recaptcha", "public_key"); - print $view; - } } diff --git a/modules/server_add/controllers/server_add.php b/modules/server_add/controllers/server_add.php index d5278b3b..c37eab58 100644 --- a/modules/server_add/controllers/server_add.php +++ b/modules/server_add/controllers/server_add.php @@ -21,10 +21,11 @@ class Server_Add_Controller extends Controller { public function index($id) { $paths = unserialize(module::get_var("server_add", "authorized_paths")); - $item = ORM::factory("item", $id); - access::required("server_add", $item); - access::required("add", $item); + if (!user::active()->admin) { + access::forbidden(); + } + $item = ORM::factory("item", $id); $view = new View("server_add_tree_dialog.html"); $view->action = url::abs_site("__ARGS__/{$id}__TASK_ID__?csrf=" . access::csrf_token()); $view->parents = $item->parents(); @@ -41,8 +42,11 @@ class Server_Add_Controller extends Controller { } public function children() { - $paths = unserialize(module::get_var("server_add", "authorized_paths")); + if (!user::active()->admin) { + access::forbidden(); + } + $paths = unserialize(module::get_var("server_add", "authorized_paths")); $path_valid = false; $path = $this->input->post("path"); @@ -66,7 +70,12 @@ class Server_Add_Controller extends Controller { } function start($id) { + if (!user::active()->admin) { + access::forbidden(); + } access::verify_csrf(); + + $item = ORM::factory("item", $id); $paths = unserialize(module::get_var("server_add", "authorized_paths")); $input_files = $this->input->post("path"); $files = array(); @@ -114,9 +123,15 @@ class Server_Add_Controller extends Controller { } function add_photo($task_id) { + if (!user::active()->admin) { + access::forbidden(); + } access::verify_csrf(); $task = task::run($task_id); + if (!$task->loaded || $task->owner_id != user::active()->id) { + access::forbidden(); + } if ($task->done) { switch ($task->state) { @@ -146,10 +161,16 @@ class Server_Add_Controller extends Controller { } public function finish($id, $task_id) { + if (!user::active()->admin) { + access::forbidden(); + } access::verify_csrf(); - $task = ORM::factory("task", $task_id); + if (!$task->loaded || $task->owner_id != user::active()->id) { + access::forbidden(); + } + if (!$task->done) { message::warning(t("Add from server was cancelled prior to completion")); } @@ -159,9 +180,14 @@ class Server_Add_Controller extends Controller { } public function pause($id, $task_id) { + if (!user::active()->admin) { + access::forbidden(); + } access::verify_csrf(); - $task = ORM::factory("task", $task_id); + if (!$task->loaded || $task->owner_id != user::active()->id) { + access::forbidden(); + } message::warning(t("Add from server was cancelled prior to completion")); batch::stop(); diff --git a/modules/server_add/helpers/server_add_installer.php b/modules/server_add/helpers/server_add_installer.php index b592b448..f8773a2e 100644 --- a/modules/server_add/helpers/server_add_installer.php +++ b/modules/server_add/helpers/server_add_installer.php @@ -22,7 +22,6 @@ class server_add_installer { $db = Database::instance(); $version = module::get_version("server_add"); if ($version == 0) { - access::register_permission("server_add", t("Add files from server")); module::set_version("server_add", 1); } server_add::check_config(); @@ -31,8 +30,4 @@ class server_add_installer { static function deactivate() { site_status::clear("server_add_configuration"); } - - static function uninstall() { - access::delete_permission("server_add"); - } } diff --git a/modules/server_add/helpers/server_add_menu.php b/modules/server_add/helpers/server_add_menu.php index 04c94493..7269d952 100644 --- a/modules/server_add/helpers/server_add_menu.php +++ b/modules/server_add/helpers/server_add_menu.php @@ -28,11 +28,9 @@ class server_add_menu_Core { static function site($menu, $theme) { $item = $theme->item(); - $paths = unserialize(module::get_var("server_add", "authorized_paths")); - if ($item && access::can("edit", $item) && access::can("server_add", $item) && - $item->is_album() && !empty($paths)) { + if (user::active()->admin && $item->is_album() && !empty($paths)) { $options_menu = $menu->get("options_menu") ->append(Menu::factory("dialog") ->id("server_add") diff --git a/modules/server_add/helpers/server_add_task.php b/modules/server_add/helpers/server_add_task.php index c5a7f067..98575915 100644 --- a/modules/server_add/helpers/server_add_task.php +++ b/modules/server_add/helpers/server_add_task.php @@ -31,7 +31,6 @@ class server_add_task_Core { if (!empty($context["files"][$path])) { $file = $context["files"][$path][$context["position"]]; $parent = ORM::factory("item", $file["parent_id"]); - access::required("server_add", $parent); access::required("add", $parent); if (!$parent->is_album()) { throw new Exception("@todo BAD_ALBUM"); diff --git a/modules/tag/controllers/admin_tags.php b/modules/tag/controllers/admin_tags.php index 1176b0ca..01884bb8 100644 --- a/modules/tag/controllers/admin_tags.php +++ b/modules/tag/controllers/admin_tags.php @@ -42,6 +42,7 @@ class Admin_Tags_Controller extends Admin_Controller { public function delete($id) { access::verify_csrf(); + $tag = ORM::factory("tag", $id); if (!$tag->loaded) { kohana::show_404(); diff --git a/modules/tag/controllers/tags.php b/modules/tag/controllers/tags.php index aecd1db7..930c1252 100644 --- a/modules/tag/controllers/tags.php +++ b/modules/tag/controllers/tags.php @@ -48,6 +48,7 @@ class Tags_Controller extends REST_Controller { public function _create($tag) { $item = ORM::factory("item", $this->input->post("item_id")); + access::required("view", $item); access::required("edit", $item); $form = tag::get_add_form($item); @@ -73,6 +74,7 @@ class Tags_Controller extends REST_Controller { public function _form_add($item_id) { $item = ORM::factory("item", $item_id); access::required("view", $item); + access::required("edit", $item); return tag::get_add_form($item); } diff --git a/modules/user/controllers/admin_users.php b/modules/user/controllers/admin_users.php index ac17c577..fe8061aa 100644 --- a/modules/user/controllers/admin_users.php +++ b/modules/user/controllers/admin_users.php @@ -28,6 +28,7 @@ class Admin_Users_Controller extends Controller { public function add_user() { access::verify_csrf(); + $form = user::get_add_form_admin(); $valid = $form->validate(); $name = $form->add_user->inputs["name"]->value; @@ -63,6 +64,7 @@ class Admin_Users_Controller extends Controller { public function delete_user($id) { access::verify_csrf(); + if ($id == user::active()->id || $id == user::guest()->id) { access::forbidden(); } @@ -97,6 +99,7 @@ class Admin_Users_Controller extends Controller { public function edit_user($id) { access::verify_csrf(); + $user = ORM::factory("user", $id); if (!$user->loaded) { kohana::show_404(); @@ -182,6 +185,7 @@ class Admin_Users_Controller extends Controller { public function add_group() { access::verify_csrf(); + $form = group::get_add_form_admin(); $valid = $form->validate(); if ($valid) { @@ -210,6 +214,7 @@ class Admin_Users_Controller extends Controller { public function delete_group($id) { access::verify_csrf(); + $group = ORM::factory("group", $id); if (!$group->loaded) { kohana::show_404(); @@ -240,6 +245,7 @@ class Admin_Users_Controller extends Controller { public function edit_group($id) { access::verify_csrf(); + $group = ORM::factory("group", $id); if (!$group->loaded) { kohana::show_404(); diff --git a/modules/user/controllers/login.php b/modules/user/controllers/login.php index 6ee2e69d..54a7905e 100644 --- a/modules/user/controllers/login.php +++ b/modules/user/controllers/login.php @@ -26,6 +26,8 @@ class Login_Controller extends Controller { } public function auth_ajax() { + access::verify_csrf(); + list ($valid, $form) = $this->_auth("login/auth_ajax"); if ($valid) { print json_encode( @@ -42,6 +44,8 @@ class Login_Controller extends Controller { } public function auth_html() { + access::verify_csrf(); + list ($valid, $form) = $this->_auth("login/auth_html"); if ($valid) { url::redirect("albums/1"); diff --git a/modules/user/controllers/logout.php b/modules/user/controllers/logout.php index b43680d5..6ceb7192 100644 --- a/modules/user/controllers/logout.php +++ b/modules/user/controllers/logout.php @@ -19,6 +19,8 @@ */ class Logout_Controller extends Controller { public function index() { + access::verify_csrf(); + $user = user::active(); user::logout(); log::info("user", t("User %name logged out", array("name" => $user->name)), diff --git a/modules/user/controllers/password.php b/modules/user/controllers/password.php index c3e66634..3b0eac66 100644 --- a/modules/user/controllers/password.php +++ b/modules/user/controllers/password.php @@ -19,6 +19,8 @@ */ class Password_Controller extends Controller { public function reset() { + access::verify_csrf(); + if (request::method() == "post") { $this->_send_reset(); } else { @@ -27,6 +29,8 @@ class Password_Controller extends Controller { } public function do_reset() { + access::verify_csrf(); + if (request::method() == "post") { $this->_change_password(); } else { diff --git a/modules/user/views/login.html.php b/modules/user/views/login.html.php index cce2fb54..3889f06e 100644 --- a/modules/user/views/login.html.php +++ b/modules/user/views/login.html.php @@ -12,7 +12,7 @@ '" title="' . t("Edit Your Profile") . '" id="gUserProfileLink" class="gDialogLink">' . p::clean(empty($user->full_name) ? $user->name : $user->full_name) . '')) ?> -
  • " id="gLogoutLink">
  • diff --git a/modules/watermark/controllers/admin_watermarks.php b/modules/watermark/controllers/admin_watermarks.php index d487edb8..423196ac 100644 --- a/modules/watermark/controllers/admin_watermarks.php +++ b/modules/watermark/controllers/admin_watermarks.php @@ -38,6 +38,8 @@ class Admin_Watermarks_Controller extends Admin_Controller { } public function edit() { + access::verify_csrf(); + $form = watermark::get_edit_form(); if ($form->validate()) { module::set_var("watermark", "position", $form->edit_watermark->position->value); @@ -61,6 +63,8 @@ class Admin_Watermarks_Controller extends Admin_Controller { } public function delete() { + access::verify_csrf(); + $form = watermark::get_delete_form(); if ($form->validate()) { if ($name = module::get_var("watermark", "name")) { @@ -91,6 +95,8 @@ class Admin_Watermarks_Controller extends Admin_Controller { } public function add() { + access::verify_csrf(); + $form = watermark::get_add_form(); if ($form->validate()) { $file = $_POST["file"]; -- cgit v1.2.3 From 3b6567f38c206f1302c7b22d94d5eae4b458311a Mon Sep 17 00:00:00 2001 From: Bharat Mediratta Date: Mon, 1 Jun 2009 23:20:36 -0700 Subject: Unescape %20 into " " also. --- modules/gallery/controllers/file_proxy.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'modules/gallery/controllers') diff --git a/modules/gallery/controllers/file_proxy.php b/modules/gallery/controllers/file_proxy.php index dfdb4f34..1f885e53 100644 --- a/modules/gallery/controllers/file_proxy.php +++ b/modules/gallery/controllers/file_proxy.php @@ -32,8 +32,8 @@ class File_Proxy_Controller extends Controller { $request_uri = $this->input->server("REQUEST_URI"); $request_uri = preg_replace("/\?.*/", "", $request_uri); - // Firefox converts ~ to %7E breaking our url comparison, below. Convert that back here. - $request_uri = str_replace("%7E", "~", $request_uri); + // Unescape %7E ("~") and %20 (" ") + $request_uri = str_replace(array("%7E", "%20"), array("~", " "), $request_uri); // var_uri: http://example.com/gallery3/var/ $var_uri = url::file("var/"); -- cgit v1.2.3