From bf085a1a176f32546f86988049e0c3f809842ce7 Mon Sep 17 00:00:00 2001 From: Bharat Mediratta Date: Sat, 16 Jan 2010 00:51:31 -0800 Subject: Convert photo uploading over to the new model based validation approach. - Rearrange Simple_Uploader_Controller::add_photo() to validate the form early in the process, and switch to using model based validation. - Move thumbnail generation into gallery_event::item_created() so that it's decoupled from the model. - Delete photo::create() and move all of its logic into Item_Model::save(). - Add Item_Model::$data_file to track the data file associated with new movies and photos. - Do some cleanup on the validation callbacks -- it turns out the 2nd argument is the field name not the value. --- modules/gallery/helpers/gallery_event.php | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) (limited to 'modules/gallery/helpers/gallery_event.php') diff --git a/modules/gallery/helpers/gallery_event.php b/modules/gallery/helpers/gallery_event.php index 679d65c2..9452e855 100644 --- a/modules/gallery/helpers/gallery_event.php +++ b/modules/gallery/helpers/gallery_event.php @@ -73,6 +73,22 @@ class gallery_event_Core { static function item_created($item) { access::add_item($item); + + if ($item->is_photo() || $item->is_movie()) { + // Build our thumbnail/resizes. + try { + graphics::generate($item); + } catch (Exception $e) { + log::failure("Unable to create a thumbnail for item id {$item->id}"); + Kohana_Log::add("error", $e->getMessage() . "\n" . $e->getTraceAsString()); + } + + // If the parent has no cover item, make this it. + $parent = $item->parent(); + if (access::can("edit", $parent) && $parent->album_cover_item_id == null) { + item::make_album_cover($item); + } + } } static function item_deleted($item) { -- cgit v1.2.3 From b5a6a6a5d5741f592d504b8a444899964101b6b6 Mon Sep 17 00:00:00 2001 From: Bharat Mediratta Date: Sat, 16 Jan 2010 11:44:21 -0800 Subject: Oops, log::failure() doesn't exist. Use log::error(). --- modules/gallery/helpers/gallery_event.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'modules/gallery/helpers/gallery_event.php') diff --git a/modules/gallery/helpers/gallery_event.php b/modules/gallery/helpers/gallery_event.php index 9452e855..db3b34fe 100644 --- a/modules/gallery/helpers/gallery_event.php +++ b/modules/gallery/helpers/gallery_event.php @@ -79,7 +79,9 @@ class gallery_event_Core { try { graphics::generate($item); } catch (Exception $e) { - log::failure("Unable to create a thumbnail for item id {$item->id}"); + log::error("graphics", t("Couldn't create a thumbnail or resize for %item_title", + array("item_title" => $item->title)), + html::anchor($item->abs_url(), t("details"))); Kohana_Log::add("error", $e->getMessage() . "\n" . $e->getTraceAsString()); } -- cgit v1.2.3 From cedbc82dccaf74a983f1f92846735b69391fdf10 Mon Sep 17 00:00:00 2001 From: Tim Almdal Date: Thu, 28 Jan 2010 07:44:58 -0800 Subject: Do all the html::clean|purify calls in the views and not the controller. Also clean the subject line and email message body of the contact user email. --- modules/gallery/controllers/user_profile.php | 4 ++-- modules/gallery/helpers/gallery_event.php | 2 +- modules/gallery/views/user_profile.html.php | 2 +- modules/gallery/views/user_profile_info.html.php | 2 +- modules/rest/views/user_profile_rest.html.php | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) (limited to 'modules/gallery/helpers/gallery_event.php') diff --git a/modules/gallery/controllers/user_profile.php b/modules/gallery/controllers/user_profile.php index a0e6619e..327d2ff1 100644 --- a/modules/gallery/controllers/user_profile.php +++ b/modules/gallery/controllers/user_profile.php @@ -53,11 +53,11 @@ class User_Profile_Controller extends Controller { if ($form->validate()) { Sendmail::factory() ->to($user->email) - ->subject($form->message->subject->value) + ->subject(html::clean($form->message->subject->value)) ->header("Mime-Version", "1.0") ->header("Content-type", "text/html; charset=iso-8859-1") ->reply_to($form->message->reply_to->value) - ->message($form->message->message->value) + ->message(html::purify($form->message->message->value)) ->send(); message::success(t("Sent message to %user_name", array("user_name" => $user->display_name()))); print json_encode(array("result" => "success")); diff --git a/modules/gallery/helpers/gallery_event.php b/modules/gallery/helpers/gallery_event.php index 70c6de4a..9b252f61 100644 --- a/modules/gallery/helpers/gallery_event.php +++ b/modules/gallery/helpers/gallery_event.php @@ -411,7 +411,7 @@ class gallery_event_Core { if ($field == "locale") { $value = locales::display_name($value); } - $v->fields[(string) $label] = html::clean($value); + $v->fields[(string) $label] = $value; } } $data->content[] = (object) array("title" => t("User information"), "view" => $v); diff --git a/modules/gallery/views/user_profile.html.php b/modules/gallery/views/user_profile.html.php index 708b1613..7dc9d13e 100644 --- a/modules/gallery/views/user_profile.html.php +++ b/modules/gallery/views/user_profile.html.php @@ -41,7 +41,7 @@
- +
view ?>
diff --git a/modules/gallery/views/user_profile_info.html.php b/modules/gallery/views/user_profile_info.html.php index 2a2549c8..2f2d68d3 100644 --- a/modules/gallery/views/user_profile_info.html.php +++ b/modules/gallery/views/user_profile_info.html.php @@ -3,7 +3,7 @@ $value): ?> - + diff --git a/modules/rest/views/user_profile_rest.html.php b/modules/rest/views/user_profile_rest.html.php index 3807817e..397afa89 100644 --- a/modules/rest/views/user_profile_rest.html.php +++ b/modules/rest/views/user_profile_rest.html.php @@ -2,7 +2,7 @@
  • -

    :

    +

    :

-- cgit v1.2.3 From c51fe9682075c961972c344f4888a4adceabe3eb Mon Sep 17 00:00:00 2001 From: Tim Almdal Date: Thu, 28 Jan 2010 09:27:27 -0800 Subject: Make the varible for the profile name more descriptive and clean the label --- modules/gallery/helpers/gallery_event.php | 4 ++-- modules/gallery/tests/xss_data.txt | 1 - modules/gallery/views/user_profile_info.html.php | 4 ++-- 3 files changed, 4 insertions(+), 5 deletions(-) (limited to 'modules/gallery/helpers/gallery_event.php') diff --git a/modules/gallery/helpers/gallery_event.php b/modules/gallery/helpers/gallery_event.php index 9b252f61..b3d4daab 100644 --- a/modules/gallery/helpers/gallery_event.php +++ b/modules/gallery/helpers/gallery_event.php @@ -404,14 +404,14 @@ class gallery_event_Core { if (!$data->display_all) { $fields = array("name" => t("Name"), "full_name" => t("Full name"), "url" => "Web site"); } - $v->fields = array(); + $v->user_profile_data = array(); foreach ($fields as $field => $label) { if (!empty($data->user->$field)) { $value = $data->user->$field; if ($field == "locale") { $value = locales::display_name($value); } - $v->fields[(string) $label] = $value; + $v->user_profile_data[(string) $label] = $value; } } $data->content[] = (object) array("title" => t("User information"), "view" => $v); diff --git a/modules/gallery/tests/xss_data.txt b/modules/gallery/tests/xss_data.txt index 04add4c7..663080a0 100644 --- a/modules/gallery/tests/xss_data.txt +++ b/modules/gallery/tests/xss_data.txt @@ -224,7 +224,6 @@ modules/gallery/views/upgrader.html.php 102 DIRTY_ATTR $don modules/gallery/views/user_languages_block.html.php 2 DIRTY form::dropdown("g-select-session-locale",$installed_locales,$selected) modules/gallery/views/user_profile.html.php 35 DIRTY_ATTR $user->avatar_url(40,$theme->url(,true)) modules/gallery/views/user_profile.html.php 46 DIRTY $info->view -modules/gallery/views/user_profile_info.html.php 5 DIRTY $field modules/image_block/views/image_block_block.html.php 3 DIRTY_JS $item->url() modules/image_block/views/image_block_block.html.php 4 DIRTY $item->thumb_img(array("class"=>"g-thumbnail")) modules/info/views/info_block.html.php 22 DIRTY date("M j, Y H:i:s",$item->captured) diff --git a/modules/gallery/views/user_profile_info.html.php b/modules/gallery/views/user_profile_info.html.php index 2f2d68d3..58e134bb 100644 --- a/modules/gallery/views/user_profile_info.html.php +++ b/modules/gallery/views/user_profile_info.html.php @@ -1,8 +1,8 @@ - $value): ?> + $value): ?> - + -- cgit v1.2.3 From 743fbe76965b00087d8e091f742acd61d3a740d0 Mon Sep 17 00:00:00 2001 From: Bharat Mediratta Date: Thu, 28 Jan 2010 23:22:38 -0800 Subject: Add page_type to the rotate and delete context menu items so that the quick menu knows where to send you after the action is done. --- modules/gallery/helpers/gallery_event.php | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'modules/gallery/helpers/gallery_event.php') diff --git a/modules/gallery/helpers/gallery_event.php b/modules/gallery/helpers/gallery_event.php index b3d4daab..80452276 100644 --- a/modules/gallery/helpers/gallery_event.php +++ b/modules/gallery/helpers/gallery_event.php @@ -286,6 +286,7 @@ class gallery_event_Core { ->label(t("Options")) ->css_class("ui-icon-carat-1-n")); + $page_type = $theme->page_type(); if (access::can("edit", $item)) { switch ($item->type) { case "movie": @@ -324,7 +325,7 @@ class gallery_event_Core { ->css_class("ui-icon-rotate-ccw") ->ajax_handler("function(data) { " . "\$.gallery_replace_image(data, \$('$thumb_css_selector')) }") - ->url(url::site("quick/rotate/$item->id/ccw?csrf=$csrf&from_id=$theme_item->id"))) + ->url(url::site("quick/rotate/$item->id/ccw?csrf=$csrf&from_id=$theme_item->id&page_type=$page_type"))) ->append( Menu::factory("ajax_link") ->id("rotate_cw") @@ -332,7 +333,7 @@ class gallery_event_Core { ->css_class("ui-icon-rotate-cw") ->ajax_handler("function(data) { " . "\$.gallery_replace_image(data, \$('$thumb_css_selector')) }") - ->url(url::site("quick/rotate/$item->id/cw?csrf=$csrf&from_id=$theme_item->id"))); + ->url(url::site("quick/rotate/$item->id/cw?csrf=$csrf&from_id=$theme_item->id&page_type=$page_type"))); } // @todo Don't move photos from the photo page; we don't yet have a good way of redirecting @@ -372,7 +373,7 @@ class gallery_event_Core { ->label($delete_title) ->css_class("ui-icon-trash") ->css_id("g-quick-delete") - ->url(url::site("quick/form_delete/$item->id?csrf=$csrf&from_id=$theme_item->id"))); + ->url(url::site("quick/form_delete/$item->id?csrf=$csrf&from_id=$theme_item->id&page_type=$page_type"))); } if ($item->is_album()) { -- cgit v1.2.3 From 2bfcec9620814a6f3d0163a174d7ba90efef369d Mon Sep 17 00:00:00 2001 From: Bharat Mediratta Date: Sat, 30 Jan 2010 19:48:57 -0800 Subject: Prevent brute force login attacks by reducing login attempts to 1 per minute after there have been 5 consecutive failed login attempts. Fix for ticket #589. --- modules/gallery/controllers/login.php | 7 ++--- modules/gallery/helpers/auth.php | 45 ++++++++++++++++++++++++++- modules/gallery/helpers/gallery_event.php | 5 +++ modules/gallery/helpers/gallery_installer.php | 22 ++++++++++++- modules/gallery/models/failed_login.php | 20 ++++++++++++ modules/gallery/module.info | 3 +- 6 files changed, 94 insertions(+), 8 deletions(-) create mode 100644 modules/gallery/models/failed_login.php (limited to 'modules/gallery/helpers/gallery_event.php') diff --git a/modules/gallery/controllers/login.php b/modules/gallery/controllers/login.php index cfe86cfb..1426f0d8 100644 --- a/modules/gallery/controllers/login.php +++ b/modules/gallery/controllers/login.php @@ -62,11 +62,10 @@ class Login_Controller extends Controller { if ($valid) { $user = identity::lookup_user_by_name($form->login->inputs["name"]->value); if (empty($user) || !identity::is_correct_password($user, $form->login->password->value)) { - log::warning( - "user", - t("Failed login for %name", - array("name" => $form->login->inputs["name"]->value))); $form->login->inputs["name"]->add_error("invalid_login", 1); + $name = $form->login->inputs["name"]->value; + log::warning("user", t("Failed login for %name", array("name" => $name))); + module::event("user_login_failed", $name); $valid = false; } } diff --git a/modules/gallery/helpers/auth.php b/modules/gallery/helpers/auth.php index f7d4f7e8..e112f127 100644 --- a/modules/gallery/helpers/auth.php +++ b/modules/gallery/helpers/auth.php @@ -22,7 +22,10 @@ class auth_Core { $form = new Forge($url, "", "post", array("id" => "g-login-form")); $form->set_attr('class', "g-narrow"); $group = $form->group("login")->label(t("Login")); - $group->input("name")->label(t("Username"))->id("g-username")->class(null); + $group->input("name")->label(t("Username"))->id("g-username")->class(null) + ->callback("auth::validate_too_many_failed_logins") + ->error_messages( + "too_many_failed_logins", t("Too many failed login attempts. Try again later")); $group->password("password")->label(t("Password"))->id("g-password")->class(null); $group->inputs["name"]->error_messages("invalid_login", t("Invalid name or password")); $group->submit("")->value(t("Login")); @@ -55,4 +58,44 @@ class auth_Core { array("url" => user_profile::url($user->id), "user_name" => html::clean($user->name)))); } + + /** + * After there have been 5 failed login attempts, any failure leads to getting locked out for a + * minute. + */ + static function validate_too_many_failed_logins($name_input) { + $failed_login = ORM::factory("failed_login") + ->where("name", "=", $name_input->value) + ->find(); + if ($failed_login->loaded() && + $failed_login->count > 5 && + (time() - $failed_login->time < 60)) { + $name_input->add_error("too_many_failed_logins", 1); + } + } + + /** + * Record a failed login for this user + */ + static function record_failed_login($name) { + $failed_login = ORM::factory("failed_login") + ->where("name", "=", $name) + ->find(); + if (!$failed_login->loaded()) { + $failed_login->name = $name; + } + $failed_login->time = time(); + $failed_login->count++; + $failed_login->save(); + } + + /** + * Clear any failed logins for this user + */ + static function record_successful_login($user) { + db::build() + ->delete("failed_logins") + ->where("name", "=", $user->name) + ->execute(); + } } \ No newline at end of file diff --git a/modules/gallery/helpers/gallery_event.php b/modules/gallery/helpers/gallery_event.php index 80452276..6479e2c3 100644 --- a/modules/gallery/helpers/gallery_event.php +++ b/modules/gallery/helpers/gallery_event.php @@ -110,6 +110,11 @@ class gallery_event_Core { graphics::choose_default_toolkit(); module::clear_var("gallery", "choose_default_tookit"); } + auth::record_successful_login($user); + } + + static function user_login_failed($name) { + auth::record_failed_login($name); } static function item_index_data($item, $data) { diff --git a/modules/gallery/helpers/gallery_installer.php b/modules/gallery/helpers/gallery_installer.php index d2378d64..cf701ed4 100644 --- a/modules/gallery/helpers/gallery_installer.php +++ b/modules/gallery/helpers/gallery_installer.php @@ -42,6 +42,14 @@ class gallery_installer { KEY (`tags`)) DEFAULT CHARSET=utf8;"); + $db->query("CREATE TABLE {failed_logins} ( + `id` int(9) NOT NULL auto_increment, + `count` int(9) NOT NULL, + `name` varchar(255) NOT NULL, + `time` int(9) NOT NULL, + PRIMARY KEY (`id`)) + DEFAULT CHARSET=utf8;"); + $db->query("CREATE TABLE {graphics_rules} ( `id` int(9) NOT NULL auto_increment, `active` BOOLEAN default 0, @@ -276,7 +284,7 @@ class gallery_installer { // @todo this string needs to be picked up by l10n_scanner module::set_var("gallery", "credits", "Powered by Gallery %version"); module::set_var("gallery", "simultaneous_upload_limit", 5); - module::set_version("gallery", 22); + module::set_version("gallery", 23); } static function upgrade($version) { @@ -485,6 +493,17 @@ class gallery_installer { } module::set_version("gallery", $version = 23); } + + if ($version = 23) { + $db->query("CREATE TABLE {failed_logins} ( + `id` int(9) NOT NULL auto_increment, + `count` int(9) NOT NULL, + `name` varchar(255) NOT NULL, + `time` int(9) NOT NULL, + PRIMARY KEY (`id`)) + DEFAULT CHARSET=utf8;"); + module::set_version("gallery", $version = 24); + } } static function uninstall() { @@ -493,6 +512,7 @@ class gallery_installer { $db->query("DROP TABLE IF EXISTS {access_intents}"); $db->query("DROP TABLE IF EXISTS {graphics_rules}"); $db->query("DROP TABLE IF EXISTS {incoming_translations}"); + $db->query("DROP TABLE IF EXISTS {failed_logins}"); $db->query("DROP TABLE IF EXISTS {items}"); $db->query("DROP TABLE IF EXISTS {logs}"); $db->query("DROP TABLE IF EXISTS {modules}"); diff --git a/modules/gallery/models/failed_login.php b/modules/gallery/models/failed_login.php new file mode 100644 index 00000000..0b84c295 --- /dev/null +++ b/modules/gallery/models/failed_login.php @@ -0,0 +1,20 @@ +