Skip to content

Commit c1030a3

Browse files
authored
Merge pull request #4062 from nextcloud/downstream-26872
Adding dav resource for avatars
2 parents 626d03e + 7cc96c2 commit c1030a3

8 files changed

Lines changed: 427 additions & 3 deletions

File tree

Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
<?php
2+
/**
3+
* @author Thomas Müller <thomas.mueller@tmit.eu>
4+
*
5+
* @copyright Copyright (c) 2016, ownCloud GmbH
6+
* @license AGPL-3.0
7+
*
8+
* This code is free software: you can redistribute it and/or modify
9+
* it under the terms of the GNU Affero General Public License, version 3,
10+
* as published by the Free Software Foundation.
11+
*
12+
* This program is distributed in the hope that it will be useful,
13+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
14+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15+
* GNU Affero General Public License for more details.
16+
*
17+
* You should have received a copy of the GNU Affero General Public License, version 3,
18+
* along with this program. If not, see <http://www.gnu.org/licenses/>
19+
*
20+
*/
21+
22+
23+
namespace OCA\DAV\Avatars;
24+
25+
26+
use OCP\IAvatarManager;
27+
use Sabre\DAV\Exception\Forbidden;
28+
use Sabre\DAV\Exception\MethodNotAllowed;
29+
use Sabre\DAV\Exception\NotFound;
30+
use Sabre\DAV\ICollection;
31+
use Sabre\Uri;
32+
33+
class AvatarHome implements ICollection {
34+
35+
/** @var array */
36+
private $principalInfo;
37+
/** @var IAvatarManager */
38+
private $avatarManager;
39+
40+
/**
41+
* AvatarHome constructor.
42+
*
43+
* @param array $principalInfo
44+
* @param IAvatarManager $avatarManager
45+
*/
46+
public function __construct($principalInfo, IAvatarManager $avatarManager) {
47+
$this->principalInfo = $principalInfo;
48+
$this->avatarManager = $avatarManager;
49+
}
50+
51+
public function createFile($name, $data = null) {
52+
throw new Forbidden('Permission denied to create a file');
53+
}
54+
55+
public function createDirectory($name) {
56+
throw new Forbidden('Permission denied to create a folder');
57+
}
58+
59+
public function getChild($name) {
60+
$elements = pathinfo($name);
61+
$ext = isset($elements['extension']) ? $elements['extension'] : '';
62+
$size = (int)(isset($elements['filename']) ? $elements['filename'] : '64');
63+
if (!in_array($ext, ['jpeg', 'png'], true)) {
64+
throw new MethodNotAllowed('File format not allowed');
65+
}
66+
if ($size <= 0 || $size > 1024) {
67+
throw new MethodNotAllowed('Invalid image size');
68+
}
69+
$avatar = $this->avatarManager->getAvatar($this->getName());
70+
if ($avatar === null || !$avatar->exists()) {
71+
throw new NotFound();
72+
}
73+
return new AvatarNode($size, $ext, $avatar);
74+
}
75+
76+
public function getChildren() {
77+
try {
78+
return [
79+
$this->getChild('96.jpeg')
80+
];
81+
} catch(NotFound $exception) {
82+
return [];
83+
}
84+
}
85+
86+
public function childExists($name) {
87+
try {
88+
$ret = $this->getChild($name);
89+
return $ret !== null;
90+
} catch (NotFound $ex) {
91+
return false;
92+
} catch (MethodNotAllowed $ex) {
93+
return false;
94+
}
95+
}
96+
97+
public function delete() {
98+
throw new Forbidden('Permission denied to delete this folder');
99+
}
100+
101+
public function getName() {
102+
list(,$name) = Uri\split($this->principalInfo['uri']);
103+
return $name;
104+
}
105+
106+
public function setName($name) {
107+
throw new Forbidden('Permission denied to rename this folder');
108+
}
109+
110+
/**
111+
* Returns the last modification time, as a unix timestamp
112+
*
113+
* @return int|null
114+
*/
115+
public function getLastModified() {
116+
return null;
117+
}
118+
119+
120+
}
Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
<?php
2+
/**
3+
* @author Thomas Müller <thomas.mueller@tmit.eu>
4+
*
5+
* @copyright Copyright (c) 2016, ownCloud GmbH
6+
* @license AGPL-3.0
7+
*
8+
* This code is free software: you can redistribute it and/or modify
9+
* it under the terms of the GNU Affero General Public License, version 3,
10+
* as published by the Free Software Foundation.
11+
*
12+
* This program is distributed in the hope that it will be useful,
13+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
14+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15+
* GNU Affero General Public License for more details.
16+
*
17+
* You should have received a copy of the GNU Affero General Public License, version 3,
18+
* along with this program. If not, see <http://www.gnu.org/licenses/>
19+
*
20+
*/
21+
22+
23+
namespace OCA\DAV\Avatars;
24+
25+
26+
use OCP\IAvatar;
27+
use Sabre\DAV\File;
28+
29+
class AvatarNode extends File {
30+
private $ext;
31+
private $size;
32+
private $avatar;
33+
34+
/**
35+
* AvatarNode constructor.
36+
*
37+
* @param integer $size
38+
* @param string $ext
39+
* @param IAvatar $avatar
40+
*/
41+
public function __construct($size, $ext, $avatar) {
42+
$this->size = $size;
43+
$this->ext = $ext;
44+
$this->avatar = $avatar;
45+
}
46+
47+
/**
48+
* Returns the name of the node.
49+
*
50+
* This is used to generate the url.
51+
*
52+
* @return string
53+
*/
54+
public function getName() {
55+
return "$this->size.$this->ext";
56+
}
57+
58+
public function get() {
59+
$image = $this->avatar->get($this->size);
60+
$res = $image->resource();
61+
62+
ob_start();
63+
if ($this->ext === 'png') {
64+
imagepng($res);
65+
} else {
66+
imagejpeg($res);
67+
}
68+
69+
return ob_get_clean();
70+
}
71+
72+
/**
73+
* Returns the mime-type for a file
74+
*
75+
* If null is returned, we'll assume application/octet-stream
76+
*
77+
* @return string|null
78+
*/
79+
public function getContentType() {
80+
if ($this->ext === 'png') {
81+
return 'image/png';
82+
}
83+
return 'image/jpeg';
84+
}
85+
86+
public function getETag() {
87+
return $this->avatar->getFile($this->size)->getEtag();
88+
}
89+
90+
public function getLastModified() {
91+
$timestamp = $this->avatar->getFile($this->size)->getMTime();
92+
if (!empty($timestamp)) {
93+
return (int)$timestamp;
94+
}
95+
return $timestamp;
96+
97+
}
98+
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
<?php
2+
3+
namespace OCA\DAV\Avatars;
4+
5+
use Sabre\DAVACL\AbstractPrincipalCollection;
6+
7+
8+
class RootCollection extends AbstractPrincipalCollection {
9+
10+
/**
11+
* This method returns a node for a principal.
12+
*
13+
* The passed array contains principal information, and is guaranteed to
14+
* at least contain a uri item. Other properties may or may not be
15+
* supplied by the authentication backend.
16+
*
17+
* @param array $principalInfo
18+
* @return AvatarHome
19+
*/
20+
public function getChildForPrincipal(array $principalInfo) {
21+
$avatarManager = \OC::$server->getAvatarManager();
22+
return new AvatarHome($principalInfo, $avatarManager);
23+
}
24+
25+
public function getName() {
26+
return 'avatars';
27+
}
28+
29+
}

apps/dav/lib/Connector/Sabre/Principal.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -223,8 +223,8 @@ protected function userToPrincipal($user) {
223223
$email = $user->getEMailAddress();
224224
if (!empty($email)) {
225225
$principal['{http://sabredav.org/ns}email-address'] = $email;
226-
return $principal;
227226
}
227+
228228
return $principal;
229229
}
230230

apps/dav/lib/RootCollection.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,9 @@ public function __construct() {
9999
$uploadCollection = new Upload\RootCollection($userPrincipalBackend, 'principals/users');
100100
$uploadCollection->disableListing = $disableListing;
101101

102+
$avatarCollection = new Avatars\RootCollection($userPrincipalBackend, 'principals/users');
103+
$avatarCollection->disableListing = $disableListing;
104+
102105
$children = [
103106
new SimpleCollection('principals', [
104107
$userPrincipals,
@@ -114,6 +117,7 @@ public function __construct() {
114117
$systemTagRelationsCollection,
115118
$commentsCollection,
116119
$uploadCollection,
120+
$avatarCollection
117121
];
118122

119123
parent::__construct('root', $children);

0 commit comments

Comments
 (0)