/** * @PublicPage * @NoCSRFRequired * * @return TemplateResponse */ public function show() { try { $user = $this->activityManager->getCurrentUserId(); $userLang = $this->config->getUserValue($user, 'core', 'lang'); // Overwrite user and language in the helper $l = Util::getL10N('activity', $userLang); $l->forceLanguage($userLang); $this->helper->setL10n($l); $this->helper->setUser($user); $description = (string) $l->t('Personal activity feed for %s', $user); $activities = $this->data->read($this->helper, $this->settings, 0, self::DEFAULT_PAGE_SIZE, 'all', $user); } catch (\UnexpectedValueException $e) { $l = Util::getL10N('activity'); $description = (string) $l->t('Your feed URL is invalid'); $activities = [['activity_id' => -1, 'timestamp' => time(), 'subject' => true, 'subjectformatted' => ['full' => $description]]]; } $response = new TemplateResponse('activity', 'rss', ['rssLang' => $l->getLanguageCode(), 'rssLink' => $this->urlGenerator->linkToRouteAbsolute('activity.Feed.show'), 'rssPubDate' => date('r'), 'description' => $description, 'activities' => $activities], ''); if ($this->request->getHeader('accept') !== null && stristr($this->request->getHeader('accept'), 'application/rss+xml')) { $response->addHeader('Content-Type', 'application/rss+xml'); } else { $response->addHeader('Content-Type', 'text/xml; charset=UTF-8'); } return $response; }
/** * @param IEvent $event * @param string $parameter The parameter to be formatted * @return string The formatted parameter */ public function format(IEvent $event, $parameter) { $param = $this->fixLegacyFilename($parameter); // If the activity is about the very same file, we use the current path // for the link generation instead of the one that was saved. $fileId = ''; if (is_array($param)) { $fileId = key($param); $param = $param[$fileId]; $info = $this->infoCache->getInfoById($this->user, $fileId, $param); } elseif ($event->getObjectType() === 'files' && $event->getObjectName() === $param) { $fileId = $event->getObjectId(); $info = $this->infoCache->getInfoById($this->user, $fileId, $param); } else { $info = $this->infoCache->getInfoByPath($this->user, $param); } if ($info['is_dir']) { $linkData = ['dir' => $info['path']]; } else { $parentDir = substr_count($info['path'], '/') === 1 ? '/' : dirname($info['path']); $fileName = basename($info['path']); $linkData = ['dir' => $parentDir, 'scrollto' => $fileName]; } if ($info['view'] !== '') { $linkData['view'] = $info['view']; } $param = trim($param, '/'); $fileLink = $this->urlGenerator->linkToRouteAbsolute('files.view.index', $linkData); return '<file link="' . $fileLink . '" id="' . Util::sanitizeHTML($fileId) . '">' . Util::sanitizeHTML($param) . '</file>'; }
/** * @NoAdminRequired * @UseSession * * @return RedirectResponse */ public function logout() { $loginToken = $this->request->getCookie('oc_token'); if (!is_null($loginToken)) { $this->config->deleteUserValue($this->userSession->getUser()->getUID(), 'login_token', $loginToken); } $this->userSession->logout(); return new RedirectResponse($this->urlGenerator->linkToRouteAbsolute('core.login.showLoginForm')); }
/** * Construct * * @param IL10N $l * @param IManager $manager * @param IURLGenerator $URLGenerator * @param string $user * @param string $rssToken * @param null|string $active Navigation entry that should be marked as active */ public function __construct(IL10N $l, IManager $manager, IURLGenerator $URLGenerator, $user, $rssToken, $active = 'all') { $this->l = $l; $this->activityManager = $manager; $this->URLGenerator = $URLGenerator; $this->user = $user; $this->active = $active; if ($rssToken) { $this->rssLink = $this->URLGenerator->linkToRouteAbsolute('activity.Feed.show', array('token' => $rssToken)); } else { $this->rssLink = ''; } }
/** * @param string $user * @throws \Exception */ protected function sendEmail($user) { if (!$this->userManager->userExists($user)) { throw new \Exception($this->l10n->t('Couldn\'t send reset email. Please make sure your username is correct.')); } $email = $this->config->getUserValue($user, 'settings', 'email'); if (empty($email)) { throw new \Exception($this->l10n->t('Couldn\'t send reset email because there is no ' . 'email address for this username. Please ' . 'contact your administrator.')); } $token = $this->secureRandom->getMediumStrengthGenerator()->generate(21, ISecureRandom::CHAR_DIGITS . ISecureRandom::CHAR_LOWER . ISecureRandom::CHAR_UPPER); $this->config->setUserValue($user, 'owncloud', 'lostpassword', $token); $link = $this->urlGenerator->linkToRouteAbsolute('core.lost.resetform', array('userId' => $user, 'token' => $token)); $tmpl = new \OC_Template('core/lostpassword', 'email'); $tmpl->assign('link', $link, false); $msg = $tmpl->fetchPage(); try { $message = $this->mailer->createMessage(); $message->setTo([$email => $user]); $message->setSubject($this->l10n->t('%s password reset', [$this->defaults->getName()])); $message->setPlainBody($msg); $message->setFrom([$this->from => $this->defaults->getName()]); $this->mailer->send($message); } catch (\Exception $e) { throw new \Exception($this->l10n->t('Couldn\'t send reset email. Please contact your administrator.')); } }
/** * @PublicPage * @NoCSRFRequired * * @return TemplateResponse */ public function show() { try { $user = $this->activityManager->getCurrentUserId(); $userLang = $this->config->getUserValue($user, 'core', 'lang'); // Overwrite user and language in the helper $this->l = $this->l10nFactory->get('activity', $userLang); $parser = new PlainTextParser($this->l); $this->helper->setL10n($this->l); $this->helper->setUser($user); $description = (string) $this->l->t('Personal activity feed for %s', $user); $response = $this->data->get($this->helper, $this->settings, $user, 0, self::DEFAULT_PAGE_SIZE, 'desc', 'all'); $data = $response['data']; $activities = []; foreach ($data as $activity) { $activity['subject_prepared'] = $parser->parseMessage($activity['subject_prepared']); $activity['message_prepared'] = $parser->parseMessage($activity['message_prepared']); $activities[] = $activity; } } catch (\UnexpectedValueException $e) { $this->l = $this->l10nFactory->get('activity'); $description = (string) $this->l->t('Your feed URL is invalid'); $activities = [['activity_id' => -1, 'timestamp' => time(), 'subject' => true, 'subject_prepared' => $description]]; } $response = new TemplateResponse('activity', 'rss', ['rssLang' => $this->l->getLanguageCode(), 'rssLink' => $this->urlGenerator->linkToRouteAbsolute('activity.Feed.show'), 'rssPubDate' => date('r'), 'description' => $description, 'activities' => $activities], ''); if ($this->request->getHeader('accept') !== null && stristr($this->request->getHeader('accept'), 'application/rss+xml')) { $response->addHeader('Content-Type', 'application/rss+xml'); } else { $response->addHeader('Content-Type', 'text/xml; charset=UTF-8'); } return $response; }
/** * Convert an IShare to an array for OCS output * * @param \OCP\Share\IShare $share * @return array * @throws NotFoundException In case the node can't be resolved. */ protected function formatShare(\OCP\Share\IShare $share) { $sharedBy = $this->userManager->get($share->getSharedBy()); $shareOwner = $this->userManager->get($share->getShareOwner()); $result = ['id' => $share->getId(), 'share_type' => $share->getShareType(), 'uid_owner' => $share->getSharedBy(), 'displayname_owner' => $sharedBy !== null ? $sharedBy->getDisplayName() : $share->getSharedBy(), 'permissions' => $share->getPermissions(), 'stime' => $share->getShareTime()->getTimestamp(), 'parent' => null, 'expiration' => null, 'token' => null, 'uid_file_owner' => $share->getShareOwner(), 'displayname_file_owner' => $shareOwner !== null ? $shareOwner->getDisplayName() : $share->getShareOwner()]; $userFolder = $this->rootFolder->getUserFolder($this->currentUser->getUID()); $nodes = $userFolder->getById($share->getNodeId()); if (empty($nodes)) { throw new NotFoundException(); } $node = $nodes[0]; $result['path'] = $userFolder->getRelativePath($node->getPath()); if ($node instanceof \OCP\Files\Folder) { $result['item_type'] = 'folder'; } else { $result['item_type'] = 'file'; } $result['mimetype'] = $node->getMimeType(); $result['storage_id'] = $node->getStorage()->getId(); $result['storage'] = $node->getStorage()->getCache()->getNumericStorageId(); $result['item_source'] = $node->getId(); $result['file_source'] = $node->getId(); $result['file_parent'] = $node->getParent()->getId(); $result['file_target'] = $share->getTarget(); if ($share->getShareType() === \OCP\Share::SHARE_TYPE_USER) { $sharedWith = $this->userManager->get($share->getSharedWith()); $result['share_with'] = $share->getSharedWith(); $result['share_with_displayname'] = $sharedWith !== null ? $sharedWith->getDisplayName() : $share->getSharedWith(); } else { if ($share->getShareType() === \OCP\Share::SHARE_TYPE_GROUP) { $result['share_with'] = $share->getSharedWith(); $result['share_with_displayname'] = $share->getSharedWith(); } else { if ($share->getShareType() === \OCP\Share::SHARE_TYPE_LINK) { $result['share_with'] = $share->getPassword(); $result['share_with_displayname'] = $share->getPassword(); $result['token'] = $share->getToken(); $result['url'] = $this->urlGenerator->linkToRouteAbsolute('files_sharing.sharecontroller.showShare', ['token' => $share->getToken()]); $expiration = $share->getExpirationDate(); if ($expiration !== null) { $result['expiration'] = $expiration->format('Y-m-d 00:00:00'); } } else { if ($share->getShareType() === \OCP\Share::SHARE_TYPE_REMOTE) { $result['share_with'] = $share->getSharedWith(); $result['share_with_displayname'] = $share->getSharedWith(); $result['token'] = $share->getToken(); } } } } $result['mail_send'] = $share->getMailSend() ? 1 : 0; return $result; }
/** * Transformator which will rewrite all HTTPS and HTTP urls to * @param \HTMLPurifier_URI $uri * @param HTMLPurifier_Config $config * @param \HTMLPurifier_Context $context * @return bool */ public function filter(&$uri, $config, $context) { /** @var \HTMLPurifier_Context $context */ /** @var \HTMLPurifier_Config $config */ // Only HTTPS and HTTP urls should get rewritten if ($uri->scheme === 'https' || $uri->scheme === 'http') { $uri = $this->filterHttp($uri, $context); } if ($uri->scheme === 'cid') { $attachmentId = $this->mapCidToAttachmentId->__invoke($uri->path); if (is_null($attachmentId)) { return true; } $this->messageParameters['attachmentId'] = $attachmentId; $imgUrl = $this->urlGenerator->linkToRouteAbsolute('mail.messages.downloadAttachment', $this->messageParameters); $parser = new HTMLPurifier_URIParser(); $uri = $parser->parse($imgUrl); } return true; }
/** * Check all installed apps for updates */ protected function checkAppUpdates() { $apps = $this->appManager->getInstalledApps(); foreach ($apps as $app) { $update = $this->isUpdateAvailable($app); if ($update !== false) { $url = $this->urlGenerator->linkToRouteAbsolute('settings.AppSettings.viewApps') . '#app-' . $app; $this->createNotifications($app, $update, $url); } } }
/** * @NoAdminRequired * * @param string $enable 'true' if the feed is enabled * @return DataResponse */ public function feed($enable) { $token = $tokenUrl = ''; if ($enable === 'true') { $conflicts = true; // Check for collisions while (!empty($conflicts)) { $token = $this->random->generate(30); $conflicts = $this->config->getUsersForUserValue('activity', 'rsstoken', $token); } $tokenUrl = $this->urlGenerator->linkToRouteAbsolute('activity.Feed.show', ['token' => $token]); } $this->config->setUserValue($this->user, 'activity', 'rsstoken', $token); return new DataResponse(array('data' => array('message' => (string) $this->l10n->t('Your settings have been updated.'), 'rsslink' => $tokenUrl))); }
/** * inform users if a file was shared with them * * @param IUser[] $recipientList list of recipients * @param string $itemSource shared item source * @param string $itemType shared item type * @return array list of user to whom the mail send operation failed */ public function sendInternalShareMail($recipientList, $itemSource, $itemType) { $noMail = []; foreach ($recipientList as $recipient) { $recipientDisplayName = $recipient->getDisplayName(); $to = $recipient->getEMailAddress(); if ($to === '') { $noMail[] = $recipientDisplayName; continue; } $items = $this->getItemSharedWithUser($itemSource, $itemType, $recipient); $filename = trim($items[0]['file_target'], '/'); $subject = (string) $this->l->t('%s shared »%s« with you', array($this->senderDisplayName, $filename)); $expiration = null; if (isset($items[0]['expiration'])) { try { $date = new DateTime($items[0]['expiration']); $expiration = $date->getTimestamp(); } catch (\Exception $e) { $this->logger->error("Couldn't read date: " . $e->getMessage(), ['app' => 'sharing']); } } $link = $this->urlGenerator->linkToRouteAbsolute('files.viewcontroller.showFile', ['fileId' => $items[0]['item_source']]); list($htmlBody, $textBody) = $this->createMailBody($filename, $link, $expiration, 'internal'); // send it out now try { $message = $this->mailer->createMessage(); $message->setSubject($subject); $message->setTo([$to => $recipientDisplayName]); $message->setHtmlBody($htmlBody); $message->setPlainBody($textBody); $message->setFrom([Util::getDefaultEmailAddress('sharing-noreply') => (string) $this->l->t('%s via %s', [$this->senderDisplayName, $this->defaults->getName()])]); if (!is_null($this->replyTo)) { $message->setReplyTo([$this->replyTo]); } $this->mailer->send($message); } catch (\Exception $e) { $this->logger->error("Can't send mail to inform the user about an internal share: " . $e->getMessage(), ['app' => 'sharing']); $noMail[] = $recipientDisplayName; } } return $noMail; }
/** * Adds the activity and email for a user when the settings require it * * @param string $user * @param string $subject * @param array $subjectParams * @param int $fileId * @param string $path * @param bool $isFile If the item is a file, we link to the parent directory * @param bool $streamSetting * @param int $emailSetting * @param string $type */ protected function addNotificationsForUser($user, $subject, $subjectParams, $fileId, $path, $isFile, $streamSetting, $emailSetting, $type = Files_Sharing::TYPE_SHARED) { if (!$streamSetting && !$emailSetting) { return; } $selfAction = $user === $this->currentUser; $app = $type === Files_Sharing::TYPE_SHARED ? 'files_sharing' : 'files'; $link = $this->urlGenerator->linkToRouteAbsolute('files.view.index', array('dir' => $isFile ? dirname($path) : $path)); $objectType = $fileId ? 'files' : ''; $event = $this->manager->generateEvent(); $event->setApp($app)->setType($type)->setAffectedUser($user)->setAuthor($this->currentUser)->setTimestamp(time())->setSubject($subject, $subjectParams)->setObject($objectType, $fileId, $path)->setLink($link); // Add activity to stream if ($streamSetting && (!$selfAction || $this->userSettings->getUserSetting($this->currentUser, 'setting', 'self'))) { $this->activityData->send($event); } // Add activity to mail queue if ($emailSetting && (!$selfAction || $this->userSettings->getUserSetting($this->currentUser, 'setting', 'selfemail'))) { $latestSend = time() + $emailSetting; $this->activityData->storeMail($event, $latestSend); } }
/** * @PublicPage * @NoCSRFRequired * * @param string $token * @param string $path * @return TemplateResponse|RedirectResponse * @throws NotFoundException */ public function showShare($token, $path = '') { \OC_User::setIncognitoMode(true); // Check whether share exists try { $share = $this->shareManager->getShareByToken($token); } catch (\OC\Share20\Exception\ShareNotFound $e) { return new NotFoundResponse(); } // Share is password protected - check whether the user is permitted to access the share if ($share->getPassword() !== null && !$this->linkShareAuth($share)) { return new RedirectResponse($this->urlGenerator->linkToRoute('files_sharing.sharecontroller.authenticate', array('token' => $token))); } // We can't get the path of a file share if ($share->getNode() instanceof \OCP\Files\File && $path !== '') { throw new NotFoundException(); } $rootFolder = null; if ($share->getNode() instanceof \OCP\Files\Folder) { /** @var \OCP\Files\Folder $rootFolder */ $rootFolder = $share->getNode(); try { $path = $rootFolder->get($path); } catch (\OCP\Files\NotFoundException $e) { throw new NotFoundException(); } } $shareTmpl = []; $shareTmpl['displayName'] = $share->getShareOwner()->getDisplayName(); $shareTmpl['owner'] = $share->getShareOwner()->getUID(); $shareTmpl['filename'] = $share->getNode()->getName(); $shareTmpl['directory_path'] = $share->getTarget(); $shareTmpl['mimetype'] = $share->getNode()->getMimetype(); $shareTmpl['previewSupported'] = $this->previewManager->isMimeSupported($share->getNode()->getMimetype()); $shareTmpl['dirToken'] = $token; $shareTmpl['sharingToken'] = $token; $shareTmpl['server2serversharing'] = Helper::isOutgoingServer2serverShareEnabled(); $shareTmpl['protected'] = $share->getPassword() !== null ? 'true' : 'false'; $shareTmpl['dir'] = ''; $shareTmpl['nonHumanFileSize'] = $share->getNode()->getSize(); $shareTmpl['fileSize'] = \OCP\Util::humanFileSize($share->getNode()->getSize()); // Show file list if ($share->getNode() instanceof \OCP\Files\Folder) { $shareTmpl['dir'] = $rootFolder->getRelativePath($path->getPath()); /* * The OC_Util methods require a view. This just uses the node API */ $freeSpace = $share->getNode()->getStorage()->free_space($share->getNode()->getInternalPath()); if ($freeSpace !== \OCP\Files\FileInfo::SPACE_UNKNOWN) { $freeSpace = max($freeSpace, 0); } else { $freeSpace = INF > 0 ? INF : PHP_INT_MAX; // work around https://bugs.php.net/bug.php?id=69188 } $uploadLimit = Util::uploadLimit(); $maxUploadFilesize = min($freeSpace, $uploadLimit); $folder = new Template('files', 'list', ''); $folder->assign('dir', $rootFolder->getRelativePath($path->getPath())); $folder->assign('dirToken', $token); $folder->assign('permissions', \OCP\Constants::PERMISSION_READ); $folder->assign('isPublic', true); $folder->assign('publicUploadEnabled', 'no'); $folder->assign('uploadMaxFilesize', $maxUploadFilesize); $folder->assign('uploadMaxHumanFilesize', OCP\Util::humanFileSize($maxUploadFilesize)); $folder->assign('freeSpace', $freeSpace); $folder->assign('uploadLimit', $uploadLimit); // PHP upload limit $folder->assign('usedSpacePercent', 0); $folder->assign('trash', false); $shareTmpl['folder'] = $folder->fetchPage(); } $shareTmpl['downloadURL'] = $this->urlGenerator->linkToRouteAbsolute('files_sharing.sharecontroller.downloadShare', array('token' => $token)); $shareTmpl['maxSizeAnimateGif'] = $this->config->getSystemValue('max_filesize_animated_gifs_public_sharing', 10); $shareTmpl['previewEnabled'] = $this->config->getSystemValue('enable_previews', true); $csp = new OCP\AppFramework\Http\ContentSecurityPolicy(); $csp->addAllowedFrameDomain('\'self\''); $response = new TemplateResponse($this->appName, 'public', $shareTmpl, 'base'); $response->setContentSecurityPolicy($csp); return $response; }