avatarcontroller.php 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267
  1. <?php
  2. /**
  3. * @author Joas Schilling <nickvergessen@owncloud.com>
  4. * @author Lukas Reschke <lukas@owncloud.com>
  5. * @author Morris Jobke <hey@morrisjobke.de>
  6. * @author Robin Appelman <icewind@owncloud.com>
  7. * @author Roeland Jago Douma <roeland@famdouma.nl>
  8. *
  9. * @copyright Copyright (c) 2015, ownCloud, Inc.
  10. * @license AGPL-3.0
  11. *
  12. * This code is free software: you can redistribute it and/or modify
  13. * it under the terms of the GNU Affero General Public License, version 3,
  14. * as published by the Free Software Foundation.
  15. *
  16. * This program is distributed in the hope that it will be useful,
  17. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  18. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  19. * GNU Affero General Public License for more details.
  20. *
  21. * You should have received a copy of the GNU Affero General Public License, version 3,
  22. * along with this program. If not, see <http://www.gnu.org/licenses/>
  23. *
  24. */
  25. namespace OC\Core\Avatar;
  26. use OCP\AppFramework\Controller;
  27. use OCP\AppFramework\Http;
  28. use OCP\AppFramework\Http\DataResponse;
  29. use OCP\AppFramework\Http\DataDisplayResponse;
  30. use OCP\IAvatarManager;
  31. use OCP\ICache;
  32. use OCP\IL10N;
  33. use OCP\IRequest;
  34. use OCP\IUserManager;
  35. use OCP\IUserSession;
  36. /**
  37. * Class AvatarController
  38. *
  39. * @package OC\Core\Avatar
  40. */
  41. class AvatarController extends Controller {
  42. /** @var IAvatarManager */
  43. protected $avatarManager;
  44. /** @var \OC\Cache\File */
  45. protected $cache;
  46. /** @var IL10N */
  47. protected $l;
  48. /** @var IUserManager */
  49. protected $userManager;
  50. /** @var IUserSession */
  51. protected $userSession;
  52. /**
  53. * @param string $appName
  54. * @param IRequest $request
  55. * @param IAvatarManager $avatarManager
  56. * @param \OC\Cache\File $cache
  57. * @param IL10N $l10n
  58. * @param IUserManager $userManager
  59. * @param IUserSession $userSession
  60. */
  61. public function __construct($appName,
  62. IRequest $request,
  63. IAvatarManager $avatarManager,
  64. \OC\Cache\File $cache,
  65. IL10N $l10n,
  66. IUserManager $userManager,
  67. IUserSession $userSession) {
  68. parent::__construct($appName, $request);
  69. $this->avatarManager = $avatarManager;
  70. $this->cache = $cache;
  71. $this->l = $l10n;
  72. $this->userManager = $userManager;
  73. $this->userSession = $userSession;
  74. }
  75. /**
  76. * @NoAdminRequired
  77. *
  78. * @param string $userId
  79. * @param int $size
  80. * @return DataResponse|DataDisplayResponse
  81. */
  82. public function getAvatar($userId, $size) {
  83. if ($size > 2048) {
  84. $size = 2048;
  85. } elseif ($size <= 0) {
  86. $size = 64;
  87. }
  88. $avatar = $this->avatarManager->getAvatar($userId);
  89. $image = $avatar->get($size);
  90. if ($image instanceof \OCP\IImage) {
  91. $resp = new DataDisplayResponse($image->data(),
  92. Http::STATUS_OK,
  93. ['Content-Type' => $image->mimeType()]);
  94. $resp->setETag(crc32($image->data()));
  95. } else {
  96. $user = $this->userManager->get($userId);
  97. $userName = $user ? $user->getDisplayName() : '';
  98. $resp = new DataResponse([
  99. 'data' => [
  100. 'displayname' => $userName,
  101. ],
  102. ]);
  103. }
  104. $resp->addHeader('Pragma', 'public');
  105. $resp->cacheFor(0);
  106. $resp->setLastModified(new \DateTime('now', new \DateTimeZone('GMT')));
  107. return $resp;
  108. }
  109. /**
  110. * @NoAdminRequired
  111. *
  112. * @param string $path
  113. * @return DataResponse
  114. */
  115. public function postAvatar($path) {
  116. $userId = $this->userSession->getUser()->getUID();
  117. $files = $this->request->getUploadedFile('files');
  118. if (isset($path)) {
  119. $path = stripslashes($path);
  120. $view = new \OC\Files\View('/'.$userId.'/files');
  121. $fileName = $view->getLocalFile($path);
  122. } elseif (!is_null($files)) {
  123. if (
  124. $files['error'][0] === 0 &&
  125. is_uploaded_file($files['tmp_name'][0]) &&
  126. !\OC\Files\Filesystem::isFileBlacklisted($files['tmp_name'][0])
  127. ) {
  128. $this->cache->set('avatar_upload', file_get_contents($files['tmp_name'][0]), 7200);
  129. $view = new \OC\Files\View('/'.$userId.'/cache');
  130. $fileName = $view->getLocalFile('avatar_upload');
  131. unlink($files['tmp_name'][0]);
  132. } else {
  133. return new DataResponse(['data' => ['message' => $this->l->t('Invalid file provided')]],
  134. Http::STATUS_BAD_REQUEST);
  135. }
  136. } else {
  137. //Add imgfile
  138. return new DataResponse(['data' => ['message' => $this->l->t('No image or file provided')]],
  139. Http::STATUS_BAD_REQUEST);
  140. }
  141. try {
  142. $image = new \OC_Image();
  143. $image->loadFromFile($fileName);
  144. $image->fixOrientation();
  145. if ($image->valid()) {
  146. $mimeType = $image->mimeType();
  147. if ($mimeType !== 'image/jpeg' && $mimeType !== 'image/png') {
  148. return new DataResponse(['data' => ['message' => $this->l->t('Unknown filetype')]]);
  149. }
  150. $this->cache->set('tmpAvatar', $image->data(), 7200);
  151. return new DataResponse(['data' => 'notsquare']);
  152. } else {
  153. return new DataResponse(['data' => ['message' => $this->l->t('Invalid image')]]);
  154. }
  155. } catch (\Exception $e) {
  156. return new DataResponse(['data' => ['message' => $e->getMessage()]]);
  157. }
  158. }
  159. /**
  160. * @NoAdminRequired
  161. *
  162. * @return DataResponse
  163. */
  164. public function deleteAvatar() {
  165. $userId = $this->userSession->getUser()->getUID();
  166. try {
  167. $avatar = $this->avatarManager->getAvatar($userId);
  168. $avatar->remove();
  169. return new DataResponse();
  170. } catch (\Exception $e) {
  171. return new DataResponse(['data' => ['message' => $e->getMessage()]], Http::STATUS_BAD_REQUEST);
  172. }
  173. }
  174. /**
  175. * @NoAdminRequired
  176. *
  177. * @return DataResponse|DataDisplayResponse
  178. */
  179. public function getTmpAvatar() {
  180. $tmpAvatar = $this->cache->get('tmpAvatar');
  181. if (is_null($tmpAvatar)) {
  182. return new DataResponse(['data' => [
  183. 'message' => $this->l->t("No temporary profile picture available, try again")
  184. ]],
  185. Http::STATUS_NOT_FOUND);
  186. }
  187. $image = new \OC_Image($tmpAvatar);
  188. $resp = new DataDisplayResponse($image->data(),
  189. Http::STATUS_OK,
  190. ['Content-Type' => $image->mimeType()]);
  191. $resp->setETag(crc32($image->data()));
  192. $resp->cacheFor(0);
  193. $resp->setLastModified(new \DateTime('now', new \DateTimeZone('GMT')));
  194. return $resp;
  195. }
  196. /**
  197. * @NoAdminRequired
  198. *
  199. * @param array $crop
  200. * @return DataResponse
  201. */
  202. public function postCroppedAvatar($crop) {
  203. $userId = $this->userSession->getUser()->getUID();
  204. if (is_null($crop)) {
  205. return new DataResponse(['data' => ['message' => $this->l->t("No crop data provided")]],
  206. Http::STATUS_BAD_REQUEST);
  207. }
  208. if (!isset($crop['x'], $crop['y'], $crop['w'], $crop['h'])) {
  209. return new DataResponse(['data' => ['message' => $this->l->t("No valid crop data provided")]],
  210. Http::STATUS_BAD_REQUEST);
  211. }
  212. $tmpAvatar = $this->cache->get('tmpAvatar');
  213. if (is_null($tmpAvatar)) {
  214. return new DataResponse(['data' => [
  215. 'message' => $this->l->t("No temporary profile picture available, try again")
  216. ]],
  217. Http::STATUS_BAD_REQUEST);
  218. }
  219. $image = new \OC_Image($tmpAvatar);
  220. $image->crop($crop['x'], $crop['y'], round($crop['w']), round($crop['h']));
  221. try {
  222. $avatar = $this->avatarManager->getAvatar($userId);
  223. $avatar->set($image);
  224. // Clean up
  225. $this->cache->remove('tmpAvatar');
  226. return new DataResponse(['status' => 'success']);
  227. } catch (\OC\NotSquareException $e) {
  228. return new DataResponse(['data' => ['message' => $this->l->t('Crop is not square')]],
  229. Http::STATUS_BAD_REQUEST);
  230. }catch (\Exception $e) {
  231. return new DataResponse(['data' => ['message' => $e->getMessage()]],
  232. Http::STATUS_BAD_REQUEST);
  233. }
  234. }
  235. }