summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--index.php17
-rw-r--r--installer/index.php2
-rwxr-xr-xinstaller/install.sql4
-rw-r--r--installer/installer.php3
-rwxr-xr-xinstaller/package.php239
-rw-r--r--modules/akismet/controllers/admin_akismet.php3
-rw-r--r--modules/comment/controllers/admin_comments.php2
-rw-r--r--modules/comment/controllers/comments.php5
-rw-r--r--modules/exif/helpers/exif_theme.php14
-rw-r--r--modules/g2_import/controllers/admin_g2_import.php2
-rw-r--r--modules/gallery/controllers/admin.php3
-rw-r--r--modules/gallery/controllers/admin_dashboard.php4
-rw-r--r--modules/gallery/controllers/admin_graphics.php1
-rw-r--r--modules/gallery/controllers/admin_languages.php4
-rw-r--r--modules/gallery/controllers/admin_theme_details.php2
-rw-r--r--modules/gallery/controllers/albums.php14
-rw-r--r--modules/gallery/controllers/file_proxy.php3
-rw-r--r--modules/gallery/controllers/l10n_client.php11
-rw-r--r--modules/gallery/controllers/move.php9
-rw-r--r--modules/gallery/controllers/movies.php3
-rw-r--r--modules/gallery/controllers/package.php169
-rw-r--r--modules/gallery/controllers/permissions.php4
-rw-r--r--modules/gallery/controllers/photos.php5
-rw-r--r--modules/gallery/controllers/quick.php26
-rw-r--r--modules/gallery/controllers/rest.php10
-rw-r--r--modules/gallery/controllers/simple_uploader.php18
-rw-r--r--modules/gallery/helpers/gallery.php2
-rw-r--r--modules/gallery/helpers/item.php17
-rw-r--r--modules/gallery/libraries/MY_Forge.php1
-rw-r--r--modules/gallery/models/item.php4
-rw-r--r--modules/gallery/tests/xss_data.txt17
-rw-r--r--modules/gallery/views/permissions_browse.html.php2
-rw-r--r--modules/gallery/views/simple_uploader.html.php2
-rw-r--r--modules/notification/helpers/notification.php2
-rw-r--r--modules/organize/controllers/organize.php85
-rw-r--r--modules/organize/helpers/organize.php8
-rw-r--r--modules/organize/helpers/organize_task.php29
-rw-r--r--modules/recaptcha/controllers/admin_recaptcha.php8
-rw-r--r--modules/recaptcha/helpers/recaptcha_installer.php2
-rw-r--r--modules/server_add/controllers/server_add.php38
-rw-r--r--modules/server_add/helpers/server_add_installer.php5
-rw-r--r--modules/server_add/helpers/server_add_menu.php4
-rw-r--r--modules/server_add/helpers/server_add_task.php1
-rw-r--r--modules/tag/controllers/admin_tags.php1
-rw-r--r--modules/tag/controllers/tags.php14
-rw-r--r--modules/user/controllers/admin_users.php6
-rw-r--r--modules/user/controllers/login.php4
-rw-r--r--modules/user/controllers/logout.php2
-rw-r--r--modules/user/controllers/password.php4
-rw-r--r--modules/user/helpers/user.php1
-rw-r--r--modules/user/views/admin_users.html.php2
-rw-r--r--modules/user/views/admin_users_group.html.php42
-rw-r--r--modules/user/views/login.html.php2
-rw-r--r--modules/watermark/controllers/admin_watermarks.php6
-rw-r--r--themes/admin_default/css/screen.css36
-rw-r--r--themes/default/views/login_page.html.php24
56 files changed, 560 insertions, 388 deletions
diff --git a/index.php b/index.php
index a70053a8..f5b24ee7 100644
--- a/index.php
+++ b/index.php
@@ -27,7 +27,7 @@ version_compare(PHP_VERSION, '5.2.3', '<') and exit('Gallery requires PHP 5.2.3
!ini_get('short_open_tag') and exit('Gallery requires short_open_tag to be on.');
// Set the error reporting level. Use E_ALL unless you have a special need.
-error_reporting(E_NONE);
+error_reporting(0);
// Disabling display_errors will effectively disable Kohana error display
// and logging. You can turn off Kohana errors in application/config/config.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/index.php b/installer/index.php
index 6b1d434b..317f27b8 100644
--- a/installer/index.php
+++ b/installer/index.php
@@ -27,7 +27,7 @@ if (version_compare(PHP_VERSION, "5.2.3", "<")) {
}
require(DOCROOT . "installer/installer.php");
-if (php_sapi_name() == "cli") {
+if (PHP_SAPI == "cli") {
include("cli.php");
} else {
if (@$_GET["page"] == "check") {
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 <a href=\"%url\">Gallery %version</a>'),(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 <a href=\"%url\">Gallery %version</a>'),(21,'comment','spam_caught','0');
diff --git a/installer/installer.php b/installer/installer.php
index ab2963ba..1a36ddb5 100644
--- a/installer/installer.php
+++ b/installer/installer.php
@@ -50,6 +50,7 @@ class installer {
static function unpack_sql($config) {
$prefix = $config["prefix"];
+ $buf = null;
foreach (file(DOCROOT . "installer/install.sql") as $line) {
$buf .= $line;
if (preg_match("/;$/", $buf)) {
@@ -133,4 +134,4 @@ class installer {
static function prepend_prefix($prefix, $sql) {
return preg_replace("#{([a-zA-Z0-9_]+)}#", "{$prefix}$1", $sql);
}
-} \ No newline at end of file
+}
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
-<?php
-define('EXT', '.php');
-define("DOCROOT", realpath("../") . "/");
-define("VARPATH", DOCROOT . "var/");
-
-// Define application and system paths
-define("SYSPATH", DOCROOT . "system/");
-define('APPPATH', DOCROOT . "application/");
-define('MODPATH', DOCROOT . "modules/");
-define('THEMEPATH', DOCROOT . "themes/");
-
-$modules_list = null;
-$active_modules = null;
-
-function setup($config) {
- system("rm -rf tmp");
- mkdir("tmp");
-
- // Lets backup the database
- $conn = $config["connection"];
- do_system("mysqldump -u{$conn['user']} -p{$conn['pass']} -h{$conn['host']} --add-drop-table " .
- "--compact {$conn['database']} > 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, "<?php defined(\"SYSPATH\") or die(\"No direct script access.\") ?>\n");
- fwrite($fd, "<?php\n");
- foreach ($paths as $path) {
- fwrite($fd, "!file_exists($path) && mkdir($path);\n");
- }
- fclose($fd);
-}
-
-// Bootstrap kohana so we can use it as we need it
-kohana_bootstrap();
-
-$config = Kohana::config("database.default");
-
-try {
- // Empty the tmp directory, backup the database, and copy the var directory
- setup($config);
-} catch (Exception $e) {
- print $e->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/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/exif/helpers/exif_theme.php b/modules/exif/helpers/exif_theme.php
index 14186d15..bb6926d3 100644
--- a/modules/exif/helpers/exif_theme.php
+++ b/modules/exif/helpers/exif_theme.php
@@ -21,13 +21,13 @@ class exif_theme_Core {
static function sidebar_bottom($theme) {
$item = $theme->item();
if ($item && $item->is_photo()) {
- if (Database::instance()
- ->select("key_count")
- ->from("exif_records")
- ->where("item_id", $item->id)
- ->get()
- ->current()
- ->key_count) {
+ $record = Database::instance()
+ ->select("key_count")
+ ->from("exif_records")
+ ->where("item_id", $item->id)
+ ->get()
+ ->current();
+ if ($record && $record->key_count) {
$view = new View("exif_sidebar.html");
$view->item = $item;
return $view;
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/file_proxy.php b/modules/gallery/controllers/file_proxy.php
index 2037ad98..1f885e53 100644
--- a/modules/gallery/controllers/file_proxy.php
+++ b/modules/gallery/controllers/file_proxy.php
@@ -32,6 +32,9 @@ class File_Proxy_Controller extends Controller {
$request_uri = $this->input->server("REQUEST_URI");
$request_uri = preg_replace("/\?.*/", "", $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/");
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/package.php b/modules/gallery/controllers/package.php
new file mode 100644
index 00000000..f5146fc8
--- /dev/null
+++ b/modules/gallery/controllers/package.php
@@ -0,0 +1,169 @@
+<?php defined("SYSPATH") or die("No direct script access.");
+/**
+ * Gallery - a web based photo album viewer and editor
+ * Copyright (C) 2000-2009 Bharat Mediratta
+ *
+ * This program 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 2 of the License, or (at
+ * your option) any later version.
+ *
+ * This program 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 this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+class Package_Controller extends Controller {
+ function index() {
+ if (PHP_SAPI != 'cli') {
+ Kohana::show_404();
+ }
+
+ 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;
+ }
+
+ print "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);
+
+ 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);
+ }
+ }
+
+ 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}");
+ $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 "<pre>";
+ print "$command\n";
+ print "Failed to dump database\n";
+ print implode("\n", $output);
+ return;
+ }
+
+ // 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);
+ }
+
+ private function _dump_var() {
+ $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, "<?php defined(\"SYSPATH\") or die(\"No direct script access.\") ?>\n");
+ fwrite($fd, "<?php\n");
+ foreach ($paths as $path) {
+ fwrite($fd, "!file_exists($path) && mkdir($path);\n");
+ }
+ fclose($fd);
+ }
+} \ No newline at end of file
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/gallery.php b/modules/gallery/helpers/gallery.php
index 34671f1f..1686571c 100644
--- a/modules/gallery/helpers/gallery.php
+++ b/modules/gallery/helpers/gallery.php
@@ -23,7 +23,7 @@ class gallery_Core {
* down for maintenance" page.
*/
static function maintenance_mode() {
- $maintenance_mode = Kohana::config("gallery.maintenance_mode", false, false);
+ $maintenance_mode = Kohana::config("core.maintenance_mode", false, false);
if (Router::$controller != "login" && !empty($maintenance_mode) && !user::active()->admin) {
Router::$controller = "maintenance";
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/models/item.php b/modules/gallery/models/item.php
index 4b8cac8e..9406f5d9 100644
--- a/modules/gallery/models/item.php
+++ b/modules/gallery/models/item.php
@@ -287,6 +287,10 @@ class Item_Model extends ORM_MPTT {
* @return string
*/
public function relative_path() {
+ if (!$this->loaded) {
+ return;
+ }
+
if (!isset($this->relative_path_cache)) {
$paths = array();
foreach (Database::instance()
diff --git a/modules/gallery/tests/xss_data.txt b/modules/gallery/tests/xss_data.txt
index c79f859a..4aaa520d 100644
--- a/modules/gallery/tests/xss_data.txt
+++ b/modules/gallery/tests/xss_data.txt
@@ -458,15 +458,16 @@ modules/user/views/admin_users.html.php 83 DIRTY $user->la
modules/user/views/admin_users.html.php 86 DIRTY $user->id
modules/user/views/admin_users.html.php 91 DIRTY $user->id
modules/user/views/admin_users.html.php 121 DIRTY $group->id
+modules/user/views/admin_users.html.php 121 DIRTY $group->special
modules/user/views/admin_users.html.php 123 DIRTY $v
-modules/user/views/admin_users_group.html.php 2 CLEAN $group->name
-modules/user/views/admin_users_group.html.php 4 DIRTY $group->id
-modules/user/views/admin_users_group.html.php 5 CLEAN $group->name
-modules/user/views/admin_users_group.html.php 16 CLEAN $user->name
-modules/user/views/admin_users_group.html.php 18 DIRTY $user->id
-modules/user/views/admin_users_group.html.php 18 DIRTY $group->id
-modules/user/views/admin_users_group.html.php 22 CLEAN $user->name
-modules/user/views/admin_users_group.html.php 22 CLEAN $group->name
+modules/user/views/admin_users_group.html.php 3 CLEAN $group->name
+modules/user/views/admin_users_group.html.php 5 DIRTY $group->id
+modules/user/views/admin_users_group.html.php 6 CLEAN $group->name
+modules/user/views/admin_users_group.html.php 20 CLEAN $user->name
+modules/user/views/admin_users_group.html.php 22 DIRTY $user->id
+modules/user/views/admin_users_group.html.php 22 DIRTY $group->id
+modules/user/views/admin_users_group.html.php 25 CLEAN $user->name
+modules/user/views/admin_users_group.html.php 25 CLEAN $group->name
modules/user/views/login.html.php 11 DIRTY $user->id
modules/user/views/login.html.php 14 CLEAN $user->full_name
modules/user/views/login.html.php 14 CLEAN $user->name
diff --git a/modules/gallery/views/permissions_browse.html.php b/modules/gallery/views/permissions_browse.html.php
index 5cd9cf82..8bb2e830 100644
--- a/modules/gallery/views/permissions_browse.html.php
+++ b/modules/gallery/views/permissions_browse.html.php
@@ -27,7 +27,7 @@
<? if (!$htaccess_works): ?>
<ul id="gMessage">
<li class="gError">
- <?= t("Oh no! Your server needs a configuration change in order for you to hide photos! Ask your server administrator to set <a href=\"%url\"><i>AllowOverride FileInfo Options</i></a> to fix this.", array("url" => "http://httpd.apache.org/docs/2.0/mod/gallery.html#allowoverride")) ?>
+ <?= t("Oh no! Your server needs a configuration change in order for you to hide photos! Ask your server administrator to set <a %attrs><i>AllowOverride FileInfo Options</i></a> to fix this.", array("attrs" => "href=\"http://httpd.apache.org/docs/2.0/mod/core.html#allowoverride\" target=\"_blank\"")) ?>
</li>
</ul>
<? endif ?>
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 @@
<script type="text/javascript" src="<?= url::file("lib/swfupload/swfupload.queue.js") ?>"></script>
<!-- hack to set the title for the dialog -->
-<form id="gAddPhotosForm" action="<?= url::site("simple_uploader/finish") ?>">
+<form id="gAddPhotosForm" action="<?= url::site("simple_uploader/finish?csrf=$csrf") ?>">
<fieldset>
<legend> <?= t("Add photos to %album_title", array("album_title" => p::clean($item->title))) ?> </legend>
</fieldset>
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" => "<div class=\"gWarning\">{$definition['pauseMsg']}</div>",
- "resumeMsg" => "<div class=\"gWarning\">{$definition['resumeMsg']}</div>",
- "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" => "<div class=\"gWarning\">{$definition['pauseMsg']}</div>",
+ "resumeMsg" => "<div class=\"gWarning\">{$definition['resumeMsg']}</div>",
+ "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/recaptcha/helpers/recaptcha_installer.php b/modules/recaptcha/helpers/recaptcha_installer.php
index 6269c632..f74bf558 100644
--- a/modules/recaptcha/helpers/recaptcha_installer.php
+++ b/modules/recaptcha/helpers/recaptcha_installer.php
@@ -29,7 +29,7 @@ class recaptcha_installer {
recaptcha::check_config();
}
- static function uninstall() {
+ static function deactivate() {
site_status::clear("recaptcha_config");
}
}
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..295a9d3b 100644
--- a/modules/tag/controllers/tags.php
+++ b/modules/tag/controllers/tags.php
@@ -27,16 +27,16 @@ class Tags_Controller extends REST_Controller {
$offset = ($page-1) * $page_size;
// Make sure that the page references a valid offset
- if ($page < 1 || $page > ceil($children_count / $page_size)) {
+ if ($page < 1 || ($children_count && $page > ceil($children_count / $page_size))) {
Kohana::show_404();
}
$template = new Theme_View("page.html", "tag");
- $template->set_global('page_size', $page_size);
- $template->set_global('page_title', t("Browse Tag::%name", array("name" => $tag->name)));
- $template->set_global('tag', $tag);
- $template->set_global('children', $tag->items($page_size, $offset));
- $template->set_global('children_count', $children_count);
+ $template->set_global("page_size", $page_size);
+ $template->set_global("page_title", t("Browse Tag::%name", array("name" => $tag->name)));
+ $template->set_global("tag", $tag);
+ $template->set_global("children", $tag->items($page_size, $offset));
+ $template->set_global("children_count", $children_count);
$template->content = new View("dynamic.html");
print $template;
@@ -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/helpers/user.php b/modules/user/helpers/user.php
index 5d70b8c9..9e9d4ca1 100644
--- a/modules/user/helpers/user.php
+++ b/modules/user/helpers/user.php
@@ -123,6 +123,7 @@ class user_Core {
// upconvert into a user.
if ($user === 2) {
$user = model_cache::get("user", 2);
+ user::login($user);
$session->set("user", $user);
}
diff --git a/modules/user/views/admin_users.html.php b/modules/user/views/admin_users.html.php
index 859f3c8e..a99c9506 100644
--- a/modules/user/views/admin_users.html.php
+++ b/modules/user/views/admin_users.html.php
@@ -118,7 +118,7 @@
<div class="gBlockContent">
<ul>
<? foreach ($groups as $i => $group): ?>
- <li id="group-<?= $group->id ?>" class="gGroup">
+ <li id="group-<?= $group->id ?>" class="gGroup <?= ($group->special ? "gDefaultGroup" : "") ?>" />
<? $v = new View("admin_users_group.html"); $v->group = $group; ?>
<?= $v ?>
</li>
diff --git a/modules/user/views/admin_users_group.html.php b/modules/user/views/admin_users_group.html.php
index 820b3031..bfd79dba 100644
--- a/modules/user/views/admin_users_group.html.php
+++ b/modules/user/views/admin_users_group.html.php
@@ -1,28 +1,38 @@
<?php defined("SYSPATH") or die("No direct script access.") ?>
-<strong><?= p::clean($group->name) ?></strong>
-<? if (!$group->special): ?>
-<a href="<?= url::site("admin/users/delete_group_form/$group->id") ?>"
- title="<?= t("Delete %name", array("name" => p::clean($group->name))) ?>"
- class="gDialogLink gButtonLink ui-state-default ui-corner-all">
- <span class="ui-icon ui-icon-trash"><?= t("delete") ?></span></a>
-<? else: ?>
-<a title="<?= t("This group cannot be deleted") ?>"
- class="gDialogLink gButtonLink ui-state-disabled ui-corner-all ui-icon-left">
- <span class="ui-icon ui-icon-trash"><?= t("delete") ?></span></a>
-<? endif ?>
+<h4>
+ <?= p::clean($group->name) ?>
+ <? if (!$group->special): ?>
+ <a href="<?= url::site("admin/users/delete_group_form/$group->id") ?>"
+ title="<?= t("Delete the %name group", array("name" => p::clean($group->name))) ?>"
+ class="gDialogLink gButtonLink ui-state-default ui-corner-all">
+ <span class="ui-icon ui-icon-trash"><?= t("delete") ?></span></a>
+ <? else: ?>
+ <a title="<?= t("This default group cannot be deleted") ?>"
+ class="gDialogLink gButtonLink ui-state-disabled ui-corner-all ui-icon-left">
+ <span class="ui-icon ui-icon-trash"><?= t("delete") ?></span></a>
+ <? endif ?>
+</h4>
+
+<? if ($group->users->count() > 0): ?>
<ul>
<? foreach ($group->users as $i => $user): ?>
<li class="gUser">
<?= p::clean($user->name) ?>
<? if (!$group->special): ?>
<a href="javascript:remove_user(<?= $user->id ?>, <?= $group->id ?>)"
- class="gButtonLink ui-state-default ui-corner-all ui-icon-left">
- <span class="ui-icon ui-icon-closethick">
- <?= t("Remove %user from %group",
- array("user" => p::clean($user->name), "group" => p::clean($group->name))) ?>
- </span>
+ class="gButtonLink ui-state-default ui-corner-all ui-icon-left"
+ title="<?= t("Remove %user from %group group",
+ array("user" => p::clean($user->name), "group" => p::clean($group->name))) ?>">
+ <span class="ui-icon ui-icon-closethick"><?= t("remove") ?></span>
</a>
<? endif ?>
</li>
<? endforeach ?>
</ul>
+<? else: ?>
+<div>
+ <p>
+ <?= t("Drag &amp; drop users from the User Admin above into this group box to add group members.") ?>
+ </p>
+</div>
+<? endif ?>
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) . '</a>')) ?></li>
- <li><a href="<?= url::site("logout?continue=" . url::current(true)) ?>"
+ <li><a href="<?= url::site("logout?csrf=$csrf&continue=" . url::current(true)) ?>"
id="gLogoutLink"><?= t("Logout") ?></a></li>
<? endif; ?>
</ul>
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"];
diff --git a/themes/admin_default/css/screen.css b/themes/admin_default/css/screen.css
index 2d5f086c..38fcf089 100644
--- a/themes/admin_default/css/screen.css
+++ b/themes/admin_default/css/screen.css
@@ -192,6 +192,9 @@
#gUserAdminList {
margin-bottom: 1em;
}
+#gUserAdminList td {
+ vertical-align: bottom;
+}
#gUserAdminList .gDraggable:hover {
border: 1px dashed black;
@@ -211,11 +214,38 @@ li.gGroup {
float: left;
display: block;
width: 200px;
- height: 200px;
border: 1px solid gray;
- padding: .5em;
- margin-right: 0 1em 1em 0;
+ padding: 0;
+ margin: 0 1em 1em 0;
+}
+li.gGroup h4 {
+ background-color: #EEEEEE;
+ border-bottom: 1px dashed #CCCCCC;
+ padding: .5em 0 .5em .5em;
+}
+li.gGroup .gButtonLink {
+ padding: 0;
+}
+li.gGroup ul, li.gGroup div {
+ height: 180px;
+ margin: 1px;
overflow: auto;
+ padding-top: .2em;
+}
+li.gGroup div p {
+ color: gray;
+ text-align: center;
+ padding: 2em .5em 0 .5em
+}
+li.gGroup .gUser {
+ padding: .2em 0 0 .5em;
+}
+li.gGroup .gUser .gButtonLink {
+ vertical-align: middle;
+}
+
+li.gDefaultGroup h4, li.gDefaultGroup .gUser {
+ color: gray;
}
#gAdminAdvancedSettings tr.setting:hover {
diff --git a/themes/default/views/login_page.html.php b/themes/default/views/login_page.html.php
index 1bd76c18..27f8571e 100644
--- a/themes/default/views/login_page.html.php
+++ b/themes/default/views/login_page.html.php
@@ -7,33 +7,11 @@
<title>
<?= t("Please Login to Gallery") ?>
</title>
- <link rel="shortcut icon" href="<?= $theme->url("images/favicon.ico") ?>" type="image/x-icon" />
- <link rel="stylesheet" type="text/css" href="<?= url::file("lib/yui/reset-fonts-grids.css") ?>"
- media="screen,print,projection" />
- <link rel="stylesheet" type="text/css" href="<?= url::file("lib/superfish/css/superfish.css") ?>"
- media="screen" />
- <link rel="stylesheet" type="text/css" href="<?= url::file("lib/themeroller/ui.base.css") ?>"
- media="screen,print,projection" />
<link rel="stylesheet" type="text/css" href="<?= $theme->url("css/screen.css") ?>"
media="screen,print,projection" />
- <!--[if IE]>
- <link rel="stylesheet" type="text/css" href="<?= $theme->url("css/fix-ie.css") ?>"
- media="screen,print,projection" />
- <![endif]-->
- <script src="<?= url::file("lib/jquery.js") ?>" type="text/javascript"></script>
- <script src="<?= url::file("lib/jquery.form.js") ?>" type="text/javascript"></script>
- <script src="<?= url::file("lib/jquery-ui.js") ?>" type="text/javascript"></script>
- <script src="<?= url::file("lib/gallery.dialog.js") ?>" type="text/javascript"></script>
- <script src="<?= url::file("lib/superfish/js/superfish.js") ?>" type="text/javascript"></script>
- <script src="<?= $theme->url("js/ui.init.js") ?>" type="text/javascript"></script>
- <script>
- $("#gLoginLink").ready(function() {
- $("#gLoginLink").click();
- });
- </script>
</head>
<body>
- <a id="gLoginLink" href="<?= url::site("login/ajax") ?>">Log in</a>
+ <?= user::get_login_form("login/auth_html") ?>
</body>
</html>