mirror of https://github.com/nextcloud/server.git
Merge branch 'master' into master
commit
63974992f9
@ -1 +1 @@
|
||||
Subproject commit a7b34d6f831c8fa363f389d27acd0150128fc0b9
|
||||
Subproject commit a5b2a3cdb03cbf5a7246c6185cd4d473f697803e
|
@ -0,0 +1,42 @@
|
||||
<?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/>
|
||||
*
|
||||
*/
|
||||
|
||||
$cm = \OC::$server->getContactsManager();
|
||||
$cm->register(function() use ($cm) {
|
||||
$db = \OC::$server->getDatabaseConnection();
|
||||
$userId = \OC::$server->getUserSession()->getUser()->getUID();
|
||||
$principal = new \OCA\DAV\Connector\Sabre\Principal(
|
||||
\OC::$server->getConfig(),
|
||||
\OC::$server->getUserManager()
|
||||
);
|
||||
$cardDav = new \OCA\DAV\CardDAV\CardDavBackend($db, $principal, \OC::$server->getLogger());
|
||||
$addressBooks = $cardDav->getAddressBooksForUser("principals/$userId");
|
||||
foreach ($addressBooks as $addressBookInfo) {
|
||||
$addressBook = new \OCA\DAV\CardDAV\AddressBook($cardDav, $addressBookInfo);
|
||||
$cm->registerAddressBook(
|
||||
new OCA\DAV\CardDAV\AddressBookImpl(
|
||||
$addressBook,
|
||||
$addressBookInfo,
|
||||
$cardDav
|
||||
)
|
||||
);
|
||||
}
|
||||
});
|
@ -0,0 +1,219 @@
|
||||
<?php
|
||||
/**
|
||||
* @author Thomas Müller <thomas.mueller@tmit.eu>
|
||||
* @author Björn Schießle <schiessle@owncloud.com>
|
||||
*
|
||||
* @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\Constants;
|
||||
use OCP\IAddressBook;
|
||||
use Sabre\VObject\Component\VCard;
|
||||
use Sabre\VObject\Property\Text;
|
||||
use Sabre\VObject\Reader;
|
||||
use Sabre\VObject\UUIDUtil;
|
||||
|
||||
class AddressBookImpl implements IAddressBook {
|
||||
|
||||
/** @var CardDavBackend */
|
||||
private $backend;
|
||||
|
||||
/** @var array */
|
||||
private $addressBookInfo;
|
||||
|
||||
/** @var AddressBook */
|
||||
private $addressBook;
|
||||
|
||||
/**
|
||||
* AddressBookImpl constructor.
|
||||
*
|
||||
* @param AddressBook $addressBook
|
||||
* @param array $addressBookInfo
|
||||
* @param CardDavBackend $backend
|
||||
*/
|
||||
public function __construct(
|
||||
AddressBook $addressBook,
|
||||
array $addressBookInfo,
|
||||
CardDavBackend $backend) {
|
||||
|
||||
$this->addressBook = $addressBook;
|
||||
$this->addressBookInfo = $addressBookInfo;
|
||||
$this->backend = $backend;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string defining the technical unique key
|
||||
* @since 5.0.0
|
||||
*/
|
||||
public function getKey() {
|
||||
return $this->addressBookInfo['id'];
|
||||
}
|
||||
|
||||
/**
|
||||
* In comparison to getKey() this function returns a human readable (maybe translated) name
|
||||
*
|
||||
* @return mixed
|
||||
* @since 5.0.0
|
||||
*/
|
||||
public function getDisplayName() {
|
||||
return $this->addressBookInfo['{DAV:}displayname'];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $pattern which should match within the $searchProperties
|
||||
* @param array $searchProperties defines the properties within the query pattern should match
|
||||
* @param array $options - for future use. One should always have options!
|
||||
* @return array an array of contacts which are arrays of key-value-pairs
|
||||
* @since 5.0.0
|
||||
*/
|
||||
public function search($pattern, $searchProperties, $options) {
|
||||
$result = $this->backend->search($this->getKey(), $pattern, $searchProperties);
|
||||
|
||||
$vCards = [];
|
||||
foreach ($result as $cardData) {
|
||||
$vCards[] = $this->vCard2Array($this->readCard($cardData));
|
||||
}
|
||||
|
||||
return $vCards;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $properties this array if key-value-pairs defines a contact
|
||||
* @return array an array representing the contact just created or updated
|
||||
* @since 5.0.0
|
||||
*/
|
||||
public function createOrUpdate($properties) {
|
||||
$update = false;
|
||||
if (!isset($properties['UID'])) { // create a new contact
|
||||
$uid = $this->createUid();
|
||||
$uri = $uid . '.vcf';
|
||||
$vCard = $this->createEmptyVCard($uid);
|
||||
} else { // update existing contact
|
||||
$uid = $properties['UID'];
|
||||
$uri = $uid . '.vcf';
|
||||
$vCardData = $this->backend->getCard($this->getKey(), $uri);
|
||||
$vCard = $this->readCard($vCardData['carddata']);
|
||||
$update = true;
|
||||
}
|
||||
|
||||
foreach ($properties as $key => $value) {
|
||||
$vCard->$key = $vCard->createProperty($key, $value);
|
||||
}
|
||||
|
||||
if ($update) {
|
||||
$this->backend->updateCard($this->getKey(), $uri, $vCard->serialize());
|
||||
} else {
|
||||
$this->backend->createCard($this->getKey(), $uri, $vCard->serialize());
|
||||
}
|
||||
|
||||
return $this->vCard2Array($vCard);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
* @since 5.0.0
|
||||
*/
|
||||
public function getPermissions() {
|
||||
$permissions = $this->addressBook->getACL();
|
||||
$result = 0;
|
||||
foreach ($permissions as $permission) {
|
||||
switch($permission['privilege']) {
|
||||
case '{DAV:}read':
|
||||
$result |= Constants::PERMISSION_READ;
|
||||
break;
|
||||
case '{DAV:}write':
|
||||
$result |= Constants::PERMISSION_CREATE;
|
||||
$result |= Constants::PERMISSION_UPDATE;
|
||||
break;
|
||||
case '{DAV:}all':
|
||||
$result |= Constants::PERMISSION_ALL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param object $id the unique identifier to a contact
|
||||
* @return bool successful or not
|
||||
* @since 5.0.0
|
||||
*/
|
||||
public function delete($id) {
|
||||
$uri = $this->backend->getCardUri($id);
|
||||
return $this->backend->deleteCard($this->addressBookInfo['id'], $uri);
|
||||
}
|
||||
|
||||
/**
|
||||
* read vCard data into a vCard object
|
||||
*
|
||||
* @param string $cardData
|
||||
* @return VCard
|
||||
*/
|
||||
protected function readCard($cardData) {
|
||||
return Reader::read($cardData);
|
||||
}
|
||||
|
||||
/**
|
||||
* create UID for contact
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function createUid() {
|
||||
do {
|
||||
$uid = $this->getUid();
|
||||
} while (!empty($this->backend->getContact($uid . '.vcf')));
|
||||
|
||||
return $uid;
|
||||
}
|
||||
|
||||
/**
|
||||
* getUid is only there for testing, use createUid instead
|
||||
*/
|
||||
protected function getUid() {
|
||||
return UUIDUtil::getUUID();
|
||||
}
|
||||
|
||||
/**
|
||||
* create empty vcard
|
||||
*
|
||||
* @param string $uid
|
||||
* @return VCard
|
||||
*/
|
||||
protected function createEmptyVCard($uid) {
|
||||
$vCard = new VCard();
|
||||
$vCard->add(new Text($vCard, 'UID', $uid));
|
||||
return $vCard;
|
||||
}
|
||||
|
||||
/**
|
||||
* create array with all vCard properties
|
||||
*
|
||||
* @param VCard $vCard
|
||||
* @return array
|
||||
*/
|
||||
protected function vCard2Array(VCard $vCard) {
|
||||
$result = [];
|
||||
foreach ($vCard->children as $property) {
|
||||
$result[$property->name] = $property->getValue();
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
}
|
@ -0,0 +1,65 @@
|
||||
<?php
|
||||
|
||||
namespace OCA\DAV\CardDAV\Sharing\Xml;
|
||||
|
||||
use Sabre\Xml\Reader;
|
||||
use Sabre\Xml\XmlDeserializable;
|
||||
|
||||
class ShareRequest implements XmlDeserializable {
|
||||
|
||||
public $set = [];
|
||||
|
||||
public $remove = [];
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param array $set
|
||||
* @param array $remove
|
||||
*/
|
||||
function __construct(array $set, array $remove) {
|
||||
|
||||
$this->set = $set;
|
||||
$this->remove = $remove;
|
||||
|
||||
}
|
||||
|
||||
static function xmlDeserialize(Reader $reader) {
|
||||
|
||||
$elems = $reader->parseInnerTree([
|
||||
'{' . \Sabre\CardDAV\Plugin::NS_CARDDAV. '}set' => 'Sabre\\Xml\\Element\\KeyValue',
|
||||
'{' . \Sabre\CardDAV\Plugin::NS_CARDDAV . '}remove' => 'Sabre\\Xml\\Element\\KeyValue',
|
||||
]);
|
||||
|
||||
$set = [];
|
||||
$remove = [];
|
||||
|
||||
foreach ($elems as $elem) {
|
||||
switch ($elem['name']) {
|
||||
|
||||
case '{' . \Sabre\CardDAV\Plugin::NS_CARDDAV . '}set' :
|
||||
$sharee = $elem['value'];
|
||||
|
||||
$sumElem = '{' . \Sabre\CardDAV\Plugin::NS_CARDDAV . '}summary';
|
||||
$commonName = '{' . \Sabre\CardDAV\Plugin::NS_CARDDAV . '}common-name';
|
||||
|
||||
$set[] = [
|
||||
'href' => $sharee['{DAV:}href'],
|
||||
'commonName' => isset($sharee[$commonName]) ? $sharee[$commonName] : null,
|
||||
'summary' => isset($sharee[$sumElem]) ? $sharee[$sumElem] : null,
|
||||
'readOnly' => !array_key_exists('{' . \Sabre\CardDAV\Plugin::NS_CARDDAV . '}read-write', $sharee),
|
||||
];
|
||||
break;
|
||||
|
||||
case '{' . \Sabre\CardDAV\Plugin::NS_CARDDAV . '}remove' :
|
||||
$remove[] = $elem['value']['{DAV:}href'];
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return new self($set, $remove);
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,20 @@
|
||||
#!/usr/bin/env bash
|
||||
SCRIPT=`realpath $0`
|
||||
SCRIPTPATH=`dirname $SCRIPT`
|
||||
|
||||
|
||||
if [ ! -f CalDAVTester/run.py ]; then
|
||||
cd "$SCRIPTPATH"
|
||||
git clone https://github.com/DeepDiver1975/CalDAVTester.git
|
||||
cd "$SCRIPTPATH/CalDAVTester"
|
||||
python run.py -s
|
||||
cd "$SCRIPTPATH"
|
||||
fi
|
||||
|
||||
# create test user
|
||||
cd "$SCRIPTPATH/../../../../../"
|
||||
OC_PASS=user01 php occ user:add --password-from-env user01
|
||||
php occ dav:create-calendar user01 calendar
|
||||
OC_PASS=user02 php occ user:add --password-from-env user02
|
||||
php occ dav:create-calendar user02 calendar
|
||||
cd "$SCRIPTPATH/../../../../../"
|
@ -0,0 +1,18 @@
|
||||
#!/usr/bin/env bash
|
||||
SCRIPT=`realpath $0`
|
||||
SCRIPTPATH=`dirname $SCRIPT`
|
||||
|
||||
# start the server
|
||||
php -S 127.0.0.1:8888 -t "$SCRIPTPATH/../../../../.." &
|
||||
|
||||
sleep 30
|
||||
|
||||
# run the tests
|
||||
cd "$SCRIPTPATH/CalDAVTester"
|
||||
PYTHONPATH="$SCRIPTPATH/pycalendar/src" python testcaldav.py --print-details-onfail -s "$SCRIPTPATH/../caldavtest/config/serverinfo.xml" -o cdt.txt \
|
||||
"$SCRIPTPATH/../caldavtest/tests/CalDAV/current-user-principal.xml"
|
||||
RESULT=$?
|
||||
|
||||
tail "$/../../../../../data-autotest/owncloud.log"
|
||||
|
||||
exit $RESULT
|
@ -0,0 +1,151 @@
|
||||
<?xml version="1.0" standalone="no"?>
|
||||
|
||||
<!DOCTYPE caldavtest SYSTEM "caldavtest.dtd">
|
||||
|
||||
<!--
|
||||
Copyright (c) 2006-2015 Apple Inc. All rights reserved.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
|
||||
<caldavtest>
|
||||
<description>Test DAV:current-user-principal support</description>
|
||||
|
||||
<require-feature>
|
||||
<feature>caldav</feature>
|
||||
<feature>current-user-principal</feature>
|
||||
</require-feature>
|
||||
|
||||
<start/>
|
||||
|
||||
<test-suite name='Check for the property on /'>
|
||||
<require-feature>
|
||||
<feature>own-root</feature>
|
||||
</require-feature>
|
||||
<test name='1'>
|
||||
<description>Check for authenticated property on /</description>
|
||||
<request>
|
||||
<method>PROPFIND</method>
|
||||
<ruri>$root:</ruri>
|
||||
<header>
|
||||
<name>Depth</name>
|
||||
<value>0</value>
|
||||
</header>
|
||||
<data>
|
||||
<content-type>text/xml; charset=utf-8</content-type>
|
||||
<filepath>Resource/CalDAV/current-user-principal/1.xml</filepath>
|
||||
</data>
|
||||
<verify>
|
||||
<callback>propfindItems</callback>
|
||||
<arg>
|
||||
<name>okprops</name>
|
||||
<value><![CDATA[{DAV:}current-user-principal$<href xmlns="DAV:">$principaluri1:</href>]]></value>
|
||||
</arg>
|
||||
</verify>
|
||||
</request>
|
||||
</test>
|
||||
<test name='3'>
|
||||
<description>Check for authenticated property on / (user02)</description>
|
||||
<request user="$userid2:" pswd="$pswd2:">
|
||||
<method>PROPFIND</method>
|
||||
<ruri>$root:</ruri>
|
||||
<header>
|
||||
<name>Depth</name>
|
||||
<value>0</value>
|
||||
</header>
|
||||
<data>
|
||||
<content-type>text/xml; charset=utf-8</content-type>
|
||||
<filepath>Resource/CalDAV/current-user-principal/1.xml</filepath>
|
||||
</data>
|
||||
<verify>
|
||||
<callback>propfindItems</callback>
|
||||
<arg>
|
||||
<name>okprops</name>
|
||||
<value><![CDATA[{DAV:}current-user-principal$<href xmlns="DAV:">$principaluri2:</href>]]></value>
|
||||
</arg>
|
||||
</verify>
|
||||
</request>
|
||||
</test>
|
||||
</test-suite>
|
||||
|
||||
<test-suite name='Check for the property on /principals/'>
|
||||
<test name='1'>
|
||||
<description>Check for authenticated property on /</description>
|
||||
<request>
|
||||
<method>PROPFIND</method>
|
||||
<ruri>$principalcollection:</ruri>
|
||||
<header>
|
||||
<name>Depth</name>
|
||||
<value>0</value>
|
||||
</header>
|
||||
<data>
|
||||
<content-type>text/xml; charset=utf-8</content-type>
|
||||
<filepath>Resource/CalDAV/current-user-principal/1.xml</filepath>
|
||||
</data>
|
||||
<verify>
|
||||
<callback>propfindItems</callback>
|
||||
<arg>
|
||||
<name>okprops</name>
|
||||
<value><![CDATA[{DAV:}current-user-principal$<href xmlns="DAV:">$principaluri1:</href>]]></value>
|
||||
</arg>
|
||||
</verify>
|
||||
</request>
|
||||
</test>
|
||||
<test name='2'>
|
||||
<description>Check for unauthenticated property on /</description>
|
||||
<request auth="no">
|
||||
<method>PROPFIND</method>
|
||||
<ruri>$principals_users:</ruri>
|
||||
<header>
|
||||
<name>Depth</name>
|
||||
<value>0</value>
|
||||
</header>
|
||||
<data>
|
||||
<content-type>text/xml; charset=utf-8</content-type>
|
||||
<filepath>Resource/CalDAV/current-user-principal/1.xml</filepath>
|
||||
</data>
|
||||
<verify>
|
||||
<callback>statusCode</callback>
|
||||
<arg>
|
||||
<name>status</name>
|
||||
<value>401</value>
|
||||
</arg>
|
||||
</verify>
|
||||
</request>
|
||||
</test>
|
||||
<test name='3'>
|
||||
<description>Check for authenticated property on / (user02)</description>
|
||||
<request user="$userid2:" pswd="$pswd2:">
|
||||
<method>PROPFIND</method>
|
||||
<ruri>$principalcollection:</ruri>
|
||||
<header>
|
||||
<name>Depth</name>
|
||||
<value>0</value>
|
||||
</header>
|
||||
<data>
|
||||
<content-type>text/xml; charset=utf-8</content-type>
|
||||
<filepath>Resource/CalDAV/current-user-principal/1.xml</filepath>
|
||||
</data>
|
||||
<verify>
|
||||
<callback>propfindItems</callback>
|
||||
<arg>
|
||||
<name>okprops</name>
|
||||
<value><![CDATA[{DAV:}current-user-principal$<href xmlns="DAV:">$principaluri2:</href>]]></value>
|
||||
</arg>
|
||||
</verify>
|
||||
</request>
|
||||
</test>
|
||||
</test-suite>
|
||||
|
||||
<end/>
|
||||
</caldavtest>
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,20 @@
|
||||
#!/usr/bin/env bash
|
||||
SCRIPT=`realpath $0`
|
||||
SCRIPTPATH=`dirname $SCRIPT`
|
||||
|
||||
|
||||
if [ ! -f CalDAVTester/run.py ]; then
|
||||
cd "$SCRIPTPATH"
|
||||
git clone https://github.com/DeepDiver1975/CalDAVTester.git
|
||||
cd "$SCRIPTPATH/CalDAVTester"
|
||||
python run.py -s
|
||||
cd "$SCRIPTPATH"
|
||||
fi
|
||||
|
||||
# create test user
|
||||
cd "$SCRIPTPATH/../../../../../"
|
||||
OC_PASS=user01 php occ user:add --password-from-env user01
|
||||
php occ dav:create-addressbook user01 addressbook
|
||||
OC_PASS=user02 php occ user:add --password-from-env user02
|
||||
php occ dav:create-addressbook user02 addressbook
|
||||
cd "$SCRIPTPATH/../../../../../"
|
@ -0,0 +1,19 @@
|
||||
#!/usr/bin/env bash
|
||||
SCRIPT=`realpath $0`
|
||||
SCRIPTPATH=`dirname $SCRIPT`
|
||||
|
||||
# start the server
|
||||
php -S 127.0.0.1:8888 -t "$SCRIPTPATH/../../../../.." &
|
||||
|
||||
sleep 30
|
||||
|
||||
# run the tests
|
||||
cd "$SCRIPTPATH/CalDAVTester"
|
||||
PYTHONPATH="$SCRIPTPATH/pycalendar/src" python testcaldav.py --print-details-onfail -s "$SCRIPTPATH/../caldavtest/config/serverinfo.xml" -o cdt.txt \
|
||||
"$SCRIPTPATH/../caldavtest/tests/CardDAV/current-user-principal.xml" \
|
||||
"$SCRIPTPATH/../caldavtest/tests/CardDAV/sync-report.xml"
|
||||
RESULT=$?
|
||||
|
||||
tail "$/../../../../../data-autotest/owncloud.log"
|
||||
|
||||
exit $RESULT
|
@ -1,35 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
SCRIPT=`realpath $0`
|
||||
SCRIPTPATH=`dirname $SCRIPT`
|
||||
|
||||
|
||||
# start the server
|
||||
php -S 127.0.0.1:8888 -t "$SCRIPTPATH/../../../.." &
|
||||
|
||||
|
||||
if [ ! -f CalDAVTester/run.py ]; then
|
||||
cd "$SCRIPTPATH"
|
||||
git clone https://github.com/DeepDiver1975/CalDAVTester.git
|
||||
cd "$SCRIPTPATH/CalDAVTester"
|
||||
python run.py -s
|
||||
cd "$SCRIPTPATH"
|
||||
fi
|
||||
|
||||
# create test user
|
||||
cd "$SCRIPTPATH/../../../../"
|
||||
OC_PASS=user01 php occ user:add --password-from-env user01
|
||||
php occ dav:create-addressbook user01 addressbook
|
||||
OC_PASS=user02 php occ user:add --password-from-env user02
|
||||
php occ dav:create-addressbook user02 addressbook
|
||||
cd "$SCRIPTPATH/../../../../"
|
||||
|
||||
# run the tests
|
||||
cd "$SCRIPTPATH/CalDAVTester"
|
||||
PYTHONPATH="$SCRIPTPATH/pycalendar/src" python testcaldav.py --print-details-onfail -s "$SCRIPTPATH/caldavtest/config/serverinfo.xml" -o cdt.txt \
|
||||
"$SCRIPTPATH/caldavtest/tests/CardDAV/current-user-principal.xml" \
|
||||
"$SCRIPTPATH/caldavtest/tests/CardDAV/sync-report.xml"
|
||||
RESULT=$?
|
||||
|
||||
tail "$SCRIPTPATH/../../../../data-autotest/owncloud.log"
|
||||
|
||||
exit $RESULT
|
@ -0,0 +1,13 @@
|
||||
#!/usr/bin/env bash
|
||||
SCRIPT=`realpath $0`
|
||||
SCRIPTPATH=`dirname $SCRIPT`
|
||||
|
||||
|
||||
# start the server
|
||||
php -S 127.0.0.1:8888 -t "$SCRIPTPATH/../../../../.." &
|
||||
|
||||
sleep 30
|
||||
|
||||
# run the tests
|
||||
cd /tmp/litmus/litmus-0.13
|
||||
make URL=http://127.0.0.1:8888/remote.php/webdav CREDS="admin admin" TESTS="basic copymove props locks" check
|
@ -0,0 +1,13 @@
|
||||
#!/usr/bin/env bash
|
||||
SCRIPT=`realpath $0`
|
||||
SCRIPTPATH=`dirname $SCRIPT`
|
||||
|
||||
|
||||
# start the server
|
||||
php -S 127.0.0.1:8888 -t "$SCRIPTPATH/../../../../.." &
|
||||
|
||||
sleep 30
|
||||
|
||||
# run the tests
|
||||
cd /tmp/litmus/litmus-0.13
|
||||
make URL=http://127.0.0.1:8888/remote.php/dav/files/admin CREDS="admin admin" TESTS="basic copymove props locks" check
|
@ -0,0 +1,287 @@
|
||||
<?php
|
||||
/**
|
||||
* @author Björn Schießle <schiessle@owncloud.com>
|
||||
*
|
||||
* @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\CardDAV;
|
||||
|
||||
|
||||
use OCA\DAV\CardDAV\AddressBook;
|
||||
use OCA\DAV\CardDAV\AddressBookImpl;
|
||||
use OCA\DAV\CardDAV\CardDavBackend;
|
||||
use Sabre\VObject\Component\VCard;
|
||||
use Sabre\VObject\Property\Text;
|
||||
use Test\TestCase;
|
||||
|
||||
class AddressBookImplTest extends TestCase {
|
||||
|
||||
/** @var AddressBookImpl */
|
||||
private $addressBookImpl;
|
||||
|
||||
/** @var array */
|
||||
private $addressBookInfo;
|
||||
|
||||
/** @var AddressBook | \PHPUnit_Framework_MockObject_MockObject */
|
||||
private $addressBook;
|
||||
|
||||
/** @var CardDavBackend | \PHPUnit_Framework_MockObject_MockObject */
|
||||
private $backend;
|
||||
|
||||
/** @var VCard | \PHPUnit_Framework_MockObject_MockObject */
|
||||
private $vCard;
|
||||
|
||||
public function setUp() {
|
||||
parent::setUp();
|
||||
|
||||
$this->addressBookInfo = [
|
||||
'id' => 42,
|
||||
'{DAV:}displayname' => 'display name'
|
||||
];
|
||||
$this->addressBook = $this->getMockBuilder('OCA\DAV\CardDAV\AddressBook')
|
||||
->disableOriginalConstructor()->getMock();
|
||||
$this->backend = $this->getMockBuilder('\OCA\DAV\CardDAV\CardDavBackend')
|
||||
->disableOriginalConstructor()->getMock();
|
||||
$this->vCard = $this->getMock('Sabre\VObject\Component\VCard');
|
||||
|
||||
$this->addressBookImpl = new AddressBookImpl(
|
||||
$this->addressBook,
|
||||
$this->addressBookInfo,
|
||||
$this->backend
|
||||
);
|
||||
}
|
||||
|
||||
public function testGetKey() {
|
||||
$this->assertSame($this->addressBookInfo['id'],
|
||||
$this->addressBookImpl->getKey());
|
||||
}
|
||||
|
||||
public function testGetDisplayName() {
|
||||
$this->assertSame($this->addressBookInfo['{DAV:}displayname'],
|
||||
$this->addressBookImpl->getDisplayName());
|
||||
}
|
||||
|
||||
public function testSearch() {
|
||||
|
||||
/** @var \PHPUnit_Framework_MockObject_MockObject | AddressBookImpl $addressBookImpl */
|
||||
$addressBookImpl = $this->getMockBuilder('OCA\DAV\CardDAV\AddressBookImpl')
|
||||
->setConstructorArgs(
|
||||
[
|
||||
$this->addressBook,
|
||||
$this->addressBookInfo,
|
||||
$this->backend
|
||||
]
|
||||
)
|
||||
->setMethods(['vCard2Array', 'readCard'])
|
||||
->getMock();
|
||||
|
||||
$pattern = 'pattern';
|
||||
$searchProperties = 'properties';
|
||||
|
||||
$this->backend->expects($this->once())->method('search')
|
||||
->with($this->addressBookInfo['id'], $pattern, $searchProperties)
|
||||
->willReturn(
|
||||
[
|
||||
'cardData1',
|
||||
'cardData2'
|
||||
]
|
||||
);
|
||||
|
||||
$addressBookImpl->expects($this->exactly(2))->method('readCard')
|
||||
->willReturn($this->vCard);
|
||||
$addressBookImpl->expects($this->exactly(2))->method('vCard2Array')
|
||||
->with($this->vCard)->willReturn('vCard');
|
||||
|
||||
$result = $addressBookImpl->search($pattern, $searchProperties, []);
|
||||
$this->assertTrue((is_array($result)));
|
||||
$this->assertSame(2, count($result));
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider dataTestCreate
|
||||
*
|
||||
* @param array $properties
|
||||
*/
|
||||
public function testCreate($properties) {
|
||||
|
||||
$uid = 'uid';
|
||||
|
||||
/** @var \PHPUnit_Framework_MockObject_MockObject | AddressBookImpl $addressBookImpl */
|
||||
$addressBookImpl = $this->getMockBuilder('OCA\DAV\CardDAV\AddressBookImpl')
|
||||
->setConstructorArgs(
|
||||
[
|
||||
$this->addressBook,
|
||||
$this->addressBookInfo,
|
||||
$this->backend
|
||||
]
|
||||
)
|
||||
->setMethods(['vCard2Array', 'createUid', 'createEmptyVCard'])
|
||||
->getMock();
|
||||
|
||||
$addressBookImpl->expects($this->once())->method('createUid')
|
||||
->willReturn($uid);
|
||||
$addressBookImpl->expects($this->once())->method('createEmptyVCard')
|
||||
->with($uid)->willReturn($this->vCard);
|
||||
$this->vCard->expects($this->exactly(count($properties)))
|
||||
->method('createProperty');
|
||||
$this->backend->expects($this->once())->method('createCard');
|
||||
$this->backend->expects($this->never())->method('updateCard');
|
||||
$this->backend->expects($this->never())->method('getCard');
|
||||
$addressBookImpl->expects($this->once())->method('vCard2Array')
|
||||
->with($this->vCard)->willReturn(true);
|
||||
|
||||
$this->assertTrue($addressBookImpl->createOrUpdate($properties));
|
||||
}
|
||||
|
||||
public function dataTestCreate() {
|
||||
return [
|
||||
[[]],
|
||||
[['FN' => 'John Doe']]
|
||||
];
|
||||
}
|
||||
|
||||
public function testUpdate() {
|
||||
|
||||
$uid = 'uid';
|
||||
$properties = ['UID' => $uid, 'FN' => 'John Doe'];
|
||||
|
||||
/** @var \PHPUnit_Framework_MockObject_MockObject | AddressBookImpl $addressBookImpl */
|
||||
$addressBookImpl = $this->getMockBuilder('OCA\DAV\CardDAV\AddressBookImpl')
|
||||
->setConstructorArgs(
|
||||
[
|
||||
$this->addressBook,
|
||||
$this->addressBookInfo,
|
||||
$this->backend
|
||||
]
|
||||
)
|
||||
->setMethods(['vCard2Array', 'createUid', 'createEmptyVCard', 'readCard'])
|
||||
->getMock();
|
||||
|
||||
$addressBookImpl->expects($this->never())->method('createUid');
|
||||
$addressBookImpl->expects($this->never())->method('createEmptyVCard');
|
||||
$this->backend->expects($this->once())->method('getCard')
|
||||
->with($this->addressBookInfo['id'], $uid . '.vcf')
|
||||
->willReturn(['carddata' => 'data']);
|
||||
$addressBookImpl->expects($this->once())->method('readCard')
|
||||
->with('data')->willReturn($this->vCard);
|
||||
$this->vCard->expects($this->exactly(count($properties)))
|
||||
->method('createProperty');
|
||||
$this->backend->expects($this->never())->method('createCard');
|
||||
$this->backend->expects($this->once())->method('updateCard');
|
||||
$addressBookImpl->expects($this->once())->method('vCard2Array')
|
||||
->with($this->vCard)->willReturn(true);
|
||||
|
||||
$this->assertTrue($addressBookImpl->createOrUpdate($properties));
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider dataTestGetPermissions
|
||||
*
|
||||
* @param array $permissions
|
||||
* @param int $expected
|
||||
*/
|
||||
public function testGetPermissions($permissions, $expected) {
|
||||
$this->addressBook->expects($this->once())->method('getACL')
|
||||
->willReturn($permissions);
|
||||
|
||||
$this->assertSame($expected,
|
||||
$this->addressBookImpl->getPermissions()
|
||||
);
|
||||
}
|
||||
|
||||
public function dataTestGetPermissions() {
|
||||
return [
|
||||
[[], 0],
|
||||
[[['privilege' => '{DAV:}read']], 1],
|
||||
[[['privilege' => '{DAV:}write']], 6],
|
||||
[[['privilege' => '{DAV:}all']], 31],
|
||||
[[['privilege' => '{DAV:}read'],['privilege' => '{DAV:}write']], 7],
|
||||
[[['privilege' => '{DAV:}read'],['privilege' => '{DAV:}all']], 31],
|
||||
[[['privilege' => '{DAV:}all'],['privilege' => '{DAV:}write']], 31],
|
||||
[[['privilege' => '{DAV:}read'],['privilege' => '{DAV:}write'],['privilege' => '{DAV:}all']], 31],
|
||||
[[['privilege' => '{DAV:}all'],['privilege' => '{DAV:}read'],['privilege' => '{DAV:}write']], 31],
|
||||
];
|
||||
}
|
||||
|
||||
public function testDelete() {
|
||||
$cardId = 1;
|
||||
$cardUri = 'cardUri';
|
||||
$this->backend->expects($this->once())->method('getCardUri')
|
||||
->with($cardId)->willReturn($cardUri);
|
||||
$this->backend->expects($this->once())->method('deleteCard')
|
||||
->with($this->addressBookInfo['id'], $cardUri)
|
||||
->willReturn(true);
|
||||
|
||||
$this->assertTrue($this->addressBookImpl->delete($cardId));
|
||||
}
|
||||
|
||||
public function testReadCard() {
|
||||
$vCard = new VCard();
|
||||
$vCard->add(new Text($vCard, 'UID', 'uid'));
|
||||
$vCardSerialized = $vCard->serialize();
|
||||
|
||||
$result = $this->invokePrivate($this->addressBookImpl, 'readCard', [$vCardSerialized]);
|
||||
$resultSerialized = $result->serialize();
|
||||
|
||||
$this->assertSame($vCardSerialized, $resultSerialized);
|
||||
}
|
||||
|
||||
public function testCreateUid() {
|
||||
/** @var \PHPUnit_Framework_MockObject_MockObject | AddressBookImpl $addressBookImpl */
|
||||
$addressBookImpl = $this->getMockBuilder('OCA\DAV\CardDAV\AddressBookImpl')
|
||||
->setConstructorArgs(
|
||||
[
|
||||
$this->addressBook,
|
||||
$this->addressBookInfo,
|
||||
$this->backend
|
||||
]
|
||||
)
|
||||
->setMethods(['getUid'])
|
||||
->getMock();
|
||||
|
||||
$addressBookImpl->expects($this->at(0))->method('getUid')->willReturn('uid0');
|
||||
$addressBookImpl->expects($this->at(1))->method('getUid')->willReturn('uid1');
|
||||
|
||||
// simulate that 'uid0' already exists, so the second uid will be returned
|
||||
$this->backend->expects($this->exactly(2))->method('getContact')
|
||||
->willReturnCallback(
|
||||
function($uid) {
|
||||
return ($uid === 'uid0.vcf');
|
||||
}
|
||||
);
|
||||
|
||||
$this->assertSame('uid1',
|
||||
$this->invokePrivate($addressBookImpl, 'createUid', [])
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
public function testCreateEmptyVCard() {
|
||||
$uid = 'uid';
|
||||
$expectedVCard = new VCard();
|
||||
$expectedVCard->add(new Text($expectedVCard, 'UID', $uid));
|
||||
$expectedVCardSerialized = $expectedVCard->serialize();
|
||||
|
||||
$result = $this->invokePrivate($this->addressBookImpl, 'createEmptyVCard', [$uid]);
|
||||
$resultSerialized = $result->serialize();
|
||||
|
||||
$this->assertSame($expectedVCardSerialized, $resultSerialized);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,81 @@
|
||||
<?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\CardDAV;
|
||||
|
||||
|
||||
use OCA\DAV\CardDAV\Sharing\IShareableAddressBook;
|
||||
use OCA\DAV\CardDAV\Sharing\Plugin;
|
||||
use OCA\DAV\Connector\Sabre\Auth;
|
||||
use OCP\IRequest;
|
||||
use Sabre\DAV\Server;
|
||||
use Sabre\DAV\SimpleCollection;
|
||||
use Sabre\HTTP\Request;
|
||||
use Sabre\HTTP\Response;
|
||||
use Test\TestCase;
|
||||
|
||||
class PluginTest extends TestCase {
|
||||
|
||||
/** @var Plugin */
|
||||
private $plugin;
|
||||
/** @var Server */
|
||||
private $server;
|
||||
/** @var IShareableAddressBook | \PHPUnit_Framework_MockObject_MockObject */
|
||||
private $book;
|
||||
|
||||
public function setUp() {
|
||||
parent::setUp();
|
||||
|
||||
/** @var Auth | \PHPUnit_Framework_MockObject_MockObject $authBackend */
|
||||
$authBackend = $this->getMockBuilder('OCA\DAV\Connector\Sabre\Auth')->disableOriginalConstructor()->getMock();
|
||||
$authBackend->method('isDavAuthenticated')->willReturn(true);
|
||||
|
||||
/** @var IRequest $request */
|
||||
$request = $this->getMockBuilder('OCP\IRequest')->disableOriginalConstructor()->getMock();
|
||||
$this->plugin = new Plugin($authBackend, $request);
|
||||
|
||||
$root = new SimpleCollection('root');
|
||||
$this->server = new \Sabre\DAV\Server($root);
|
||||
/** @var SimpleCollection $node */
|
||||
$this->book = $this->getMockBuilder('OCA\DAV\CardDAV\Sharing\IShareableAddressBook')->disableOriginalConstructor()->getMock();
|
||||
$this->book->method('getName')->willReturn('addressbook1.vcf');
|
||||
$root->addChild($this->book);
|
||||
$this->plugin->initialize($this->server);
|
||||
}
|
||||
|
||||
public function testSharing() {
|
||||
|
||||
$this->book->expects($this->once())->method('updateShares')->with([[
|
||||
'href' => 'principal:principals/admin',
|
||||
'commonName' => null,
|
||||
'summary' => null,
|
||||
'readOnly' => false
|
||||
]], ['mailto:wilfredo@example.com']);
|
||||
|
||||
// setup request
|
||||
$request = new Request();
|
||||
$request->addHeader('Content-Type', 'application/xml');
|
||||
$request->setUrl('addressbook1.vcf');
|
||||
$request->setBody('<?xml version="1.0" encoding="utf-8" ?><CS:share xmlns:D="DAV:" xmlns:CS="urn:ietf:params:xml:ns:carddav"><CS:set><D:href>principal:principals/admin</D:href><CS:read-write/></CS:set> <CS:remove><D:href>mailto:wilfredo@example.com</D:href></CS:remove></CS:share>');
|
||||
$response = new Response();
|
||||
$this->plugin->httpPost($request, $response);
|
||||
}
|
||||
}
|
@ -1,87 +0,0 @@
|
||||
<?php
|
||||
/* Note; This class can be removed as soon as we drop PHP 5.4 support.
|
||||
*
|
||||
*
|
||||
* Password Hashing With PBKDF2 (http://crackstation.net/hashing-security.htm).
|
||||
* Copyright (c) 2013, Taylor Hornby
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
namespace OCA\Encryption\Vendor;
|
||||
|
||||
class PBKDF2Fallback {
|
||||
|
||||
/*
|
||||
* PBKDF2 key derivation function as defined by RSA's PKCS #5: https://www.ietf.org/rfc/rfc2898.txt
|
||||
* $algorithm - The hash algorithm to use. Recommended: SHA256
|
||||
* $password - The password.
|
||||
* $salt - A salt that is unique to the password.
|
||||
* $count - Iteration count. Higher is better, but slower. Recommended: At least 1000.
|
||||
* $key_length - The length of the derived key in bytes.
|
||||
* $raw_output - If true, the key is returned in raw binary format. Hex encoded otherwise.
|
||||
* Returns: A $key_length-byte key derived from the password and salt.
|
||||
*
|
||||
* Test vectors can be found here: https://www.ietf.org/rfc/rfc6070.txt
|
||||
*
|
||||
* This implementation of PBKDF2 was originally created by https://defuse.ca
|
||||
* With improvements by http://www.variations-of-shadow.com
|
||||
*/
|
||||
public function pbkdf2($algorithm, $password, $salt, $count, $key_length, $raw_output = false) {
|
||||
$algorithm = strtolower($algorithm);
|
||||
if (!in_array($algorithm, hash_algos(), true))
|
||||
trigger_error('PBKDF2 ERROR: Invalid hash algorithm.', E_USER_ERROR);
|
||||
if ($count <= 0 || $key_length <= 0)
|
||||
trigger_error('PBKDF2 ERROR: Invalid parameters.', E_USER_ERROR);
|
||||
|
||||
if (function_exists("hash_pbkdf2")) {
|
||||
// The output length is in NIBBLES (4-bits) if $raw_output is false!
|
||||
if (!$raw_output) {
|
||||
$key_length = $key_length * 2;
|
||||
}
|
||||
return hash_pbkdf2($algorithm, $password, $salt, $count, $key_length, $raw_output);
|
||||
}
|
||||
|
||||
$hash_length = strlen(hash($algorithm, "", true));
|
||||
$block_count = ceil($key_length / $hash_length);
|
||||
|
||||
$output = "";
|
||||
for ($i = 1; $i <= $block_count; $i++) {
|
||||
// $i encoded as 4 bytes, big endian.
|
||||
$last = $salt . pack("N", $i);
|
||||
// first iteration
|
||||
$last = $xorsum = hash_hmac($algorithm, $last, $password, true);
|
||||
// perform the other $count - 1 iterations
|
||||
for ($j = 1; $j < $count; $j++) {
|
||||
$xorsum ^= ($last = hash_hmac($algorithm, $last, $password, true));
|
||||
}
|
||||
$output .= $xorsum;
|
||||
}
|
||||
|
||||
if ($raw_output)
|
||||
return substr($output, 0, $key_length);
|
||||
else
|
||||
return bin2hex(substr($output, 0, $key_length));
|
||||
}
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue