Skip to content
GitLab
Menu
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
die_coolen_jungs
our_own_cloud_project
Commits
d8b73fde
Commit
d8b73fde
authored
Nov 18, 2015
by
Thomas Müller
Browse files
Merge pull request #20371 from owncloud/add-caldav-2
Introducing CalDAV into core
parents
90bd53c9
e4568234
Changes
8
Expand all
Hide whitespace changes
Inline
Side-by-side
apps/dav/appinfo/database.xml
View file @
d8b73fde
...
...
@@ -183,4 +183,391 @@ CREATE TABLE addressbookchanges (
</declaration>
</table>
<!--
CREATE TABLE calendarobjects (
id INT(11) UNSIGNED NOT NULL PRIMARY KEY AUTO_INCREMENT,
calendardata MEDIUMBLOB,
uri VARBINARY(200),
calendarid INTEGER UNSIGNED NOT NULL,
lastmodified INT(11) UNSIGNED,
etag VARBINARY(32),
size INT(11) UNSIGNED NOT NULL,
componenttype VARBINARY(8),
firstoccurence INT(11) UNSIGNED,
lastoccurence INT(11) UNSIGNED,
uid VARBINARY(200),
UNIQUE(calendarid, uri)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
-->
<table>
<name>
*dbprefix*calendarobjects
</name>
<declaration>
<field>
<name>
id
</name>
<type>
integer
</type>
<default>
0
</default>
<notnull>
true
</notnull>
<autoincrement>
1
</autoincrement>
<unsigned>
true
</unsigned>
<length>
11
</length>
</field>
<field>
<name>
calendardata
</name>
<type>
blob
</type>
</field>
<field>
<name>
uri
</name>
<type>
text
</type>
</field>
<field>
<name>
calendarid
</name>
<type>
integer
</type>
<unsigned>
true
</unsigned>
<notnull>
true
</notnull>
</field>
<field>
<name>
lastmodified
</name>
<type>
integer
</type>
<unsigned>
true
</unsigned>
</field>
<field>
<name>
etag
</name>
<type>
text
</type>
<length>
32
</length>
</field>
<field>
<name>
size
</name>
<type>
integer
</type>
<notnull>
true
</notnull>
<unsigned>
true
</unsigned>
<length>
11
</length>
</field>
<field>
<name>
componenttype
</name>
<type>
text
</type>
</field>
<field>
<name>
firstoccurence
</name>
<type>
integer
</type>
<unsigned>
true
</unsigned>
</field>
<field>
<name>
lastoccurence
</name>
<type>
integer
</type>
<unsigned>
true
</unsigned>
</field>
<field>
<name>
uid
</name>
<type>
text
</type>
</field>
<index>
<name>
calobjects_index
</name>
<unique>
true
</unique>
<field>
<name>
calendarid
</name>
</field>
<field>
<name>
uri
</name>
</field>
</index>
</declaration>
</table>
<!--
CREATE TABLE calendars (
id INTEGER UNSIGNED NOT NULL PRIMARY KEY AUTO_INCREMENT,
principaluri VARBINARY(100),
displayname VARCHAR(100),
uri VARBINARY(200),
synctoken INTEGER UNSIGNED NOT NULL DEFAULT '1',
description TEXT,
calendarorder INT(11) UNSIGNED NOT NULL DEFAULT '0',
calendarcolor VARBINARY(10),
timezone TEXT,
components VARBINARY(20),
transparent TINYINT(1) NOT NULL DEFAULT '0',
UNIQUE(principaluri, uri)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
-->
<table>
<name>
*dbprefix*calendars
</name>
<declaration>
<field>
<name>
id
</name>
<type>
integer
</type>
<default>
0
</default>
<notnull>
true
</notnull>
<autoincrement>
1
</autoincrement>
<unsigned>
true
</unsigned>
<length>
11
</length>
</field>
<field>
<name>
principaluri
</name>
<type>
text
</type>
</field>
<field>
<name>
displayname
</name>
<type>
text
</type>
</field>
<field>
<name>
uri
</name>
<type>
text
</type>
</field>
<field>
<name>
synctoken
</name>
<type>
integer
</type>
<default>
1
</default>
<notnull>
true
</notnull>
<unsigned>
true
</unsigned>
</field>
<field>
<name>
description
</name>
<type>
text
</type>
</field>
<field>
<name>
calendarorder
</name>
<type>
integer
</type>
<default>
0
</default>
<notnull>
true
</notnull>
<unsigned>
true
</unsigned>
</field>
<field>
<name>
calendarcolor
</name>
<type>
text
</type>
</field>
<field>
<name>
timezone
</name>
<type>
text
</type>
</field>
<field>
<name>
components
</name>
<type>
text
</type>
</field>
<field>
<name>
transparent
</name>
<type>
integer
</type>
<length>
1
</length>
<notnull>
true
</notnull>
<default>
0
</default>
</field>
<index>
<name>
calendars_index
</name>
<unique>
true
</unique>
<field>
<name>
principaluri
</name>
</field>
<field>
<name>
uri
</name>
</field>
</index>
</declaration>
</table>
<!--
CREATE TABLE calendarchanges (
id INT(11) UNSIGNED NOT NULL PRIMARY KEY AUTO_INCREMENT,
uri VARBINARY(200) NOT NULL,
synctoken INT(11) UNSIGNED NOT NULL,
calendarid INT(11) UNSIGNED NOT NULL,
operation TINYINT(1) NOT NULL,
INDEX calendarid_synctoken (calendarid, synctoken)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
-->
<table>
<name>
*dbprefix*calendarchanges
</name>
<declaration>
<field>
<name>
id
</name>
<type>
integer
</type>
<default>
0
</default>
<notnull>
true
</notnull>
<autoincrement>
1
</autoincrement>
<unsigned>
true
</unsigned>
<length>
11
</length>
</field>
<field>
<name>
uri
</name>
<type>
text
</type>
</field>
<field>
<name>
synctoken
</name>
<type>
integer
</type>
<default>
1
</default>
<notnull>
true
</notnull>
<unsigned>
true
</unsigned>
</field>
<field>
<name>
calendarid
</name>
<type>
integer
</type>
<notnull>
true
</notnull>
</field>
<field>
<name>
operation
</name>
<type>
integer
</type>
<notnull>
true
</notnull>
<length>
1
</length>
</field>
<index>
<name>
calendarid_synctoken
</name>
<field>
<name>
calendarid
</name>
</field>
<field>
<name>
synctoken
</name>
</field>
</index>
</declaration>
</table>
<!--
CREATE TABLE calendarsubscriptions (
id INT(11) UNSIGNED NOT NULL PRIMARY KEY AUTO_INCREMENT,
uri VARBINARY(200) NOT NULL,
principaluri VARBINARY(100) NOT NULL,
source TEXT,
displayname VARCHAR(100),
refreshrate VARCHAR(10),
calendarorder INT(11) UNSIGNED NOT NULL DEFAULT '0',
calendarcolor VARBINARY(10),
striptodos TINYINT(1) NULL,
stripalarms TINYINT(1) NULL,
stripattachments TINYINT(1) NULL,
lastmodified INT(11) UNSIGNED,
UNIQUE(principaluri, uri)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
-->
<table>
<name>
*dbprefix*calendarsubscriptions
</name>
<declaration>
<field>
<name>
id
</name>
<type>
integer
</type>
<default>
0
</default>
<notnull>
true
</notnull>
<autoincrement>
1
</autoincrement>
<unsigned>
true
</unsigned>
<length>
11
</length>
</field>
<field>
<name>
uri
</name>
<type>
text
</type>
</field>
<field>
<name>
principaluri
</name>
<type>
text
</type>
</field>
<field>
<name>
source
</name>
<type>
text
</type>
</field>
<field>
<name>
displayname
</name>
<type>
text
</type>
<length>
100
</length>
</field>
<field>
<name>
refreshrate
</name>
<type>
text
</type>
<length>
10
</length>
</field>
<field>
<name>
calendarorder
</name>
<type>
integer
</type>
<default>
0
</default>
<notnull>
true
</notnull>
<unsigned>
true
</unsigned>
</field>
<field>
<name>
calendarcolor
</name>
<type>
text
</type>
</field>
<field>
<name>
striptodos
</name>
<type>
integer
</type>
<length>
1
</length>
</field>
<field>
<name>
stripalarms
</name>
<type>
integer
</type>
<length>
1
</length>
</field>
<field>
<name>
stripattachments
</name>
<type>
integer
</type>
<length>
1
</length>
</field>
<field>
<name>
lastmodified
</name>
<type>
integer
</type>
<unsigned>
true
</unsigned>
</field>
<index>
<name>
calsub_index
</name>
<unique>
true
</unique>
<field>
<name>
principaluri
</name>
</field>
<field>
<name>
uri
</name>
</field>
</index>
</declaration>
</table>
<!--
CREATE TABLE schedulingobjects (
id INT(11) UNSIGNED NOT NULL PRIMARY KEY AUTO_INCREMENT,
principaluri VARBINARY(255),
calendardata MEDIUMBLOB,
uri VARBINARY(200),
lastmodified INT(11) UNSIGNED,
etag VARBINARY(32),
size INT(11) UNSIGNED NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
-->
<table>
<name>
*dbprefix*schedulingobjects
</name>
<declaration>
<field>
<name>
id
</name>
<type>
integer
</type>
<default>
0
</default>
<notnull>
true
</notnull>
<autoincrement>
1
</autoincrement>
<unsigned>
true
</unsigned>
<length>
11
</length>
</field>
<field>
<name>
principaluri
</name>
<type>
text
</type>
</field>
<field>
<name>
calendardata
</name>
<type>
blob
</type>
</field>
<field>
<name>
uri
</name>
<type>
text
</type>
</field>
<field>
<name>
lastmodified
</name>
<type>
integer
</type>
<unsigned>
true
</unsigned>
</field>
<field>
<name>
etag
</name>
<type>
text
</type>
<length>
32
</length>
</field>
<field>
<name>
size
</name>
<type>
integer
</type>
<notnull>
true
</notnull>
<unsigned>
true
</unsigned>
<length>
11
</length>
</field>
</declaration>
</table>
</database>
apps/dav/appinfo/info.xml
View file @
d8b73fde
...
...
@@ -5,7 +5,7 @@
<description>
ownCloud WebDAV endpoint
</description>
<licence>
AGPL
</licence>
<author>
owncloud.org
</author>
<version>
0.1.
2
</version>
<version>
0.1.
3
</version>
<requiremin>
9.0
</requiremin>
<shipped>
true
</shipped>
<standalone/>
...
...
apps/dav/appinfo/register_command.php
View file @
d8b73fde
<?php
use
OCA\DAV\Command\CreateAddressBook
;
use
OCA\DAV\Command\CreateCalendar
;
$dbConnection
=
\
OC
::
$server
->
getDatabaseConnection
();
$userManager
=
OC
::
$server
->
getUserManager
();
/** @var Symfony\Component\Console\Application $application */
$application
->
add
(
new
CreateAddressBook
(
$userManager
,
$dbConnection
));
$application
->
add
(
new
CreateCalendar
(
$userManager
,
$dbConnection
));
apps/dav/command/createcalendar.php
0 → 100644
View file @
d8b73fde
<?php
namespace
OCA\DAV\Command
;
use
OCA\DAV\CalDAV\CalDavBackend
;
use
OCP\IDBConnection
;
use
OCP\IUserManager
;
use
Symfony\Component\Console\Command\Command
;
use
Symfony\Component\Console\Input\InputArgument
;
use
Symfony\Component\Console\Input\InputInterface
;
use
Symfony\Component\Console\Output\OutputInterface
;
class
CreateCalendar
extends
Command
{
/** @var IUserManager */
protected
$userManager
;
/** @var \OCP\IDBConnection */
protected
$dbConnection
;
/**
* @param IUserManager $userManager
* @param IDBConnection $dbConnection
*/
function
__construct
(
IUserManager
$userManager
,
IDBConnection
$dbConnection
)
{
parent
::
__construct
();
$this
->
userManager
=
$userManager
;
$this
->
dbConnection
=
$dbConnection
;
}
protected
function
configure
()
{
$this
->
setName
(
'dav:create-calendar'
)
->
setDescription
(
'Create a dav calendar'
)
->
addArgument
(
'user'
,
InputArgument
::
REQUIRED
,
'User for whom the calendar will be created'
)
->
addArgument
(
'name'
,
InputArgument
::
REQUIRED
,
'Name of the calendar'
);
}
protected
function
execute
(
InputInterface
$input
,
OutputInterface
$output
)
{
$user
=
$input
->
getArgument
(
'user'
);
if
(
!
$this
->
userManager
->
userExists
(
$user
))
{
throw
new
\
InvalidArgumentException
(
"User <
$user
> in unknown."
);
}
$name
=
$input
->
getArgument
(
'name'
);
$caldav
=
new
CalDavBackend
(
$this
->
dbConnection
);
$caldav
->
createCalendar
(
"principals/
$user
"
,
$name
,
[]);
}
}
apps/dav/lib/caldav/caldavbackend.php
0 → 100644
View file @
d8b73fde
This diff is collapsed.
Click to expand it.
apps/dav/lib/rootcollection.php
View file @
d8b73fde
...
...
@@ -2,8 +2,10 @@
namespace
OCA\DAV
;
use
OCA\DAV\CalDAV\CalDavBackend
;
use
OCA\DAV\CardDAV\CardDavBackend
;
use
OCA\DAV\Connector\Sabre\Principal
;
use
Sabre\CalDAV\CalendarRoot
;
use
Sabre\CalDAV\Principal\Collection
;
use
Sabre\CardDAV\AddressBookRoot
;
use
Sabre\DAV\SimpleCollection
;
...
...
@@ -12,9 +14,10 @@ class RootCollection extends SimpleCollection {
public
function
__construct
()
{
$config
=
\
OC
::
$server
->
getConfig
();
$db
=
\
OC
::
$server
->
getDatabaseConnection
();
$principalBackend
=
new
Principal
(
$config
,
\
OC
::
$server
->
getUserManager
()
$config
,
\
OC
::
$server
->
getUserManager
()
);
// as soon as debug mode is enabled we allow listing of principals
$disableListing
=
!
$config
->
getSystemValue
(
'debug'
,
false
);
...
...
@@ -24,14 +27,18 @@ class RootCollection extends SimpleCollection {
$principalCollection
->
disableListing
=
$disableListing
;
$filesCollection
=
new
Files\RootCollection
(
$principalBackend
);
$filesCollection
->
disableListing
=
$disableListing
;
$cardDavBackend
=
new
CardDavBackend
(
\
OC
::
$server
->
getDatabaseConnection
());
$caldavBackend
=
new
CalDavBackend
(
$db
);
$calendarRoot
=
new
CalendarRoot
(
$principalBackend
,
$caldavBackend
);
$calendarRoot
->
disableListing
=
$disableListing
;
$cardDavBackend
=
new
CardDavBackend
(
$db
);
$addressBookRoot
=
new
AddressBookRoot
(
$principalBackend
,
$cardDavBackend
);
$addressBookRoot
->
disableListing
=
$disableListing
;
$children
=
[
$principalCollection
,
$filesCollection
,
$addressBookRoot
,
$principalCollection
,
$filesCollection
,
$calendarRoot
,
$addressBookRoot
,
];
parent
::
__construct
(
'root'
,
$children
);
...
...
apps/dav/lib/server.php
View file @
d8b73fde
...
...
@@ -33,8 +33,18 @@ class Server {
$this
->
server
->
addPlugin
(
new
BlockLegacyClientPlugin
(
\
OC
::
$server
->
getConfig
()));
$this
->
server
->
addPlugin
(
new
Plugin
(
$authBackend
,
'ownCloud'
));
// calendar plugins
$this
->
server
->
addPlugin
(
new
\
Sabre\CalDAV\Plugin
());
$this
->
server
->
addPlugin
(
new
\
Sabre\DAVACL\Plugin
());
$this
->
server
->
addPlugin
(
new
\
Sabre\CalDAV\ICSExportPlugin
());
$senderEmail
=
\
OCP\Util
::
getDefaultEmailAddress
(
'no-reply'
);
$this
->
server
->
addPlugin
(
new
\
Sabre\CalDAV\Schedule\Plugin
());
$this
->
server
->
addPlugin
(
new
\
Sabre\CalDAV\Schedule\IMipPlugin
(
$senderEmail
));
$this
->
server
->
addPlugin
(
new
\
Sabre\CalDAV\SharingPlugin
());
$this
->
server
->
addPlugin
(
new
\
Sabre\CalDAV\Subscriptions\Plugin
());
$this
->
server
->
addPlugin
(
new
\
Sabre\CalDAV\Notifications\Plugin
());
// addressbook plugins
$this
->
server
->
addPlugin
(
new
\
Sabre\CardDAV\Plugin
());
// Finder on OS X requires Class 2 WebDAV support (locking), since we do
...
...
apps/dav/tests/unit/caldav/caldavbackendtest.php
0 → 100644
View file @
d8b73fde
<?php
/**
* @author Lukas Reschke <lukas@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
Tests\Connector\Sabre
;
use
DateTime
;
use
DateTimeZone
;
use
OCA\DAV\CalDAV\CalDavBackend
;
use
Sabre\CalDAV\Property\SupportedCalendarComponentSet
;
use
Sabre\DAV\Property\Href
;
use
Sabre\DAV\PropPatch
;
use
Test\TestCase
;
/**
* Class CalDavBackendTest
*
* @group DB
*
* @package Tests\Connector\Sabre
*/
class
CalDavBackendTest
extends
TestCase
{
/** @var CalDavBackend */
private
$backend
;
const
UNIT_TEST_USER
=
'caldav-unit-test'
;
public
function
setUp
()
{
parent
::
setUp
();
$db
=
\
OC
::
$server
->
getDatabaseConnection
();
$this
->
backend
=
new
CalDavBackend
(
$db
);
$this
->
tearDown
();
}
public
function
tearDown
()
{
parent
::
tearDown
();
if
(
is_null
(
$this
->
backend
))
{
return
;
}
$books
=
$this
->
backend
->
getCalendarsForUser
(
self
::
UNIT_TEST_USER
);
foreach
(
$books
as
$book
)
{
$this
->
backend
->
deleteCalendar
(
$book
[
'id'
]);
}
$subscriptions
=
$this
->
backend
->
getSubscriptionsForUser
(
self
::
UNIT_TEST_USER
);
foreach
(
$subscriptions
as
$subscription
)
{
$this
->
backend
->
deleteSubscription
(
$subscription
[
'id'
]);
}
}
public
function
testCalendarOperations
()
{
$calendarId
=
$this
->
createTestCalendar
();
// update it's display name
$patch
=
new
PropPatch
([
'{DAV:}displayname'
=>
'Unit test'
,
'{urn:ietf:params:xml:ns:caldav}calendar-description'
=>
'Calendar used for unit testing'
]);
$this
->
backend
->
updateCalendar
(
$calendarId
,
$patch
);
$patch
->
commit
();
$books
=
$this
->
backend
->
getCalendarsForUser
(
self
::
UNIT_TEST_USER
);
$this
->
assertEquals
(
1
,
count
(
$books
));
$this
->
assertEquals
(
'Unit test'
,
$books
[
0
][
'{DAV:}displayname'
]);
$this
->
assertEquals
(
'Calendar used for unit testing'
,
$books
[
0
][
'{urn:ietf:params:xml:ns:caldav}calendar-description'
]);
// delete the address book
$this
->
backend
->
deleteCalendar
(
$books
[
0
][
'id'
]);
$books
=
$this
->
backend
->
getCalendarsForUser
(
self
::
UNIT_TEST_USER
);
$this
->
assertEquals
(
0
,
count
(
$books
));