Merge pull request #20719 from owncloud/adding-system-addressbook-of-users
Adding system addressbook for users of this instance - a occ command …
This commit is contained in:
commit
df5872ec50
|
@ -2,7 +2,9 @@
|
|||
|
||||
use OCA\DAV\Command\CreateAddressBook;
|
||||
use OCA\DAV\Command\CreateCalendar;
|
||||
use OCA\DAV\Command\SyncSystemAddressBook;
|
||||
|
||||
$config = \OC::$server->getConfig();
|
||||
$dbConnection = \OC::$server->getDatabaseConnection();
|
||||
$userManager = OC::$server->getUserManager();
|
||||
$config = \OC::$server->getConfig();
|
||||
|
@ -10,3 +12,4 @@ $config = \OC::$server->getConfig();
|
|||
/** @var Symfony\Component\Console\Application $application */
|
||||
$application->add(new CreateAddressBook($userManager, $dbConnection, $config));
|
||||
$application->add(new CreateCalendar($userManager, $dbConnection));
|
||||
$application->add(new SyncSystemAddressBook($userManager, $dbConnection, $config));
|
||||
|
|
|
@ -0,0 +1,107 @@
|
|||
<?php
|
||||
|
||||
namespace OCA\DAV\Command;
|
||||
|
||||
use OCA\DAV\CardDAV\CardDavBackend;
|
||||
use OCA\DAV\CardDAV\Converter;
|
||||
use OCA\DAV\Connector\Sabre\Principal;
|
||||
use OCP\IConfig;
|
||||
use OCP\IDBConnection;
|
||||
use OCP\IUser;
|
||||
use OCP\IUserManager;
|
||||
use Sabre\CardDAV\Plugin;
|
||||
use Sabre\VObject\Component\VCard;
|
||||
use Sabre\VObject\Property\Text;
|
||||
use Sabre\VObject\Reader;
|
||||
use Symfony\Component\Console\Command\Command;
|
||||
use Symfony\Component\Console\Helper\ProgressBar;
|
||||
use Symfony\Component\Console\Input\InputArgument;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
|
||||
class SyncSystemAddressBook extends Command {
|
||||
|
||||
/** @var IUserManager */
|
||||
protected $userManager;
|
||||
|
||||
/** @var \OCP\IDBConnection */
|
||||
protected $dbConnection;
|
||||
|
||||
/** @var IConfig */
|
||||
protected $config;
|
||||
|
||||
/** @var CardDavBackend */
|
||||
private $backend;
|
||||
|
||||
/**
|
||||
* @param IUserManager $userManager
|
||||
* @param IDBConnection $dbConnection
|
||||
* @param IConfig $config
|
||||
*/
|
||||
function __construct(IUserManager $userManager, IDBConnection $dbConnection, IConfig $config) {
|
||||
parent::__construct();
|
||||
$this->userManager = $userManager;
|
||||
$this->dbConnection = $dbConnection;
|
||||
$this->config = $config;
|
||||
}
|
||||
|
||||
protected function configure() {
|
||||
$this
|
||||
->setName('dav:sync-system-addressbook')
|
||||
->setDescription('Synchronizes users to the system addressbook');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param InputInterface $input
|
||||
* @param OutputInterface $output
|
||||
*/
|
||||
protected function execute(InputInterface $input, OutputInterface $output) {
|
||||
$principalBackend = new Principal(
|
||||
$this->config,
|
||||
$this->userManager
|
||||
);
|
||||
|
||||
$this->backend = new CardDavBackend($this->dbConnection, $principalBackend);
|
||||
|
||||
// ensure system addressbook exists
|
||||
$systemAddressBook = $this->ensureSystemAddressBookExists();
|
||||
$converter = new Converter();
|
||||
|
||||
$output->writeln('Syncing users ...');
|
||||
$progress = new ProgressBar($output);
|
||||
$progress->start();
|
||||
$this->userManager->callForAllUsers(function($user) use ($systemAddressBook, $converter, $progress) {
|
||||
/** @var IUser $user */
|
||||
$name = $user->getBackendClassName();
|
||||
$userId = $user->getUID();
|
||||
|
||||
$cardId = "$name:$userId.vcf";
|
||||
$card = $this->backend->getCard($systemAddressBook['id'], $cardId);
|
||||
if ($card === false) {
|
||||
$vCard = $converter->createCardFromUser($user);
|
||||
$this->backend->createCard($systemAddressBook['id'], $cardId, $vCard->serialize());
|
||||
} else {
|
||||
$vCard = Reader::read($card['carddata']);
|
||||
if ($converter->updateCard($vCard, $user)) {
|
||||
$this->backend->updateCard($systemAddressBook['id'], $cardId, $vCard->serialize());
|
||||
}
|
||||
}
|
||||
$progress->advance();
|
||||
});
|
||||
$progress->finish();
|
||||
$output->writeln('');
|
||||
}
|
||||
|
||||
protected function ensureSystemAddressBookExists() {
|
||||
$book = $this->backend->getAddressBooksByUri('system');
|
||||
if (!is_null($book)) {
|
||||
return $book;
|
||||
}
|
||||
$systemPrincipal = "principals/system/system";
|
||||
$this->backend->createAddressBook($systemPrincipal, 'system', [
|
||||
'{' . Plugin::NS_CARDDAV . '}addressbook-description' => 'System addressbook which holds all users of this instance'
|
||||
]);
|
||||
|
||||
return $this->backend->getAddressBooksByUri('system');
|
||||
}
|
||||
}
|
|
@ -3,6 +3,7 @@
|
|||
namespace OCA\DAV\CardDAV;
|
||||
|
||||
use OCA\DAV\CardDAV\Sharing\IShareableAddressBook;
|
||||
use Sabre\DAV\Exception\NotFound;
|
||||
|
||||
class AddressBook extends \Sabre\CardDAV\AddressBook implements IShareableAddressBook {
|
||||
|
||||
|
@ -51,4 +52,39 @@ class AddressBook extends \Sabre\CardDAV\AddressBook implements IShareableAddres
|
|||
$carddavBackend = $this->carddavBackend;
|
||||
$carddavBackend->getShares($this->getName());
|
||||
}
|
||||
|
||||
function getACL() {
|
||||
$acl = parent::getACL();
|
||||
if ($this->getOwner() === 'principals/system/system') {
|
||||
$acl[] = [
|
||||
'privilege' => '{DAV:}read',
|
||||
'principal' => '{DAV:}authenticated',
|
||||
'protected' => true,
|
||||
];
|
||||
}
|
||||
|
||||
return $acl;
|
||||
}
|
||||
|
||||
function getChildACL() {
|
||||
$acl = parent::getChildACL();
|
||||
if ($this->getOwner() === 'principals/system/system') {
|
||||
$acl[] = [
|
||||
'privilege' => '{DAV:}read',
|
||||
'principal' => '{DAV:}authenticated',
|
||||
'protected' => true,
|
||||
];
|
||||
}
|
||||
|
||||
return $acl;
|
||||
}
|
||||
|
||||
function getChild($name) {
|
||||
$obj = $this->carddavBackend->getCard($this->addressBookInfo['id'], $name);
|
||||
if (!$obj) {
|
||||
throw new NotFound('Card not found');
|
||||
}
|
||||
return new Card($this->carddavBackend, $this->addressBookInfo, $obj);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -20,4 +20,14 @@ class AddressBookRoot extends \Sabre\CardDAV\AddressBookRoot {
|
|||
|
||||
}
|
||||
|
||||
}
|
||||
function getName() {
|
||||
|
||||
// Grabbing all the components of the principal path.
|
||||
$parts = explode('/', $this->principalPrefix);
|
||||
|
||||
// We are only interested in the second part.
|
||||
return $parts[1];
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,39 @@
|
|||
<?php
|
||||
/**
|
||||
* @author Thomas Müller <thomas.mueller@tmit.eu>
|
||||
*
|
||||
* @copyright Copyright (c) 2015, ownCloud, Inc.
|
||||
* @license AGPL-3.0
|
||||
*
|
||||
* This code is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License, version 3,
|
||||
* as published by the Free Software Foundation.
|
||||
*
|
||||
* 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 Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License, version 3,
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
*
|
||||
*/
|
||||
|
||||
namespace OCA\DAV\CardDAV;
|
||||
|
||||
class Card extends \Sabre\CardDAV\Card {
|
||||
|
||||
function getACL() {
|
||||
$acl = parent::getACL();
|
||||
if ($this->getOwner() === 'principals/system/system') {
|
||||
$acl[] = [
|
||||
'privilege' => '{DAV:}read',
|
||||
'principal' => '{DAV:}authenticated',
|
||||
'protected' => true,
|
||||
];
|
||||
}
|
||||
|
||||
return $acl;
|
||||
}
|
||||
|
||||
}
|
|
@ -108,7 +108,7 @@ class CardDavBackend implements BackendInterface, SyncSupport {
|
|||
return $addressBooks;
|
||||
}
|
||||
|
||||
private function getAddressBooksByUri($addressBookUri) {
|
||||
public function getAddressBooksByUri($addressBookUri) {
|
||||
$query = $this->db->getQueryBuilder();
|
||||
$result = $query->select(['id', 'uri', 'displayname', 'principaluri', 'description', 'synctoken'])
|
||||
->from('addressbooks')
|
||||
|
@ -117,10 +117,10 @@ class CardDavBackend implements BackendInterface, SyncSupport {
|
|||
->execute();
|
||||
|
||||
$row = $result->fetch();
|
||||
if (is_null($row)) {
|
||||
$result->closeCursor();
|
||||
if ($row === false) {
|
||||
return null;
|
||||
}
|
||||
$result->closeCursor();
|
||||
|
||||
return [
|
||||
'id' => $row['id'],
|
||||
|
|
|
@ -0,0 +1,158 @@
|
|||
<?php
|
||||
/**
|
||||
* @author Thomas Müller <thomas.mueller@tmit.eu>
|
||||
*
|
||||
* @copyright Copyright (c) 2015, ownCloud, Inc.
|
||||
* @license AGPL-3.0
|
||||
*
|
||||
* This code is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License, version 3,
|
||||
* as published by the Free Software Foundation.
|
||||
*
|
||||
* 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 Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License, version 3,
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
*
|
||||
*/
|
||||
|
||||
namespace OCA\DAV\CardDAV;
|
||||
|
||||
use OCP\IImage;
|
||||
use OCP\IUser;
|
||||
use Sabre\VObject\Component\VCard;
|
||||
use Sabre\VObject\Property\Text;
|
||||
|
||||
class Converter {
|
||||
|
||||
/**
|
||||
* @param IUser $user
|
||||
* @return VCard
|
||||
*/
|
||||
public function createCardFromUser(IUser $user) {
|
||||
|
||||
$uid = $user->getUID();
|
||||
$displayName = $user->getDisplayName();
|
||||
$displayName = empty($displayName ) ? $uid : $displayName;
|
||||
$emailAddress = $user->getEMailAddress();
|
||||
$cloudId = $user->getCloudId();
|
||||
$image = $user->getAvatarImage(-1);
|
||||
|
||||
$vCard = new VCard();
|
||||
$vCard->add(new Text($vCard, 'UID', $uid));
|
||||
if (!empty($displayName)) {
|
||||
$vCard->add(new Text($vCard, 'FN', $displayName));
|
||||
$vCard->add(new Text($vCard, 'N', $this->splitFullName($displayName)));
|
||||
}
|
||||
if (!empty($emailAddress)) {
|
||||
$vCard->add(new Text($vCard, 'EMAIL', $emailAddress, ['TYPE' => 'OTHER']));
|
||||
}
|
||||
if (!empty($cloudId)) {
|
||||
$vCard->add(new Text($vCard, 'CLOUD', $cloudId));
|
||||
}
|
||||
if ($image) {
|
||||
$vCard->add('PHOTO', $image->data(), ['ENCODING' => 'b', 'TYPE' => $image->mimeType()]);
|
||||
}
|
||||
$vCard->validate();
|
||||
|
||||
return $vCard;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param VCard $vCard
|
||||
* @param IUser $user
|
||||
* @return bool
|
||||
*/
|
||||
public function updateCard(VCard $vCard, IUser $user) {
|
||||
$uid = $user->getUID();
|
||||
$displayName = $user->getDisplayName();
|
||||
$displayName = empty($displayName ) ? $uid : $displayName;
|
||||
$emailAddress = $user->getEMailAddress();
|
||||
$cloudId = $user->getCloudId();
|
||||
$image = $user->getAvatarImage(-1);
|
||||
|
||||
$updated = false;
|
||||
if($this->propertyNeedsUpdate($vCard, 'FN', $displayName)) {
|
||||
$vCard->FN = new Text($vCard, 'FN', $displayName);
|
||||
unset($vCard->N);
|
||||
$vCard->add(new Text($vCard, 'N', $this->splitFullName($displayName)));
|
||||
$updated = true;
|
||||
}
|
||||
if($this->propertyNeedsUpdate($vCard, 'EMAIL', $emailAddress)) {
|
||||
$vCard->EMAIL = new Text($vCard, 'EMAIL', $emailAddress);
|
||||
$updated = true;
|
||||
}
|
||||
if($this->propertyNeedsUpdate($vCard, 'CLOUD', $cloudId)) {
|
||||
$vCard->CLOUD = new Text($vCard, 'CLOUD', $cloudId);
|
||||
$updated = true;
|
||||
}
|
||||
|
||||
if($this->propertyNeedsUpdate($vCard, 'PHOTO', $image)) {
|
||||
$vCard->add('PHOTO', $image->data(), ['ENCODING' => 'b', 'TYPE' => $image->mimeType()]);
|
||||
$updated = true;
|
||||
}
|
||||
|
||||
if (empty($emailAddress) && !is_null($vCard->EMAIL)) {
|
||||
unset($vCard->EMAIL);
|
||||
$updated = true;
|
||||
}
|
||||
if (empty($cloudId) && !is_null($vCard->CLOUD)) {
|
||||
unset($vCard->CLOUD);
|
||||
$updated = true;
|
||||
}
|
||||
if (empty($image) && !is_null($vCard->PHOTO)) {
|
||||
unset($vCard->PHOTO);
|
||||
$updated = true;
|
||||
}
|
||||
|
||||
return $updated;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param VCard $vCard
|
||||
* @param string $name
|
||||
* @param string|IImage $newValue
|
||||
* @return bool
|
||||
*/
|
||||
private function propertyNeedsUpdate(VCard $vCard, $name, $newValue) {
|
||||
if (is_null($newValue)) {
|
||||
return false;
|
||||
}
|
||||
$value = $vCard->__get($name);
|
||||
if (!is_null($value)) {
|
||||
$value = $value->getValue();
|
||||
$newValue = $newValue instanceof IImage ? $newValue->data() : $newValue;
|
||||
|
||||
return $value !== $newValue;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $fullName
|
||||
* @return string[]
|
||||
*/
|
||||
public function splitFullName($fullName) {
|
||||
// Very basic western style parsing. I'm not gonna implement
|
||||
// https://github.com/android/platform_packages_providers_contactsprovider/blob/master/src/com/android/providers/contacts/NameSplitter.java ;)
|
||||
|
||||
$elements = explode(' ', $fullName);
|
||||
$result = ['', '', '', '', ''];
|
||||
if (count($elements) > 2) {
|
||||
$result[0] = implode(' ', array_slice($elements, count($elements)-1));
|
||||
$result[1] = $elements[0];
|
||||
$result[2] = implode(' ', array_slice($elements, 1, count($elements)-2));
|
||||
} elseif (count($elements) === 2) {
|
||||
$result[0] = $elements[1];
|
||||
$result[1] = $elements[0];
|
||||
} else {
|
||||
$result[0] = $elements[0];
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,47 @@
|
|||
<?php
|
||||
/**
|
||||
* @author Thomas Müller <thomas.mueller@tmit.eu>
|
||||
*
|
||||
* @copyright Copyright (c) 2015, ownCloud, Inc.
|
||||
* @license AGPL-3.0
|
||||
*
|
||||
* This code is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License, version 3,
|
||||
* as published by the Free Software Foundation.
|
||||
*
|
||||
* 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 Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License, version 3,
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
*
|
||||
*/
|
||||
|
||||
namespace OCA\DAV\CardDAV;
|
||||
|
||||
use Sabre\HTTP\URLUtil;
|
||||
|
||||
class Plugin extends \Sabre\CardDAV\Plugin {
|
||||
|
||||
/**
|
||||
* Returns the addressbook home for a given principal
|
||||
*
|
||||
* @param string $principal
|
||||
* @return string
|
||||
*/
|
||||
protected function getAddressbookHomeForPrincipal($principal) {
|
||||
|
||||
if (strrpos($principal, 'principals/users', -strlen($principal)) !== FALSE) {
|
||||
list(, $principalId) = URLUtil::splitPath($principal);
|
||||
return self::ADDRESSBOOK_ROOT . '/users/' . $principalId;
|
||||
}
|
||||
if (strrpos($principal, 'principals/system', -strlen($principal)) !== FALSE) {
|
||||
list(, $principalId) = URLUtil::splitPath($principal);
|
||||
return self::ADDRESSBOOK_ROOT . '/system/' . $principalId;
|
||||
}
|
||||
|
||||
throw new \LogicException('This is not supposed to happen');
|
||||
}
|
||||
}
|
|
@ -11,13 +11,39 @@ class UserAddressBooks extends \Sabre\CardDAV\AddressBookHome {
|
|||
*/
|
||||
function getChildren() {
|
||||
|
||||
$addressbooks = $this->carddavBackend->getAddressBooksForUser($this->principalUri);
|
||||
$objs = [];
|
||||
foreach($addressbooks as $addressbook) {
|
||||
$objs[] = new AddressBook($this->carddavBackend, $addressbook);
|
||||
$addressBooks = $this->carddavBackend->getAddressBooksForUser($this->principalUri);
|
||||
$objects = [];
|
||||
foreach($addressBooks as $addressBook) {
|
||||
$objects[] = new AddressBook($this->carddavBackend, $addressBook);
|
||||
}
|
||||
return $objs;
|
||||
return $objects;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a list of ACE's for this node.
|
||||
*
|
||||
* Each ACE has the following properties:
|
||||
* * 'privilege', a string such as {DAV:}read or {DAV:}write. These are
|
||||
* currently the only supported privileges
|
||||
* * 'principal', a url to the principal who owns the node
|
||||
* * 'protected' (optional), indicating that this ACE is not allowed to
|
||||
* be updated.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
function getACL() {
|
||||
|
||||
$acl = parent::getACL();
|
||||
if ($this->principalUri === 'principals/system/system') {
|
||||
$acl[] = [
|
||||
'privilege' => '{DAV:}read',
|
||||
'principal' => '{DAV:}authenticated',
|
||||
'protected' => true,
|
||||
];
|
||||
}
|
||||
|
||||
return $acl;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,183 @@
|
|||
<?php
|
||||
/**
|
||||
* @author Thomas Müller <thomas.mueller@tmit.eu>
|
||||
*
|
||||
* @copyright Copyright (c) 2015, ownCloud, Inc.
|
||||
* @license AGPL-3.0
|
||||
*
|
||||
* This code is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License, version 3,
|
||||
* as published by the Free Software Foundation.
|
||||
*
|
||||
* 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 Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License, version 3,
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
*
|
||||
*/
|
||||
|
||||
namespace OCA\DAV\DAV;
|
||||
|
||||
use Sabre\DAVACL\PrincipalBackend\AbstractBackend;
|
||||
use Sabre\HTTP\URLUtil;
|
||||
|
||||
class SystemPrincipalBackend extends AbstractBackend {
|
||||
|
||||
/**
|
||||
* Returns a list of principals based on a prefix.
|
||||
*
|
||||
* This prefix will often contain something like 'principals'. You are only
|
||||
* expected to return principals that are in this base path.
|
||||
*
|
||||
* You are expected to return at least a 'uri' for every user, you can
|
||||
* return any additional properties if you wish so. Common properties are:
|
||||
* {DAV:}displayname
|
||||
* {http://sabredav.org/ns}email-address - This is a custom SabreDAV
|
||||
* field that's actually injected in a number of other properties. If
|
||||
* you have an email address, use this property.
|
||||
*
|
||||
* @param string $prefixPath
|
||||
* @return array
|
||||
*/
|
||||
function getPrincipalsByPrefix($prefixPath) {
|
||||
$principals = [];
|
||||
|
||||
if ($prefixPath === 'principals/system') {
|
||||
$principals[] = [
|
||||
'uri' => 'principals/system/system',
|
||||
'{DAV:}displayname' => 'system',
|
||||
];
|
||||
}
|
||||
|
||||
return $principals;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a specific principal, specified by it's path.
|
||||
* The returned structure should be the exact same as from
|
||||
* getPrincipalsByPrefix.
|
||||
*
|
||||
* @param string $path
|
||||
* @return array
|
||||
*/
|
||||
function getPrincipalByPath($path) {
|
||||
|
||||
$elements = explode('/', $path);
|
||||
if ($elements[0] !== 'principals') {
|
||||
return null;
|
||||
}
|
||||
if ($elements[1] === 'system') {
|
||||
$principal = [
|
||||
'uri' => 'principals/system/system',
|
||||
'{DAV:}displayname' => 'system',
|
||||
];
|
||||
return $principal;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates one ore more webdav properties on a principal.
|
||||
*
|
||||
* The list of mutations is stored in a Sabre\DAV\PropPatch object.
|
||||
* To do the actual updates, you must tell this object which properties
|
||||
* you're going to process with the handle() method.
|
||||
*
|
||||
* Calling the handle method is like telling the PropPatch object "I
|
||||
* promise I can handle updating this property".
|
||||
*
|
||||
* Read the PropPatch documentation for more info and examples.
|
||||
*
|
||||
* @param string $path
|
||||
* @param \Sabre\DAV\PropPatch $propPatch
|
||||
* @return void
|
||||
*/
|
||||
function updatePrincipal($path, \Sabre\DAV\PropPatch $propPatch) {
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is used to search for principals matching a set of
|
||||
* properties.
|
||||
*
|
||||
* This search is specifically used by RFC3744's principal-property-search
|
||||
* REPORT.
|
||||
*
|
||||
* The actual search should be a unicode-non-case-sensitive search. The
|
||||
* keys in searchProperties are the WebDAV property names, while the values
|
||||
* are the property values to search on.
|
||||
*
|
||||
* By default, if multiple properties are submitted to this method, the
|
||||
* various properties should be combined with 'AND'. If $test is set to
|
||||
* 'anyof', it should be combined using 'OR'.
|
||||
*
|
||||
* This method should simply return an array with full principal uri's.
|
||||
*
|
||||
* If somebody attempted to search on a property the backend does not
|
||||
* support, you should simply return 0 results.
|
||||
*
|
||||
* You can also just return 0 results if you choose to not support
|
||||
* searching at all, but keep in mind that this may stop certain features
|
||||
* from working.
|
||||
*
|
||||
* @param string $prefixPath
|
||||
* @param array $searchProperties
|
||||
* @param string $test
|
||||
* @return array
|
||||
*/
|
||||
function searchPrincipals($prefixPath, array $searchProperties, $test = 'allof') {
|
||||
return [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the list of members for a group-principal
|
||||
*
|
||||
* @param string $principal
|
||||
* @return array
|
||||
*/
|
||||
function getGroupMemberSet($principal) {
|
||||
// TODO: for now the group principal has only one member, the user itself
|
||||
$principal = $this->getPrincipalByPath($principal);
|
||||
if (!$principal) {
|
||||
throw new \Sabre\DAV\Exception('Principal not found');
|
||||
}
|
||||
|
||||
return [$principal['uri']];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the list of groups a principal is a member of
|
||||
*
|
||||
* @param string $principal
|
||||
* @return array
|
||||
*/
|
||||
function getGroupMembership($principal) {
|
||||
list($prefix, $name) = URLUtil::splitPath($principal);
|
||||
|
||||
if ($prefix === 'principals/system') {
|
||||
$principal = $this->getPrincipalByPath($principal);
|
||||
if (!$principal) {
|
||||
throw new \Sabre\DAV\Exception('Principal not found');
|
||||
}
|
||||
|
||||
return [];
|
||||
}
|
||||
return [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the list of group members for a group principal.
|
||||
*
|
||||
* The principals should be passed as a list of uri's.
|
||||
*
|
||||
* @param string $principal
|
||||
* @param array $members
|
||||
* @return void
|
||||
*/
|
||||
function setGroupMemberSet($principal, array $members) {
|
||||
throw new \Sabre\DAV\Exception('Setting members of the group is not supported yet');
|
||||
}
|
||||
}
|
|
@ -6,6 +6,7 @@ use OCA\DAV\CalDAV\CalDavBackend;
|
|||
use OCA\DAV\CardDAV\AddressBookRoot;
|
||||
use OCA\DAV\CardDAV\CardDavBackend;
|
||||
use OCA\DAV\Connector\Sabre\Principal;
|
||||
use OCA\DAV\DAV\SystemPrincipalBackend;
|
||||
use Sabre\CalDAV\CalendarRoot;
|
||||
use Sabre\CalDAV\Principal\Collection;
|
||||
use Sabre\DAV\SimpleCollection;
|
||||
|
@ -23,24 +24,33 @@ class RootCollection extends SimpleCollection {
|
|||
$disableListing = !$config->getSystemValue('debug', false);
|
||||
|
||||
// setup the first level of the dav tree
|
||||
$principalCollection = new Collection($principalBackend, 'principals/users');
|
||||
$principalCollection->disableListing = $disableListing;
|
||||
$userPrincipals = new Collection($principalBackend, 'principals/users');
|
||||
$userPrincipals->disableListing = $disableListing;
|
||||
$systemPrincipals = new Collection(new SystemPrincipalBackend(), 'principals/system');
|
||||
$systemPrincipals->disableListing = $disableListing;
|
||||
$filesCollection = new Files\RootCollection($principalBackend, 'principals/users');
|
||||
$filesCollection->disableListing = $disableListing;
|
||||
$caldavBackend = new CalDavBackend($db);
|
||||
$calendarRoot = new CalendarRoot($principalBackend, $caldavBackend, 'principals/users');
|
||||
$calendarRoot->disableListing = $disableListing;
|
||||
|
||||
$cardDavBackend = new CardDavBackend(\OC::$server->getDatabaseConnection(), $principalBackend);
|
||||
$usersCardDavBackend = new CardDavBackend($db, $principalBackend);
|
||||
$usersAddressBookRoot = new AddressBookRoot($principalBackend, $usersCardDavBackend, 'principals/users');
|
||||
$usersAddressBookRoot->disableListing = $disableListing;
|
||||
|
||||
$addressBookRoot = new AddressBookRoot($principalBackend, $cardDavBackend, 'principals/users');
|
||||
$addressBookRoot->disableListing = $disableListing;
|
||||
$systemCardDavBackend = new CardDavBackend($db, $principalBackend);
|
||||
$systemAddressBookRoot = new AddressBookRoot(new SystemPrincipalBackend(), $systemCardDavBackend, 'principals/system');
|
||||
$systemAddressBookRoot->disableListing = $disableListing;
|
||||
|
||||
$children = [
|
||||
new SimpleCollection('principals', [$principalCollection]),
|
||||
new SimpleCollection('principals', [
|
||||
$userPrincipals,
|
||||
$systemPrincipals]),
|
||||
$filesCollection,
|
||||
$calendarRoot,
|
||||
$addressBookRoot,
|
||||
new SimpleCollection('addressbooks', [
|
||||
$usersAddressBookRoot,
|
||||
$systemAddressBookRoot]),
|
||||
];
|
||||
|
||||
parent::__construct('root', $children);
|
||||
|
|
|
@ -58,7 +58,7 @@ class Server {
|
|||
$this->server->addPlugin(new CardDAV\Sharing\Plugin($authBackend, \OC::$server->getRequest()));
|
||||
|
||||
// addressbook plugins
|
||||
$this->server->addPlugin(new \Sabre\CardDAV\Plugin());
|
||||
$this->server->addPlugin(new \OCA\DAV\CardDAV\Plugin());
|
||||
|
||||
// Finder on OS X requires Class 2 WebDAV support (locking), since we do
|
||||
// not provide locking we emulate it using a fake locking plugin.
|
||||
|
|
|
@ -569,7 +569,7 @@
|
|||
<!-- relative path to user addressbook home-->
|
||||
<substitution>
|
||||
<key>$addressbookhome%d:</key>
|
||||
<value>$addressbooks:$userid%d:</value>
|
||||
<value>$addressbooks:users/$userid%d:</value>
|
||||
</substitution>
|
||||
<!-- relative path to user addressbook-->
|
||||
<substitution>
|
||||
|
|
|
@ -181,8 +181,7 @@
|
|||
</verify>
|
||||
</request>
|
||||
</test>
|
||||
<!--
|
||||
<test name='6'>
|
||||
<!-- test name='6'>
|
||||
<require-feature>
|
||||
<feature>sync-report-home</feature>
|
||||
</require-feature>
|
||||
|
@ -236,7 +235,7 @@
|
|||
</arg>
|
||||
</verify>
|
||||
</request>
|
||||
</test>
|
||||
</test -->
|
||||
<test name='8'>
|
||||
<description>remove new resource</description>
|
||||
<request>
|
||||
|
@ -264,14 +263,15 @@
|
|||
<callback>multistatusItems</callback>
|
||||
<arg>
|
||||
<name>okhrefs</name>
|
||||
<value>$calendar_sync_extra_items:</value>
|
||||
<!-- no sync on addressbook level -->
|
||||
<!--<value>$calendar_sync_extra_items:</value>-->
|
||||
<value>1.vcf</value>
|
||||
<value>2.vcf</value>
|
||||
</arg>
|
||||
</verify>
|
||||
</request>
|
||||
</test>
|
||||
<test name='10'>
|
||||
<!--test name='10'>
|
||||
<require-feature>
|
||||
<feature>sync-report-home</feature>
|
||||
</require-feature>
|
||||
|
|
|
@ -0,0 +1,136 @@
|
|||
<?php
|
||||
/**
|
||||
* @author Thomas Müller <thomas.mueller@tmit.eu>
|
||||
*
|
||||
* @copyright Copyright (c) 2015, ownCloud, Inc.
|
||||
* @license AGPL-3.0
|
||||
*
|
||||
* This code is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License, version 3,
|
||||
* as published by the Free Software Foundation.
|
||||
*
|
||||
* 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 Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License, version 3,
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
*
|
||||
*/
|
||||
|
||||
namespace OCA\DAV\Tests\Unit;
|
||||
|
||||
use OCA\DAV\CardDAV\Converter;
|
||||
use Test\TestCase;
|
||||
|
||||
class ConverterTests extends TestCase {
|
||||
|
||||
/**
|
||||
* @dataProvider providesNewUsers
|
||||
*/
|
||||
public function testCreation($expectedVCard, $displayName = null, $eMailAddress = null, $cloudId = null) {
|
||||
$user = $this->getUserMock($displayName, $eMailAddress, $cloudId);
|
||||
|
||||
$converter = new Converter();
|
||||
$vCard = $converter->createCardFromUser($user);
|
||||
$cardData = $vCard->serialize();
|
||||
|
||||
$this->assertEquals($expectedVCard, $cardData);
|
||||
}
|
||||
|
||||
public function providesNewUsers() {
|
||||
return [
|
||||
["BEGIN:VCARD\r\nVERSION:3.0\r\nPRODID:-//Sabre//Sabre VObject 3.4.7//EN\r\nUID:12345\r\nFN:12345\r\nN:12345;;;;\r\nPHOTO;ENCODING=b;TYPE=JPEG:MTIzNDU2Nzg5\r\nEND:VCARD\r\n"],
|
||||
["BEGIN:VCARD\r\nVERSION:3.0\r\nPRODID:-//Sabre//Sabre VObject 3.4.7//EN\r\nUID:12345\r\nFN:Dr. Foo Bar\r\nN:Bar;Dr.;Foo;;\r\nPHOTO;ENCODING=b;TYPE=JPEG:MTIzNDU2Nzg5\r\nEND:VCARD\r\n", "Dr. Foo Bar"],
|
||||
["BEGIN:VCARD\r\nVERSION:3.0\r\nPRODID:-//Sabre//Sabre VObject 3.4.7//EN\r\nUID:12345\r\nFN:Dr. Foo Bar\r\nN:Bar;Dr.;Foo;;\r\nEMAIL;TYPE=OTHER:foo@bar.net\r\nPHOTO;ENCODING=b;TYPE=JPEG:MTIzNDU2Nzg5\r\nEND:VCARD\r\n", "Dr. Foo Bar", "foo@bar.net"],
|
||||
["BEGIN:VCARD\r\nVERSION:3.0\r\nPRODID:-//Sabre//Sabre VObject 3.4.7//EN\r\nUID:12345\r\nFN:Dr. Foo Bar\r\nN:Bar;Dr.;Foo;;\r\nCLOUD:foo@bar.net\r\nPHOTO;ENCODING=b;TYPE=JPEG:MTIzNDU2Nzg5\r\nEND:VCARD\r\n", "Dr. Foo Bar", null, "foo@bar.net"],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providesNewUsers
|
||||
*/
|
||||
public function testUpdateOfUnchangedUser($expectedVCard, $displayName = null, $eMailAddress = null, $cloudId = null) {
|
||||
$user = $this->getUserMock($displayName, $eMailAddress, $cloudId);
|
||||
|
||||
$converter = new Converter();
|
||||
$vCard = $converter->createCardFromUser($user);
|
||||
$updated = $converter->updateCard($vCard, $user);
|
||||
$this->assertFalse($updated);
|
||||
$cardData = $vCard->serialize();
|
||||
|
||||
$this->assertEquals($expectedVCard, $cardData);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providesUsersForUpdateOfRemovedElement
|
||||
*/
|
||||
public function testUpdateOfRemovedElement($expectedVCard, $displayName = null, $eMailAddress = null, $cloudId = null) {
|
||||
$user = $this->getUserMock($displayName, $eMailAddress, $cloudId);
|
||||
|
||||
$converter = new Converter();
|
||||
$vCard = $converter->createCardFromUser($user);
|
||||
|
||||
$user1 = $this->getMockBuilder('OCP\IUser')->disableOriginalConstructor()->getMock();
|
||||
$user1->method('getUID')->willReturn('12345');
|
||||
$user1->method('getDisplayName')->willReturn(null);
|
||||
$user1->method('getEMailAddress')->willReturn(null);
|
||||
$user1->method('getCloudId')->willReturn(null);
|
||||
$user1->method('getAvatarImage')->willReturn(null);
|
||||
|
||||
$updated = $converter->updateCard($vCard, $user1);
|
||||
$this->assertTrue($updated);
|
||||
$cardData = $vCard->serialize();
|
||||
|
||||
$this->assertEquals($expectedVCard, $cardData);
|
||||
}
|
||||
|
||||
public function providesUsersForUpdateOfRemovedElement() {
|
||||
return [
|
||||
["BEGIN:VCARD\r\nVERSION:3.0\r\nPRODID:-//Sabre//Sabre VObject 3.4.7//EN\r\nUID:12345\r\nFN:12345\r\nN:12345;;;;\r\nEND:VCARD\r\n", "Dr. Foo Bar"],
|
||||
["BEGIN:VCARD\r\nVERSION:3.0\r\nPRODID:-//Sabre//Sabre VObject 3.4.7//EN\r\nUID:12345\r\nFN:12345\r\nN:12345;;;;\r\nEND:VCARD\r\n", "Dr. Foo Bar", "foo@bar.net"],
|
||||
["BEGIN:VCARD\r\nVERSION:3.0\r\nPRODID:-//Sabre//Sabre VObject 3.4.7//EN\r\nUID:12345\r\nFN:12345\r\nN:12345;;;;\r\nEND:VCARD\r\n", "Dr. Foo Bar", null, "foo@bar.net"],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providesNames
|
||||
* @param $expected
|
||||
* @param $fullName
|
||||
*/
|
||||
public function testNameSplitter($expected, $fullName) {
|
||||
|
||||
$converter = new Converter();
|
||||
$r = $converter->splitFullName($fullName);
|
||||
$r = implode(';', $r);
|
||||
$this->assertEquals($expected, $r);
|
||||
}
|
||||
|
||||
public function providesNames() {
|
||||
return [
|
||||
['Sauron;;;;', 'Sauron'],
|
||||
['Baggins;Bilbo;;;', 'Bilbo Baggins'],
|
||||
['Tolkien;John;Ronald Reuel;;', 'John Ronald Reuel Tolkien'],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $displayName
|
||||
* @param $eMailAddress
|
||||
* @param $cloudId
|
||||
* @return \PHPUnit_Framework_MockObject_MockObject
|
||||
*/
|
||||
protected function getUserMock($displayName, $eMailAddress, $cloudId) {
|
||||
$image0 = $this->getMockBuilder('OCP\IImage')->disableOriginalConstructor()->getMock();
|
||||
$image0->method('mimeType')->willReturn('JPEG');
|
||||
$image0->method('data')->willReturn('123456789');
|
||||
$user = $this->getMockBuilder('OCP\IUser')->disableOriginalConstructor()->getMock();
|
||||
$user->method('getUID')->willReturn('12345');
|
||||
$user->method('getDisplayName')->willReturn($displayName);
|
||||
$user->method('getEMailAddress')->willReturn($eMailAddress);
|
||||
$user->method('getCloudId')->willReturn($cloudId);
|
||||
$user->method('getAvatarImage')->willReturn($image0);
|
||||
return $user;
|
||||
}
|
||||
}
|
|
@ -310,20 +310,4 @@ class Helper {
|
|||
\OC::$server->getConfig()->setSystemValue('share_folder', $shareFolder);
|
||||
}
|
||||
|
||||
/**
|
||||
* remove protocol from URL
|
||||
*
|
||||
* @param string $url
|
||||
* @return string
|
||||
*/
|
||||
public static function removeProtocolFromUrl($url) {
|
||||
if (strpos($url, 'https://') === 0) {
|
||||
return substr($url, strlen('https://'));
|
||||
} else if (strpos($url, 'http://') === 0) {
|
||||
return substr($url, strlen('http://'));
|
||||
}
|
||||
|
||||
return $url;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -32,9 +32,7 @@ if (count($matches) > 0 && $matches[1] <= 9) {
|
|||
$isIE8 = true;
|
||||
}
|
||||
|
||||
$uid = \OC::$server->getUserSession()->getUser()->getUID();
|
||||
$server = \OC::$server->getURLGenerator()->getAbsoluteURL('/');
|
||||
$cloudID = $uid . '@' . rtrim(\OCA\Files_Sharing\Helper::removeProtocolFromUrl($server), '/');
|
||||
$cloudID = \OC::$server->getUserSession()->getUser()->getCloudId();
|
||||
$url = 'https://owncloud.org/federation#' . $cloudID;
|
||||
$ownCloudLogoPath = \OC::$server->getURLGenerator()->imagePath('core', 'logo-icon.svg');
|
||||
|
||||
|
|
|
@ -79,7 +79,9 @@ class Avatar implements \OCP\IAvatar {
|
|||
/** @var File $node */
|
||||
$node = $this->folder->get('avatar.' . $ext);
|
||||
$avatar->loadFromData($node->getContent());
|
||||
$avatar->resize($size);
|
||||
if ($size > 0) {
|
||||
$avatar->resize($size);
|
||||
}
|
||||
$this->folder->newFile('avatar.' . $size . '.' . $ext)->putContent($avatar->data());
|
||||
}
|
||||
return $avatar;
|
||||
|
|
|
@ -294,21 +294,47 @@ class Manager extends PublicEmitter implements IUserManager {
|
|||
$userCountStatistics = array();
|
||||
foreach ($this->backends as $backend) {
|
||||
if ($backend->implementsActions(\OC_User_Backend::COUNT_USERS)) {
|
||||
$backendusers = $backend->countUsers();
|
||||
if($backendusers !== false) {
|
||||
$backendUsers = $backend->countUsers();
|
||||
if($backendUsers !== false) {
|
||||
if($backend instanceof \OCP\IUserBackend) {
|
||||
$name = $backend->getBackendName();
|
||||
} else {
|
||||
$name = get_class($backend);
|
||||
}
|
||||
if(isset($userCountStatistics[$name])) {
|
||||
$userCountStatistics[$name] += $backendusers;
|
||||
$userCountStatistics[$name] += $backendUsers;
|
||||
} else {
|
||||
$userCountStatistics[$name] = $backendusers;
|
||||
$userCountStatistics[$name] = $backendUsers;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return $userCountStatistics;
|
||||
}
|
||||
|
||||
/**
|
||||
* The callback is executed for each user on each backend.
|
||||
* If the callback returns false no further users will be retrieved.
|
||||
*
|
||||
* @param \Closure $callback
|
||||
* @return void
|
||||
* @since 9.0.0
|
||||
*/
|
||||
public function callForAllUsers(\Closure $callback, $search = '') {
|
||||
foreach($this->getBackends() as $backend) {
|
||||
$limit = 500;
|
||||
$offset = 0;
|
||||
do {
|
||||
$users = $backend->getUsers($search, $limit, $offset);
|
||||
foreach ($users as $user) {
|
||||
$user = $this->get($user);
|
||||
$return = $callback($user);
|
||||
if ($return === false) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
$offset += $limit;
|
||||
} while (count($users) >= $limit);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -30,61 +30,56 @@
|
|||
namespace OC\User;
|
||||
|
||||
use OC\Hooks\Emitter;
|
||||
use OCP\IAvatarManager;
|
||||
use OCP\IImage;
|
||||
use OCP\IURLGenerator;
|
||||
use OCP\IUser;
|
||||
use OCP\IConfig;
|
||||
|
||||
class User implements IUser {
|
||||
/**
|
||||
* @var string $uid
|
||||
*/
|
||||
/** @var string $uid */
|
||||
private $uid;
|
||||
|
||||
/**
|
||||
* @var string $displayName
|
||||
*/
|
||||
/** @var string $displayName */
|
||||
private $displayName;
|
||||
|
||||
/**
|
||||
* @var \OC_User_Interface $backend
|
||||
*/
|
||||
/** @var \OC_User_Interface $backend */
|
||||
private $backend;
|
||||
|
||||
/**
|
||||
* @var bool $enabled
|
||||
*/
|
||||
/** @var bool $enabled */
|
||||
private $enabled;
|
||||
|
||||
/**
|
||||
* @var Emitter|Manager $emitter
|
||||
*/
|
||||
/** @var Emitter|Manager $emitter */
|
||||
private $emitter;
|
||||
|
||||
/**
|
||||
* @var string $home
|
||||
*/
|
||||
/** @var string $home */
|
||||
private $home;
|
||||
|
||||
/**
|
||||
* @var int $lastLogin
|
||||
*/
|
||||
/** @var int $lastLogin */
|
||||
private $lastLogin;
|
||||
|
||||
/**
|
||||
* @var \OCP\IConfig $config
|
||||
*/
|
||||
/** @var \OCP\IConfig $config */
|
||||
private $config;
|
||||
|
||||
/** @var IAvatarManager */
|
||||
private $avatarManager;
|
||||
|
||||
/** @var IURLGenerator */
|
||||
private $urlGenerator;
|
||||
|
||||
/**
|
||||
* @param string $uid
|
||||
* @param \OC_User_Interface $backend
|
||||
* @param \OC\Hooks\Emitter $emitter
|
||||
* @param \OCP\IConfig $config
|
||||
* @param IConfig|null $config
|
||||
* @param IURLGenerator $urlGenerator
|
||||
*/
|
||||
public function __construct($uid, $backend, $emitter = null, IConfig $config = null) {
|
||||
public function __construct($uid, $backend, $emitter = null, IConfig $config = null, $urlGenerator = null) {
|
||||
$this->uid = $uid;
|
||||
$this->backend = $backend;
|
||||
$this->emitter = $emitter;
|
||||
$this->config = $config;
|
||||
$this->urlGenerator = $urlGenerator;
|
||||
if ($this->config) {
|
||||
$enabled = $this->config->getUserValue($uid, 'core', 'enabled', 'true');
|
||||
$this->enabled = ($enabled === 'true');
|
||||
|
@ -93,6 +88,9 @@ class User implements IUser {
|
|||
$this->enabled = true;
|
||||
$this->lastLogin = \OC::$server->getConfig()->getUserValue($uid, 'login', 'lastLogin', 0);
|
||||
}
|
||||
if (is_null($this->urlGenerator)) {
|
||||
$this->urlGenerator = \OC::$server->getURLGenerator();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -105,7 +103,7 @@ class User implements IUser {
|
|||
}
|
||||
|
||||
/**
|
||||
* get the displayname for the user, if no specific displayname is set it will fallback to the user id
|
||||
* get the display name for the user, if no specific display name is set it will fallback to the user id
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
|
@ -316,4 +314,52 @@ class User implements IUser {
|
|||
public function getEMailAddress() {
|
||||
return $this->config->getUserValue($this->uid, 'settings', 'email');
|
||||
}
|
||||
|
||||
/**
|
||||
* get the avatar image if it exists
|
||||
*
|
||||
* @param int $size
|
||||
* @return IImage|null
|
||||
* @since 9.0.0
|
||||
*/
|
||||
public function getAvatarImage($size) {
|
||||
// delay the initialization
|
||||
if (is_null($this->avatarManager)) {
|
||||
$this->avatarManager = \OC::$server->getAvatarManager();
|
||||
}
|
||||
|
||||
$avatar = $this->avatarManager->getAvatar($this->uid);
|
||||
$image = $avatar->get(-1);
|
||||
if ($image) {
|
||||
return $image;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* get the federation cloud id
|
||||
*
|
||||
* @return string
|
||||
* @since 9.0.0
|
||||
*/
|
||||
public function getCloudId() {
|
||||
$uid = $this->getUID();
|
||||
$server = $this->urlGenerator->getAbsoluteURL('/');
|
||||
return $uid . '@' . rtrim( $this->removeProtocolFromUrl($server), '/');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $url
|
||||
* @return string
|
||||
*/
|
||||
private function removeProtocolFromUrl($url) {
|
||||
if (strpos($url, 'https://') === 0) {
|
||||
return substr($url, strlen('https://'));
|
||||
} else if (strpos($url, 'http://') === 0) {
|
||||
return substr($url, strlen('http://'));
|
||||
}
|
||||
|
||||
return $url;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -152,4 +152,21 @@ interface IUser {
|
|||
* @since 9.0.0
|
||||
*/
|
||||
public function getEMailAddress();
|
||||
|
||||
/**
|
||||
* get the avatar image if it exists
|
||||
*
|
||||
* @param int $size
|
||||
* @return IImage|null
|
||||
* @since 9.0.0
|
||||
*/
|
||||
public function getAvatarImage($size);
|
||||
|
||||
/**
|
||||
* get the federation cloud id
|
||||
*
|
||||
* @return string
|
||||
* @since 9.0.0
|
||||
*/
|
||||
public function getCloudId();
|
||||
}
|
||||
|
|
|
@ -134,4 +134,11 @@ interface IUserManager {
|
|||
* @since 8.0.0
|
||||
*/
|
||||
public function countUsers();
|
||||
|
||||
/**
|
||||
* @param \Closure $callback
|
||||
* @return void
|
||||
* @since 9.0.0
|
||||
*/
|
||||
public function callForAllUsers (\Closure $callback, $search = '');
|
||||
}
|
||||
|
|
|
@ -98,6 +98,11 @@ class SimpleUserForTesting implements IUser {
|
|||
}
|
||||
|
||||
public function getEMailAddress() {
|
||||
// TODO: Implement getEMailAddress() method.
|
||||
}
|
||||
|
||||
public function getAvatarImage($size) {
|
||||
}
|
||||
|
||||
public function getCloudId() {
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,6 +11,13 @@ namespace Test\User;
|
|||
|
||||
use OC\Hooks\PublicEmitter;
|
||||
|
||||
/**
|
||||
* Class User
|
||||
*
|
||||
* @group DB
|
||||
*
|
||||
* @package Test\User
|
||||
*/
|
||||
class User extends \Test\TestCase {
|
||||
public function testDisplayName() {
|
||||
/**
|
||||
|
@ -454,4 +461,21 @@ class User extends \Test\TestCase {
|
|||
$this->assertTrue($user->delete());
|
||||
$this->assertEquals(2, $hooksCalled);
|
||||
}
|
||||
|
||||
public function testGetCloudId() {
|
||||
/**
|
||||
* @var \OC_User_Backend | \PHPUnit_Framework_MockObject_MockObject $backend
|
||||
*/
|
||||
$backend = $this->getMock('\Test\Util\User\Dummy');
|
||||
$urlGenerator = $this->getMockBuilder('\OC\URLGenerator')
|
||||
->setMethods(['getAbsoluteURL'])
|
||||
->disableOriginalConstructor()->getMock();
|
||||
$urlGenerator
|
||||
->expects($this->any())
|
||||
->method('getAbsoluteURL')
|
||||
->withAnyParameters()
|
||||
->willReturn('http://localhost:8888/owncloud');
|
||||
$user = new \OC\User\User('foo', $backend, null, null, $urlGenerator);
|
||||
$this->assertEquals("foo@localhost:8888/owncloud", $user->getCloudId());
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue