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