1<?php
2
3namespace SabreForRainLoop\DAVACL;
4
5use SabreForRainLoop\DAV;
6
7/**
8 * Principal class
9 *
10 * This class is a representation of a simple principal
11 *
12 * Many WebDAV specs require a user to show up in the directory
13 * structure.
14 *
15 * This principal also has basic ACL settings, only allowing the principal
16 * access it's own principal.
17 *
18 * @copyright Copyright (C) 2007-2013 fruux GmbH (https://fruux.com/).
19 * @author Evert Pot (http://evertpot.com/)
20 * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
21 */
22class Principal extends DAV\Node implements IPrincipal, DAV\IProperties, IACL {
23
24    /**
25     * Struct with principal information.
26     *
27     * @var array
28     */
29    protected $principalProperties;
30
31    /**
32     * Principal backend
33     *
34     * @var PrincipalBackend\BackendInterface
35     */
36    protected $principalBackend;
37
38    /**
39     * Creates the principal object
40     *
41     * @param IPrincipalBackend $principalBackend
42     * @param array $principalProperties
43     */
44    public function __construct(PrincipalBackend\BackendInterface $principalBackend, array $principalProperties = array()) {
45
46        if (!isset($principalProperties['uri'])) {
47            throw new DAV\Exception('The principal properties must at least contain the \'uri\' key');
48        }
49        $this->principalBackend = $principalBackend;
50        $this->principalProperties = $principalProperties;
51
52    }
53
54    /**
55     * Returns the full principal url
56     *
57     * @return string
58     */
59    public function getPrincipalUrl() {
60
61        return $this->principalProperties['uri'];
62
63    }
64
65    /**
66     * Returns a list of alternative urls for a principal
67     *
68     * This can for example be an email address, or ldap url.
69     *
70     * @return array
71     */
72    public function getAlternateUriSet() {
73
74        $uris = array();
75        if (isset($this->principalProperties['{DAV:}alternate-URI-set'])) {
76
77            $uris = $this->principalProperties['{DAV:}alternate-URI-set'];
78
79        }
80
81        if (isset($this->principalProperties['{http://sabredav.org/ns}email-address'])) {
82            $uris[] = 'mailto:' . $this->principalProperties['{http://sabredav.org/ns}email-address'];
83        }
84
85        return array_unique($uris);
86
87    }
88
89    /**
90     * Returns the list of group members
91     *
92     * If this principal is a group, this function should return
93     * all member principal uri's for the group.
94     *
95     * @return array
96     */
97    public function getGroupMemberSet() {
98
99        return $this->principalBackend->getGroupMemberSet($this->principalProperties['uri']);
100
101    }
102
103    /**
104     * Returns the list of groups this principal is member of
105     *
106     * If this principal is a member of a (list of) groups, this function
107     * should return a list of principal uri's for it's members.
108     *
109     * @return array
110     */
111    public function getGroupMembership() {
112
113        return $this->principalBackend->getGroupMemberShip($this->principalProperties['uri']);
114
115    }
116
117
118    /**
119     * Sets a list of group members
120     *
121     * If this principal is a group, this method sets all the group members.
122     * The list of members is always overwritten, never appended to.
123     *
124     * This method should throw an exception if the members could not be set.
125     *
126     * @param array $groupMembers
127     * @return void
128     */
129    public function setGroupMemberSet(array $groupMembers) {
130
131        $this->principalBackend->setGroupMemberSet($this->principalProperties['uri'], $groupMembers);
132
133    }
134
135
136    /**
137     * Returns this principals name.
138     *
139     * @return string
140     */
141    public function getName() {
142
143        $uri = $this->principalProperties['uri'];
144        list(, $name) = DAV\URLUtil::splitPath($uri);
145        return $name;
146
147    }
148
149    /**
150     * Returns the name of the user
151     *
152     * @return string
153     */
154    public function getDisplayName() {
155
156        if (isset($this->principalProperties['{DAV:}displayname'])) {
157            return $this->principalProperties['{DAV:}displayname'];
158        } else {
159            return $this->getName();
160        }
161
162    }
163
164    /**
165     * Returns a list of properties
166     *
167     * @param array $requestedProperties
168     * @return array
169     */
170    public function getProperties($requestedProperties) {
171
172        $newProperties = array();
173        foreach($requestedProperties as $propName) {
174
175            if (isset($this->principalProperties[$propName])) {
176                $newProperties[$propName] = $this->principalProperties[$propName];
177            }
178
179        }
180
181        return $newProperties;
182
183    }
184
185    /**
186     * Updates this principals properties.
187     *
188     * @param array $mutations
189     * @see SabreForRainLoop\DAV\IProperties::updateProperties
190     * @return bool|array
191     */
192    public function updateProperties($mutations) {
193
194        return $this->principalBackend->updatePrincipal($this->principalProperties['uri'], $mutations);
195
196    }
197
198    /**
199     * Returns the owner principal
200     *
201     * This must be a url to a principal, or null if there's no owner
202     *
203     * @return string|null
204     */
205    public function getOwner() {
206
207        return $this->principalProperties['uri'];
208
209
210    }
211
212    /**
213     * Returns a group principal
214     *
215     * This must be a url to a principal, or null if there's no owner
216     *
217     * @return string|null
218     */
219    public function getGroup() {
220
221        return null;
222
223    }
224
225    /**
226     * Returns a list of ACE's for this node.
227     *
228     * Each ACE has the following properties:
229     *   * 'privilege', a string such as {DAV:}read or {DAV:}write. These are
230     *     currently the only supported privileges
231     *   * 'principal', a url to the principal who owns the node
232     *   * 'protected' (optional), indicating that this ACE is not allowed to
233     *      be updated.
234     *
235     * @return array
236     */
237    public function getACL() {
238
239        return array(
240            array(
241                'privilege' => '{DAV:}read',
242                'principal' => $this->getPrincipalUrl(),
243                'protected' => true,
244            ),
245        );
246
247    }
248
249    /**
250     * Updates the ACL
251     *
252     * This method will receive a list of new ACE's.
253     *
254     * @param array $acl
255     * @return void
256     */
257    public function setACL(array $acl) {
258
259        throw new DAV\Exception\MethodNotAllowed('Updating ACLs is not allowed here');
260
261    }
262
263    /**
264     * Returns the list of supported privileges for this node.
265     *
266     * The returned data structure is a list of nested privileges.
267     * See SabreForRainLoop\DAVACL\Plugin::getDefaultSupportedPrivilegeSet for a simple
268     * standard structure.
269     *
270     * If null is returned from this method, the default privilege set is used,
271     * which is fine for most common usecases.
272     *
273     * @return array|null
274     */
275    public function getSupportedPrivilegeSet() {
276
277        return null;
278
279    }
280
281}
282