/** * @NoAdminRequired * @NoCSRFRequired * * @param int $accountId * @param string $folderId * @param string $messageId * @param string $attachmentId * @param string $targetPath * @return JSONResponse */ public function saveAttachment($accountId, $folderId, $messageId, $attachmentId, $targetPath) { $mailBox = $this->getFolder($accountId, $folderId); $attachmentIds = [$attachmentId]; if ($attachmentId === 0) { $m = $mailBox->getMessage($messageId); $attachmentIds = array_map(function ($a) { return $a['id']; }, $m->attachments); } foreach ($attachmentIds as $attachmentId) { $attachment = $mailBox->getAttachment($messageId, $attachmentId); $fileName = $attachment->getName(); $fileParts = pathinfo($fileName); $fileName = $fileParts['filename']; $fileExtension = $fileParts['extension']; $fullPath = "{$targetPath}/{$fileName}.{$fileExtension}"; $counter = 2; while ($this->userFolder->nodeExists($fullPath)) { $fullPath = "{$targetPath}/{$fileName} ({$counter}).{$fileExtension}"; $counter++; } $newFile = $this->userFolder->newFile($fullPath); $newFile->putContent($attachment->getContents()); } return new JSONResponse(); }
/** * @NoAdminRequired * * @param int $accountId * @param string $folderId * @param string $subject * @param string $body * @param string $to * @param string $cc * @param string $bcc * @param int $draftUID * @param string $messageId * @param mixed $attachments * @return JSONResponse */ public function send($accountId, $folderId, $subject, $body, $to, $cc, $bcc, $draftUID, $messageId, $attachments) { $account = $this->accountService->find($this->currentUserId, $accountId); if ($account instanceof UnifiedAccount) { list($account, $folderId, $messageId) = $account->resolve($messageId); } if (!$account instanceof Account) { return new JSONResponse(['message' => 'Invalid account'], Http::STATUS_BAD_REQUEST); } $mailbox = null; if (!is_null($folderId) && !is_null($messageId)) { // Reply $message = $account->newReplyMessage(); $mailbox = $account->getMailbox(base64_decode($folderId)); $repliedMessage = $mailbox->getMessage($messageId); if (is_null($subject)) { // No subject set – use the original one $message->setSubject($repliedMessage->getSubject()); } else { $message->setSubject($subject); } if (is_null($to)) { $message->setTo($repliedMessage->getToList()); } else { $message->setTo(Message::parseAddressList($to)); } $message->setRepliedMessage($repliedMessage); } else { // New message $message = $account->newMessage(); $message->setTo(Message::parseAddressList($to)); $message->setSubject($subject ?: ''); } $message->setFrom($account->getEMailAddress()); $message->setCC(Message::parseAddressList($cc)); $message->setBcc(Message::parseAddressList($bcc)); $message->setContent($body); if (is_array($attachments)) { foreach ($attachments as $attachment) { $fileName = $attachment['fileName']; if ($this->userFolder->nodeExists($fileName)) { $f = $this->userFolder->get($fileName); if ($f instanceof File) { $message->addAttachmentFromFiles($f); } } } } try { $account->sendMessage($message, $draftUID); // in case of reply we flag the message as answered if ($message instanceof ReplyMessage) { $mailbox->setMessageFlag($messageId, Horde_Imap_Client::FLAG_ANSWERED, true); } } catch (\Horde_Exception $ex) { $this->logger->error('Sending mail failed: ' . $ex->getMessage()); return new JSONResponse(array('message' => $ex->getMessage()), Http::STATUS_INTERNAL_SERVER_ERROR); } return new JSONResponse(); }
/** * Get the extention of the avatar. If there is no avatar throw Exception * * @return string * @throws NotFoundException */ private function getExtention() { if ($this->folder->nodeExists('avatar.jpg')) { return 'jpg'; } elseif ($this->folder->nodeExists('avatar.png')) { return 'png'; } throw new NotFoundException(); }
/** * Returns the node if it's a folder we have access to * * @param Folder $node * @param string $nodeType * * @return array|Folder */ protected function getAllowedSubFolder($node, $nodeType) { if ($nodeType === 'dir') { /** @var Folder $node */ if (!$node->nodeExists('.nomedia')) { return [$node]; } } return []; }
/** * get path of file and the title.txt and check if they are the same * file. If not the title needs to be renamed * * @param Folder $folder a folder to the notes directory * @param string $title the filename which should be used * @param string $extension the extension which should be used * @param int $id the id of the note for which the title should be generated * used to see if the file itself has the title and not a different file for * checking for filename collisions * @return string the resolved filename to prevent overwriting different * files with the same title */ private function generateFileName(Folder $folder, $title, $extension, $id) { $path = $title . '.' . $extension; // if file does not exist, that name has not been taken. Similar we don't // need to handle file collisions if it is the filename did not change if (!$folder->nodeExists($path) || $folder->get($path)->getId() === $id) { return $path; } else { // increments name (2) to name (3) $match = preg_match('/\\((?P<id>\\d+)\\)$/', $title, $matches); if ($match) { $newId = (int) $matches['id'] + 1; $newTitle = preg_replace('/(.*)\\s\\((\\d+)\\)$/', '$1 (' . $newId . ')', $title); } else { $newTitle = $title . ' (2)'; } return $this->generateFileName($folder, $newTitle, $extension, $id); } }
/** * @param \OCP\Files\Folder $parent * @param string $folderName * @return \OCP\Files\Folder * @throws SetUpException */ private function getOrCreateSubFolder(Folder $parent, $folderName) { if ($parent->nodeExists($folderName)) { return $parent->get($folderName); } else { return $parent->newFolder($folderName); } }
/** * Returns an album configuration array * * Goes through all the parent folders until either we're told the album is private or we've * reached the root folder * * @param Folder $folder * @param string $privacyChecker * @param string $configName * @param int $level * @param array $config * * @return array<null|array,bool> */ private function getAlbumConfig($folder, $privacyChecker, $configName, $level = 0, $config = []) { if ($folder->nodeExists($privacyChecker)) { // Cancel as soon as we find out that the folder is private or external return [null, true]; } $isRootFolder = $this->isRootFolder($folder, $level); if ($folder->nodeExists($configName)) { list($config) = $this->buildFolderConfig($folder, $configName, $config, $level); } if (!$isRootFolder) { return $this->getParentConfig($folder, $privacyChecker, $configName, $level, $config); } $config = $this->validatesInfoConfig($config); // We have reached the root folder return [$config, false]; }
/** * Returns the node if it's a folder we have access to * * @param Folder $node * @param string $nodeType * * @return array|Folder */ protected function getAllowedSubFolder($node, $nodeType) { if ($nodeType === 'dir') { /** @var Folder $node */ if (!$node->nodeExists($this->ignoreAlbum)) { return [$node]; } } return []; }
/** * Check if an avatar exists for the user * * @return bool */ public function exists() { return $this->folder->nodeExists('avatar.jpg') || $this->folder->nodeExists('avatar.png'); }
/** * @NoAdminRequired * * @param int $accountId * @param string $folderId * @param string $subject * @param string $body * @param string $to * @param string $cc * @param string $bcc * @param int $draftUID * @param string $messageId * @param mixed $attachments * @return JSONResponse */ public function send($accountId, $folderId, $subject, $body, $to, $cc, $bcc, $draftUID, $messageId, $attachments) { $account = $this->accountService->find($this->currentUserId, $accountId); if ($account instanceof UnifiedAccount) { list($account, $folderId, $messageId) = $account->resolve($messageId); } if (!$account instanceof Account) { return new JSONResponse(['message' => 'Invalid account'], Http::STATUS_BAD_REQUEST); } // get sender data $headers = []; /** @var Account $account */ $from = new Horde_Mail_Rfc822_Address($account->getEMailAddress()); $from->personal = $account->getName(); $headers['From'] = $from; $headers['Subject'] = $subject; if (trim($cc) !== '') { $headers['Cc'] = trim($cc); } if (trim($bcc) !== '') { $headers['Bcc'] = trim($bcc); } // in reply to handling $folderId = base64_decode($folderId); $mailbox = null; if (!is_null($folderId) && !is_null($messageId)) { $mailbox = $account->getMailbox($folderId); $message = $mailbox->getMessage($messageId); if (is_null($subject)) { // prevent 'Re: Re:' stacking if (strcasecmp(substr($message->getSubject(), 0, 4), 'Re: ') === 0) { $headers['Subject'] = $message->getSubject(); } else { $headers['Subject'] = 'Re: ' . $message->getSubject(); } } $headers['In-Reply-To'] = $message->getMessageId(); if (is_null($to)) { $to = $message->getToEmail(); } } $headers['To'] = $to; // build mime body $mail = new Horde_Mime_Mail(); $mail->addHeaders($headers); $mail->setBody($body); if (is_array($attachments)) { foreach ($attachments as $attachment) { $fileName = $attachment['fileName']; if ($this->userFolder->nodeExists($fileName)) { $f = $this->userFolder->get($fileName); if ($f instanceof File) { $a = new \Horde_Mime_Part(); $a->setCharset('us-ascii'); $a->setDisposition('attachment'); $a->setName($f->getName()); $a->setContents($f->getContent()); $a->setType($f->getMimeType()); $mail->addMimePart($a); } } } } // create transport and send try { $transport = $account->createTransport(); $mail->send($transport); // in case of reply we flag the message as answered if ($mailbox) { $mailbox->setMessageFlag($messageId, Horde_Imap_Client::FLAG_ANSWERED, true); } // save the message in the sent folder $sentFolder = $account->getSentFolder(); /** @var resource $raw */ $raw = $mail->getRaw(); $raw = stream_get_contents($raw); $sentFolder->saveMessage($raw, [Horde_Imap_Client::FLAG_SEEN]); // delete draft message if (!is_null($draftUID)) { $draftsFolder = $account->getDraftsFolder(); $folderId = $draftsFolder->getFolderId(); $this->logger->debug("deleting sent draft <{$draftUID}> in folder <{$folderId}>"); $draftsFolder->setMessageFlag($draftUID, \Horde_Imap_Client::FLAG_DELETED, true); $account->deleteDraft($draftUID); $this->logger->debug("sent draft <{$draftUID}> deleted"); } } catch (\Horde_Exception $ex) { $this->logger->error('Sending mail failed: ' . $ex->getMessage()); return new JSONResponse(array('message' => $ex->getMessage()), Http::STATUS_INTERNAL_SERVER_ERROR); } return new JSONResponse(); }
/** * Returns an album configuration array * * Goes through all the parent folders until either we're told the album is private or we've * reached the root folder * * @param Folder $folder the current folder * @param string $ignoreAlbum name of the file which blacklists folders * @param string $configName name of the configuration file * @param int $level the starting level is 0 and we add 1 each time we visit a parent folder * @param array $configSoFar the configuration collected so far * * @return array <null|array,bool> */ private function collectConfig($folder, $ignoreAlbum, $configName, $level = 0, $configSoFar = []) { if ($folder->nodeExists($ignoreAlbum)) { // Cancel as soon as we find out that the folder is private or external return [null, true]; } $isRootFolder = $this->isRootFolder($folder, $level); if ($folder->nodeExists($configName)) { $configSoFar = $this->buildFolderConfig($folder, $configName, $configSoFar, $level); } if (!$isRootFolder) { return $this->getParentConfig($folder, $ignoreAlbum, $configName, $level, $configSoFar); } $configSoFar = $this->validatesInfoConfig($configSoFar); // We have reached the root folder return [$configSoFar, false]; }