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 @@ + +
+ = t("LDAP is an alternate authentication system. When you switch to it, all your Gallery3 users and groups will be deleted and you'll use users and groups from your LDAP directory.") ?> +
+ ++ = t("Your current LDAP configuration is:") ?> +
++ = t("Base LDAP url") ?> + | ++ = $config["url"] ?> + | +
+ = t("Group LDAP Domain") ?> + | ++ = $config["group_domain"] ?> + | +
+ = t("User LDAP Domain") ?> + | ++ = $config["user_domain"] ?> + | +
+ = t("Groups") ?> + | ++ = join(", ", $config["groups"]) ?> + | +
+ = t("Admin users") ?> + | ++ = join(", ", $config["admins"]) ?> + | +
+ = t("Upon activation, all existing users and groups will be deleted. The groups listed above and all available users will be associated with Gallery 3. You will be logged in as the %username user. There is no undo!", array("username" => $config["admins"][0])) ?> +
+ + ">activate +