From 46659e09e7e32568a50722de843f8ea6acc6f55d Mon Sep 17 00:00:00 2001 From: Bharat Mediratta Date: Sun, 4 Oct 2009 12:36:06 -0700 Subject: [PATCH] Modules that provides a UserGroupStorage driver for LDAP. To use it, you have to manually update the config/ldap.php file, then go to Admin > Settings > LDAP and activate it. Very alpha quality! --- modules/ldap/config/ldap.php | 28 +++++ modules/ldap/controllers/admin_ldap.php | 64 ++++++++++ modules/ldap/helpers/ldap.php | 115 ++++++++++++++++++ modules/ldap/helpers/ldap_event.php | 28 +++++ .../drivers/UserGroupStorage/Ldap.php | 110 +++++++++++++++++ modules/ldap/models/ldap_group.php | 28 +++++ modules/ldap/models/ldap_guest.php | 36 ++++++ modules/ldap/models/ldap_user.php | 58 +++++++++ modules/ldap/module.info | 3 + modules/ldap/views/admin_ldap.html.php | 60 +++++++++ 10 files changed, 530 insertions(+) create mode 100644 modules/ldap/config/ldap.php create mode 100644 modules/ldap/controllers/admin_ldap.php create mode 100644 modules/ldap/helpers/ldap.php create mode 100644 modules/ldap/helpers/ldap_event.php create mode 100644 modules/ldap/libraries/drivers/UserGroupStorage/Ldap.php create mode 100644 modules/ldap/models/ldap_group.php create mode 100644 modules/ldap/models/ldap_guest.php create mode 100644 modules/ldap/models/ldap_user.php create mode 100644 modules/ldap/module.info create mode 100644 modules/ldap/views/admin_ldap.html.php diff --git a/modules/ldap/config/ldap.php b/modules/ldap/config/ldap.php new file mode 100644 index 00000000..07eda591 --- /dev/null +++ b/modules/ldap/config/ldap.php @@ -0,0 +1,28 @@ + array("eng", "google", "prebuild", "guest"), + "everybody_group" => "guest", + "registered_users_group" => "google", + "admins" => array("mediratta"), + "url" => "ldaps://ldap.corp.google.com/", + "group_domain" => "ou=Posix,ou=Groups,dc=google,dc=com", + "user_domain" => "ou=People,dc=google,dc=com", +); diff --git a/modules/ldap/controllers/admin_ldap.php b/modules/ldap/controllers/admin_ldap.php new file mode 100644 index 00000000..8f206bd0 --- /dev/null +++ b/modules/ldap/controllers/admin_ldap.php @@ -0,0 +1,64 @@ +content = new View("admin_ldap.html"); + $view->content->config = Kohana::config("ldap"); + print $view; + } + + public function activate() { + access::verify_csrf(); + + + if (module::get_var("gallery", "user_group_storage", "Gallery3") == "Gallery3") { + // @todo: we should have an API for these + foreach (ORM::factory("group")->find_all() as $group) { + $group->delete(); + } + foreach (ORM::factory("user")->find_all() as $user) { + $user->delete(); + } + } + + // Create LDAP groups + foreach (Kohana::config("ldap.groups") as $group_name) { + $group = ldap::lookup_group_by_name($group_name); + module::event("group_created", $group); + } + + // Fix up permissions. + $root = item::root(); + $everybody = ldap::everybody_group(); + access::allow($everybody, "view", $root); + access::allow($everybody, "view_full", $root); + $registered_users = ldap::registered_users_group(); + access::allow($registered_users, "view", $root); + access::allow($registered_users, "view_full", $root); + + // Switch authentication + module::set_var("gallery", "user_group_storage", "Ldap"); + + // Logout and go back to the top level + user::logout(); + url::redirect(item::root()->abs_url()); + } +} \ No newline at end of file diff --git a/modules/ldap/helpers/ldap.php b/modules/ldap/helpers/ldap.php new file mode 100644 index 00000000..45cae297 --- /dev/null +++ b/modules/ldap/helpers/ldap.php @@ -0,0 +1,115 @@ + 0) { + return new Ldap_User_Model($entries[0]); + } + return null; + } + + static function lookup_user($id) { + $result = ldap_search(ldap::connection(), + Kohana::config("ldap.user_domain"), + "uidNumber=$id"); + $entries = ldap_get_entries(ldap::connection(), $result); + if ($entries["count"] > 0) { + return new Ldap_User_Model($entries[0]); + } + return null; + } + + static function validate_group($input) { + if (!self::lookup_group_by_name($input->value)) { + $input->add_error("invalid_group", 1); + } + } + + static function groups_for($user) { + $result = ldap_search(ldap::connection(), + Kohana::config("ldap.group_domain"), + "(memberUid=$user->name)"); + + $associated_groups = Kohana::config("ldap.groups"); + $groups = array(); + for ($entry_id = ldap_first_entry(ldap::connection(), $result); + $entry_id != false; + $entry_id = ldap_next_entry(ldap::connection(), $entry_id)) { + $group_id = ldap_get_values(ldap::connection(), $entry_id, "gidNumber"); + $group_name = ldap_get_values(ldap::connection(), $entry_id, "cn"); + if (in_array($group_name[0], $associated_groups)) { + $groups[] = new Ldap_Group_Model($group_id[0], $group_name[0]); + } + } + return $groups; + } + + static function guest() { + return new Ldap_Guest_Model(); + } + + public function everybody_group() { + return ldap::lookup_group_by_name(Kohana::config("ldap.everybody_group")); + } + + public function registered_users_group() { + return ldap::lookup_group_by_name(Kohana::config("ldap.registered_users_group")); + } +} diff --git a/modules/ldap/helpers/ldap_event.php b/modules/ldap/helpers/ldap_event.php new file mode 100644 index 00000000..91217f3f --- /dev/null +++ b/modules/ldap/helpers/ldap_event.php @@ -0,0 +1,28 @@ +get("settings_menu") + ->append(Menu::factory("link") + ->id("ldap") + ->label(t("LDAP")) + ->url(url::site("admin/ldap"))); + } +} diff --git a/modules/ldap/libraries/drivers/UserGroupStorage/Ldap.php b/modules/ldap/libraries/drivers/UserGroupStorage/Ldap.php new file mode 100644 index 00000000..eab23107 --- /dev/null +++ b/modules/ldap/libraries/drivers/UserGroupStorage/Ldap.php @@ -0,0 +1,110 @@ +get("group_ids"))) { + + $ids = array(); + foreach (user::active()->groups as $group) { + $ids[] = $group->id; + } + $session->set("group_ids", $ids); + } + return $ids; + } + + public function active_user() { + $session = Session::instance(); + $user = $session->get("user", null); + if (!isset($user)) { + // Don't do this as a fallback in the Session::get() call because it can trigger unnecessary + // work. + $session->set("user", $user = user::guest()); + } + return $user; + } + + public function guest_user() { + return ldap::guest(); + } + + public function set_active_user($user) { + $session = Session::instance(); + $session->set("user", $user); + $session->delete("group_ids"); + } + + public function create_user($name, $full_name, $password) { + throw new Exception("@todo UNSUPPORTED"); + } + + public function is_correct_password($user, $password) { + try { + return ldap_bind(ldap::connection(), + "uid={$user->name}," . Kohana::config("ldap.user_domain"), + $password); + } catch (Exception $e) { + // Authentication failure + } + return false; + } + + public function login($user) { + user::set_active($user); + } + + public function logout() { + try { + Session::instance()->destroy(); + } catch (Exception $e) { + Kohana::log("error", $e); + } + } + + public function lookup_user($id) { + return ldap::lookup_user($id); + } + + public function lookup_user_by_name($name) { + return ldap::lookup_user_by_name($name); + } + + public function lookup_group($id) { + return ldap::lookup_group($id); + } + + public function lookup_group_by_name($name) { + return ldap::lookup_group_by_name($name); + } + + public function create_group($name) { + throw new Exception("@todo UNSUPPORTED"); + } + + public function everybody_group() { + return ldap::everybody_group(); + } + + public function registered_users_group() { + return ldap::registered_users_group(); + } +} diff --git a/modules/ldap/models/ldap_group.php b/modules/ldap/models/ldap_group.php new file mode 100644 index 00000000..22e2ae4b --- /dev/null +++ b/modules/ldap/models/ldap_group.php @@ -0,0 +1,28 @@ +id = $id; + $this->name = $name; + } +} diff --git a/modules/ldap/models/ldap_guest.php b/modules/ldap/models/ldap_guest.php new file mode 100644 index 00000000..645ec095 --- /dev/null +++ b/modules/ldap/models/ldap_guest.php @@ -0,0 +1,36 @@ +ldap_entry = $ldap_entry; + } + + public function display_name() { + return $this->ldap_entry["displayname"][0]; + } + + public function __get($key) { + switch($key) { + case "name": + return $this->ldap_entry["uid"][0]; + + case "guest": + return false; + + case "login_count": + return 0; + + case "id": + return $this->ldap_entry["uidnumber"][0]; + + case "groups": + return ldap::groups_for($this); + + case "locale": // @todo + return null; + + case "admin": + return in_array($this->ldap_entry["uid"][0], Kohana::config("ldap.admins")); + + default: + throw new Exception("@todo UNKNOWN_KEY ($key)"); + } + } +} diff --git a/modules/ldap/module.info b/modules/ldap/module.info new file mode 100644 index 00000000..06fa311b --- /dev/null +++ b/modules/ldap/module.info @@ -0,0 +1,3 @@ +name = "LDAP" +description = "Use LDAP for authentication" +version = 1 diff --git a/modules/ldap/views/admin_ldap.html.php b/modules/ldap/views/admin_ldap.html.php new file mode 100644 index 00000000..e8080449 --- /dev/null +++ b/modules/ldap/views/admin_ldap.html.php @@ -0,0 +1,60 @@ + +
+

+

+ will be deleted and you'll use users and groups from your LDAP directory.") ?> +

+ +

+ +

+ + + + + + + + + + + + + + + + + + + + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ +

+

+ %username user. There is no undo!", array("username" => $config["admins"][0])) ?> +

+ + ">activate +