Moved logic from controller to AvatarService

Signed-off-by: Vitor Mattos <vitor@php.rio>
This commit is contained in:
Vitor Mattos 2022-11-10 16:44:29 -03:00 committed by Joas Schilling
parent 9a381b6ad3
commit 14bb70c5d4
No known key found for this signature in database
GPG key ID: 74434EFE0D2E2205
4 changed files with 65 additions and 60 deletions

View file

@ -34,13 +34,11 @@ use OCP\AppFramework\Http\DataResponse;
use OCP\AppFramework\Http\FileDisplayResponse;
use OCP\AppFramework\Http\Response;
use OCP\Files\IAppData;
use OCP\Files\NotFoundException;
use OCP\IL10N;
use OCP\IRequest;
use OCP\IUserSession;
class AvatarController extends AEnvironmentAwareController {
private IAppData $appData;
private AvatarService $avatarService;
private IUserSession $userSession;
private IL10N $l;
@ -65,59 +63,27 @@ class AvatarController extends AEnvironmentAwareController {
* @RequireModeratorParticipant
*/
public function uploadAvatar(): DataResponse {
$file = $this->request->getUploadedFile('file');
try {
$file = $this->request->getUploadedFile('file');
if (is_null($file)) {
throw new InvalidArgumentException($this->l->t('No image file provided'));
}
if (
$file['error'] === 0 &&
is_uploaded_file($file['tmp_name']) &&
!Filesystem::isFileBlacklisted($file['tmp_name'])
) {
if ($file['size'] > 20 * 1024 * 1024) {
return new DataResponse(
['message' => $this->l->t('File is too big')],
Http::STATUS_BAD_REQUEST
);
if (is_null($file)) {
throw new InvalidArgumentException($this->l->t('No image file provided'));
}
if (
$file['error'] !== 0 ||
!is_uploaded_file($file['tmp_name']) ||
Filesystem::isFileBlacklisted($file['tmp_name'])
) {
throw new InvalidArgumentException($this->l->t('Invalid file provided'));
}
if ($file['size'] > 20 * 1024 * 1024) {
throw new InvalidArgumentException($this->l->t('File is too big'));
}
$content = file_get_contents($file['tmp_name']);
unlink($file['tmp_name']);
} else {
throw new InvalidArgumentException($this->l->t('Invalid file provided'));
}
try {
$image = new \OC_Image();
$image->loadFromData($content);
$image->readExif($content);
$image->fixOrientation();
if (!($image->height() === $image->width())) {
throw new InvalidArgumentException($this->l->t('Avatar image is not square'));
}
if (!$image->valid()) {
throw new InvalidArgumentException($this->l->t('Invalid image'));
}
$mimeType = $image->mimeType();
$allowedMimeTypes = [
'image/jpeg',
'image/png',
'image/svg',
];
if (!in_array($mimeType, $allowedMimeTypes)) {
throw new InvalidArgumentException($this->l->t('Unknown filetype'));
}
try {
$folder = $this->appData->getFolder('room-avatar');
} catch (NotFoundException $e) {
$folder = $this->appData->newFolder('room-avatar');
}
$token = $this->getRoom()->getToken();
$folder->newFile($token, $image->data());
$this->avatarService->setAvatar($this->getRoom(), $content);
return new DataResponse();
} catch (InvalidArgumentException $e) {
return new DataResponse(['message' => $e->getMessage()], Http::STATUS_BAD_REQUEST);

View file

@ -26,26 +26,63 @@ declare(strict_types=1);
namespace OCA\Talk\Service;
use InvalidArgumentException;
use OCA\Talk\Room;
use OCP\Files\IAppData;
use OCP\Files\NotFoundException;
use OCP\Files\SimpleFS\InMemoryFile;
use OCP\Files\SimpleFS\ISimpleFile;
use OCP\IAvatarManager;
use OCP\IL10N;
use OCP\IUser;
class AvatarService {
private IAppData $appData;
private IL10N $l;
private IAvatarManager $avatarManager;
public function __construct(
IAppData $appData,
IL10N $l,
IAvatarManager $avatarManager
) {
$this->appData = $appData;
$this->l = $l;
$this->avatarManager = $avatarManager;
}
public function setAvatar(Room $room, string $content): void {
$image = new \OC_Image();
$image->loadFromData($content);
$image->readExif($content);
$image->fixOrientation();
if (!($image->height() === $image->width())) {
throw new InvalidArgumentException($this->l->t('Avatar image is not square'));
}
if (!$image->valid()) {
throw new InvalidArgumentException($this->l->t('Invalid image'));
}
$mimeType = $image->mimeType();
$allowedMimeTypes = [
'image/jpeg',
'image/png',
'image/svg',
];
if (!in_array($mimeType, $allowedMimeTypes)) {
throw new InvalidArgumentException($this->l->t('Unknown filetype'));
}
try {
$folder = $this->appData->getFolder('room-avatar');
} catch (NotFoundException $e) {
$folder = $this->appData->newFolder('room-avatar');
}
$token = $room->getToken();
$folder->newFile($token, $image->data());
}
public function getAvatar(Room $room, ?IUser $user, bool $dark = false): ISimpleFile {
try {
$folder = $this->appData->getFolder('room-avatar');

View file

@ -2879,7 +2879,7 @@ class FeatureContext implements Context, SnippetAcceptingContext {
'multipart' => [
[
'name' => 'file',
'contents' => fopen($this->baseUrl . $file, 'r'),
'contents' => $file !== 'invalid' ? fopen(__DIR__ . '/../../../..' . $file, 'r') : '',
],
],
];
@ -2898,9 +2898,10 @@ class FeatureContext implements Context, SnippetAcceptingContext {
/**
* @When /^user "([^"]*)" delete the avatar of room "([^"]*)" with (\d+)(?: \((v1)\))?$/
*/
public function userDeleteTheAvatarOfRoom(string $user, string $identifier, string $apiVersion = 'v1'): void {
public function userDeleteTheAvatarOfRoom(string $user, string $identifier, int $statusCode, string $apiVersion = 'v1'): void {
$this->setCurrentUser($user);
$this->sendRequest('DELETE', '/apps/spreed/api/' . $apiVersion . '/room/' . self::$identifierToToken[$identifier] . '/avatar');
$this->assertStatusCode($this->response, $statusCode);
}
/**

View file

@ -3,20 +3,21 @@ Feature: chat/avatar
Given user "participant1" exists
Given user "participant2" exists
Scenario: Define an image as avatar when the conversation already exists
Scenario: Misteps
Given user "participant1" creates room "room1" (v4)
| roomType | 3 |
| roomName | room1 |
And user "participant1" send the file "/apps/spreed/img/favicon.png" as avatar of room "room1" with 200
Then the room "room1" need to have an avatar with 200
And user "participant1" delete the avatar of room "room1" with 200
Then user "participant1" send the file "invalid" as avatar of room "room1" with 400
And user "participant2" send the file "/img/favicon.png" as avatar of room "room1" with 404
And user "participant2" delete the avatar of room "room1" with 404
Scenario: Try to change the room avatar without success
Scenario: Define an image as avatar with success
Given user "participant1" creates room "room2" (v4)
| roomType | 3 |
| roomName | room2 |
Then user "participant2" send the file "/apps/spreed/img/favicon.png" as avatar of room "room2" with 404
And user "participant1" delete the avatar of room "room2" with 404
And user "participant1" send the file "/img/favicon.png" as avatar of room "room2" with 200
Then the room "room2" need to have an avatar with 200
And user "participant1" delete the avatar of room "room2" with 200
Scenario: Get avatar of conversation without custom avatar (fallback)
Given user "participant1" creates room "room3" (v4)