summaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authoricewind1991 <icewind1991@gmail.com>2013-07-24 06:13:05 -0700
committericewind1991 <icewind1991@gmail.com>2013-07-24 06:13:05 -0700
commit98858e6f00bbafc6b93a9c01b3ad8a6d826d5373 (patch)
treefe38cdfeef7c88a570938f3f4194f9b2fea0ee53 /lib
parentb91c6827b79d4ab3337539dff6d44b301e1250d3 (diff)
parent60ce492fac01a0d8ae2c2119376e2eff97579e5b (diff)
downloadnextcloud-server-98858e6f00bbafc6b93a9c01b3ad8a6d826d5373.tar.gz
nextcloud-server-98858e6f00bbafc6b93a9c01b3ad8a6d826d5373.zip
Merge pull request #3995 from owncloud/groups
Refactoring of group management code
Diffstat (limited to 'lib')
-rw-r--r--lib/group.php225
-rw-r--r--lib/group/group.php238
-rw-r--r--lib/group/manager.php169
-rw-r--r--lib/user.php4
-rw-r--r--lib/user/manager.php3
-rw-r--r--lib/user/user.php2
6 files changed, 511 insertions, 130 deletions
diff --git a/lib/group.php b/lib/group.php
index d1a830730b7..8fbf5f86418 100644
--- a/lib/group.php
+++ b/lib/group.php
@@ -34,28 +34,43 @@
* post_removeFromGroup(uid, gid)
*/
class OC_Group {
- // The backend used for group management
/**
- * @var OC_Group_Interface[]
+ * @var \OC\Group\Manager $manager
*/
- private static $_usedBackends = array();
+ private static $manager;
+
+ /**
+ * @var \OC\User\Manager
+ */
+ private static $userManager;
+
+ /**
+ * @return \OC\Group\Manager
+ */
+ public static function getManager() {
+ if (self::$manager) {
+ return self::$manager;
+ }
+ self::$userManager = \OC_User::getManager();
+ self::$manager = new \OC\Group\Manager(self::$userManager);
+ return self::$manager;
+ }
/**
* @brief set the group backend
- * @param string $backend The backend to use for user managment
+ * @param \OC_Group_Backend $backend The backend to use for user managment
* @return bool
*/
- public static function useBackend( $backend ) {
- if($backend instanceof OC_Group_Interface) {
- self::$_usedBackends[]=$backend;
- }
+ public static function useBackend($backend) {
+ self::getManager()->addBackend($backend);
+ return true;
}
/**
* remove all used backends
*/
public static function clearBackends() {
- self::$_usedBackends=array();
+ self::getManager()->clearBackends();
}
/**
@@ -66,32 +81,13 @@ class OC_Group {
* Tries to create a new group. If the group name already exists, false will
* be returned. Basic checking of Group name
*/
- public static function createGroup( $gid ) {
- // No empty group names!
- if( !$gid ) {
- return false;
- }
- // No duplicate group names
- if( in_array( $gid, self::getGroups())) {
- return false;
- }
-
- $run = true;
- OC_Hook::emit( "OC_Group", "pre_createGroup", array( "run" => &$run, "gid" => $gid ));
-
- if($run) {
- //create the group in the first backend that supports creating groups
- foreach(self::$_usedBackends as $backend) {
- if(!$backend->implementsActions(OC_GROUP_BACKEND_CREATE_GROUP))
- continue;
+ public static function createGroup($gid) {
+ OC_Hook::emit("OC_Group", "pre_createGroup", array("run" => true, "gid" => $gid));
- $backend->createGroup($gid);
- OC_Hook::emit( "OC_User", "post_createGroup", array( "gid" => $gid ));
-
- return true;
- }
- return false;
- }else{
+ if (self::getManager()->createGroup($gid)) {
+ OC_Hook::emit("OC_User", "post_createGroup", array("gid" => $gid));
+ return true;
+ } else {
return false;
}
}
@@ -103,30 +99,22 @@ class OC_Group {
*
* Deletes a group and removes it from the group_user-table
*/
- public static function deleteGroup( $gid ) {
+ public static function deleteGroup($gid) {
// Prevent users from deleting group admin
- if( $gid == "admin" ) {
+ if ($gid == "admin") {
return false;
}
- $run = true;
- OC_Hook::emit( "OC_Group", "pre_deleteGroup", array( "run" => &$run, "gid" => $gid ));
-
- if($run) {
- //delete the group from all backends
- foreach(self::$_usedBackends as $backend) {
- if(!$backend->implementsActions(OC_GROUP_BACKEND_DELETE_GROUP))
- continue;
-
- $backend->deleteGroup($gid);
- OC_Hook::emit( "OC_User", "post_deleteGroup", array( "gid" => $gid ));
+ OC_Hook::emit("OC_Group", "pre_deleteGroup", array("run" => true, "gid" => $gid));
+ $group = self::getManager()->get($gid);
+ if ($group) {
+ if ($group->delete()) {
+ OC_Hook::emit("OC_User", "post_deleteGroup", array("gid" => $gid));
return true;
}
- return false;
- }else{
- return false;
}
+ return false;
}
/**
@@ -137,11 +125,11 @@ class OC_Group {
*
* Checks whether the user is member of a group or not.
*/
- public static function inGroup( $uid, $gid ) {
- foreach(self::$_usedBackends as $backend) {
- if($backend->inGroup($uid, $gid)) {
- return true;
- }
+ public static function inGroup($uid, $gid) {
+ $group = self::getManager()->get($gid);
+ $user = self::$userManager->get($uid);
+ if ($group and $user) {
+ return $group->inGroup($user);
}
return false;
}
@@ -154,33 +142,15 @@ class OC_Group {
*
* Adds a user to a group.
*/
- public static function addToGroup( $uid, $gid ) {
- // Does the group exist?
- if( !OC_Group::groupExists($gid)) {
- return false;
- }
-
- // Go go go
- $run = true;
- OC_Hook::emit( "OC_Group", "pre_addToGroup", array( "run" => &$run, "uid" => $uid, "gid" => $gid ));
-
- if($run) {
- $success=false;
-
- //add the user to the all backends that have the group
- foreach(self::$_usedBackends as $backend) {
- if(!$backend->implementsActions(OC_GROUP_BACKEND_ADD_TO_GROUP))
- continue;
-
- if($backend->groupExists($gid)) {
- $success|=$backend->addToGroup($uid, $gid);
- }
- }
- if($success) {
- OC_Hook::emit( "OC_User", "post_addToGroup", array( "uid" => $uid, "gid" => $gid ));
- }
- return $success;
- }else{
+ public static function addToGroup($uid, $gid) {
+ $group = self::getManager()->get($gid);
+ $user = self::$userManager->get($uid);
+ if ($group and $user) {
+ OC_Hook::emit("OC_Group", "pre_addToGroup", array("run" => true, "uid" => $uid, "gid" => $gid));
+ $group->addUser($user);
+ OC_Hook::emit("OC_User", "post_addToGroup", array("uid" => $uid, "gid" => $gid));
+ return true;
+ } else {
return false;
}
}
@@ -193,21 +163,15 @@ class OC_Group {
*
* removes the user from a group.
*/
- public static function removeFromGroup( $uid, $gid ) {
- $run = true;
- OC_Hook::emit( "OC_Group", "pre_removeFromGroup", array( "run" => &$run, "uid" => $uid, "gid" => $gid ));
-
- if($run) {
- //remove the user from the all backends that have the group
- foreach(self::$_usedBackends as $backend) {
- if(!$backend->implementsActions(OC_GROUP_BACKEND_REMOVE_FROM_GOUP))
- continue;
-
- $backend->removeFromGroup($uid, $gid);
- OC_Hook::emit( "OC_User", "post_removeFromGroup", array( "uid" => $uid, "gid" => $gid ));
- }
+ public static function removeFromGroup($uid, $gid) {
+ $group = self::getManager()->get($gid);
+ $user = self::$userManager->get($uid);
+ if ($group and $user) {
+ OC_Hook::emit("OC_Group", "pre_removeFromGroup", array("run" => true, "uid" => $uid, "gid" => $gid));
+ $group->removeUser($user);
+ OC_Hook::emit("OC_User", "post_removeFromGroup", array("uid" => $uid, "gid" => $gid));
return true;
- }else{
+ } else {
return false;
}
}
@@ -220,13 +184,18 @@ class OC_Group {
* This function fetches all groups a user belongs to. It does not check
* if the user exists at all.
*/
- public static function getUserGroups( $uid ) {
- $groups=array();
- foreach(self::$_usedBackends as $backend) {
- $groups=array_merge($backend->getUserGroups($uid), $groups);
+ public static function getUserGroups($uid) {
+ $user = self::$userManager->get($uid);
+ if ($user) {
+ $groups = self::getManager()->getUserGroups($user);
+ $groupIds = array();
+ foreach ($groups as $group) {
+ $groupIds[] = $group->getGID();
+ }
+ return $groupIds;
+ } else {
+ return array();
}
- asort($groups);
- return $groups;
}
/**
@@ -235,27 +204,23 @@ class OC_Group {
*
* Returns a list with all groups
*/
- public static function getGroups($search = '', $limit = -1, $offset = 0) {
- $groups = array();
- foreach (self::$_usedBackends as $backend) {
- $groups = array_merge($backend->getGroups($search, $limit, $offset), $groups);
+ public static function getGroups($search = '', $limit = null, $offset = null) {
+ $groups = self::getManager()->search($search, $limit, $offset);
+ $groupIds = array();
+ foreach ($groups as $group) {
+ $groupIds[] = $group->getGID();
}
- asort($groups);
- return $groups;
+ return $groupIds;
}
/**
* check if a group exists
+ *
* @param string $gid
* @return bool
*/
public static function groupExists($gid) {
- foreach(self::$_usedBackends as $backend) {
- if ($backend->groupExists($gid)) {
- return true;
- }
- }
- return false;
+ return self::getManager()->groupExists($gid);
}
/**
@@ -263,11 +228,17 @@ class OC_Group {
* @returns array with user ids
*/
public static function usersInGroup($gid, $search = '', $limit = -1, $offset = 0) {
- $users=array();
- foreach(self::$_usedBackends as $backend) {
- $users = array_merge($backend->usersInGroup($gid, $search, $limit, $offset), $users);
+ $group = self::getManager()->get($gid);
+ if ($group) {
+ $users = $group->searchUsers($search . $limit, $offset);
+ $userIds = array();
+ foreach ($users as $user) {
+ $userIds[] = $user->getUID();
+ }
+ return $userIds;
+ } else {
+ return array();
}
- return $users;
}
/**
@@ -292,17 +263,17 @@ class OC_Group {
* @returns array with display names (value) and user ids(key)
*/
public static function displayNamesInGroup($gid, $search = '', $limit = -1, $offset = 0) {
- $displayNames=array();
- foreach(self::$_usedBackends as $backend) {
- if($backend->implementsActions(OC_GROUP_BACKEND_GET_DISPLAYNAME)) {
- $displayNames = array_merge($backend->displayNamesInGroup($gid, $search, $limit, $offset), $displayNames);
- } else {
- $users = $backend->usersInGroup($gid, $search, $limit, $offset);
- $names = array_combine($users, $users);
- $displayNames = array_merge($names, $displayNames);
+ $group = self::getManager()->get($gid);
+ if ($group) {
+ $users = $group->searchDisplayName($search . $limit, $offset);
+ $displayNames = array();
+ foreach ($users as $user) {
+ $displayNames[] = $user->getDisplayName();
}
+ return $displayNames;
+ } else {
+ return array();
}
- return $displayNames;
}
/**
diff --git a/lib/group/group.php b/lib/group/group.php
new file mode 100644
index 00000000000..7a639313247
--- /dev/null
+++ b/lib/group/group.php
@@ -0,0 +1,238 @@
+<?php
+
+/**
+ * Copyright (c) 2013 Robin Appelman <icewind@owncloud.com>
+ * This file is licensed under the Affero General Public License version 3 or
+ * later.
+ * See the COPYING-README file.
+ */
+
+namespace OC\Group;
+
+class Group {
+ /**
+ * @var string $id
+ */
+ private $fid;
+
+ /**
+ * @var \OC\User\User[] $users
+ */
+ private $users;
+
+ /**
+ * @var \OC_Group_Backend[] | \OC_Group_Database[] $backend
+ */
+ private $backends;
+
+ /**
+ * @var \OC\Hooks\PublicEmitter $emitter;
+ */
+ private $emitter;
+
+ /**
+ * @var \OC\User\Manager $userManager
+ */
+ private $userManager;
+
+ /**
+ * @param string $gid
+ * @param \OC_Group_Backend[] $backends
+ * @param \OC\User\Manager $userManager
+ * @param \OC\Hooks\PublicEmitter $emitter
+ */
+ public function __construct($gid, $backends, $userManager, $emitter = null) {
+ $this->gid = $gid;
+ $this->backends = $backends;
+ $this->userManager = $userManager;
+ $this->emitter = $emitter;
+ }
+
+ public function getGID() {
+ return $this->gid;
+ }
+
+ /**
+ * get all users in the group
+ *
+ * @return \OC\User\User[]
+ */
+ public function getUsers() {
+ if ($this->users) {
+ return $this->users;
+ }
+
+ $users = array();
+ $userIds = array();
+ foreach ($this->backends as $backend) {
+ $diff = array_diff(
+ $backend->usersInGroup($this->gid),
+ $userIds
+ );
+ if ($diff) {
+ $userIds = array_merge($userIds, $diff);
+ }
+ }
+
+ foreach ($userIds as $userId) {
+ $users[] = $this->userManager->get($userId);
+ }
+ $this->users = $users;
+ return $users;
+ }
+
+ /**
+ * check if a user is in the group
+ *
+ * @param \OC\User\User $user
+ * @return bool
+ */
+ public function inGroup($user) {
+ foreach ($this->backends as $backend) {
+ if ($backend->inGroup($user->getUID(), $this->gid)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * add a user to the group
+ *
+ * @param \OC\User\User $user
+ */
+ public function addUser($user) {
+ if ($this->inGroup($user)) {
+ return;
+ }
+
+ if ($this->emitter) {
+ $this->emitter->emit('\OC\Group', 'preAddUser', array($this, $user));
+ }
+ foreach ($this->backends as $backend) {
+ if ($backend->implementsActions(OC_GROUP_BACKEND_ADD_TO_GROUP)) {
+ $backend->addToGroup($user->getUID(), $this->gid);
+ if ($this->users) {
+ $this->users[] = $user;
+ }
+ if ($this->emitter) {
+ $this->emitter->emit('\OC\Group', 'postAddUser', array($this, $user));
+ }
+ return;
+ }
+ }
+ }
+
+ /**
+ * remove a user from the group
+ *
+ * @param \OC\User\User $user
+ */
+ public function removeUser($user) {
+ $result = false;
+ if ($this->emitter) {
+ $this->emitter->emit('\OC\Group', 'preRemoveUser', array($this, $user));
+ }
+ foreach ($this->backends as $backend) {
+ if ($backend->implementsActions(OC_GROUP_BACKEND_REMOVE_FROM_GOUP) and $backend->inGroup($user->getUID(), $this->gid)) {
+ $backend->removeFromGroup($user->getUID(), $this->gid);
+ $result = true;
+ }
+ }
+ if ($result) {
+ if ($this->emitter) {
+ $this->emitter->emit('\OC\Group', 'postRemoveUser', array($this, $user));
+ }
+ if ($this->users) {
+ foreach ($this->users as $index => $groupUser) {
+ if ($groupUser->getUID() === $user->getUID()) {
+ unset($this->users[$index]);
+ return;
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ * search for users in the group by userid
+ *
+ * @param string $search
+ * @param int $limit
+ * @param int $offset
+ * @return \OC\User\User[]
+ */
+ public function searchUsers($search, $limit = null, $offset = null) {
+ $users = array();
+ foreach ($this->backends as $backend) {
+ $userIds = $backend->usersInGroup($this->gid, $search, $limit, $offset);
+ if (!is_null($limit)) {
+ $limit -= count($userIds);
+ }
+ if (!is_null($offset)) {
+ $offset -= count($userIds);
+ }
+ foreach ($userIds as $userId) {
+ $users[$userId] = $this->userManager->get($userId);
+ }
+ if (!is_null($limit) and $limit <= 0) {
+ return array_values($users);
+ }
+ }
+ return array_values($users);
+ }
+
+ /**
+ * search for users in the group by displayname
+ *
+ * @param string $search
+ * @param int $limit
+ * @param int $offset
+ * @return \OC\User\User[]
+ */
+ public function searchDisplayName($search, $limit = null, $offset = null) {
+ $users = array();
+ foreach ($this->backends as $backend) {
+ if ($backend->implementsActions(OC_GROUP_BACKEND_GET_DISPLAYNAME)) {
+ $userIds = array_keys($backend->displayNamesInGroup($this->gid, $search, $limit, $offset));
+ } else {
+ $userIds = $backend->usersInGroup($this->gid, $search, $limit, $offset);
+ }
+ if (!is_null($limit)) {
+ $limit -= count($userIds);
+ }
+ if (!is_null($offset)) {
+ $offset -= count($userIds);
+ }
+ foreach ($userIds as $userId) {
+ $users[$userId] = $this->userManager->get($userId);
+ }
+ if (!is_null($limit) and $limit <= 0) {
+ return array_values($users);
+ }
+ }
+ return array_values($users);
+ }
+
+ /**
+ * delete the group
+ *
+ * @return bool
+ */
+ public function delete() {
+ $result = false;
+ if ($this->emitter) {
+ $this->emitter->emit('\OC\Group', 'preDelete', array($this));
+ }
+ foreach ($this->backends as $backend) {
+ if ($backend->implementsActions(OC_GROUP_BACKEND_DELETE_GROUP)) {
+ $result = true;
+ $backend->deleteGroup($this->gid);
+ }
+ }
+ if ($result and $this->emitter) {
+ $this->emitter->emit('\OC\Group', 'postDelete', array($this));
+ }
+ return $result;
+ }
+}
diff --git a/lib/group/manager.php b/lib/group/manager.php
new file mode 100644
index 00000000000..bf469d51d12
--- /dev/null
+++ b/lib/group/manager.php
@@ -0,0 +1,169 @@
+<?php
+
+/**
+ * Copyright (c) 2013 Robin Appelman <icewind@owncloud.com>
+ * This file is licensed under the Affero General Public License version 3 or
+ * later.
+ * See the COPYING-README file.
+ */
+
+namespace OC\Group;
+
+use OC\Hooks\PublicEmitter;
+
+/**
+ * Class Manager
+ *
+ * Hooks available in scope \OC\Group:
+ * - preAddUser(\OC\Group\Group $group, \OC\User\User $user)
+ * - postAddUser(\OC\Group\Group $group, \OC\User\User $user)
+ * - preRemoveUser(\OC\Group\Group $group, \OC\User\User $user)
+ * - postRemoveUser(\OC\Group\Group $group, \OC\User\User $user)
+ * - preDelete(\OC\Group\Group $group)
+ * - postDelete(\OC\Group\Group $group)
+ * - preCreate(string $groupId)
+ * - postCreate(\OC\Group\Group $group)
+ *
+ * @package OC\Group
+ */
+class Manager extends PublicEmitter {
+ /**
+ * @var \OC_Group_Backend[] | \OC_Group_Database[] $backends
+ */
+ private $backends = array();
+
+ /**
+ * @var \OC\User\Manager $userManager
+ */
+ private $userManager;
+
+ /**
+ * @var \OC\Group\Group[]
+ */
+ private $cachedGroups;
+
+ /**
+ * @param \OC\User\Manager $userManager
+ */
+ public function __construct($userManager) {
+ $this->userManager = $userManager;
+ $cache = & $this->cachedGroups;
+ $this->listen('\OC\Group', 'postDelete', function ($group) use (&$cache) {
+ /**
+ * @var \OC\Group\Group $group
+ */
+ unset($cache[$group->getGID()]);
+ });
+ }
+
+ /**
+ * @param \OC_Group_Backend $backend
+ */
+ public function addBackend($backend) {
+ $this->backends[] = $backend;
+ }
+
+ public function clearBackends() {
+ $this->backends = array();
+ $this->cachedGroups = array();
+ }
+
+ /**
+ * @param string $gid
+ * @return \OC\Group\Group
+ */
+ public function get($gid) {
+ if (isset($this->cachedGroups[$gid])) {
+ return $this->cachedGroups[$gid];
+ }
+ foreach ($this->backends as $backend) {
+ if ($backend->groupExists($gid)) {
+ return $this->getGroupObject($gid);
+ }
+ }
+ return null;
+ }
+
+ protected function getGroupObject($gid) {
+ $backends = array();
+ foreach ($this->backends as $backend) {
+ if ($backend->groupExists($gid)) {
+ $backends[] = $backend;
+ }
+ }
+ $this->cachedGroups[$gid] = new Group($gid, $backends, $this->userManager, $this);
+ return $this->cachedGroups[$gid];
+ }
+
+ /**
+ * @param string $gid
+ * @return bool
+ */
+ public function groupExists($gid) {
+ return !is_null($this->get($gid));
+ }
+
+ /**
+ * @param string $gid
+ * @return \OC\Group\Group
+ */
+ public function createGroup($gid) {
+ if (!$gid) {
+ return false;
+ } else if ($this->groupExists($gid)) {
+ return $this->get($gid);
+ } else {
+ $this->emit('\OC\Group', 'preCreate', array($gid));
+ foreach ($this->backends as $backend) {
+ if ($backend->implementsActions(OC_GROUP_BACKEND_CREATE_GROUP)) {
+ $backend->createGroup($gid);
+ $group = $this->getGroupObject($gid);
+ $this->emit('\OC\Group', 'postCreate', array($group));
+ return $group;
+ }
+ }
+ return null;
+ }
+ }
+
+ /**
+ * @param string $search
+ * @param int $limit
+ * @param int $offset
+ * @return \OC\Group\Group[]
+ */
+ public function search($search, $limit = null, $offset = null) {
+ $groups = array();
+ foreach ($this->backends as $backend) {
+ $groupIds = $backend->getGroups($search, $limit, $offset);
+ if (!is_null($limit)) {
+ $limit -= count($groupIds);
+ }
+ if (!is_null($offset)) {
+ $offset -= count($groupIds);
+ }
+ foreach ($groupIds as $groupId) {
+ $groups[$groupId] = $this->getGroupObject($groupId);
+ }
+ if (!is_null($limit) and $limit <= 0) {
+ return array_values($groups);
+ }
+ }
+ return array_values($groups);
+ }
+
+ /**
+ * @param \OC\User\User $user
+ * @return \OC\Group\Group[]
+ */
+ public function getUserGroups($user) {
+ $groups = array();
+ foreach ($this->backends as $backend) {
+ $groupIds = $backend->getUserGroups($user->getUID());
+ foreach ($groupIds as $groupId) {
+ $groups[$groupId] = $this->getGroupObject($groupId);
+ }
+ }
+ return array_values($groups);
+ }
+}
diff --git a/lib/user.php b/lib/user.php
index d93ab1a5f73..ee20f2e0971 100644
--- a/lib/user.php
+++ b/lib/user.php
@@ -39,7 +39,7 @@
class OC_User {
public static $userSession = null;
- private static function getUserSession() {
+ public static function getUserSession() {
if (!self::$userSession) {
$manager = new \OC\User\Manager();
self::$userSession = new \OC\User\Session($manager, \OC::$session);
@@ -83,7 +83,7 @@ class OC_User {
/**
* @return \OC\User\Manager
*/
- private static function getManager() {
+ public static function getManager() {
return self::getUserSession()->getManager();
}
diff --git a/lib/user/manager.php b/lib/user/manager.php
index d17cdf1a200..8dc9bfe2729 100644
--- a/lib/user/manager.php
+++ b/lib/user/manager.php
@@ -30,6 +30,9 @@ class Manager extends PublicEmitter {
*/
private $backends = array();
+ /**
+ * @var \OC\User\User[] $cachedUsers
+ */
private $cachedUsers = array();
public function __construct() {
diff --git a/lib/user/user.php b/lib/user/user.php
index 55d7848a979..8115c43198c 100644
--- a/lib/user/user.php
+++ b/lib/user/user.php
@@ -44,7 +44,7 @@ class User {
*/
public function __construct($uid, $backend, $emitter = null) {
$this->uid = $uid;
- if ($backend->implementsActions(OC_USER_BACKEND_GET_DISPLAYNAME)) {
+ if ($backend and $backend->implementsActions(OC_USER_BACKEND_GET_DISPLAYNAME)) {
$this->displayName = $backend->getDisplayName($uid);
} else {
$this->displayName = $uid;