Completed
Push — master ( 6b41d8...b99d2b )
by Morris
28s
created

AddressBook::isShared()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 7
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 4
nc 2
nop 0
dl 0
loc 7
rs 9.4285
c 0
b 0
f 0
1
<?php
2
/**
3
 * @copyright Copyright (c) 2016, ownCloud, Inc.
4
 *
5
 * @author Thomas Müller <[email protected]>
6
 *
7
 * @license AGPL-3.0
8
 *
9
 * This code is free software: you can redistribute it and/or modify
10
 * it under the terms of the GNU Affero General Public License, version 3,
11
 * as published by the Free Software Foundation.
12
 *
13
 * This program is distributed in the hope that it will be useful,
14
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16
 * GNU Affero General Public License for more details.
17
 *
18
 * You should have received a copy of the GNU Affero General Public License, version 3,
19
 * along with this program.  If not, see <http://www.gnu.org/licenses/>
20
 *
21
 */
22
namespace OCA\DAV\CardDAV;
23
24
use OCA\DAV\DAV\Sharing\IShareable;
25
use OCP\IL10N;
26
use Sabre\CardDAV\Backend\BackendInterface;
27
use Sabre\CardDAV\Card;
28
use Sabre\DAV\Exception\Forbidden;
29
use Sabre\DAV\Exception\NotFound;
30
use Sabre\DAV\PropPatch;
31
32
/**
33
 * Class AddressBook
34
 *
35
 * @package OCA\DAV\CardDAV
36
 * @property BackendInterface|CardDavBackend $carddavBackend
37
 */
38
class AddressBook extends \Sabre\CardDAV\AddressBook implements IShareable {
39
40
	/**
41
	 * AddressBook constructor.
42
	 *
43
	 * @param BackendInterface $carddavBackend
44
	 * @param array $addressBookInfo
45
	 * @param IL10N $l10n
46
	 */
47
	public function __construct(BackendInterface $carddavBackend, array $addressBookInfo, IL10N $l10n) {
48
		parent::__construct($carddavBackend, $addressBookInfo);
49
50
		if ($this->addressBookInfo['{DAV:}displayname'] === CardDavBackend::PERSONAL_ADDRESSBOOK_NAME &&
51
			$this->getName() === CardDavBackend::PERSONAL_ADDRESSBOOK_URI) {
0 ignored issues
show
Bug introduced by
Consider using $this->name. There is an issue with getName() and APC-enabled PHP versions.
Loading history...
52
			$this->addressBookInfo['{DAV:}displayname'] = $l10n->t('Contacts');
53
		}
54
	}
55
56
	/**
57
	 * Updates the list of shares.
58
	 *
59
	 * The first array is a list of people that are to be added to the
60
	 * addressbook.
61
	 *
62
	 * Every element in the add array has the following properties:
63
	 *   * href - A url. Usually a mailto: address
64
	 *   * commonName - Usually a first and last name, or false
65
	 *   * summary - A description of the share, can also be false
66
	 *   * readOnly - A boolean value
67
	 *
68
	 * Every element in the remove array is just the address string.
69
	 *
70
	 * @param array $add
71
	 * @param array $remove
72
	 * @return void
73
	 * @throws Forbidden
74
	 */
75
	public function updateShares(array $add, array $remove) {
76
		if ($this->isShared()) {
77
			throw new Forbidden();
78
		}
79
		$this->carddavBackend->updateShares($this, $add, $remove);
80
	}
81
82
	/**
83
	 * Returns the list of people whom this addressbook is shared with.
84
	 *
85
	 * Every element in this array should have the following properties:
86
	 *   * href - Often a mailto: address
87
	 *   * commonName - Optional, for example a first + last name
88
	 *   * status - See the Sabre\CalDAV\SharingPlugin::STATUS_ constants.
89
	 *   * readOnly - boolean
90
	 *   * summary - Optional, a description for the share
91
	 *
92
	 * @return array
93
	 */
94
	public function getShares() {
95
		if ($this->isShared()) {
96
			return [];
97
		}
98
		return $this->carddavBackend->getShares($this->getResourceId());
99
	}
100
101 View Code Duplication
	public function getACL() {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
102
		$acl =  [
103
			[
104
				'privilege' => '{DAV:}read',
105
				'principal' => $this->getOwner(),
106
				'protected' => true,
107
			]];
108
		$acl[] = [
109
				'privilege' => '{DAV:}write',
110
				'principal' => $this->getOwner(),
111
				'protected' => true,
112
			];
113
		if ($this->getOwner() !== parent::getOwner()) {
0 ignored issues
show
Comprehensibility Bug introduced by
It seems like you call parent on a different method (getOwner() instead of getACL()). Are you sure this is correct? If so, you might want to change this to $this->getOwner().

This check looks for a call to a parent method whose name is different than the method from which it is called.

Consider the following code:

class Daddy
{
    protected function getFirstName()
    {
        return "Eidur";
    }

    protected function getSurName()
    {
        return "Gudjohnsen";
    }
}

class Son
{
    public function getFirstName()
    {
        return parent::getSurname();
    }
}

The getFirstName() method in the Son calls the wrong method in the parent class.

Loading history...
114
			$acl[] =  [
115
					'privilege' => '{DAV:}read',
116
					'principal' => parent::getOwner(),
0 ignored issues
show
Comprehensibility Bug introduced by
It seems like you call parent on a different method (getOwner() instead of getACL()). Are you sure this is correct? If so, you might want to change this to $this->getOwner().

This check looks for a call to a parent method whose name is different than the method from which it is called.

Consider the following code:

class Daddy
{
    protected function getFirstName()
    {
        return "Eidur";
    }

    protected function getSurName()
    {
        return "Gudjohnsen";
    }
}

class Son
{
    public function getFirstName()
    {
        return parent::getSurname();
    }
}

The getFirstName() method in the Son calls the wrong method in the parent class.

Loading history...
117
					'protected' => true,
118
				];
119
			if ($this->canWrite()) {
120
				$acl[] = [
121
					'privilege' => '{DAV:}write',
122
					'principal' => parent::getOwner(),
0 ignored issues
show
Comprehensibility Bug introduced by
It seems like you call parent on a different method (getOwner() instead of getACL()). Are you sure this is correct? If so, you might want to change this to $this->getOwner().

This check looks for a call to a parent method whose name is different than the method from which it is called.

Consider the following code:

class Daddy
{
    protected function getFirstName()
    {
        return "Eidur";
    }

    protected function getSurName()
    {
        return "Gudjohnsen";
    }
}

class Son
{
    public function getFirstName()
    {
        return parent::getSurname();
    }
}

The getFirstName() method in the Son calls the wrong method in the parent class.

Loading history...
123
					'protected' => true,
124
				];
125
			}
126
		}
127
		if ($this->getOwner() === 'principals/system/system') {
128
			$acl[] = [
129
					'privilege' => '{DAV:}read',
130
					'principal' => '{DAV:}authenticated',
131
					'protected' => true,
132
			];
133
		}
134
135
		if ($this->isShared()) {
136
			return $acl;
137
		}
138
139
		return $this->carddavBackend->applyShareAcl($this->getResourceId(), $acl);
140
	}
141
142
	public function getChildACL() {
143
		return $this->getACL();
144
	}
145
146
	public function getChild($name) {
147
148
		$obj = $this->carddavBackend->getCard($this->addressBookInfo['id'], $name);
149
		if (!$obj) {
150
			throw new NotFound('Card not found');
151
		}
152
		$obj['acl'] = $this->getChildACL();
153
		return new Card($this->carddavBackend, $this->addressBookInfo, $obj);
154
155
	}
156
157
	/**
158
	 * @return int
159
	 */
160
	public function getResourceId() {
161
		return $this->addressBookInfo['id'];
162
	}
163
164
	public function getOwner() {
165
		if (isset($this->addressBookInfo['{http://owncloud.org/ns}owner-principal'])) {
166
			return $this->addressBookInfo['{http://owncloud.org/ns}owner-principal'];
167
		}
168
		return parent::getOwner();
169
	}
170
171
	public function delete() {
172
		if (isset($this->addressBookInfo['{http://owncloud.org/ns}owner-principal'])) {
173
			$principal = 'principal:' . parent::getOwner();
0 ignored issues
show
Comprehensibility Bug introduced by
It seems like you call parent on a different method (getOwner() instead of delete()). Are you sure this is correct? If so, you might want to change this to $this->getOwner().

This check looks for a call to a parent method whose name is different than the method from which it is called.

Consider the following code:

class Daddy
{
    protected function getFirstName()
    {
        return "Eidur";
    }

    protected function getSurName()
    {
        return "Gudjohnsen";
    }
}

class Son
{
    public function getFirstName()
    {
        return parent::getSurname();
    }
}

The getFirstName() method in the Son calls the wrong method in the parent class.

Loading history...
174
			$shares = $this->carddavBackend->getShares($this->getResourceId());
175
			$shares = array_filter($shares, function($share) use ($principal){
176
				return $share['href'] === $principal;
177
			});
178
			if (empty($shares)) {
179
				throw new Forbidden();
180
			}
181
182
			$this->carddavBackend->updateShares($this, [], [
183
				'href' => $principal
184
			]);
185
			return;
186
		}
187
		parent::delete();
188
	}
189
190
	public function propPatch(PropPatch $propPatch) {
191
		if (isset($this->addressBookInfo['{http://owncloud.org/ns}owner-principal'])) {
192
			throw new Forbidden();
193
		}
194
		parent::propPatch($propPatch);
195
	}
196
197
	public function getContactsGroups() {
198
		return $this->carddavBackend->collectCardProperties($this->getResourceId(), 'CATEGORIES');
199
	}
200
201
	private function isShared() {
202
		if (!isset($this->addressBookInfo['{http://owncloud.org/ns}owner-principal'])) {
203
			return false;
204
		}
205
206
		return $this->addressBookInfo['{http://owncloud.org/ns}owner-principal'] !== $this->addressBookInfo['principaluri'];
207
	}
208
209
	private function canWrite() {
210
		if (isset($this->addressBookInfo['{http://owncloud.org/ns}read-only'])) {
211
			return !$this->addressBookInfo['{http://owncloud.org/ns}read-only'];
212
		}
213
		return true;
214
	}
215
}
216