summaryrefslogtreecommitdiff
path: root/modules/user
diff options
context:
space:
mode:
Diffstat (limited to 'modules/user')
-rw-r--r--modules/user/config/identity.php (renamed from modules/user/controllers/logout.php)37
-rw-r--r--modules/user/controllers/admin_users.php212
-rw-r--r--modules/user/controllers/login.php82
-rw-r--r--modules/user/controllers/password.php35
-rw-r--r--modules/user/controllers/users.php57
-rw-r--r--modules/user/css/user.css119
-rw-r--r--modules/user/helpers/group.php72
-rw-r--r--modules/user/helpers/user.php265
-rw-r--r--modules/user/helpers/user_event.php29
-rw-r--r--modules/user/helpers/user_installer.php32
-rw-r--r--modules/user/helpers/user_theme.php35
-rw-r--r--modules/user/images/progressImg1.pngbin0 -> 390 bytes
-rw-r--r--modules/user/js/password_strength.js39
-rw-r--r--modules/user/libraries/drivers/IdentityProvider/Gallery.php161
-rw-r--r--modules/user/models/group.php2
-rw-r--r--modules/user/models/user.php6
-rw-r--r--modules/user/module.info7
-rw-r--r--modules/user/tests/No_Direct_ORM_Access_Test.php77
-rw-r--r--modules/user/views/admin_users.html.php179
-rw-r--r--modules/user/views/admin_users_group.html.php20
-rw-r--r--modules/user/views/login.html.php22
-rw-r--r--modules/user/views/login_ajax.html.php44
-rw-r--r--modules/user/views/reset_password.html.php4
-rw-r--r--modules/user/views/user_form.html.php7
-rw-r--r--modules/user/views/user_languages_block.html.php19
25 files changed, 867 insertions, 695 deletions
diff --git a/modules/user/controllers/logout.php b/modules/user/config/identity.php
index 45d397ad..f9f013aa 100644
--- a/modules/user/controllers/logout.php
+++ b/modules/user/config/identity.php
@@ -17,22 +17,21 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
*/
-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)),
- html::anchor("user/$user->id", html::clean($user->name)));
- if ($continue_url = $this->input->get("continue")) {
- $item = url::get_item_from_uri($continue_url);
- if (access::can("view", $item)) {
- // Don't use url::redirect() because it'll call url::site() and munge the continue url.
- header("Location: $continue_url");
- } else {
- url::redirect(item::root()->abs_url());
- }
- }
- }
-} \ No newline at end of file
+/*
+ * @package Identity
+ *
+ * User settings, defined as arrays, or "groups". If no group name is
+ * used when loading the cache library, the group named "default" will be used.
+ *
+ * Each group can be used independently, and multiple groups can be used at once.
+ *
+ * Group Options:
+ * driver - User backend driver. Gallery comes with Gallery user driver.
+ * allow_updates - Flag to indicate that the back end allows updates.
+ * params - Driver parameters, specific to each driver.
+ */
+$config["user"] = array (
+ "driver" => "gallery",
+ "allow_updates" => true,
+ "params" => array(),
+);
diff --git a/modules/user/controllers/admin_users.php b/modules/user/controllers/admin_users.php
index 0b748955..cc2d881e 100644
--- a/modules/user/controllers/admin_users.php
+++ b/modules/user/controllers/admin_users.php
@@ -21,19 +21,22 @@ class Admin_Users_Controller extends Admin_Controller {
public function index() {
$view = new Admin_View("admin.html");
$view->content = new View("admin_users.html");
- $view->content->users = ORM::factory("user")->orderby("name")->find_all();
- $view->content->groups = ORM::factory("group")->orderby("name")->find_all();
+ $view->content->users = ORM::factory("user")
+ ->orderby("name", "ASC")
+ ->find_all();
+ $view->content->groups = ORM::factory("group")
+ ->orderby("name", "ASC")
+ ->find_all();
print $view;
}
public function add_user() {
access::verify_csrf();
- $form = user::get_add_form_admin();
+ $form = $this->_get_user_add_form_admin();
$valid = $form->validate();
$name = $form->add_user->inputs["name"]->value;
- $user = ORM::factory("user")->where("name", $name)->find();
- if ($user->loaded) {
+ if ($user = user::lookup_by_name($name)) {
$form->add_user->inputs["name"]->add_error("in_use", 1);
$valid = false;
}
@@ -60,22 +63,24 @@ class Admin_Users_Controller extends Admin_Controller {
}
public function add_user_form() {
- print user::get_add_form_admin();
+ $v = new View("user_form.html");
+ $v->form = $this->_get_user_add_form_admin();
+ print $v;
}
public function delete_user($id) {
access::verify_csrf();
- if ($id == user::active()->id || $id == user::guest()->id) {
+ if ($id == identity::active_user()->id || $id == user::guest()->id) {
access::forbidden();
}
- $user = ORM::factory("user", $id);
- if (!$user->loaded) {
+ $user = user::lookup($id);
+ if (empty($user)) {
kohana::show_404();
}
- $form = user::get_delete_form_admin($user);
+ $form = $this->_get_user_delete_form_admin($user);
if($form->validate()) {
$name = $user->name;
$user->delete();
@@ -91,31 +96,28 @@ class Admin_Users_Controller extends Admin_Controller {
}
public function delete_user_form($id) {
- $user = ORM::factory("user", $id);
- if (!$user->loaded) {
+ $user = user::lookup($id);
+ if (empty($user)) {
kohana::show_404();
}
- print user::get_delete_form_admin($user);
+ print $this->_get_user_delete_form_admin($user);
}
public function edit_user($id) {
access::verify_csrf();
- $user = ORM::factory("user", $id);
- if (!$user->loaded) {
+ $user = user::lookup($id);
+ if (empty($user)) {
kohana::show_404();
}
- $form = user::get_edit_form_admin($user);
+ $form = $this->_get_user_edit_form_admin($user);
$valid = $form->validate();
if ($valid) {
$new_name = $form->edit_user->inputs["name"]->value;
+ $temp_user = user::lookup_by_name($new_name);
if ($new_name != $user->name &&
- ORM::factory("user")
- ->where("name", $new_name)
- ->where("id !=", $user->id)
- ->find()
- ->loaded) {
+ ($temp_user && $temp_user->id != $user->id)) {
$form->edit_user->inputs["name"]->add_error("in_use", 1);
$valid = false;
} else {
@@ -136,7 +138,7 @@ class Admin_Users_Controller extends Admin_Controller {
}
// An admin can change the admin status for any user but themselves
- if ($user->id != user::active()->id) {
+ if ($user->id != identity::active_user()->id) {
$user->admin = $form->edit_user->admin->checked;
}
$user->save();
@@ -151,50 +153,51 @@ class Admin_Users_Controller extends Admin_Controller {
}
public function edit_user_form($id) {
- $user = ORM::factory("user", $id);
- if (!$user->loaded) {
+ $user = user::lookup($id);
+ if (empty($user)) {
kohana::show_404();
}
- $form = user::get_edit_form_admin($user);
+ $v = new View("user_form.html");
+ $v->form = $this->_get_user_edit_form_admin($user);
// Don't allow the user to control their own admin bit, else you can lock yourself out
- if ($user->id == user::active()->id) {
- $form->edit_user->admin->disabled(1);
+ if ($user->id == identity::active_user()->id) {
+ $v->form->edit_user->admin->disabled(1);
}
- print $form;
+ print $v;
}
public function add_user_to_group($user_id, $group_id) {
access::verify_csrf();
- $group = ORM::factory("group", $group_id);
- $user = ORM::factory("user", $user_id);
+ $group = group::lookup($group_id);
+ $user = user::lookup($user_id);
$group->add($user);
$group->save();
}
public function remove_user_from_group($user_id, $group_id) {
access::verify_csrf();
- $group = ORM::factory("group", $group_id);
- $user = ORM::factory("user", $user_id);
+ $group = group::lookup($group_id);
+ $user = user::lookup($user_id);
$group->remove($user);
$group->save();
}
public function group($group_id) {
$view = new View("admin_users_group.html");
- $view->group = ORM::factory("group", $group_id);
+ $view->group = group::lookup($group_id);
print $view;
}
public function add_group() {
access::verify_csrf();
- $form = group::get_add_form_admin();
+ $form = $this->_get_group_add_form_admin();
$valid = $form->validate();
if ($valid) {
$new_name = $form->add_group->inputs["name"]->value;
- $group = ORM::factory("group")->where("name", $new_name)->find();
- if ($group->loaded) {
+ $group = group::lookup_by_name($new_name);
+ if (!empty($group)) {
$form->add_group->inputs["name"]->add_error("in_use", 1);
$valid = false;
}
@@ -213,18 +216,18 @@ class Admin_Users_Controller extends Admin_Controller {
}
public function add_group_form() {
- print group::get_add_form_admin();
+ print $this->_get_group_add_form_admin();
}
public function delete_group($id) {
access::verify_csrf();
- $group = ORM::factory("group", $id);
- if (!$group->loaded) {
+ $group = group::lookup($id);
+ if (empty($group)) {
kohana::show_404();
}
- $form = group::get_delete_form_admin($group);
+ $form = $this->_get_group_delete_form_admin($group);
if ($form->validate()) {
$name = $group->name;
$group->delete();
@@ -240,27 +243,28 @@ class Admin_Users_Controller extends Admin_Controller {
}
public function delete_group_form($id) {
- $group = ORM::factory("group", $id);
- if (!$group->loaded) {
+ $group = group::lookup($id);
+ if (empty($group)) {
kohana::show_404();
}
- print group::get_delete_form_admin($group);
+
+ print $this->_get_group_delete_form_admin($group);
}
public function edit_group($id) {
access::verify_csrf();
- $group = ORM::factory("group", $id);
- if (!$group->loaded) {
- kohana::show_404();
+ $group = group::lookup($id);
+ if (empty($group)) {
+ kohana::show_404();
}
- $form = group::get_edit_form_admin($group);
+ $form = $this->_get_group_edit_form_admin($group);
$valid = $form->validate();
if ($valid) {
$new_name = $form->edit_group->inputs["name"]->value;
- $group = ORM::factory("group")->where("name", $new_name)->find();
+ $group = group::lookup_by_name($name);
if ($group->loaded) {
$form->edit_group->inputs["name"]->add_error("in_use", 1);
$valid = false;
@@ -282,12 +286,118 @@ class Admin_Users_Controller extends Admin_Controller {
}
public function edit_group_form($id) {
- $group = ORM::factory("group", $id);
- if (!$group->loaded) {
+ $group = group::lookup($id);
+ if (empty($group)) {
kohana::show_404();
}
- print group::get_edit_form_admin($group);
+ print $this->_get_group_edit_form_admin($group);
+ }
+
+ /* User Form Definitions */
+ static function _get_user_edit_form_admin($user) {
+ $form = new Forge(
+ "admin/users/edit_user/$user->id", "", "post", array("id" => "g-edit-user-form"));
+ $group = $form->group("edit_user")->label(t("Edit user"));
+ $group->input("name")->label(t("Username"))->id("g-username")->value($user->name);
+ $group->inputs["name"]->error_messages(
+ "in_use", t("There is already a user with that username"));
+ $group->input("full_name")->label(t("Full name"))->id("g-fullname")->value($user->full_name);
+ self::_add_locale_dropdown($group, $user);
+ $group->password("password")->label(t("Password"))->id("g-password");
+ $group->password("password2")->label(t("Confirm password"))->id("g-password2")
+ ->matches($group->password);
+ $group->input("email")->label(t("Email"))->id("g-email")->value($user->email);
+ $group->input("url")->label(t("URL"))->id("g-url")->value($user->url);
+ $group->checkbox("admin")->label(t("Admin"))->id("g-admin")->checked($user->admin);
+ $form->add_rules_from($user);
+ $minimum_length = module::get_var("user", "mininum_password_length", 5);
+ $form->edit_user->password
+ ->rules($minimum_length ? "length[$minimum_length, 40]" : "length[40]");
+
+ module::event("user_edit_form_admin", $user, $form);
+ $group->submit("")->value(t("Modify User"));
+ return $form;
+ }
+
+ static function _get_user_add_form_admin() {
+ $form = new Forge("admin/users/add_user", "", "post", array("id" => "g-add-user-form"));
+ $group = $form->group("add_user")->label(t("Add user"));
+ $group->input("name")->label(t("Username"))->id("g-username")
+ ->error_messages("in_use", t("There is already a user with that username"));
+ $group->input("full_name")->label(t("Full name"))->id("g-fullname");
+ $group->password("password")->label(t("Password"))->id("g-password");
+ $group->password("password2")->label(t("Confirm password"))->id("g-password2")
+ ->matches($group->password);
+ $group->input("email")->label(t("Email"))->id("g-email");
+ $group->input("url")->label(t("URL"))->id("g-url");
+ self::_add_locale_dropdown($group);
+ $group->checkbox("admin")->label(t("Admin"))->id("g-admin");
+ $form->add_rules_from(ORM::factory("user"));
+
+ $minimum_length = module::get_var("user", "mininum_password_length", 5);
+ $form->add_user->password
+ ->rules($minimum_length ? "required|length[$minimum_length, 40]" : "length[40]");
+
+ module::event("user_add_form_admin", $user, $form);
+ $group->submit("")->value(t("Add User"));
+ return $form;
+ }
+
+ private function _add_locale_dropdown(&$form, $user=null) {
+ $locales = locales::installed();
+ foreach ($locales as $locale => $display_name) {
+ $locales[$locale] = SafeString::of_safe_html($display_name);
+ }
+ if (count($locales) > 1) {
+ // Put "none" at the first position in the array
+ $locales = array_merge(array("" => t("« none »")), $locales);
+ $selected_locale = ($user && $user->locale) ? $user->locale : "";
+ $form->dropdown("locale")
+ ->label(t("Language Preference"))
+ ->options($locales)
+ ->selected($selected_locale);
+ }
+ }
+
+ private function _get_user_delete_form_admin($user) {
+ $form = new Forge("admin/users/delete_user/$user->id", "", "post",
+ array("id" => "g-delete-user-form"));
+ $group = $form->group("delete_user")->label(
+ t("Are you sure you want to delete user %name?", array("name" => $user->name)));
+ $group->submit("")->value(t("Delete user %name", array("name" => $user->name)));
+ return $form;
}
+ /* Group Form Definitions */
+ private function _get_group_edit_form_admin($group) {
+ $form = new Forge("admin/users/edit_group/$group->id", "", "post", array("id" => "g-edit-group-form"));
+ $form_group = $form->group("edit_group")->label(t("Edit group"));
+ $form_group->input("name")->label(t("Name"))->id("g-name")->value($group->name);
+ $form_group->inputs["name"]->error_messages(
+ "in_use", t("There is already a group with that name"));
+ $form_group->submit("")->value(t("Save"));
+ $form->add_rules_from($group);
+ return $form;
+ }
+
+ private function _get_group_add_form_admin() {
+ $form = new Forge("admin/users/add_group", "", "post", array("id" => "g-add-group-form"));
+ $form_group = $form->group("add_group")->label(t("Add group"));
+ $form_group->input("name")->label(t("Name"))->id("g-name");
+ $form_group->inputs["name"]->error_messages(
+ "in_use", t("There is already a group with that name"));
+ $form_group->submit("")->value(t("Add group"));
+ $form->add_rules_from(ORM::factory("group"));
+ return $form;
+ }
+
+ private function _get_group_delete_form_admin($group) {
+ $form = new Forge("admin/users/delete_group/$group->id", "", "post",
+ array("id" => "g-delete-group-form"));
+ $form_group = $form->group("delete_group")->label(
+ t("Are you sure you want to delete group %group_name?", array("group_name" => $group->name)));
+ $form_group->submit("")->value(t("Delete"));
+ return $form;
+ }
}
diff --git a/modules/user/controllers/login.php b/modules/user/controllers/login.php
deleted file mode 100644
index 8bee7db5..00000000
--- a/modules/user/controllers/login.php
+++ /dev/null
@@ -1,82 +0,0 @@
-<?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 Login_Controller extends Controller {
-
- public function ajax() {
- $view = new View("login_ajax.html");
- $view->form = user::get_login_form("login/auth_ajax");
- print $view;
- }
-
- public function auth_ajax() {
- access::verify_csrf();
-
- list ($valid, $form) = $this->_auth("login/auth_ajax");
- if ($valid) {
- print json_encode(
- array("result" => "success"));
- } else {
- print json_encode(
- array("result" => "error",
- "form" => $form->__toString()));
- }
- }
-
- public function html() {
- print user::get_login_form("login/auth_html");
- }
-
- public function auth_html() {
- access::verify_csrf();
-
- list ($valid, $form) = $this->_auth("login/auth_html");
- if ($valid) {
- url::redirect(item::root()->abs_url());
- } else {
- print $form;
- }
- }
-
- private function _auth($url) {
- $form = user::get_login_form($url);
- $valid = $form->validate();
- if ($valid) {
- $user = ORM::factory("user")->where("name", $form->login->inputs["name"]->value)->find();
- if (!$user->loaded || !user::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);
- $valid = false;
- }
- }
-
- if ($valid) {
- user::login($user);
- log::info("user", t("User %name logged in", array("name" => $user->name)));
- }
-
- // Either way, regenerate the session id to avoid session trapping
- Session::instance()->regenerate();
-
- return array($valid, $form);
- }
-} \ No newline at end of file
diff --git a/modules/user/controllers/password.php b/modules/user/controllers/password.php
index 92608dcd..5f36b554 100644
--- a/modules/user/controllers/password.php
+++ b/modules/user/controllers/password.php
@@ -32,10 +32,8 @@ class Password_Controller extends Controller {
if (request::method() == "post") {
$this->_change_password();
} else {
- $user = ORM::factory("user")
- ->where("hash", Input::instance()->get("key"))
- ->find();
- if ($user->loaded) {
+ $user = user::lookup_by_hash(Input::instance()->get("key"));
+ if (!empty($user)) {
print $this->_new_password_form($user->hash);
} else {
throw new Exception("@todo FORBIDDEN", 503);
@@ -48,7 +46,7 @@ class Password_Controller extends Controller {
$valid = $form->validate();
if ($valid) {
- $user = ORM::factory("user")->where("name", $form->reset->inputs["name"]->value)->find();
+ $user = user::lookup_by_name($form->reset->inputs["name"]->value);
if (!$user->loaded || empty($user->email)) {
$form->reset->inputs["name"]->add_error("no_email", 1);
$valid = false;
@@ -85,9 +83,9 @@ class Password_Controller extends Controller {
}
private function _reset_form() {
- $form = new Forge(url::current(true), "", "post", array("id" => "gResetForm"));
+ $form = new Forge(url::current(true), "", "post", array("id" => "g-reset-form"));
$group = $form->group("reset")->label(t("Reset Password"));
- $group->input("name")->label(t("Username"))->id("gName")->class(null)->rules("required");
+ $group->input("name")->label(t("Username"))->id("g-name")->class(null)->rules("required");
$group->inputs["name"]->error_messages("no_email", t("No email, unable to reset password"));
$group->submit("")->value(t("Reset"));
@@ -97,36 +95,35 @@ class Password_Controller extends Controller {
private function _new_password_form($hash=null) {
$template = new Theme_View("page.html", "reset");
- $form = new Forge("password/do_reset", "", "post", array("id" => "gChangePasswordForm"));
+ $form = new Forge("password/do_reset", "", "post", array("id" => "g-change-password-form"));
$group = $form->group("reset")->label(t("Change Password"));
$hidden = $group->hidden("hash");
if (!empty($hash)) {
$hidden->value($hash);
}
- $group->password("password")->label(t("Password"))->id("gPassword")
- ->rules("required|length[1,40]");
- $group->password("password2")->label(t("Confirm Password"))->id("gPassword2")
+ $minimum_length = module::get_var("user", "mininum_password_length", 5);
+ $input_password = $group->password("password")->label(t("Password"))->id("g-password")
+ ->rules($minimum_length ? "required|length[$minimum_length, 40]" : "length[40]");
+ $group->password("password2")->label(t("Confirm Password"))->id("g-password2")
->matches($group->password);
$group->inputs["password2"]->error_messages(
"mistyped", t("The password and the confirm password must match"));
$group->submit("")->value(t("Update"));
- $template->content = $form;
+ $template->content = new View("user_form.html");
+ $template->content->form = $form;
return $template;
}
private function _change_password() {
$view = $this->_new_password_form();
- if ($view->content->validate()) {
- $user = ORM::factory("user")
- ->where("hash", $view->content->reset->hash->value)
- ->find();
-
- if (!$user->loaded) {
+ if ($view->content->form->validate()) {
+ $user = user::lookup_by_hash(Input::instance()->post("hash"));
+ if (empty($user)) {
throw new Exception("@todo FORBIDDEN", 503);
}
- $user->password = $view->content->reset->password->value;
+ $user->password = $view->content->form->reset->password->value;
$user->hash = null;
$user->save();
message::success(t("Password reset successfully"));
diff --git a/modules/user/controllers/users.php b/modules/user/controllers/users.php
index 4ad704f0..ca218393 100644
--- a/modules/user/controllers/users.php
+++ b/modules/user/controllers/users.php
@@ -17,15 +17,15 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
*/
-class Users_Controller extends REST_Controller {
- protected $resource_type = "user";
+class Users_Controller extends Controller {
+ public function update($id) {
+ $user = user::lookup($id);
- public function _update($user) {
- if ($user->guest || $user->id != user::active()->id) {
+ if ($user->guest || $user->id != identity::active_user()->id) {
access::forbidden();
}
- $form = user::get_edit_form($user);
+ $form = $this->_get_edit_form($user);
$valid = $form->validate();
if ($valid) {
$user->full_name = $form->edit_user->full_name->value;
@@ -57,11 +57,52 @@ class Users_Controller extends REST_Controller {
}
}
- public function _form_edit($user) {
- if ($user->guest || $user->id != user::active()->id) {
+ public function form_edit($id) {
+ $user = user::lookup($id);
+ if ($user->guest || $user->id != identity::active_user()->id) {
access::forbidden();
}
- print user::get_edit_form($user);
+ $v = new View("user_form.html");
+ $v->form = $this->_get_edit_form($user);
+ print $v;
+ }
+
+ private function _get_edit_form($user) {
+ $form = new Forge("users/update/$user->id", "", "post", array("id" => "g-edit-user-form"));
+ $group = $form->group("edit_user")->label(t("Edit User: %name", array("name" => $user->name)));
+ $group->input("full_name")->label(t("Full Name"))->id("g-fullname")->value($user->full_name);
+ self::_add_locale_dropdown($group, $user);
+ $group->password("password")->label(t("Password"))->id("g-password");
+ $group->password("password2")->label(t("Confirm Password"))->id("g-password2")
+ ->matches($group->password);
+ $group->input("email")->label(t("Email"))->id("g-email")->value($user->email);
+ $group->input("url")->label(t("URL"))->id("g-url")->value($user->url);
+ $form->add_rules_from($user);
+
+ $minimum_length = module::get_var("user", "mininum_password_length", 5);
+ $form->edit_user->password
+ ->rules($minimum_length ? "length[$minimum_length, 40]" : "length[40]");
+
+ module::event("user_edit_form", $user, $form);
+ $group->submit("")->value(t("Save"));
+ return $form;
+ }
+
+ /** @todo combine with Admin_Users_Controller::_add_locale_dropdown */
+ private function _add_locale_dropdown(&$form, $user=null) {
+ $locales = locales::installed();
+ foreach ($locales as $locale => $display_name) {
+ $locales[$locale] = SafeString::of_safe_html($display_name);
+ }
+ if (count($locales) > 1) {
+ // Put "none" at the first position in the array
+ $locales = array_merge(array("" => t("« none »")), $locales);
+ $selected_locale = ($user && $user->locale) ? $user->locale : "";
+ $form->dropdown("locale")
+ ->label(t("Language Preference"))
+ ->options($locales)
+ ->selected($selected_locale);
+ }
}
}
diff --git a/modules/user/css/user.css b/modules/user/css/user.css
new file mode 100644
index 00000000..084eac31
--- /dev/null
+++ b/modules/user/css/user.css
@@ -0,0 +1,119 @@
+/* User- and group-related form width ~~~~ */
+
+#g-login-form,
+#g-add-user-form
+#g-edit-user-form,
+#g-delete-user-form,
+#g-user-admin {
+ width: 270px;
+}
+
+/* User/group admin ~~~~~~~~~~~~~~~~~~~~~~ */
+
+#g-user-admin {
+ width: auto;
+}
+
+#g-group-admin {
+}
+
+#g-user-admin-list .g-admin {
+ color: #55f;
+ font-weight: bold;
+}
+
+.g-group {
+ display: block;
+ border: 1px solid #999;
+ margin: 0 1em 1em 0;
+ padding: 0;
+ width: 200px;
+}
+
+.g-group h4 {
+ background-color: #eee;
+ border-bottom: 1px dashed #ccc;
+ padding: .5em 0 .5em .5em;
+}
+
+.g-group .g-button {
+ padding: 0;
+}
+
+.g-group .g-member-list,
+.g-group div {
+ height: 180px;
+ margin: 1px;
+ overflow: auto;
+}
+
+.g-group p {
+ margin-top: 1em;
+ padding: .5em;
+ text-align: center;
+}
+
+.g-group .g-user {
+ padding: .2em 0 0 .5em;
+}
+
+.g-group .g-user .g-button {
+ vertical-align: middle;
+}
+
+.g-default-group h4,
+.g-default-group .g-user {
+ color: #999;
+}
+
+.g-group.ui-droppable {
+ padding: 0 !important;
+}
+
+/* Password strength meter ~~~~~~~~~~~~~~~ */
+
+.g-password-strength0 {
+ background: url(../images/progressImg1.png) no-repeat 0 0;
+ width: 138px;
+ height: 7px;
+}
+
+.g-password-strength10 {
+ background-position:0 -7px;
+}
+
+.g-password-strength20 {
+ background-position:0 -14px;
+}
+
+.g-password-strength30 {
+ background-position:0 -21px;
+}
+
+.g-password-strength40 {
+ background-position:0 -28px;
+}
+
+.g-password-strength50 {
+ background-position:0 -35px;
+}
+
+.g-password-strength60 {
+ background-position:0 -42px;
+}
+
+.g-password-strength70 {
+ background-position:0 -49px;
+}
+
+.g-password-strength80 {
+ background-position:0 -56px;
+}
+
+.g-password-strength90 {
+ background-position:0 -63px;
+}
+
+.g-password-strength100 {
+ background-position:0 -70px;
+}
diff --git a/modules/user/helpers/group.php b/modules/user/helpers/group.php
index 04e6efd6..3aaf1b11 100644
--- a/modules/user/helpers/group.php
+++ b/modules/user/helpers/group.php
@@ -28,7 +28,7 @@ class group_Core {
* Create a new group.
*
* @param string $name
- * @return Group_Model
+ * @return Group_Definition the group object
*/
static function create($name) {
$group = ORM::factory("group")->where("name", $name)->find();
@@ -38,14 +38,13 @@ class group_Core {
$group->name = $name;
$group->save();
-
return $group;
}
/**
* The group of all possible visitors. This includes the guest user.
*
- * @return Group_Model
+ * @return Group_Definition the group object
*/
static function everybody() {
return model_cache::get("group", 1);
@@ -54,54 +53,47 @@ class group_Core {
/**
* The group of all logged-in visitors. This does not include guest users.
*
- * @return Group_Model
+ * @return Group_Definition the group object
*/
static function registered_users() {
return model_cache::get("group", 2);
}
/**
+ * Look up a group by id.
+ * @param integer $id the user id
+ * @return Group_Definition the group object, or null if the id was invalid.
+ */
+ static function lookup($id) {
+ return self::_lookup_by_field("id", $id);
+ }
+
+ /**
* Look up a group by name.
* @param integer $id the group name
- * @return Group_Model the group object, or null if the name was invalid.
+ * @return Group_Definition the group object, or null if the name was invalid.
*/
static function lookup_by_name($name) {
- $group = model_cache::get("group", $name, "name");
- if ($group->loaded) {
- return $group;
- }
- return null;
+ return self::_lookup_by_field("name", $name);
}
- static function get_edit_form_admin($group) {
- $form = new Forge("admin/users/edit_group/$group->id", "", "post", array("id" => "gEditGroupForm"));
- $form_group = $form->group("edit_group")->label(t("Edit Group"));
- $form_group->input("name")->label(t("Name"))->id("gName")->value($group->name);
- $form_group->inputs["name"]->error_messages(
- "in_use", t("There is already a group with that name"));
- $form_group->submit("")->value(t("Save"));
- $form->add_rules_from($group);
- return $form;
- }
-
- static function get_add_form_admin() {
- $form = new Forge("admin/users/add_group", "", "post", array("id" => "gAddGroupForm"));
- $form_group = $form->group("add_group")->label(t("Add Group"));
- $form_group->input("name")->label(t("Name"))->id("gName");
- $form_group->inputs["name"]->error_messages(
- "in_use", t("There is already a group with that name"));
- $form_group->submit("")->value(t("Add Group"));
- $group = ORM::factory("group");
- $form->add_rules_from($group);
- return $form;
- }
-
- static function get_delete_form_admin($group) {
- $form = new Forge("admin/users/delete_group/$group->id", "", "post",
- array("id" => "gDeleteGroupForm"));
- $form_group = $form->group("delete_group")->label(
- t("Are you sure you want to delete group %group_name?", array("group_name" => $group->name)));
- $form_group->submit("")->value(t("Delete"));
- return $form;
+ /**
+ * Search the groups by the field and value.
+ * @param string $field_name column to look up the user by
+ * @param string $value value to match
+ * @return Group_Definition the group object, or null if the name was invalid.
+ */
+ private static function _lookup_by_field($field_name, $value) {
+ try {
+ $user = model_cache::get("group", $value, $field_name);
+ if ($user->loaded) {
+ return $user;
+ }
+ } catch (Exception $e) {
+ if (strpos($e->getMessage(), "MISSING_MODEL") === false) {
+ throw $e;
+ }
+ }
+ return null;
}
}
diff --git a/modules/user/helpers/user.php b/modules/user/helpers/user.php
index b9162b92..f9f16da5 100644
--- a/modules/user/helpers/user.php
+++ b/modules/user/helpers/user.php
@@ -24,153 +24,6 @@
* Note: by design, this class does not do any permission checking.
*/
class user_Core {
- static function get_edit_form($user) {
- $form = new Forge("users/$user->id?_method=put", "", "post", array("id" => "gEditUserForm"));
- $group = $form->group("edit_user")->label(t("Edit User: %name", array("name" => $user->name)));
- $group->input("full_name")->label(t("Full Name"))->id("gFullName")->value($user->full_name);
- self::_add_locale_dropdown($group, $user);
- $group->password("password")->label(t("Password"))->id("gPassword");
- $group->password("password2")->label(t("Confirm Password"))->id("gPassword2")
- ->matches($group->password);
- $group->input("email")->label(t("Email"))->id("gEmail")->value($user->email);
- $group->input("url")->label(t("URL"))->id("gUrl")->value($user->url);
- $form->add_rules_from($user);
-
- module::event("user_edit_form", $user, $form);
- $group->submit("")->value(t("Save"));
- return $form;
- }
-
- static function get_edit_form_admin($user) {
- $form = new Forge(
- "admin/users/edit_user/$user->id", "", "post", array("id" => "gEditUserForm"));
- $group = $form->group("edit_user")->label(t("Edit User"));
- $group->input("name")->label(t("Username"))->id("gUsername")->value($user->name);
- $group->inputs["name"]->error_messages(
- "in_use", t("There is already a user with that username"));
- $group->input("full_name")->label(t("Full Name"))->id("gFullName")->value($user->full_name);
- self::_add_locale_dropdown($group, $user);
- $group->password("password")->label(t("Password"))->id("gPassword");
- $group->password("password2")->label(t("Confirm Password"))->id("gPassword2")
- ->matches($group->password);
- $group->input("email")->label(t("Email"))->id("gEmail")->value($user->email);
- $group->input("url")->label(t("URL"))->id("gUrl")->value($user->url);
- $group->checkbox("admin")->label(t("Admin"))->id("gAdmin")->checked($user->admin);
- $form->add_rules_from($user);
- $form->edit_user->password->rules("-required");
-
- module::event("user_edit_form_admin", $user, $form);
- $group->submit("")->value(t("Modify User"));
- return $form;
- }
-
- static function get_add_form_admin() {
- $form = new Forge("admin/users/add_user", "", "post", array("id" => "gAddUserForm"));
- $group = $form->group("add_user")->label(t("Add User"));
- $group->input("name")->label(t("Username"))->id("gUsername")
- ->error_messages("in_use", t("There is already a user with that username"));
- $group->input("full_name")->label(t("Full Name"))->id("gFullName");
- $group->password("password")->label(t("Password"))->id("gPassword");
- $group->password("password2")->label(t("Confirm Password"))->id("gPassword2")
- ->matches($group->password);
- $group->input("email")->label(t("Email"))->id("gEmail");
- $group->input("url")->label(t("URL"))->id("gUrl");
- self::_add_locale_dropdown($group);
- $group->checkbox("admin")->label(t("Admin"))->id("gAdmin");
- $user = ORM::factory("user");
- $form->add_rules_from($user);
-
- module::event("user_add_form_admin", $user, $form);
- $group->submit("")->value(t("Add User"));
- return $form;
- }
-
- private static function _add_locale_dropdown(&$form, $user=null) {
- $locales = locales::installed();
- foreach ($locales as $locale => $display_name) {
- $locales[$locale] = SafeString::of_safe_html($display_name);
- }
- if (count($locales) > 1) {
- // Put "none" at the first position in the array
- $locales = array_merge(array("" => t("« none »")), $locales);
- $selected_locale = ($user && $user->locale) ? $user->locale : "";
- $form->dropdown("locale")
- ->label(t("Language Preference"))
- ->options($locales)
- ->selected($selected_locale);
- }
- }
-
- static function get_delete_form_admin($user) {
- $form = new Forge("admin/users/delete_user/$user->id", "", "post",
- array("id" => "gDeleteUserForm"));
- $group = $form->group("delete_user")->label(
- t("Are you sure you want to delete user %name?", array("name" => $user->name)));
- $group->submit("")->value(t("Delete user %name", array("name" => $user->name)));
- return $form;
- }
-
- static function get_login_form($url) {
- $form = new Forge($url, "", "post", array("id" => "gLoginForm"));
- $group = $form->group("login")->label(t("Login"));
- $group->input("name")->label(t("Username"))->id("gUsername")->class(null);
- $group->password("password")->label(t("Password"))->id("gPassword")->class(null);
- $group->inputs["name"]->error_messages("invalid_login", t("Invalid name or password"));
- $group->submit("")->value(t("Login"));
- return $form;
- }
-
- /**
- * Make sure that we have a session and group_ids cached in the session.
- */
- static function load_user() {
- $session = Session::instance();
- if (!($user = $session->get("user"))) {
- $session->set("user", $user = user::guest());
- }
-
- // The installer cannot set a user into the session, so it just sets an id which we should
- // upconvert into a user.
- if ($user === 2) {
- $user = model_cache::get("user", 2);
- user::login($user);
- $session->set("user", $user);
- }
-
- if (!$session->get("group_ids")) {
- $ids = array();
- foreach ($user->groups as $group) {
- $ids[] = $group->id;
- }
- $session->set("group_ids", $ids);
- }
- }
-
- /**
- * Return the array of group ids this user belongs to
- *
- * @return array
- */
- static function group_ids() {
- return Session::instance()->get("group_ids", array(1));
- }
-
- /**
- * Return the active user. If there's no active user, return the guest user.
- *
- * @return User_Model
- */
- static function active() {
- // @todo (maybe) cache this object so we're not always doing session lookups.
- $user = Session::instance()->get("user", null);
- if (!isset($user)) {
- // Don't do this as a fallback in the Session::get() call because it can trigger unnecessary
- // work.
- $user = user::guest();
- }
- return $user;
- }
-
/**
* Return the guest user.
*
@@ -183,18 +36,6 @@ class user_Core {
}
/**
- * Change the active user.
- *
- * @return User_Model
- */
- static function set_active($user) {
- $session = Session::instance();
- $session->set("user", $user);
- $session->delete("group_ids");
- self::load_user();
- }
-
- /**
* Create a new user.
*
* @param string $name
@@ -267,91 +108,69 @@ class user_Core {
}
/**
- * Log in as a given user.
- * @param object $user the user object.
- */
- static function login($user) {
- $user->login_count += 1;
- $user->last_login = time();
- $user->save();
-
- user::set_active($user);
- module::event("user_login", $user);
- }
-
- /**
- * Log out the active user and destroy the session.
- * @param object $user the user object.
- */
- static function logout() {
- $user = user::active();
- if (!$user->guest) {
- try {
- Session::instance()->destroy();
- } catch (Exception $e) {
- Kohana::log("error", $e);
- }
- module::event("user_logout", $user);
- }
- }
-
- /**
* Look up a user by id.
* @param integer $id the user id
* @return User_Model the user object, or null if the id was invalid.
*/
static function lookup($id) {
- $user = model_cache::get("user", $id);
- if ($user->loaded) {
- return $user;
- }
- return null;
+ return self::_lookup_user_by_field("id", $id);
}
/**
* Look up a user by name.
- * @param integer $id the user name
+ * @param integer $name the user name
* @return User_Model the user object, or null if the name was invalid.
*/
static function lookup_by_name($name) {
- $user = model_cache::get("user", $name, "name");
- if ($user->loaded) {
- return $user;
- }
- return null;
+ return self::_lookup_user_by_field("name", $name);
}
/**
- * Create a hashed password using md5 plus salt.
- * @param string $password plaintext password
- * @param string $salt (optional) salt or hash containing salt (randomly generated if omitted)
- * @return string hashed password
+ * Look up a user by hash.
+ * @param integer $hash the user hash value
+ * @return User_Model the user object, or null if the name was invalid.
*/
- private static function _md5Salt($password, $salt="") {
- if (empty($salt)) {
- for ($i = 0; $i < 4; $i++) {
- $char = mt_rand(48, 109);
- $char += ($char > 90) ? 13 : ($char > 57) ? 7 : 0;
- $salt .= chr($char);
+ static function lookup_by_hash($hash) {
+ return self::_lookup_user_by_field("hash", $hash);
+ }
+
+ /**
+ * List the users
+ * @param mixed filters (@see Database.php
+ * @return array the user list.
+ */
+ static function get_user_list($filter=array()) {
+ $user = ORM::factory("user");
+
+ foreach($filter as $method => $args) {
+ switch ($method) {
+ case "in":
+ $user->in($args[0], $args[1]);
+ break;
+ default:
+ $user->$method($args);
}
- } else {
- $salt = substr($salt, 0, 4);
}
- return $salt . md5($salt . $password);
+ return $user->find_all();
}
- static function cookie_locale() {
- $cookie_data = Input::instance()->cookie("g_locale");
- $locale = null;
- if ($cookie_data) {
- if (preg_match("/^([a-z]{2,3}(?:_[A-Z]{2})?)$/", trim($cookie_data), $matches)) {
- $requested_locale = $matches[1];
- $installed_locales = locales::installed();
- if (isset($installed_locales[$requested_locale])) {
- $locale = $requested_locale;
- }
+ /**
+ * Look up a user by field value.
+ * @param string search field
+ * @param string search value
+ * @return User_Core the user object, or null if the name was invalid.
+ */
+ private static function _lookup_user_by_field($field_name, $value) {
+ try {
+ $user = model_cache::get("user", $value, $field_name);
+ if ($user->loaded) {
+ return $user;
+ }
+ } catch (Exception $e) {
+ if (strpos($e->getMessage(), "MISSING_MODEL") === false) {
+ throw $e;
}
}
- return $locale;
+ return null;
}
} \ No newline at end of file
diff --git a/modules/user/helpers/user_event.php b/modules/user/helpers/user_event.php
index ede4e515..cf91812e 100644
--- a/modules/user/helpers/user_event.php
+++ b/modules/user/helpers/user_event.php
@@ -17,37 +17,14 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
*/
-class user_event_Core {
- /**
- * Initialization.
- */
- static function gallery_ready() {
- user::load_user();
- self::set_request_locale();
- }
+class user_event_Core {
static function admin_menu($menu, $theme) {
- $menu->add_after("appearance_menu",
- Menu::factory("link")
+ $menu->add_after("appearance_menu", Menu::factory("link")
->id("users_groups")
->label(t("Users/Groups"))
->url(url::site("admin/users")));
- }
- static function set_request_locale() {
- // 1. Check the session specific preference (cookie)
- $locale = user::cookie_locale();
- // 2. Check the user's preference
- if (!$locale) {
- $locale = user::active()->locale;
- }
- // 3. Check the browser's / OS' preference
- if (!$locale) {
- $locale = locales::locale_from_http_request();
- }
- // If we have any preference, override the site's default locale
- if ($locale) {
- I18n::instance()->locale($locale);
- }
+ return $menu;
}
}
diff --git a/modules/user/helpers/user_installer.php b/modules/user/helpers/user_installer.php
index 8ef4f13d..0cba502f 100644
--- a/modules/user/helpers/user_installer.php
+++ b/modules/user/helpers/user_installer.php
@@ -70,9 +70,18 @@ class user_installer {
$admin->admin = true;
$admin->save();
- // Let the admin own everything
- $db->update("items", array("owner_id" => $admin->id), array("owner_id" => "IS NULL"));
- module::set_version("user", 1);
+ $current_provider = module::get_var("gallery", "identity_provider");
+ if (empty($current_provider)) {
+ // If there is no provider defined then we are doing an initial install
+ // so we need to set the provider and make the administrator own everything
+ // If the installer is called and there is an identity provider, then we
+ // are switching identity providers and and the event handlers will do the
+ // right things
+ module::set_var("gallery", "identity_provider", "user");
+
+ // Let the admin own everything
+ $db->query("update {items} set owner_id = {$admin->id}");
+ }
$root = ORM::factory("item", 1);
access::allow($everybody, "view", $root);
@@ -80,6 +89,18 @@ class user_installer {
access::allow($registered, "view", $root);
access::allow($registered, "view_full", $root);
+
+ module::set_var("user", "mininum_password_length", 5);
+
+ module::set_version("user", 2);
+ }
+
+ static function upgrade($version) {
+ if ($version == 1) {
+ module::set_var("user", "mininum_password_length", 5);
+
+ module::set_version("user", $version = 2);
+ }
}
static function uninstall() {
@@ -92,11 +113,6 @@ class user_installer {
$group->delete();
}
- try {
- Session::instance()->destroy();
- } catch (Exception $e) {
- // We don't care if there was a problem destroying the session.
- }
$db = Database::instance();
$db->query("DROP TABLE IF EXISTS {users};");
$db->query("DROP TABLE IF EXISTS {groups};");
diff --git a/modules/user/helpers/user_theme.php b/modules/user/helpers/user_theme.php
index 098d87fd..31e2e8c0 100644
--- a/modules/user/helpers/user_theme.php
+++ b/modules/user/helpers/user_theme.php
@@ -19,35 +19,12 @@
*/
class user_theme_Core {
static function head($theme) {
- if (count(locales::installed())) {
- // Needed by the languages block
- $theme->script("jquery.cookie.js");
- }
- return "";
+ $theme->css("user.css");
+ $theme->script("password_strength.js");
}
- static function header_top($theme) {
- if ($theme->page_type != "login") {
- $view = new View("login.html");
- $view->user = user::active();
- return $view->render();
- }
+ static function admin_head($theme) {
+ $theme->css("user.css");
+ $theme->script("password_strength.js");
}
-
- static function sidebar_blocks($theme) {
- $locales = locales::installed();
- foreach ($locales as $locale => $display_name) {
- $locales[$locale] = SafeString::of_safe_html($display_name);
- }
- if (count($locales) > 1) {
- $block = new Block();
- $block->css_id = "gUserLanguageBlock";
- $block->title = t("Language Preference");
- $block->content = new View("user_languages_block.html");
- $block->content->installed_locales =
- array_merge(array("" => t("« none »")), $locales);
- $block->content->selected = (string) user::cookie_locale();
- return $block;
- }
- }
-}
+} \ No newline at end of file
diff --git a/modules/user/images/progressImg1.png b/modules/user/images/progressImg1.png
new file mode 100644
index 00000000..a9093647
--- /dev/null
+++ b/modules/user/images/progressImg1.png
Binary files differ
diff --git a/modules/user/js/password_strength.js b/modules/user/js/password_strength.js
new file mode 100644
index 00000000..2442b8de
--- /dev/null
+++ b/modules/user/js/password_strength.js
@@ -0,0 +1,39 @@
+(function($) {
+ // Based on the Password Strength Indictor By Benjamin Sterling
+ // http://benjaminsterling.com/password-strength-indicator-and-generator/
+ $.widget("ui.user_password_strength", {
+ _init: function() {
+ var self = this;
+ $(this.element).keyup(function() {
+ var strength = self.calculateStrength (this.value);
+ var index = Math.min(Math.floor( strength / 10 ), 10);
+ $("#g-password-gauge")
+ .removeAttr('class')
+ .addClass( "g-password-strength0" )
+ .addClass( self.options.classes[ index ] );
+ }).after("<div id='g-password-gauge' class='g-password-strength0'></div>");
+ },
+
+ calculateStrength: function(value) {
+ // Factor in the length of the password
+ var strength = Math.min(5, value.length) * 10 - 20;
+ // Factor in the number of numbers
+ strength += Math.min(3, value.length - value.replace(/[0-9]/g,"").length) * 10;
+ // Factor in the number of non word characters
+ strength += Math.min(3, value.length - value.replace(/\W/g,"").length) * 15;
+ // Factor in the number of Upper case letters
+ strength += Math.min(3, value.length - value.replace(/[A-Z]/g,"").length) * 10;
+
+ // Normalizxe between 0 and 100
+ return Math.max(0, Math.min(100, strength));
+ }
+ });
+ $.extend($.ui.user_password_strength, {
+ defaults: {
+ classes : ['g-password-strength10', 'g-password-strength20', 'g-password-strength30',
+ 'g-password-strength40', 'g-password-strength50', 'g-password-strength60',
+ 'g-password-strength70',' g-password-strength80',' g-password-strength90',
+ 'g-password-strength100']
+ }
+ });
+ })(jQuery);
diff --git a/modules/user/libraries/drivers/IdentityProvider/Gallery.php b/modules/user/libraries/drivers/IdentityProvider/Gallery.php
new file mode 100644
index 00000000..f02c53a2
--- /dev/null
+++ b/modules/user/libraries/drivers/IdentityProvider/Gallery.php
@@ -0,0 +1,161 @@
+<?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.
+ */
+/*
+ * Based on the Cache_Sqlite_Driver developed by the Kohana Team
+ */
+class IdentityProvider_Gallery_Driver implements IdentityProvider_Driver {
+ /**
+ * @see IdentityProvider_Driver::guest.
+ */
+ public function guest() {
+ return user::guest();
+ }
+
+ /**
+ * @see IdentityProvider_Driver::guest.
+ */
+ public function admin_user() {
+ return self::lookup_user(2);
+ }
+
+ /**
+ * @see IdentityProvider_Driver::create_user.
+ */
+ public function create_user($name, $full_name, $password) {
+ return user::create($name, $full_name, $password);
+ }
+
+ /**
+ * @see IdentityProvider_Driver::is_correct_password.
+ */
+ public function is_correct_password($user, $password) {
+ $valid = $user->password;
+
+ // Try phpass first, since that's what we generate.
+ if (strlen($valid) == 34) {
+ require_once(MODPATH . "user/lib/PasswordHash.php");
+ $hashGenerator = new PasswordHash(10, true);
+ return $hashGenerator->CheckPassword($password, $valid);
+ }
+
+ $salt = substr($valid, 0, 4);
+ // Support both old (G1 thru 1.4.0; G2 thru alpha-4) and new password schemes:
+ $guess = (strlen($valid) == 32) ? md5($password) : ($salt . md5($salt . $password));
+ if (!strcmp($guess, $valid)) {
+ return true;
+ }
+
+ // Passwords with <&"> created by G2 prior to 2.1 were hashed with entities
+ $sanitizedPassword = html::specialchars($password, false);
+ $guess = (strlen($valid) == 32) ? md5($sanitizedPassword)
+ : ($salt . md5($salt . $sanitizedPassword));
+ if (!strcmp($guess, $valid)) {
+ return true;
+ }
+
+ return false;
+ }
+
+ /**
+ * @see IdentityProvider_Driver::lookup_user.
+ */
+ public function lookup_user($id) {
+ return user::lookup($id);
+ }
+
+ /**
+ * @see IdentityProvider_Driver::lookup_user_by_name.
+ */
+ public function lookup_user_by_name($name) {
+ return user::lookup_by_name($name);
+ }
+
+ /**
+ * @see IdentityProvider_Driver::create_group.
+ */
+ public function create_group($name) {
+ return group::create($name);
+ }
+
+ /**
+ * @see IdentityProvider_Driver::everybody.
+ */
+ public function everybody() {
+ return group::everybody();
+ }
+
+ /**
+ * @see IdentityProvider_Driver::registered_users.
+ */
+ public function registered_users() {
+ return group::registered_users();
+ }
+
+ /**
+ * @see IdentityProvider_Driver::lookup_group.
+ */
+ public function lookup_group($id) {
+ return group::lookup($id);
+ }
+
+ /**
+ * @see IdentityProvider_Driver::lookup_group_by_name.
+ */
+ public function lookup_group_by_name($name) {
+ return group::lookup_by_name($name);
+ }
+
+ /**
+ * @see IdentityProvider_Driver::get_user_list.
+ */
+ public function get_user_list($ids) {
+ return ORM::factory("user")
+ ->in("id", $ids)
+ ->find_all()
+ ->as_array();
+ }
+
+ /**
+ * @see IdentityProvider_Driver::groups.
+ */
+ public function groups() {
+ return ORM::factory("group")->find_all();
+ }
+
+ /**
+ * @see IdentityProvider_Driver::add_user_to_group.
+ */
+ static function add_user_to_group($user, $group_id) {
+ $group = self::lookup_group($group_id);
+
+ $group->add($user);
+ $group->save();
+ }
+
+ /**
+ * @see IdentityProvider_Driver::remove_user_to_group.
+ */
+ static function remove_user_from_group($user, $group_id) {
+ $group = self::lookup_group_by_name($group_id);
+ $group->remove($user);
+ $group->save();
+ }
+} // End Identity Gallery Driver
+
diff --git a/modules/user/models/group.php b/modules/user/models/group.php
index 8af78012..4432fc69 100644
--- a/modules/user/models/group.php
+++ b/modules/user/models/group.php
@@ -17,7 +17,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
*/
-class Group_Model extends ORM {
+class Group_Model extends ORM implements Group_Definition {
protected $has_and_belongs_to_many = array("users");
var $rules = array(
diff --git a/modules/user/models/user.php b/modules/user/models/user.php
index 55562f34..184ce70a 100644
--- a/modules/user/models/user.php
+++ b/modules/user/models/user.php
@@ -17,11 +17,11 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
*/
-class User_Model extends ORM {
+class User_Model extends ORM implements User_Definition {
protected $has_and_belongs_to_many = array("groups");
var $rules = array(
- "name" => "length[1,32]",
+ "name" => "required|length[1,32]",
"full_name" => "length[0,255]",
"email" => "valid_email|length[1,255]",
"password" => "length[1,40]",
@@ -82,4 +82,4 @@ class User_Model extends ORM {
public function display_name() {
return empty($this->full_name) ? $this->name : $this->full_name;
}
-} \ No newline at end of file
+}
diff --git a/modules/user/module.info b/modules/user/module.info
index 8a9af407..7178f108 100644
--- a/modules/user/module.info
+++ b/modules/user/module.info
@@ -1,3 +1,6 @@
name = "Users and Groups"
-description = "Provides user and group management"
-version = 1
+description = "Gallery 3 user and group management"
+version = 2
+
+; Don't show this module on the module administration screen
+no_module_admin = 1
diff --git a/modules/user/tests/No_Direct_ORM_Access_Test.php b/modules/user/tests/No_Direct_ORM_Access_Test.php
new file mode 100644
index 00000000..440321fa
--- /dev/null
+++ b/modules/user/tests/No_Direct_ORM_Access_Test.php
@@ -0,0 +1,77 @@
+<?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.
+ */
+require_once(MODPATH . "gallery/tests/Gallery_Filters.php");
+
+class No_Direct_ORM_Access_Test extends Unit_Test_Case {
+ public function no_access_to_users_table_test() {
+ $dir = new UserModuleFilterIterator(
+ new PhpCodeFilterIterator(
+ new GalleryCodeFilterIterator(
+ new RecursiveIteratorIterator(
+ new RecursiveDirectoryIterator(DOCROOT)))));
+ $errors = array();
+ foreach ($dir as $file) {
+ //if (basename(dirname($file)) == "helpers") {
+ $file_as_string = file_get_contents($file);
+ if (preg_match("/ORM::factory\\(\"user\"/", $file_as_string)) {
+ foreach (split("\n", $file_as_string) as $l => $line) {
+ if (preg_match('/ORM::factory\\(\"user\"/', $line)) {
+ $errors[] = "$file($l) => $line";
+ }
+ }
+ }
+ $file_as_string = null;
+ }
+ if ($errors) {
+ $this->assert_false(true, "Direct access to the users table found:\n" . join("\n", $errors));
+ }
+ }
+
+ public function no_access_to_groups_table_test() {
+ $dir = new UserModuleFilterIterator(
+ new PhpCodeFilterIterator(
+ new GalleryCodeFilterIterator(
+ new RecursiveIteratorIterator(
+ new RecursiveDirectoryIterator(DOCROOT)))));
+ $errors = array();
+ foreach ($dir as $file) {
+ $file_as_string = file_get_contents($file);
+ if (preg_match("/ORM::factory\\(\"group\"/", $file_as_string)) {
+ foreach (split("\n", $file_as_string) as $l => $line) {
+ if (preg_match('/ORM::factory\\(\"group\"/', $line)) {
+ $errors[] = "$file($l) => $line";
+ }
+ }
+ }
+ $file_as_string = null;
+ }
+ if ($errors) {
+ $this->assert_false(true, "Direct access to the groups table found:\n" . join("\n", $errors));
+ }
+ }
+
+}
+
+class UserModuleFilterIterator extends FilterIterator {
+ public function accept() {
+ $path_name = $this->getInnerIterator()->getPathName();
+ return strpos($path_name, "/modules/user") === false;
+ }
+}
diff --git a/modules/user/views/admin_users.html.php b/modules/user/views/admin_users.html.php
index c065e4b1..45d04916 100644
--- a/modules/user/views/admin_users.html.php
+++ b/modules/user/views/admin_users.html.php
@@ -2,15 +2,15 @@
<script type="text/javascript">
var add_user_to_group_url = "<?= url::site("admin/users/add_user_to_group/__USERID__/__GROUPID__?csrf=$csrf") ?>";
$(document).ready(function(){
- $("#gUserAdminList .core-info").draggable({
+ $("#g-user-admin-list .g-core-info").draggable({
helper: "clone"
});
- $("#gGroupAdmin .gGroup").droppable({
- accept: ".core-info",
- hoverClass: "gSelected",
+ $("#g-group-admin .g-group").droppable({
+ accept: ".g-core-info",
+ hoverClass: "g-selected",
drop: function(ev, ui) {
- var user_id = $(ui.draggable).attr("id").replace("user-", "");
- var group_id = $(this).attr("id").replace("group-", "");
+ var user_id = $(ui.draggable).attr("id").replace("g-user-", "");
+ var group_id = $(this).attr("id").replace("g-group-", "");
$.get(add_user_to_group_url.replace("__USERID__", user_id).replace("__GROUPID__", group_id),
{},
function() {
@@ -18,8 +18,8 @@
});
}
});
- $("#group-1").droppable("destroy");
- $("#group-2").droppable("destroy");
+ $("#g-group-1").droppable("destroy");
+ $("#g-group-2").droppable("destroy");
});
var reload_group = function(group_id) {
@@ -27,8 +27,8 @@
$.get(reload_group_url.replace("__GROUPID__", group_id),
{},
function(data) {
- $("#group-" + group_id).html(data);
- $("#group-" + group_id + " .gDialogLink").gallery_dialog();
+ $("#g-group-" + group_id).html(data);
+ $("#g-group-" + group_id + " .g-dialog-link").gallery_dialog();
});
}
@@ -41,88 +41,93 @@
});
}
</script>
-<div class="gBlock">
- <a href="<?= url::site("admin/users/add_user_form") ?>"
- class="gDialogLink gButtonLink right ui-icon-left ui-state-default ui-corner-all"
- title="<?= t("Create a new user")->for_html_attr() ?>">
- <span class="ui-icon ui-icon-circle-plus"></span>
- <?= t("Add a new user") ?>
- </a>
- <h2>
- <?= t("User Admin") ?>
- </h2>
+<div class="g-block">
+ <h1> <?= t("Users and groups") ?> </h1>
- <div class="gBlockContent">
- <table id="gUserAdminList">
- <tr>
- <th><?= t("Username") ?></th>
- <th><?= t("Full name") ?></th>
- <th><?= t("Email") ?></th>
- <th><?= t("Last login") ?></th>
- <th><?= t("Actions") ?></th>
- </tr>
+ <div class="g-block-content">
- <? foreach ($users as $i => $user): ?>
- <tr id="gUser-<?= $user->id ?>" class="<?= text::alternate("gOddRow", "gEvenRow") ?> user <?= $user->admin ? "admin" : "" ?>">
- <td id="user-<?= $user->id ?>" class="core-info gDraggable">
- <img src="<?= $user->avatar_url(20, $theme->url("images/avatar.jpg", true)) ?>"
- title="<?= t("Drag user onto group below to add as a new member")->for_html_attr() ?>"
- alt="<?= html::clean_attribute($user->name) ?>"
- width="20"
- height="20" />
- <?= html::clean($user->name) ?>
- </td>
- <td>
- <?= html::clean($user->full_name) ?>
- </td>
- <td>
- <?= html::clean($user->email) ?>
- </td>
- <td>
- <?= ($user->last_login == 0) ? "" : gallery::date($user->last_login) ?>
- </td>
- <td class="gActions">
- <a href="<?= url::site("admin/users/edit_user_form/$user->id") ?>"
- open_text="<?= t("close") ?>"
- class="gPanelLink gButtonLink ui-state-default ui-corner-all ui-icon-left">
- <span class="ui-icon ui-icon-pencil"></span><span class="gButtonText"><?= t("edit") ?></span></a>
- <? if (user::active()->id != $user->id && !$user->guest): ?>
- <a href="<?= url::site("admin/users/delete_user_form/$user->id") ?>"
- class="gDialogLink gButtonLink ui-state-default ui-corner-all ui-icon-left">
- <span class="ui-icon ui-icon-trash"></span><?= t("delete") ?></a>
- <? else: ?>
- <span title="<?= t("This user cannot be deleted")->for_html_attr() ?>"
- class="gButtonLink ui-state-disabled ui-corner-all ui-icon-left">
- <span class="ui-icon ui-icon-trash"></span><?= t("delete") ?></span>
- <? endif ?>
- </td>
- </tr>
- <? endforeach ?>
- </table>
- </div>
-</div>
+ <div id="g-user-admin" class="g-block">
+ <a href="<?= url::site("admin/users/add_user_form") ?>"
+ class="g-dialog-link g-button g-right ui-icon-left ui-state-default ui-corner-all"
+ title="<?= t("Create a new user")->for_html_attr() ?>">
+ <span class="ui-icon ui-icon-circle-plus"></span>
+ <?= t("Add a new user") ?>
+ </a>
+
+ <h2> <?= t("Users") ?> </h2>
+
+ <div class="g-block-content">
+ <table id="g-user-admin-list">
+ <tr>
+ <th><?= t("Username") ?></th>
+ <th><?= t("Full name") ?></th>
+ <th><?= t("Email") ?></th>
+ <th><?= t("Last login") ?></th>
+ <th><?= t("Actions") ?></th>
+ </tr>
+
+ <? foreach ($users as $i => $user): ?>
+ <tr id="g-user-<?= $user->id ?>" class="<?= text::alternate("g-odd", "g-even") ?> g-user <?= $user->admin ? "g-admin" : "" ?>">
+ <td id="g-user-<?= $user->id ?>" class="g-core-info g-draggable">
+ <img src="<?= $user->avatar_url(20, $theme->url("images/avatar.jpg", true)) ?>"
+ title="<?= t("Drag user onto a group to add as a new member")->for_html_attr() ?>"
+ alt="<?= html::clean_attribute($user->name) ?>"
+ width="20"
+ height="20" />
+ <?= html::clean($user->name) ?>
+ </td>
+ <td>
+ <?= html::clean($user->full_name) ?>
+ </td>
+ <td>
+ <?= html::clean($user->email) ?>
+ </td>
+ <td>
+ <?= ($user->last_login == 0) ? "" : gallery::date($user->last_login) ?>
+ </td>
+ <td>
+ <a href="<?= url::site("admin/users/edit_user_form/$user->id") ?>"
+ open_text="<?= t("Close") ?>"
+ class="g-panel-link g-button ui-state-default ui-corner-all ui-icon-left">
+ <span class="ui-icon ui-icon-pencil"></span><span class="g-button-text"><?= t("Edit") ?></span></a>
+ <? if (identity::active_user()->id != $user->id && !$user->guest): ?>
+ <a href="<?= url::site("admin/users/delete_user_form/$user->id") ?>"
+ class="g-dialog-link g-button ui-state-default ui-corner-all ui-icon-left">
+ <span class="ui-icon ui-icon-trash"></span><?= t("Delete") ?></a>
+ <? else: ?>
+ <span title="<?= t("This user cannot be deleted")->for_html_attr() ?>"
+ class="g-button ui-state-disabled ui-corner-all ui-icon-left">
+ <span class="ui-icon ui-icon-trash"></span><?= t("Delete") ?></span>
+ <? endif ?>
+ </td>
+ </tr>
+ <? endforeach ?>
+ </table>
+ </div>
+ </div>
+
+ <div id="g-group-admin" class="g-block g-right ui-helper-clearfix">
+ <a href="<?= url::site("admin/users/add_group_form") ?>"
+ class="g-dialog-link g-button g-right ui-icon-left ui-state-default ui-corner-all"
+ title="<?= t("Create a new group")->for_html_attr() ?>">
+ <span class="ui-icon ui-icon-circle-plus"></span>
+ <?= t("Add a new group") ?>
+ </a>
-<div id="gGroupAdmin" class="gBlock">
- <a href="<?= url::site("admin/users/add_group_form") ?>"
- class="gDialogLink gButtonLink right ui-icon-left ui-state-default ui-corner-all"
- title="<?= t("Create a new group")->for_html_attr() ?>">
- <span class="ui-icon ui-icon-circle-plus"></span>
- <?= t("Add a new group") ?>
- </a>
+ <h2> <?= t("Groups") ?> </h2>
- <h2>
- <?= t("Group Admin") ?>
- </h2>
+ <div class="g-block-content">
+ <ul>
+ <? foreach ($groups as $i => $group): ?>
+ <li id="g-group-<?= $group->id ?>" class="g-group g-left <?= ($group->special ? "g-default-group" : "") ?>" />
+ <? $v = new View("admin_users_group.html"); $v->group = $group; ?>
+ <?= $v ?>
+ </li>
+ <? endforeach ?>
+ </ul>
+ </div>
+ </div>
- <div class="gBlockContent">
- <ul>
- <? foreach ($groups as $i => $group): ?>
- <li id="group-<?= $group->id ?>" class="gGroup <?= ($group->special ? "gDefaultGroup" : "") ?>" />
- <? $v = new View("admin_users_group.html"); $v->group = $group; ?>
- <?= $v ?>
- </li>
- <? endforeach ?>
- </ul>
</div>
</div>
diff --git a/modules/user/views/admin_users_group.html.php b/modules/user/views/admin_users_group.html.php
index 476e0817..b7e573b3 100644
--- a/modules/user/views/admin_users_group.html.php
+++ b/modules/user/views/admin_users_group.html.php
@@ -4,26 +4,26 @@
<? if (!$group->special): ?>
<a href="<?= url::site("admin/users/delete_group_form/$group->id") ?>"
title="<?= t("Delete the %name group", array("name" => $group->name))->for_html_attr() ?>"
- class="gDialogLink gButtonLink ui-state-default ui-corner-all">
- <span class="ui-icon ui-icon-trash"><?= t("delete") ?></span></a>
+ class="g-dialog-link g-button g-right">
+ <span class="ui-icon ui-icon-trash"><?= t("Delete") ?></span></a>
<? else: ?>
<a title="<?= t("This default group cannot be deleted")->for_html_attr() ?>"
- class="gDialogLink gButtonLink ui-state-disabled ui-corner-all ui-icon-left">
- <span class="ui-icon ui-icon-trash"><?= t("delete") ?></span></a>
+ class="g-button g-right ui-state-disabled ui-icon-left">
+ <span class="ui-icon ui-icon-trash"><?= t("Delete") ?></span></a>
<? endif ?>
</h4>
<? if ($group->users->count() > 0): ?>
-<ul>
+<ul class="g-member-list">
<? foreach ($group->users as $i => $user): ?>
- <li class="gUser">
+ <li class="g-user">
<?= html::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"
+ class="g-button g-right ui-state-default ui-corner-all ui-icon-left"
title="<?= t("Remove %user from %group group",
array("user" => $user->name, "group" => $group->name))->for_html_attr() ?>">
- <span class="ui-icon ui-icon-closethick"><?= t("remove") ?></span>
+ <span class="ui-icon ui-icon-closethick"><?= t("Remove") ?></span>
</a>
<? endif ?>
</li>
@@ -31,8 +31,8 @@
</ul>
<? else: ?>
<div>
- <p>
- <?= t("Drag &amp; drop users from the User Admin above into this group box to add group members.") ?>
+ <p class="ui-state-disabled">
+ <?= t("Drag &amp; drop users from the \"Users\" list onto this group to add group members.") ?>
</p>
</div>
<? endif ?>
diff --git a/modules/user/views/login.html.php b/modules/user/views/login.html.php
deleted file mode 100644
index bb670d51..00000000
--- a/modules/user/views/login.html.php
+++ /dev/null
@@ -1,22 +0,0 @@
-<?php defined("SYSPATH") or die("No direct script access.") ?>
-<ul id="gLoginMenu">
- <? if ($user->guest): ?>
- <li class="first">
- <a href="<?= url::site("login/ajax") ?>"
- title="<?= t("Login to Gallery")->for_html_attr() ?>"
- id="gLoginLink"><?= t("Login") ?></a>
- </li>
- <? else: ?>
- <li class="first">
- <?= t('Logged in as %name', array('name' => html::mark_clean(
- '<a href="' . url::site("form/edit/users/{$user->id}") .
- '" title="' . t("Edit Your Profile")->for_html_attr() .
- '" id="gUserProfileLink" class="gDialogLink">' .
- html::clean($user->display_name()) . '</a>'))) ?>
- </li>
- <li>
- <a href="<?= url::site("logout?csrf=$csrf&amp;continue=" . urlencode(url::current(true))) ?>"
- id="gLogoutLink"><?= t("Logout") ?></a>
- </li>
- <? endif ?>
-</ul>
diff --git a/modules/user/views/login_ajax.html.php b/modules/user/views/login_ajax.html.php
deleted file mode 100644
index 56bc1cbd..00000000
--- a/modules/user/views/login_ajax.html.php
+++ /dev/null
@@ -1,44 +0,0 @@
-<?php defined("SYSPATH") or die("No direct script access.") ?>
-<script type="text/javascript">
- $("#gLoginForm").ready(function() {
- $("#gForgotPasswordLink").click(function() {
- $.ajax({
- url: "<?= url::site("password/reset") ?>",
- success: function(data) {
- $("div#gLoginView").html(data);
- $("#ui-dialog-title-gDialog").html(<?= t("Reset Password")->for_js() ?>);
- ajaxify_login_reset_form();
- }
- });
- });
- });
-
- function ajaxify_login_reset_form() {
- $("#gLoginView form").ajaxForm({
- dataType: "json",
- success: function(data) {
- if (data.form) {
- $("#gLoginView form").replaceWith(data.form);
- ajaxify_login_reset_form();
- }
- if (data.result == "success") {
- $("#gDialog").dialog("close");
- window.location.reload();
- }
-
- }
- });
- };
-</script>
-<div id="gLoginView">
- <ul>
- <li>
- <div id="gLoginViewForm">
- <?= $form ?>
- </div>
- </li>
- <li>
- <a href="#" id="gForgotPasswordLink"><?= t("Forgot Your Password?") ?></a>
- </li>
- </ul>
-</div>
diff --git a/modules/user/views/reset_password.html.php b/modules/user/views/reset_password.html.php
index 92ca4917..3afca881 100644
--- a/modules/user/views/reset_password.html.php
+++ b/modules/user/views/reset_password.html.php
@@ -1,10 +1,10 @@
<?php defined("SYSPATH") or die("No direct script access.") ?>
<html>
<head>
- <title><?= t("Password Reset Request") ?> </title>
+ <title><?= t("Password reset request") ?> </title>
</head>
<body>
- <h2><?= t("Password Reset Request") ?> </h2>
+ <h2><?= t("Password reset request") ?> </h2>
<p>
<?= t("Hello, %name,", array("name" => $user->full_name ? $user->full_name : $user->name)) ?>
</p>
diff --git a/modules/user/views/user_form.html.php b/modules/user/views/user_form.html.php
new file mode 100644
index 00000000..039ae8a5
--- /dev/null
+++ b/modules/user/views/user_form.html.php
@@ -0,0 +1,7 @@
+<?php defined("SYSPATH") or die("No direct script access.") ?>
+<script type="text/javascript">
+ $("form").ready(function(){
+ $('input[name="password"]').user_password_strength();
+ });
+</script>
+<?= $form ?>
diff --git a/modules/user/views/user_languages_block.html.php b/modules/user/views/user_languages_block.html.php
deleted file mode 100644
index b5ae674c..00000000
--- a/modules/user/views/user_languages_block.html.php
+++ /dev/null
@@ -1,19 +0,0 @@
-<?php defined("SYSPATH") or die("No direct script access.") ?>
-<?= form::dropdown("gSelectSessionLocale", $installed_locales, $selected) ?>
-<script type="text/javascript">
- $("#gSelectSessionLocale").change(function() {
- var old_locale_preference = <?= html::js_string($selected) ?>;
- var locale = $(this).val();
- if (old_locale_preference == locale) {
- return;
- }
-
- var expires = -1;
- if (locale) {
- expires = 365;
- }
- $.cookie("g_locale", locale, {"expires": expires, "path": "/"});
- window.location.reload(true);
- });
-</script>
-