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