aboutsummaryrefslogtreecommitdiffstats
path: root/apps/contacts
diff options
context:
space:
mode:
Diffstat (limited to 'apps/contacts')
-rw-r--r--apps/contacts/appinfo/app.php5
-rw-r--r--apps/contacts/css/contacts.css3
-rw-r--r--apps/contacts/js/loader.js4
-rw-r--r--apps/contacts/js/settings.js1
-rw-r--r--apps/contacts/lib/addressbook.php16
-rw-r--r--apps/contacts/lib/app.php29
-rw-r--r--apps/contacts/lib/share/addressbook.php93
-rw-r--r--apps/contacts/lib/share/contact.php53
-rw-r--r--apps/contacts/lib/vcard.php87
-rw-r--r--apps/contacts/templates/settings.php3
10 files changed, 272 insertions, 22 deletions
diff --git a/apps/contacts/appinfo/app.php b/apps/contacts/appinfo/app.php
index 7e73f315dd0..68163430186 100644
--- a/apps/contacts/appinfo/app.php
+++ b/apps/contacts/appinfo/app.php
@@ -3,6 +3,8 @@ OC::$CLASSPATH['OC_Contacts_App'] = 'apps/contacts/lib/app.php';
OC::$CLASSPATH['OC_Contacts_Addressbook'] = 'apps/contacts/lib/addressbook.php';
OC::$CLASSPATH['OC_Contacts_VCard'] = 'apps/contacts/lib/vcard.php';
OC::$CLASSPATH['OC_Contacts_Hooks'] = 'apps/contacts/lib/hooks.php';
+OC::$CLASSPATH['OC_Share_Backend_Contact'] = 'apps/contacts/lib/share/contact.php';
+OC::$CLASSPATH['OC_Share_Backend_Addressbook'] = 'apps/contacts/lib/share/addressbook.php';
OC::$CLASSPATH['OC_Connector_Sabre_CardDAV'] = 'apps/contacts/lib/connector_sabre.php';
OC::$CLASSPATH['Sabre_CardDAV_VCFExportPlugin'] = 'apps/contacts/lib/VCFExportPlugin.php';
OC::$CLASSPATH['OC_Search_Provider_Contacts'] = 'apps/contacts/lib/search.php';
@@ -20,3 +22,6 @@ OCP\App::addNavigationEntry( array(
OCP\Util::addscript('contacts', 'loader');
OC_Search::registerProvider('OC_Search_Provider_Contacts');
+OCP\Share::registerBackend('contact', 'OC_Share_Backend_Contact');
+OCP\Share::registerBackend('addressbook', 'OC_Share_Backend_Addressbook', 'contact');
+
diff --git a/apps/contacts/css/contacts.css b/apps/contacts/css/contacts.css
index c5308c4d25a..ad8762167b5 100644
--- a/apps/contacts/css/contacts.css
+++ b/apps/contacts/css/contacts.css
@@ -50,11 +50,12 @@ label:hover, dt:hover { color: #333; }
.float { float: left; }
.svg { border: inherit; background: inherit; }
.listactions { height: 1em; width:60px; float: left; clear: right; }
-.add,.edit,.delete,.mail, .globe, .upload, .download, .cloud { cursor: pointer; width: 20px; height: 20px; margin: 0; float: left; position:relative; opacity: 0.1; }
+.add,.edit,.delete,.mail, .globe, .upload, .download, .cloud, .share { cursor: pointer; width: 20px; height: 20px; margin: 0; float: left; position:relative; opacity: 0.1; }
.add:hover,.edit:hover,.delete:hover,.mail:hover, .globe:hover, .upload:hover, .download:hover .cloud:hover { opacity: 1.0 }
.add { background:url('%webroot%/core/img/actions/add.svg') no-repeat center; clear: both; }
.delete { background:url('%webroot%/core/img/actions/delete.svg') no-repeat center; }
.edit { background:url('%webroot%/core/img/actions/rename.svg') no-repeat center; }
+.share { background:url('%webroot%/core/img/actions/share.svg') no-repeat center; }
.mail { background:url('%webroot%/core/img/actions/mail.svg') no-repeat center; }
.upload { background:url('%webroot%/core/img/actions/upload.svg') no-repeat center; }
.download { background:url('%webroot%/core/img/actions/download.svg') no-repeat center; }
diff --git a/apps/contacts/js/loader.js b/apps/contacts/js/loader.js
index 5bca0ab7237..3b1f4070485 100644
--- a/apps/contacts/js/loader.js
+++ b/apps/contacts/js/loader.js
@@ -78,9 +78,9 @@ Contacts_Import={
}
$(document).ready(function(){
if(typeof FileActions !== 'undefined'){
- FileActions.register('text/vcard','importaddressbook', '', Contacts_Import.importdialog);
+ FileActions.register('text/vcard','importaddressbook', FileActions.PERMISSION_READ, '', Contacts_Import.importdialog);
FileActions.setDefault('text/vcard','importaddressbook');
- FileActions.register('text/x-vcard','importaddressbook', '', Contacts_Import.importdialog);
+ FileActions.register('text/x-vcard','importaddressbook', FileActions.PERMISSION_READ, '', Contacts_Import.importdialog);
FileActions.setDefault('text/x-vcard','importaddressbook');
};
}); \ No newline at end of file
diff --git a/apps/contacts/js/settings.js b/apps/contacts/js/settings.js
index 67aaa5b5f88..69cf473e06a 100644
--- a/apps/contacts/js/settings.js
+++ b/apps/contacts/js/settings.js
@@ -4,6 +4,7 @@ OC.Contacts.Settings = OC.Contacts.Settings || {
this.Addressbook.adrsettings = $('.addressbooks-settings').first();
this.Addressbook.adractions = $('#contacts-settings').find('div.actions');
console.log('actions: ' + this.Addressbook.adractions.length);
+ OC.Share.loadIcons('addressbook');
},
Addressbook:{
showActions:function(act) {
diff --git a/apps/contacts/lib/addressbook.php b/apps/contacts/lib/addressbook.php
index eb61b6dbced..92c5f4da3a7 100644
--- a/apps/contacts/lib/addressbook.php
+++ b/apps/contacts/lib/addressbook.php
@@ -64,10 +64,10 @@ class OC_Contacts_Addressbook {
while( $row = $result->fetchRow()) {
$addressbooks[] = $row;
}
+ $addressbooks = array_merge($addressbooks, OCP\Share::getItemsSharedWith('addressbook', OC_Share_Backend_Addressbook::FORMAT_ADDRESSBOOKS));
if(!$active && !count($addressbooks)) {
self::addDefault($uid);
}
-
return $addressbooks;
}
@@ -208,7 +208,12 @@ class OC_Contacts_Addressbook {
public static function edit($id,$name,$description) {
// Need these ones for checking uri
$addressbook = self::find($id);
-
+ if ($addressbook['userid'] != OCP\User::getUser()) {
+ $sharedAddressbook = OCP\Share::getItemSharedWithBySource('addressbook', $id);
+ if (!$sharedAddressbook || !($sharedAddressbook['permissions'] & OCP\Share::PERMISSION_UPDATE)) {
+ return false;
+ }
+ }
if(is_null($name)) {
$name = $addressbook['name'];
}
@@ -270,6 +275,13 @@ class OC_Contacts_Addressbook {
* @return boolean
*/
public static function delete($id) {
+ $addressbook = self::find($id);
+ if ($addressbook['userid'] != OCP\User::getUser()) {
+ $sharedAddressbook = OCP\Share::getItemSharedWithBySource('addressbook', $id);
+ if (!$sharedAddressbook || !($sharedAddressbook['permissions'] & OCP\Share::PERMISSION_DELETE)) {
+ return false;
+ }
+ }
self::setActive($id, false);
try {
$stmt = OCP\DB::prepare( 'DELETE FROM *PREFIX*contacts_addressbooks WHERE id = ?' );
diff --git a/apps/contacts/lib/app.php b/apps/contacts/lib/app.php
index b59a8372b74..f6ce213c49b 100644
--- a/apps/contacts/lib/app.php
+++ b/apps/contacts/lib/app.php
@@ -37,21 +37,24 @@ class OC_Contacts_App {
)
)
);
- }
- else {
- OCP\Util::writeLog('contacts',
- 'Addressbook('.$id.') is not from '.OCP\USER::getUser(),
- OCP\Util::ERROR);
- //throw new Exception('This is not your addressbook.');
- OCP\JSON::error(
- array(
- 'data' => array(
- 'message' => self::$l10n->t('This is not your addressbook.')
+ } else {
+ $sharedAddressbook = OCP\Share::getItemSharedWithBySource('addressbook', $id, OC_Share_Backend_Addressbook::FORMAT_ADDRESSBOOKS);
+ if ($sharedAddressbook) {
+ return $sharedAddressbook;
+ } else {
+ OCP\Util::writeLog('contacts',
+ 'Addressbook('.$id.') is not from '.OCP\USER::getUser(),
+ OCP\Util::ERROR);
+ //throw new Exception('This is not your addressbook.');
+ OCP\JSON::error(
+ array(
+ 'data' => array(
+ 'message' => self::$l10n->t('This is not your addressbook.')
+ )
)
- )
- );
+ );
+ }
}
- exit();
}
return $addressbook;
}
diff --git a/apps/contacts/lib/share/addressbook.php b/apps/contacts/lib/share/addressbook.php
new file mode 100644
index 00000000000..62799696d95
--- /dev/null
+++ b/apps/contacts/lib/share/addressbook.php
@@ -0,0 +1,93 @@
+<?php
+/**
+ * Copyright (c) 2012 Bart Visscher <bartv@thisnet.nl>
+ * This file is licensed under the Affero General Public License version 3 or
+ * later.
+ * See the COPYING-README file.
+ */
+
+class OC_Share_Backend_Addressbook implements OCP\Share_Backend_Collection {
+ const FORMAT_ADDRESSBOOKS = 1;
+
+ /**
+ * @brief Get the source of the item to be stored in the database
+ * @param string Item
+ * @param string Owner of the item
+ * @return mixed|array|false Source
+ *
+ * Return an array if the item is file dependent, the array needs two keys: 'item' and 'file'
+ * Return false if the item does not exist for the user
+ *
+ * The formatItems() function will translate the source returned back into the item
+ */
+ public function isValidSource($itemSource, $uidOwner) {
+ $addressbook = OC_Contacts_Addressbook::find( $itemSource );
+ if( $addressbook === false || $addressbook['userid'] != $uidOwner) {
+ return false;
+ }
+ return true;
+ }
+
+ /**
+ * @brief Get a unique name of the item for the specified user
+ * @param string Item
+ * @param string|false User the item is being shared with
+ * @param array|null List of similar item names already existing as shared items
+ * @return string Target name
+ *
+ * This function needs to verify that the user does not already have an item with this name.
+ * If it does generate a new name e.g. name_#
+ */
+ public function generateTarget($itemSource, $shareWith, $exclude = null) {
+ $addressbook = OC_Contacts_Addressbook::find( $itemSource );
+ $user_addressbooks = array();
+ foreach(OC_Contacts_Addressbook::all($uid) as $user_addressbook) {
+ $user_addressbooks[] = $user_addressbook['displayname'];
+ }
+ $name = $addressbook['userid']."'s ".$addressbook['displayname'];
+ $suffix = '';
+ while (in_array($name.$suffix, $user_addressbooks)) {
+ $suffix++;
+ }
+
+ return $name.$suffix;
+ }
+
+ /**
+ * @brief Converts the shared item sources back into the item in the specified format
+ * @param array Shared items
+ * @param int Format
+ * @return ?
+ *
+ * The items array is a 3-dimensional array with the item_source as the first key and the share id as the second key to an array with the share info.
+ * The key/value pairs included in the share info depend on the function originally called:
+ * If called by getItem(s)Shared: id, item_type, item, item_source, share_type, share_with, permissions, stime, file_source
+ * If called by getItem(s)SharedWith: id, item_type, item, item_source, item_target, share_type, share_with, permissions, stime, file_source, file_target
+ * This function allows the backend to control the output of shared items with custom formats.
+ * It is only called through calls to the public getItem(s)Shared(With) functions.
+ */
+ public function formatItems($items, $format, $parameters = null) {
+ $addressbooks = array();
+ if ($format == self::FORMAT_ADDRESSBOOKS) {
+ foreach ($items as $item) {
+ $addressbook = OC_Contacts_Addressbook::find($item['item_source']);
+ if ($addressbook) {
+ $addressbook['displayname'] = $item['item_target'];
+ $addressbooks[] = $addressbook;
+ }
+ }
+ }
+ return $addressbooks;
+ }
+
+ public function getChildren($itemSource) {
+ $query = OCP\DB::prepare('SELECT id FROM *PREFIX*contacts_cards WHERE addressbookid = ?');
+ $result = $query->execute(array($itemSource));
+ $sources = array();
+ while ($contact = $result->fetchRow()) {
+ $sources[] = $contact['id'];
+ }
+ return $sources;
+ }
+
+}
diff --git a/apps/contacts/lib/share/contact.php b/apps/contacts/lib/share/contact.php
new file mode 100644
index 00000000000..718c8f9025f
--- /dev/null
+++ b/apps/contacts/lib/share/contact.php
@@ -0,0 +1,53 @@
+<?php
+/**
+* ownCloud
+*
+* @author Michael Gapczynski
+* @copyright 2012 Michael Gapczynski mtgap@owncloud.com
+*
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
+* License as published by the Free Software Foundation; either
+* version 3 of the License, or any later version.
+*
+* This library 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 along with this library. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+class OC_Share_Backend_Contact implements OCP\Share_Backend {
+
+ const FORMAT_CONTACT = 0;
+
+ private static $contact;
+
+ public function isValidSource($itemSource, $uidOwner) {
+ self::$contact = OC_Contacts_VCard::find($itemSource);
+ if (self::$contact) {
+ return true;
+ }
+ return false;
+ }
+
+ public function generateTarget($itemSource, $shareWith, $exclude = null) {
+ // TODO Get default addressbook and check for conflicts
+ return self::$contact['fullname'];
+ }
+
+ public function formatItems($items, $format, $parameters = null) {
+ $contacts = array();
+ if ($format == self::FORMAT_CONTACT) {
+ foreach ($items as $item) {
+ $contact = OC_Contacts_VCard::find($item['item_source']);
+ $contact['fullname'] = $item['item_target'];
+ $contacts[] = $contact;
+ }
+ }
+ return $contacts;
+ }
+
+} \ No newline at end of file
diff --git a/apps/contacts/lib/vcard.php b/apps/contacts/lib/vcard.php
index 81ae689d9a2..8c38f1ba15d 100644
--- a/apps/contacts/lib/vcard.php
+++ b/apps/contacts/lib/vcard.php
@@ -293,12 +293,17 @@ class OC_Contacts_VCard{
OCP\Util::writeLog('contacts', 'OC_Contacts_VCard::add. No vCard supplied', OCP\Util::ERROR);
return null;
};
-
+ $addressbook = OC_Contacts_Addressbook::find($aid);
+ if ($addressbook['userid'] != OCP\User::getUser()) {
+ $sharedAddressbook = OCP\Share::getItemSharedWithBySource('addressbook', $aid);
+ if (!$sharedAddressbook || !($sharedAddressbook['permissions'] & OCP\Share::PERMISSION_CREATE)) {
+ return false;
+ }
+ }
if(!$isChecked) {
OC_Contacts_App::loadCategoriesFromVCard($card);
self::updateValuesFromAdd($aid, $card);
}
-
$card->setString('VERSION', '3.0');
// Add product ID is missing.
$prodid = trim($card->getAsString('PRODID'));
@@ -357,6 +362,17 @@ class OC_Contacts_VCard{
foreach($objects as $object) {
$vcard = OC_VObject::parse($object[1]);
if(!is_null($vcard)) {
+ $oldcard = self::find($object[0]);
+ if (!$oldcard) {
+ return false;
+ }
+ $addressbook = OC_Contacts_Addressbook::find($oldcard['addressbookid']);
+ if ($addressbook['userid'] != OCP\User::getUser()) {
+ $sharedContact = OCP\Share::getItemSharedWithBySource('contact', $object[0], OCP\Share::FORMAT_NONE, null, true);
+ if (!$sharedContact || !($sharedContact['permissions'] & OCP\Share::PERMISSION_UPDATE)) {
+ return false;
+ }
+ }
$vcard->setString('REV', $now->format(DateTime::W3C));
$data = $vcard->serialize();
try {
@@ -378,11 +394,20 @@ class OC_Contacts_VCard{
*/
public static function edit($id, OC_VObject $card){
$oldcard = self::find($id);
-
+ if (!$oldcard) {
+ return false;
+ }
if(is_null($card)) {
return false;
}
-
+ // NOTE: Owner checks are being made in the ajax files, which should be done inside the lib files to prevent any redundancies with sharing checks
+ $addressbook = OC_Contacts_Addressbook::find($oldcard['addressbookid']);
+ if ($addressbook['userid'] != OCP\User::getUser()) {
+ $sharedContact = OCP\Share::getItemSharedWithBySource('contact', $id, OCP\Share::FORMAT_NONE, null, true);
+ if (!$sharedContact || !($sharedContact['permissions'] & OCP\Share::PERMISSION_UPDATE)) {
+ return false;
+ }
+ }
OC_Contacts_App::loadCategoriesFromVCard($card);
$fn = $card->getAsString('FN');
@@ -431,6 +456,17 @@ class OC_Contacts_VCard{
* @return boolean
*/
public static function delete($id){
+ $card = self::find($id);
+ if (!$card) {
+ return false;
+ }
+ $addressbook = OC_Contacts_Addressbook::find($card['addressbookid']);
+ if ($addressbook['userid'] != OCP\User::getUser()) {
+ $sharedContact = OCP\Share::getItemSharedWithBySource('contact', $id, OCP\Share::FORMAT_NONE, null, true);
+ if (!$sharedContact || !($sharedContact['permissions'] & OCP\Share::PERMISSION_DELETE)) {
+ return false;
+ }
+ }
OC_Hook::emit('OC_Contacts_VCard', 'pre_deleteVCard', array('aid' => null, 'id' => $id, 'uri' => null));
$stmt = OCP\DB::prepare( 'DELETE FROM *PREFIX*contacts_cards WHERE id = ?' );
try {
@@ -451,6 +487,18 @@ class OC_Contacts_VCard{
* @return boolean
*/
public static function deleteFromDAVData($aid,$uri){
+ $addressbook = OC_Contacts_Addressbook::find($aid);
+ if ($addressbook['userid'] != OCP\User::getUser()) {
+ $query = OCP\DB::prepare( 'SELECT id FROM *PREFIX*contacts_cards WHERE addressbookid = ? AND uri = ?' );
+ $id = $query->execute(array($aid, $uri))->fetchOne();
+ if (!$id) {
+ return false;
+ }
+ $sharedContact = OCP\Share::getItemSharedWithBySource('contact', $id, OCP\Share::FORMAT_NONE, null, true);
+ if (!$sharedContact || !($sharedContact['permissions'] & OCP\Share::PERMISSION_DELETE)) {
+ return false;
+ }
+ }
OC_Hook::emit('OC_Contacts_VCard', 'pre_deleteVCard', array('aid' => $aid, 'id' => null, 'uri' => $uri));
$stmt = OCP\DB::prepare( 'DELETE FROM *PREFIX*contacts_cards WHERE addressbookid = ? AND uri=?' );
try {
@@ -594,7 +642,27 @@ class OC_Contacts_VCard{
*/
public static function moveToAddressBook($aid, $id, $isAddressbook = false) {
OC_Contacts_App::getAddressbook($aid); // check for user ownership.
+ $addressbook = OC_Contacts_Addressbook::find($aid);
+ if ($addressbook['userid'] != OCP\User::getUser()) {
+ $sharedAddressbook = OCP\Share::getItemSharedWithBySource('addressbook', $aid);
+ if (!$sharedAddressbook || !($sharedAddressbook['permissions'] & OCP\Share::PERMISSION_CREATE)) {
+ return false;
+ }
+ }
if(is_array($id)) {
+ foreach ($id as $index => $cardId) {
+ $card = self::find($cardId);
+ if (!$card) {
+ unset($id[$index]);
+ }
+ $oldAddressbook = OC_Contacts_Addressbook::find($card['addressbookid']);
+ if ($oldAddressbook['userid'] != OCP\User::getUser()) {
+ $sharedContact = OCP\Share::getItemSharedWithBySource('contact', $cardId, OCP\Share::FORMAT_NONE, null, true);
+ if (!$sharedContact || !($sharedContact['permissions'] & OCP\Share::PERMISSION_DELETE)) {
+ unset($id[$index]);
+ }
+ }
+ }
$id_sql = join(',', array_fill(0, count($id), '?'));
$prep = 'UPDATE *PREFIX*contacts_cards SET addressbookid = ? WHERE id IN ('.$id_sql.')';
try {
@@ -613,6 +681,17 @@ class OC_Contacts_VCard{
if($isAddressbook) {
$stmt = OCP\DB::prepare( 'UPDATE *PREFIX*contacts_cards SET addressbookid = ? WHERE addressbookid = ?' );
} else {
+ $card = self::find($id);
+ if (!$card) {
+ return false;
+ }
+ $oldAddressbook = OC_Contacts_Addressbook::find($card['addressbookid']);
+ if ($oldAddressbook['userid'] != OCP\User::getUser()) {
+ $sharedContact = OCP\Share::getItemSharedWithBySource('contact', $id, OCP\Share::FORMAT_NONE, null, true);
+ if (!$sharedContact || !($sharedContact['permissions'] & OCP\Share::PERMISSION_DELETE)) {
+ return false;
+ }
+ }
$stmt = OCP\DB::prepare( 'UPDATE *PREFIX*contacts_cards SET addressbookid = ? WHERE id = ?' );
}
try {
diff --git a/apps/contacts/templates/settings.php b/apps/contacts/templates/settings.php
index 3fddc59588a..e3536c7b461 100644
--- a/apps/contacts/templates/settings.php
+++ b/apps/contacts/templates/settings.php
@@ -23,6 +23,9 @@
<a class="svg action cloud" title="<?php echo $l->t('Show read-only VCF link'); ?>"></a>
</td>
<td class="action">
+ <a class="svg action share" data-item-type="addressbook" data-item="<?php echo $addressbook['id'] ?>" title="<?php echo $l->t("Share"); ?>"></a>
+ </td>
+ <td class="action">
<a class="svg action download" title="<?php echo $l->t('Download'); ?>"
href="<?php echo OCP\Util::linkToAbsolute('contacts', 'export.php'); ?>?bookid=<?php echo $addressbook['id'] ?>"></a>
</td>