diff --git a/.idea/cssxfire.xml b/.idea/cssxfire.xml new file mode 100644 index 0000000..f4acc38 --- /dev/null +++ b/.idea/cssxfire.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/README.md b/README.md index 3899ec1..2fe6f75 100644 --- a/README.md +++ b/README.md @@ -1,25 +1,52 @@ -groupoffice-owncloud -==================== +# groupoffice <-> owncloud connector ownCloud plugin to connect with Group-Office +This is a fork, which additionally shows and syncs Shared Folders (for which you have at least read permissions in Group-Office) like this: -Make sure ownCloud and Group-Office are installed on the same server. -Put the "groupoffice" ownCloud app folder in the "apps" folder of ownCloud. +* OwnCloud +* NotInGroupOfficeFolder1 +* NotInGroupOfficeFolder1 +* Groupoffice +* Groupoffice – SharedFolder1 +* Groupoffice – SharedFolder2 +* Groupoffice – ownFolder – myPrivateFolder1 +* Groupoffice – ownFolder – myPrivateFolder2 -If Group-Office is not installed in /usr/share/groupoffice add this variable to -"config/config.php": -'groupoffice_root'=>'/path/to/groupoffice' +## Installation +Put this line into a ssh shell to clone this repository. -If you need to specify a Group-Office config.php location you can add: + git clone https://github.com/horfic/groupoffice-owncloud.git groupoffice + +Put the now cloned "groupoffice" folder into ownCloud "apps" folder. -'groupoffice_config'=>'/path/to/groupoffice/config.php' +#### Make sure ownCloud and Group-Office are installed on the same server. -Now you can install the Group-Office app in the app manager of ownCloud. + If Group-Office is **not** installed in **/usr/share/groupoffice** add this variable to the config array of + "/path/to/OwnCloud/config/config.php" configuration file. + + 'groupoffice_root'=>'/path/to/groupoffice' + +Tested with Group-Office 5.0.75 and ownCloud 7.0.1 + + If you need to specify a Group-Office config.php location you can add: + + 'groupoffice_config'=>'/path/to/groupoffice/config.php' + +**Now you can install the Group-Office app in the app manager of ownCloud.** Enjoy! -Intermesh Group-Office Team +### Keep in mind + +* the user- and accessmanagement stays in groupoffice +* no users are created within owncloud, only access is granted +* sharing folders in owncloud to groupmembers of groupoffice does not work. This only works in groupoffice and the folders are then accessible in owncloud. + +--- + +Intermesh Group-Office Team & ALLMENDA Informatik +http://www.group-office.com http://ALLMENDA.com/informatik -http://www.group-office.com +- diff --git a/appinfo/app.php b/appinfo/app.php index a582d6f..252fd09 100644 --- a/appinfo/app.php +++ b/appinfo/app.php @@ -1,7 +1,13 @@ groupoffice Group-Office integration - Use Group-Office users, groups and files. Group-Office must run on the same server. + Use Group-Office users, groups and files. Group-Office must run on the same server. Version 1.4.0 now shows ownFolder and all Shared Folders, a user has access to in Group-Office. AGPL - Intermesh BV - 4.93 + Intermesh BV, ALLMENDA Social Business eG, web wack creations + 6.0.4 + 1.5.0 false + + + http://ALLMENDA.com/owncloud + https://github.com/horfic/groupoffice-owncloud + diff --git a/appinfo/version b/appinfo/version index 3eefcb9..bc80560 100644 --- a/appinfo/version +++ b/appinfo/version @@ -1 +1 @@ -1.0.0 +1.5.0 diff --git a/group_groupoffice.php b/group_groupoffice.php index b7417f4..c935a94 100644 --- a/group_groupoffice.php +++ b/group_groupoffice.php @@ -1,78 +1,112 @@ start($offset) - ->searchQuery($search); - - if($limit>0) - $fp->limit($limit); - - $stmt = GO_Base_Model_Group::model()->find($fp); - - foreach($stmt as $group){ - $returnArray[]=$group->name; - } - - return $returnArray; - } - - public function getUserGroups($uid) { - $groups = array(); - - $user = GO_Base_Model_User::model()->findSingleByAttribute('username', $uid); - - if($user){ - $stmt = $user->groups(); - - foreach($stmt as $group){ - $groups[]=$group->name; - } - } - - return $groups; - } - - public function groupExists($gid) { - $group = GO_Base_Model_Group::model()->findSingleByAttribute('name', $gid); - - return $group!=false; - } - - public function inGroup($uid, $gid) { - $user = GO_Base_Model_User::model()->findSingleByAttribute('username', $uid); - if(!$user) - return false; - - $group = GO_Base_Model_Group::model()->findSingleByAttribute('name', $gid); - if(!$group) - return false; - - $ug = GO_Base_Model_UserGroup::model()->findByPk(array('user_id'=>$user->id, 'group_id'=>$group->id)); - - return $ug!=false; - } - - public function usersInGroup($gid, $search = '', $limit = -1, $offset = 0) { - - $users = array(); - - $group = GO_Base_Model_Group::model()->findSingleByAttribute('name', $gid); - - $findParams = GO_Base_Db_FindParams::newInstance() - ->start($offset) - ->limit($limit) - ->searchQuery($search); - - $stmt = $group->users($findParams); - foreach($stmt as $user){ - $users[]=$user->username; - } - - return $users; - } +namespace OCA\groupoffice; + +class Group extends \OC_Group_Backend +{ + + public function getGroups($search = '', $limit = -1, $offset = 0) + { + $returnArray = array(); + + $fp = \GO_Base_Db_FindParams::newInstance() + ->start($offset) + ->searchQuery('%' . $search . '%'); + + if ($limit > 0) + $fp->limit($limit); + + $stmt = \GO_Base_Model_Group::model()->find($fp); + + foreach ($stmt as $group) { + $returnArray[] = $group->name; + } + + return $returnArray; + } + + public function getUserGroups($uid) + { + $groups = array(); + + $user = \GO_Base_Model_User::model()->findSingleByAttribute('username', $uid); + + if ($user) { + $stmt = $user->groups(); + + foreach ($stmt as $group) { + $groups[] = $group->name; + } + } + + return $groups; + } + + public function groupExists($gid) + { + $group = \GO_Base_Model_Group::model()->findSingleByAttribute('name', $gid); + + return $group != false; + } + + public function inGroup($uid, $gid) + { + $user = \GO_Base_Model_User::model()->findSingleByAttribute('username', $uid); + if (!$user) + return false; + + $group = \GO_Base_Model_Group::model()->findSingleByAttribute('name', $gid); + if (!$group) + return false; + + $ug = \GO_Base_Model_UserGroup::model()->findByPk(array('user_id' => $user->id, 'group_id' => $group->id)); + + return $ug != false; + } + + public function usersInGroup($gid, $search = '', $limit = -1, $offset = 0) + { + + $users = array(); + + $group = \GO_Base_Model_Group::model()->findSingleByAttribute('name', $gid); + + $findParams = \GO_Base_Db_FindParams::newInstance() + ->start($offset) + ->searchQuery('%' . $search . '%'); + + if ($limit > 0) + $findParams->limit($limit); + + $stmt = $group->users($findParams); + + foreach ($stmt as $user) { + $users[] = $user->username; + } + + return $users; + } + + public function countUsersInGroup($gid, $search = '') + { + $group = \GO_Base_Model_Group::model()->findSingleByAttribute('name', $gid); + + + $findParams = \GO_Base_Db_FindParams::newInstance() + ->single() + ->select('count(*) as total'); + + //if ($search != '') + // $findParams->searchQuery('%'.$search.'%'); + + $record = $group->users($findParams); + + return $record->total; + } + + public function implementsActions($actions) + { + return (bool)(OC_GROUP_BACKEND_COUNT_USERS & $actions); + } + } diff --git a/lib/groupofficestorage.php b/lib/groupofficestorage.php new file mode 100644 index 0000000..1a742ca --- /dev/null +++ b/lib/groupofficestorage.php @@ -0,0 +1,443 @@ +id = 'groupoffice::'.$arguments['user'].'/'; + $this->groupoffice_data = \GO::config()->file_storage_path; + + $this->groupoffice_shares['ownFolder'] = 'users/'.$arguments['user']; + \GO::session()->setCurrentUser(\GO_Base_Model_User::model()->findSingleByAttribute('username', $arguments['user'])); + + $shares = \GO_Files_Model_Folder::model()->getTopLevelShares(\GO_Base_Db_FindParams::newInstance()->limit(100)); + foreach($shares as $folder){ + $this->groupoffice_shares[$folder->name] = $folder->path; + } + + } else { + throw new \Exception('Creating \OC\Files\Storage\Groupoffice storage failed'); + } + } + + public static function setup($options) { + if (\OCP\User::isLoggedIn()) { + \OC\Files\Filesystem::mount('\OC\Files\Storage\Groupoffice', array('user' => $options['user']), + $options['user_dir'] . '/Groupoffice/'); + } + } + + public function getId(){ + return $this->id; + } + + public function rename($path1, $path2) { + if (!$this->isUpdatable($path1)) { + return false; + } + if (!$this->file_exists($path1)) { + return false; + } + + if ($return = rename($this->groupoffice_data . $this->get_real_path($path1), $this->groupoffice_data . $this->get_real_path($path2))) { + } + return $return; + } + + public function isSharable($path) { + return false; + } + + public function isReadable($path) { + if ($path == '' || $path == '/') { + return true; + } else { + $fullpath = $this->get_real_path($path); + + if ($this->is_file($path)) + $fullpath = dirname($fullpath); + + $folder = \GO_Files_Model_Folder::model()->findByPath($fullpath); + + if ($folder != '') { + if ($folder->checkPermissionLevel(\GO_Base_Model_Acl::READ_PERMISSION)) + { + return true; + } else { + return false; + } + } + + return false; + } + } + + public function opendir($path) { + if ($path == '' || $path == '/') { + $files = array(); + $files[] = 'ownFolder'; + + $shares = \GO_Files_Model_Folder::model()->getTopLevelShares(\GO_Base_Db_FindParams::newInstance()->limit(100)); + + foreach($shares as $folder){ + $files[] = $folder->name; + } + + \OC\Files\Stream\Dir::register('groupoffice'. $path, $files); + return opendir('fakedir://groupoffice'. $path); + } else { + return opendir($this->groupoffice_data.$this->get_real_path($path)); + } + } + + private function get_real_path($path) { + $tmp = explode("/", $path); + $basefolder = $tmp[0]; + unset($tmp[0]); + $realfolder = implode("/", $tmp); + + if (array_key_exists($basefolder,$this->groupoffice_shares)) + { + $realpath = $this->groupoffice_shares[$basefolder].'/'.$realfolder; + return $realpath; + } + else + return $path; + } + + private function is_root_shared_folder($path) { + $tmp = explode("/", $path); + $basefolder = $tmp[0]; + unset($tmp[0]); + $realfolder = implode("/", $tmp); + + if (array_key_exists($basefolder,$this->groupoffice_shares) && $realfolder == '') + return true; + else + return false; + } + + public function is_dir($path) { + if ($path == '' || $path == '/') { + return true; + } else { + if (substr($path, -1) == '/') { + $path = substr($path, 0, -1); + } + return is_dir($this->groupoffice_data.$this->get_real_path($path)); + } + } + + public function is_file($path) { + if ($path == '' || $path == '/') { + return false; + } else { + return is_file($this->groupoffice_data.$this->get_real_path($path)); + } + } + + public function getMimeType($path) { + if ($this->isReadable($path)) { + if ($path == '' || $path == '/') { + return 'httpd/unix-directory'; + } else { + return \OC_Helper::getMimeType($this->groupoffice_data.$this->get_real_path($path)); + } + } else { + return false; + } + } + + public function filetype($path) { + if ($path == '' || $path == '/') { + return 'dir'; + } else { + $realpath = $this->groupoffice_data.$this->get_real_path($path); + $filetype = filetype($realpath); + if ($filetype == 'link') { + $filetype = filetype(realpath($realpath)); + } + return $filetype; + } + } + + public function stat($path) { + if ($path == '' || $path == '/') { + $stat['size'] = 0; + $stat['ctime'] = 0; + $stat['atime'] = 0; + $stat['mtime'] = 0; + return $stat; + } else { + $fullPath = $this->groupoffice_data.$this->get_real_path($path); + $statResult = stat($fullPath); + + if ($statResult['size'] < 0) { + $size = self::getFileSizeFromOS($fullPath); + $statResult['size'] = $size; + $statResult[7] = $size; + } + return $statResult; + } + } + + public function hasUpdated($path, $time) { + return $this->filemtime($path) > $time; + } + + public function filemtime($path) + { + if ($path == '' || $path == '/') { + $mtime = 0; + foreach ($this->groupoffice_shares as $map => $folder) { + $tmpmtime = $this->filemtime($map); + if ($tmpmtime > $mtime) { + $mtime = $tmpmtime; + } + } + return $mtime; + } else { + return filemtime($this->groupoffice_data . $this->get_real_path($path)); + } + } + + public function isUpdatable($path) { + if ($path == '' || $path == '/') { + return false; + } else { + if ($this->is_root_shared_folder($path)) { + return false; + } + + $fullpath = $this->get_real_path($path); + + if ($this->is_file($path)) + $fullpath = dirname($fullpath); + + $folder = \GO_Files_Model_Folder::model()->findByPath($fullpath); + + if ($folder != '') { + if ($folder->checkPermissionLevel(\GO_Base_Model_Acl::WRITE_PERMISSION)) + { + return true; + } else { + return false; + } + } + return false; + } + } + + public function isCreatable($path) { + if ($path == '' || $path == '/') { + return false; + } else { + $fullpath = $this->get_real_path($path); + + if ($this->is_file($path)) + $fullpath = dirname($fullpath); + + $folder = \GO_Files_Model_Folder::model()->findByPath($fullpath); + + if ($folder != '') { + if ($folder->checkPermissionLevel(\GO_Base_Model_Acl::CREATE_PERMISSION)) + { + return true; + } else { + return false; + } + } + + return false; + } + } + + public function isDeletable($path) { + if ($path == '' || $path == '/') { + return false; + } else { + if ($this->is_root_shared_folder($path)) { + return false; + } + + $fullpath = $this->get_real_path($path); + + if ($this->is_file($path)) + $fullpath = dirname($fullpath); + + $folder = \GO_Files_Model_Folder::model()->findByPath($fullpath); + + if ($folder != '') { + if ($folder->checkPermissionLevel(\GO_Base_Model_Acl::DELETE_PERMISSION)) + { + return true; + } else { + return false; + } + } + return false; + } + } + + public function file_exists($path) { + if ($path == '' || $path == '/') { + return true; + } else { + return file_exists($this->groupoffice_data.$this->get_real_path($path)); + } + } + + public function free_space($path) { + if ($path == '' || $path == '/') { + return \OC\Files\SPACE_UNKNOWN; + } else { + $space = @disk_free_space($this->groupoffice_data.$this->get_real_path($path)); + if ($space === false) { + return \OC\Files\SPACE_UNKNOWN; + } + return $space; + } + } + + public function mkdir($path) { + if ($path == '' || $path == '/') { + return false; + } else { + $tmp_path = dirname($path); + if ($tmp_path == '.') + $tmp_path = ''; + + if ($this->isCreatable($tmp_path)) { + $fullpath = $this->get_real_path($path); + $fullpath = dirname($fullpath); + + $folder = \GO_Files_Model_Folder::model()->findByPath($fullpath); + $folder->addFolder(basename($path)); + return true; + + } + + return false; + } + } + + public function rmdir($path) { + if ($this->isDeletable($path)) { + return $this->delTree($path); + + } else + return false; + } + + public function fopen($path, $mode) { + if ($path == '' || $path == '/') { + return false; + } else { + if ($return = fopen($this->groupoffice_data.$this->get_real_path($path), $mode)) { + switch ($mode) { + case 'r': + break; + case 'r+': + case 'w+': + case 'x+': + case 'a+': + break; + case 'w': + case 'x': + case 'a': + break; + } + } + return $return; + } + } + + public function copy($path1, $path2) { + if ($this->isCreatable(dirname($path2))) { + if ($this->is_dir($path2)) { + if (!$this->file_exists($path2)) { + $this->mkdir($path2); + } + $source = substr($path1, strrpos($path1, '/') + 1); + $path2 .= $source; + } + return copy($this->groupoffice_data.$this->get_real_path($path1), $this->groupoffice_data.$this->get_real_path($path2)); + } + } + + public function unlink($path) { + if ($path == '' || $path == '/') { + return false; + } else { + if ($this->isDeletable($path)) { + return $this->delTree($path); + } + + return false; + } + } + + private function delTree($dir) { + $dirRelative = $dir; + $dir = $this->groupoffice_data.$this->get_real_path($dir); + if (!file_exists($dir)) return true; + if (!is_dir($dir) || is_link($dir)) return unlink($dir); + foreach (scandir($dir) as $item) { + if ($item == '.' || $item == '..') continue; + if (is_file($dir . '/' . $item)) { + if (unlink($dir . '/' . $item)) { + } + } elseif (is_dir($dir . '/' . $item)) { + if (!$this->delTree($dirRelative . "/" . $item)) { + return false; + }; + } + } + if ($return = rmdir($dir)) { + } + return $return; + } + + public function file_get_contents($path) { + if ($path == '' || $path == '/') { + return false; + } else { + return file_get_contents($this->groupoffice_data.$this->get_real_path($path)); + } + } + + public function file_put_contents($path, $data) { + if ($path == '' || $path == '/') { + return false; + } else { + if (($this->file_exists($path) && !$this->isUpdatable($path)) + || ($this->is_dir($path) && !$this->isCreatable($path))) + return false; + else + return file_put_contents($this->groupoffice_data.$this->get_real_path($path), $data); + } + } + + public function touch($path, $mtime = null) { + if ($this->file_exists($path) and !$this->isUpdatable($path)) { + return false; + } + if (!is_null($mtime)) { + $result = touch($this->groupoffice_data.$this->get_real_path($path), $mtime); + } else { + $result = touch($this->groupoffice_data.$this->get_real_path($path)); + } + if ($result) { + clearstatcache(true, $this->groupoffice_data.$this->get_real_path($path)); + } + + return $result; + } +} + diff --git a/user_groupoffice.php b/user_groupoffice.php index 42e1b53..6600c92 100644 --- a/user_groupoffice.php +++ b/user_groupoffice.php @@ -1,142 +1,151 @@ _groupoffice_mount = '/'.trim(OC_Config::getValue("groupoffice_mount", "ownCloud"),' /'); - - require_once($groupoffice_root.'/GO.php'); - - //create group-office mount.json file - $datadir = \OC_Config::getValue("datadirectory", \OC::$SERVERROOT . "/data"); - $mountFile = $datadir.'/mount.json'; - - if(!file_exists($mountFile)){ - $mountConfig = array( - 'user'=>array( - 'all'=>array( - '/$user/files/Group-Office'=> - array( - 'class'=>'OC_Filestorage_Local', - 'options'=>array( - 'datadir'=>GO::config()->file_storage_path.'users/$user'.$this->_groupoffice_mount - ) - ), - - ) - ) - ); - - file_put_contents($mountFile, json_encode($mountConfig)); - } - } - - - - public function deleteUser($uid) { - // Can't delete user - return false; - } - - public function setPassword($uid, $password) { - // We can't change user password - return false; - } - - public function checkPassword($uid, $password) { - - $this->_user[$uid] = GO::session()->login($uid, $password, false); - - if (!$this->_user[$uid]) { - return false; - } else { - - //workaround bug in ownCloud - $cache = OC_User::getHome($uid).'/cache'; - if(!is_dir($cache)) - mkdir($cache,0755,true); - - //make sure ownCloud folder exists in Group-Office - $folder = new GO_Base_Fs_Folder(GO::config()->file_storage_path.'users/'.$uid.$this->_groupoffice_mount); - $folder->create(); - - - return $uid; - } - } - - /** - * - * @param string $username - * @return GO_Base_Model_User - */ - private function _getUser($username){ - if(!isset($this->_user[$username])){ - $this->_user[$username] = GO_Base_Model_User::model()->findSingleByAttribute('username', $username); - } - - - return $this->_user[$username]; - } - /* - * we don´t know if a user exists without the password. so we have to return true all the time - */ - - public function userExists($uid) { - - - return $this->_getUser($uid) != false; - } - - /** - * @return bool - */ - public function hasUserListings() { - return true; - } - - /* - * we don´t know the users so all we can do it return an empty array here - */ - - public function getUsers($search = '', $limit = 10, $offset = 0) { - $returnArray = array(); - - $fp = GO_Base_Db_FindParams::newInstance() - ->limit($limit) - ->start($offset) - ->searchQuery($search); - - $stmt = GO_Base_Model_User::model()->find($fp); - foreach($stmt as $user){ - $returnArray[]=$user->username; - } - - return $returnArray; - } - - public function getHome($uid) { - - $home = new GO_Base_Fs_Folder(GO::config()->file_storage_path.'owncloud/'.$this->_getUser($uid)->username); - $home->create(); - - return $home->path(); - } - - public function getDisplayName($uid) { - return $this->_getUser($uid)->name; - } +namespace OCA\groupoffice; +class User extends \OC_User_Backend +{ + + private $_user = array(); + + public function __construct() + { + + + $groupoffice_root = rtrim(\OC_Config::getValue("groupoffice_root", "/usr/share/groupoffice"), '/'); + + $groupoffice_config = \OC_Config::getValue("groupoffice_config"); + if (!empty($groupoffice_config)) + define('GO_CONFIG_FILE', $groupoffice_config); + + require_once($groupoffice_root . '/GO.php'); + + //create group-office mount.json file + $datadir = \OC_Config::getValue("datadirectory", \OC::$SERVERROOT . "/data"); + $mountFile = $datadir . '/mount.json'; + + if (!file_exists($mountFile)) { + $mountConfig = array( + 'user' => array( + 'all' => array( + '/$user/files/Groupoffice' => + array( + 'class' => '\OC\Files\Storage\Groupoffice', + 'options' => array( + 'user' => '$user' + ), + 'priority' => 150 + ), + + ) + ) + ); + + file_put_contents($mountFile, json_encode($mountConfig)); + } + } + + public function deleteUser($uid) + { + // Can't delete user + return false; + } + + public function setPassword($uid, $password) + { + // We can't change user password + return false; + } + + public function checkPassword($uid, $password) + { + + $this->_user[$uid] = \GO::session()->login($uid, $password, false); + + if (!$this->_user[$uid]) { + return false; + } else { + + //workaround bug in ownCloud + $cache = \OC_User::getHome($uid) . '/cache'; + if (!is_dir($cache)) + mkdir($cache, 0755, true); + + return $uid; + } + } + + private function _getUser($username) + { + if (!isset($this->_user[$username])) { + $this->_user[$username] = \GO_Base_Model_User::model()->findSingleByAttribute('username', $username); + } + + + return $this->_user[$username]; + } + + public function userExists($uid) + { + return $this->_getUser($uid) != false; + } + + public function hasUserListings() + { + return true; + } + + public function getUsers($search = '', $limit = -1, $offset = 0) + { + $returnArray = array(); + + $fp = \GO_Base_Db_FindParams::newInstance() + ->start($offset) + ->searchQuery('%' . $search . '%'); + + if ($limit > 0) + $fp->limit($limit); + + $stmt = \GO_Base_Model_User::model()->find($fp); + + foreach ($stmt as $user) { + $returnArray[] = $user->username; + } + + return $returnArray; + } + + public function getHome($uid) + { + + $home = new \GO_Base_Fs_Folder(\GO::config()->file_storage_path . 'owncloud/' . $this->_getUser($uid)->username); + $home->create(); + + return $home->path(); + } + + public function getDisplayName($uid) + { + return $this->_getUser($uid)->name; + } + + public function countUsers() + { + $findParams = \GO_Base_Db_FindParams::newInstance() + ->single() + ->select('count(*) as total'); + + $record = \GO_Base_Model_User::model()->find($findParams); + + return $record->total; + } + + public function implementsActions($actions) + { + return (bool)((OC_USER_BACKEND_CHECK_PASSWORD + | OC_USER_BACKEND_GET_HOME + | OC_USER_BACKEND_GET_DISPLAYNAME + | OC_USER_BACKEND_COUNT_USERS) + & $actions); + } } +