Signed-off-by: Christoph Wurst <christoph@winzerhof-wurst.at>tags/v21.0.0beta1
'ocs' => [ | 'ocs' => [ | ||||
[ | [ | ||||
'name' => 'Config#getConfig', | 'name' => 'Config#getConfig', | ||||
'url' => '/api/v1/config', | |||||
'url' => '/api/v1/config', | |||||
'verb' => 'GET', | 'verb' => 'GET', | ||||
], | ], | ||||
[ | [ | ||||
'name' => 'Config#setConfig', | 'name' => 'Config#setConfig', | ||||
'url' => '/api/v1/config/{key}', | |||||
'url' => '/api/v1/config/{key}', | |||||
'verb' => 'PUT', | 'verb' => 'PUT', | ||||
], | ], | ||||
[ | [ | ||||
'name' => 'Config#deleteConfig', | 'name' => 'Config#deleteConfig', | ||||
'url' => '/api/v1/config/{key}', | |||||
'url' => '/api/v1/config/{key}', | |||||
'verb' => 'DELETE', | 'verb' => 'DELETE', | ||||
], | ], | ||||
] | ] |
public function __construct(string $appName, | public function __construct(string $appName, | ||||
IURLGenerator $urlGenerator, | IURLGenerator $urlGenerator, | ||||
IL10N $l) { | IL10N $l) { | ||||
$this->appName = $appName; | |||||
$this->appName = $appName; | |||||
$this->urlGenerator = $urlGenerator; | $this->urlGenerator = $urlGenerator; | ||||
$this->l = $l; | |||||
$this->l = $l; | |||||
} | } | ||||
public function getThemes() { | public function getThemes() { | ||||
return [ | return [ | ||||
[ | [ | ||||
'id' => 'dark', | |||||
'img' => $this->urlGenerator->imagePath($this->appName, 'theme-dark.jpg'), | |||||
'id' => 'dark', | |||||
'img' => $this->urlGenerator->imagePath($this->appName, 'theme-dark.jpg'), | |||||
'title' => $this->l->t('Dark theme'), | 'title' => $this->l->t('Dark theme'), | ||||
'enableLabel' => $this->l->t('Enable dark theme'), | 'enableLabel' => $this->l->t('Enable dark theme'), | ||||
'text' => $this->l->t('A dark theme to ease your eyes by reducing the overall luminosity and brightness. It is still under development, so please report any issues you may find.') | |||||
'text' => $this->l->t('A dark theme to ease your eyes by reducing the overall luminosity and brightness. It is still under development, so please report any issues you may find.') | |||||
] | ] | ||||
]; | ]; | ||||
} | } | ||||
public function getHighContrast() { | public function getHighContrast() { | ||||
return [ | return [ | ||||
'id' => 'highcontrast', | |||||
'img' => $this->urlGenerator->imagePath($this->appName, 'mode-highcontrast.jpg'), | |||||
'id' => 'highcontrast', | |||||
'img' => $this->urlGenerator->imagePath($this->appName, 'mode-highcontrast.jpg'), | |||||
'title' => $this->l->t('High contrast mode'), | 'title' => $this->l->t('High contrast mode'), | ||||
'enableLabel' => $this->l->t('Enable high contrast mode'), | 'enableLabel' => $this->l->t('Enable high contrast mode'), | ||||
'text' => $this->l->t('A high contrast mode to ease your navigation. Visual quality will be reduced but clarity will be increased.') | |||||
'text' => $this->l->t('A high contrast mode to ease your navigation. Visual quality will be reduced but clarity will be increased.') | |||||
]; | ]; | ||||
} | } | ||||
public function getFonts() { | public function getFonts() { | ||||
return [ | return [ | ||||
[ | [ | ||||
'id' => 'fontdyslexic', | |||||
'img' => $this->urlGenerator->imagePath($this->appName, 'font-opendyslexic.jpg'), | |||||
'id' => 'fontdyslexic', | |||||
'img' => $this->urlGenerator->imagePath($this->appName, 'font-opendyslexic.jpg'), | |||||
'title' => $this->l->t('Dyslexia font'), | 'title' => $this->l->t('Dyslexia font'), | ||||
'enableLabel' => $this->l->t('Enable dyslexia font'), | 'enableLabel' => $this->l->t('Enable dyslexia font'), | ||||
'text' => $this->l->t('OpenDyslexic is a free typeface/font designed to mitigate some of the common reading errors caused by dyslexia.') | |||||
'text' => $this->l->t('OpenDyslexic is a free typeface/font designed to mitigate some of the common reading errors caused by dyslexia.') | |||||
] | ] | ||||
]; | ]; | ||||
} | } |
IconsCacher $iconsCacher, | IconsCacher $iconsCacher, | ||||
\OC_Defaults $defaults) { | \OC_Defaults $defaults) { | ||||
parent::__construct($appName, $request); | parent::__construct($appName, $request); | ||||
$this->appName = $appName; | |||||
$this->config = $config; | |||||
$this->userManager = $userManager; | |||||
$this->logger = $logger; | |||||
$this->appName = $appName; | |||||
$this->config = $config; | |||||
$this->userManager = $userManager; | |||||
$this->logger = $logger; | |||||
$this->urlGenerator = $urlGenerator; | $this->urlGenerator = $urlGenerator; | ||||
$this->timeFactory = $timeFactory; | |||||
$this->userSession = $userSession; | |||||
$this->appManager = $appManager; | |||||
$this->iconsCacher = $iconsCacher; | |||||
$this->defaults = $defaults; | |||||
$this->timeFactory = $timeFactory; | |||||
$this->userSession = $userSession; | |||||
$this->appManager = $appManager; | |||||
$this->iconsCacher = $iconsCacher; | |||||
$this->defaults = $defaults; | |||||
$this->serverRoot = \OC::$SERVERROOT; | $this->serverRoot = \OC::$SERVERROOT; | ||||
$this->appRoot = $this->appManager->getAppPath($this->appName); | |||||
$this->appRoot = $this->appManager->getAppPath($this->appName); | |||||
} | } | ||||
/** | /** | ||||
* @return DataDisplayResponse | * @return DataDisplayResponse | ||||
*/ | */ | ||||
public function getCss(): DataDisplayResponse { | public function getCss(): DataDisplayResponse { | ||||
$css = ''; | |||||
$imports = ''; | |||||
$css = ''; | |||||
$imports = ''; | |||||
if ($this->userSession->isLoggedIn()) { | if ($this->userSession->isLoggedIn()) { | ||||
$userValues = $this->getUserValues(); | $userValues = $this->getUserValues(); | ||||
} else { | } else { | ||||
// Rebase all urls | // Rebase all urls | ||||
$appWebRoot = substr($this->appRoot, strlen($this->serverRoot) - strlen(\OC::$WEBROOT)); | $appWebRoot = substr($this->appRoot, strlen($this->serverRoot) - strlen(\OC::$WEBROOT)); | ||||
$css = $this->rebaseUrls($css, $appWebRoot . '/css'); | |||||
$css = $this->rebaseUrls($css, $appWebRoot . '/css'); | |||||
if (in_array('dark', $userValues) && $this->iconsCacher->getCachedList() && $this->iconsCacher->getCachedList()->getSize() > 0) { | if (in_array('dark', $userValues) && $this->iconsCacher->getCachedList() && $this->iconsCacher->getCachedList()->getSize() > 0) { | ||||
$iconsCss = $this->invertSvgIconsColor($this->iconsCacher->getCachedList()->getContent()); | $iconsCss = $this->invertSvgIconsColor($this->iconsCacher->getCachedList()->getContent()); | ||||
*/ | */ | ||||
private function getUserValues(): array { | private function getUserValues(): array { | ||||
$userTheme = $this->config->getUserValue($this->userSession->getUser()->getUID(), $this->appName, 'theme', false); | $userTheme = $this->config->getUserValue($this->userSession->getUser()->getUID(), $this->appName, 'theme', false); | ||||
$userFont = $this->config->getUserValue($this->userSession->getUser()->getUID(), $this->appName, 'font', false); | |||||
$userFont = $this->config->getUserValue($this->userSession->getUser()->getUID(), $this->appName, 'font', false); | |||||
$userHighContrast = $this->config->getUserValue($this->userSession->getUser()->getUID(), $this->appName, 'highcontrast', false); | $userHighContrast = $this->config->getUserValue($this->userSession->getUser()->getUID(), $this->appName, 'highcontrast', false); | ||||
return [$userTheme, $userHighContrast, $userFont]; | return [$userTheme, $userHighContrast, $userFont]; | ||||
* @return string | * @return string | ||||
*/ | */ | ||||
private function rebaseUrls(string $css, string $webDir): string { | private function rebaseUrls(string $css, string $webDir): string { | ||||
$re = '/url\([\'"]([^\/][\.\w?=\/-]*)[\'"]\)/x'; | |||||
$re = '/url\([\'"]([^\/][\.\w?=\/-]*)[\'"]\)/x'; | |||||
$subst = 'url(\'' . $webDir . '/$1\')'; | $subst = 'url(\'' . $webDir . '/$1\')'; | ||||
return preg_replace($re, $subst, $css); | return preg_replace($re, $subst, $css); |
IUserSession $userSession, | IUserSession $userSession, | ||||
AccessibilityProvider $accessibilityProvider) { | AccessibilityProvider $accessibilityProvider) { | ||||
parent::__construct($appName, $request); | parent::__construct($appName, $request); | ||||
$this->appName = $appName; | |||||
$this->config = $config; | |||||
$this->userSession = $userSession; | |||||
$this->appName = $appName; | |||||
$this->config = $config; | |||||
$this->userSession = $userSession; | |||||
$this->accessibilityProvider = $accessibilityProvider; | $this->accessibilityProvider = $accessibilityProvider; | ||||
$this->userId = $userSession->getUser()->getUID(); | |||||
$this->userId = $userSession->getUser()->getUID(); | |||||
} | } | ||||
/** | /** | ||||
$themes = $this->accessibilityProvider->getThemes(); | $themes = $this->accessibilityProvider->getThemes(); | ||||
$highcontrast = [$this->accessibilityProvider->getHighContrast()]; | $highcontrast = [$this->accessibilityProvider->getHighContrast()]; | ||||
$fonts = $this->accessibilityProvider->getFonts(); | |||||
$fonts = $this->accessibilityProvider->getFonts(); | |||||
$availableOptions = array_map(function ($option) { | $availableOptions = array_map(function ($option) { | ||||
return $option['id']; | return $option['id']; |
IURLGenerator $urlGenerator, | IURLGenerator $urlGenerator, | ||||
AccessibilityProvider $accessibilityProvider, | AccessibilityProvider $accessibilityProvider, | ||||
IInitialStateService $initialStateService) { | IInitialStateService $initialStateService) { | ||||
$this->appName = $appName; | |||||
$this->config = $config; | |||||
$this->userSession = $userSession; | |||||
$this->l = $l; | |||||
$this->urlGenerator = $urlGenerator; | |||||
$this->appName = $appName; | |||||
$this->config = $config; | |||||
$this->userSession = $userSession; | |||||
$this->l = $l; | |||||
$this->urlGenerator = $urlGenerator; | |||||
$this->accessibilityProvider = $accessibilityProvider; | $this->accessibilityProvider = $accessibilityProvider; | ||||
$this->initialStateService = $initialStateService; | |||||
$this->initialStateService = $initialStateService; | |||||
} | } | ||||
/** | /** | ||||
$availableConfig = [ | $availableConfig = [ | ||||
'themes' => $this->accessibilityProvider->getThemes(), | 'themes' => $this->accessibilityProvider->getThemes(), | ||||
'fonts' => $this->accessibilityProvider->getFonts(), | |||||
'fonts' => $this->accessibilityProvider->getFonts(), | |||||
'highcontrast' => $this->accessibilityProvider->getHighContrast() | 'highcontrast' => $this->accessibilityProvider->getHighContrast() | ||||
]; | ]; | ||||
$userConfig = [ | $userConfig = [ | ||||
'highcontrast' => $this->config->getUserValue($this->userSession->getUser()->getUID(), $this->appName, 'highcontrast', false), | 'highcontrast' => $this->config->getUserValue($this->userSession->getUser()->getUID(), $this->appName, 'highcontrast', false), | ||||
'theme' => $this->config->getUserValue($this->userSession->getUser()->getUID(), $this->appName, 'theme', false), | |||||
'font' => $this->config->getUserValue($this->userSession->getUser()->getUID(), $this->appName, 'font', false) | |||||
'theme' => $this->config->getUserValue($this->userSession->getUser()->getUID(), $this->appName, 'theme', false), | |||||
'font' => $this->config->getUserValue($this->userSession->getUser()->getUID(), $this->appName, 'font', false) | |||||
]; | ]; | ||||
$this->initialStateService->provideInitialState($this->appName, 'available-config', $availableConfig); | $this->initialStateService->provideInitialState($this->appName, 'available-config', $availableConfig); |
public function __construct(string $appName, | public function __construct(string $appName, | ||||
IURLGenerator $urlGenerator, | IURLGenerator $urlGenerator, | ||||
IL10N $l) { | IL10N $l) { | ||||
$this->appName = $appName; | |||||
$this->appName = $appName; | |||||
$this->urlGenerator = $urlGenerator; | $this->urlGenerator = $urlGenerator; | ||||
$this->l = $l; | |||||
$this->l = $l; | |||||
} | } | ||||
/** | /** |
use RotationTrait; | use RotationTrait; | ||||
public function __construct() { | public function __construct() { | ||||
$this->setInterval(60*60*3); | |||||
$this->setInterval(60 * 60 * 3); | |||||
} | } | ||||
protected function run($argument) { | protected function run($argument) { |
private $notificationListener; | private $notificationListener; | ||||
public function __construct(ActivityListener $activityListener, NotificationListener $notificationListener) { | public function __construct(ActivityListener $activityListener, NotificationListener $notificationListener) { | ||||
$this->activityListener = $activityListener; | |||||
$this->activityListener = $activityListener; | |||||
$this->notificationListener = $notificationListener; | $this->notificationListener = $notificationListener; | ||||
} | } | ||||
$commentMocks = []; | $commentMocks = []; | ||||
foreach ($data['actors'] as $actorType => $actors) { | foreach ($data['actors'] as $actorType => $actors) { | ||||
foreach ($actors as $actorId => $noOfComments) { | foreach ($actors as $actorId => $noOfComments) { | ||||
for ($i=0;$i<$noOfComments;$i++) { | |||||
for ($i = 0;$i < $noOfComments;$i++) { | |||||
$mock = $this->createMock(IComment::class); | $mock = $this->createMock(IComment::class); | ||||
$mock->expects($this->atLeastOnce()) | $mock->expects($this->atLeastOnce()) | ||||
->method('getActorType') | ->method('getActorType') |
private $mapper; | private $mapper; | ||||
public function __construct(ITimeFactory $timeFactory, DirectMapper $mapper) { | public function __construct(ITimeFactory $timeFactory, DirectMapper $mapper) { | ||||
$this->setInterval(60*60*24); | |||||
$this->setInterval(60 * 60 * 24); | |||||
$this->timeFactory = $timeFactory; | $this->timeFactory = $timeFactory; | ||||
$this->mapper = $mapper; | $this->mapper = $mapper; | ||||
protected function run($argument) { | protected function run($argument) { | ||||
// Delete all shares expired 24 hours ago | // Delete all shares expired 24 hours ago | ||||
$this->mapper->deleteExpired($this->timeFactory->getTime() - 60*60*24); | |||||
$this->mapper->deleteExpired($this->timeFactory->getTime() - 60 * 60 * 24); | |||||
} | } | ||||
} | } |
$this->jobList = $jobList; | $this->jobList = $jobList; | ||||
// Run once a day | // Run once a day | ||||
$this->setInterval(60*60*24); | |||||
$this->setInterval(60 * 60 * 24); | |||||
} | } | ||||
protected function run($argument) { | protected function run($argument) { | ||||
$uploads = $userRoot->get('uploads'); | $uploads = $userRoot->get('uploads'); | ||||
/** @var Folder $uploadFolder */ | /** @var Folder $uploadFolder */ | ||||
$uploadFolder = $uploads->get($folder); | $uploadFolder = $uploads->get($folder); | ||||
} catch (NotFoundException|NoUserException $e) { | |||||
} catch (NotFoundException | NoUserException $e) { | |||||
$this->jobList->remove(self::class, $argument); | $this->jobList->remove(self::class, $argument); | ||||
return; | return; | ||||
} | } |
$this->calDavBackEnd->createCalendar($principal, self::BIRTHDAY_CALENDAR_URI, [ | $this->calDavBackEnd->createCalendar($principal, self::BIRTHDAY_CALENDAR_URI, [ | ||||
'{DAV:}displayname' => 'Contact birthdays', | '{DAV:}displayname' => 'Contact birthdays', | ||||
'{http://apple.com/ns/ical/}calendar-color' => '#E9D859', | '{http://apple.com/ns/ical/}calendar-color' => '#E9D859', | ||||
'components' => 'VEVENT', | |||||
'components' => 'VEVENT', | |||||
]); | ]); | ||||
return $this->calDavBackEnd->getCalendarByUri($principal, self::BIRTHDAY_CALENDAR_URI); | return $this->calDavBackEnd->getCalendarByUri($principal, self::BIRTHDAY_CALENDAR_URI); | ||||
*/ | */ | ||||
private function formatTitle(string $field, | private function formatTitle(string $field, | ||||
string $name, | string $name, | ||||
int $year=null, | |||||
bool $supports4Byte=true):string { | |||||
int $year = null, | |||||
bool $supports4Byte = true):string { | |||||
if ($supports4Byte) { | if ($supports4Byte) { | ||||
switch ($field) { | switch ($field) { | ||||
case 'BDAY': | case 'BDAY': |
* @var array | * @var array | ||||
*/ | */ | ||||
public $propertyMap = [ | public $propertyMap = [ | ||||
'{DAV:}displayname' => 'displayname', | |||||
'{DAV:}displayname' => 'displayname', | |||||
'{urn:ietf:params:xml:ns:caldav}calendar-description' => 'description', | '{urn:ietf:params:xml:ns:caldav}calendar-description' => 'description', | ||||
'{urn:ietf:params:xml:ns:caldav}calendar-timezone' => 'timezone', | |||||
'{http://apple.com/ns/ical/}calendar-order' => 'calendarorder', | |||||
'{http://apple.com/ns/ical/}calendar-color' => 'calendarcolor', | |||||
'{urn:ietf:params:xml:ns:caldav}calendar-timezone' => 'timezone', | |||||
'{http://apple.com/ns/ical/}calendar-order' => 'calendarorder', | |||||
'{http://apple.com/ns/ical/}calendar-color' => 'calendarcolor', | |||||
]; | ]; | ||||
/** | /** | ||||
* @var array | * @var array | ||||
*/ | */ | ||||
public $subscriptionPropertyMap = [ | public $subscriptionPropertyMap = [ | ||||
'{DAV:}displayname' => 'displayname', | |||||
'{http://apple.com/ns/ical/}refreshrate' => 'refreshrate', | |||||
'{http://apple.com/ns/ical/}calendar-order' => 'calendarorder', | |||||
'{http://apple.com/ns/ical/}calendar-color' => 'calendarcolor', | |||||
'{http://calendarserver.org/ns/}subscribed-strip-todos' => 'striptodos', | |||||
'{http://calendarserver.org/ns/}subscribed-strip-alarms' => 'stripalarms', | |||||
'{DAV:}displayname' => 'displayname', | |||||
'{http://apple.com/ns/ical/}refreshrate' => 'refreshrate', | |||||
'{http://apple.com/ns/ical/}calendar-order' => 'calendarorder', | |||||
'{http://apple.com/ns/ical/}calendar-color' => 'calendarcolor', | |||||
'{http://calendarserver.org/ns/}subscribed-strip-todos' => 'striptodos', | |||||
'{http://calendarserver.org/ns/}subscribed-strip-alarms' => 'stripalarms', | |||||
'{http://calendarserver.org/ns/}subscribed-strip-attachments' => 'stripattachments', | '{http://calendarserver.org/ns/}subscribed-strip-attachments' => 'stripattachments', | ||||
]; | ]; | ||||
'{' . \OCA\DAV\DAV\Sharing\Plugin::NS_OWNCLOUD . '}owner-principal' => $this->convertPrincipal($principalUri, !$this->legacyEndpoint), | '{' . \OCA\DAV\DAV\Sharing\Plugin::NS_OWNCLOUD . '}owner-principal' => $this->convertPrincipal($principalUri, !$this->legacyEndpoint), | ||||
]; | ]; | ||||
foreach ($this->propertyMap as $xmlName=>$dbName) { | |||||
foreach ($this->propertyMap as $xmlName => $dbName) { | |||||
$calendar[$xmlName] = $row[$dbName]; | $calendar[$xmlName] = $row[$dbName]; | ||||
} | } | ||||
$principals = array_map(function ($principal) { | $principals = array_map(function ($principal) { | ||||
return urldecode($principal); | return urldecode($principal); | ||||
}, $principals); | }, $principals); | ||||
$principals[]= $principalUri; | |||||
$principals[] = $principalUri; | |||||
$fields = array_values($this->propertyMap); | $fields = array_values($this->propertyMap); | ||||
$fields[] = 'a.id'; | $fields[] = 'a.id'; | ||||
$readOnlyPropertyName => $readOnly, | $readOnlyPropertyName => $readOnly, | ||||
]; | ]; | ||||
foreach ($this->propertyMap as $xmlName=>$dbName) { | |||||
foreach ($this->propertyMap as $xmlName => $dbName) { | |||||
$calendar[$xmlName] = $row[$dbName]; | $calendar[$xmlName] = $row[$dbName]; | ||||
} | } | ||||
'{' . Plugin::NS_CALDAV . '}supported-calendar-component-set' => new SupportedCalendarComponentSet($components), | '{' . Plugin::NS_CALDAV . '}supported-calendar-component-set' => new SupportedCalendarComponentSet($components), | ||||
'{' . Plugin::NS_CALDAV . '}schedule-calendar-transp' => new ScheduleCalendarTransp($row['transparent']?'transparent':'opaque'), | '{' . Plugin::NS_CALDAV . '}schedule-calendar-transp' => new ScheduleCalendarTransp($row['transparent']?'transparent':'opaque'), | ||||
]; | ]; | ||||
foreach ($this->propertyMap as $xmlName=>$dbName) { | |||||
foreach ($this->propertyMap as $xmlName => $dbName) { | |||||
$calendar[$xmlName] = $row[$dbName]; | $calendar[$xmlName] = $row[$dbName]; | ||||
} | } | ||||
'{' . \OCA\DAV\DAV\Sharing\Plugin::NS_OWNCLOUD . '}public' => (int)$row['access'] === self::ACCESS_PUBLIC, | '{' . \OCA\DAV\DAV\Sharing\Plugin::NS_OWNCLOUD . '}public' => (int)$row['access'] === self::ACCESS_PUBLIC, | ||||
]; | ]; | ||||
foreach ($this->propertyMap as $xmlName=>$dbName) { | |||||
foreach ($this->propertyMap as $xmlName => $dbName) { | |||||
$calendar[$xmlName] = $row[$dbName]; | $calendar[$xmlName] = $row[$dbName]; | ||||
} | } | ||||
'{' . \OCA\DAV\DAV\Sharing\Plugin::NS_OWNCLOUD . '}public' => (int)$row['access'] === self::ACCESS_PUBLIC, | '{' . \OCA\DAV\DAV\Sharing\Plugin::NS_OWNCLOUD . '}public' => (int)$row['access'] === self::ACCESS_PUBLIC, | ||||
]; | ]; | ||||
foreach ($this->propertyMap as $xmlName=>$dbName) { | |||||
foreach ($this->propertyMap as $xmlName => $dbName) { | |||||
$calendar[$xmlName] = $row[$dbName]; | $calendar[$xmlName] = $row[$dbName]; | ||||
} | } | ||||
'{' . Plugin::NS_CALDAV . '}schedule-calendar-transp' => new ScheduleCalendarTransp($row['transparent']?'transparent':'opaque'), | '{' . Plugin::NS_CALDAV . '}schedule-calendar-transp' => new ScheduleCalendarTransp($row['transparent']?'transparent':'opaque'), | ||||
]; | ]; | ||||
foreach ($this->propertyMap as $xmlName=>$dbName) { | |||||
foreach ($this->propertyMap as $xmlName => $dbName) { | |||||
$calendar[$xmlName] = $row[$dbName]; | $calendar[$xmlName] = $row[$dbName]; | ||||
} | } | ||||
'{' . Plugin::NS_CALDAV . '}schedule-calendar-transp' => new ScheduleCalendarTransp($row['transparent']?'transparent':'opaque'), | '{' . Plugin::NS_CALDAV . '}schedule-calendar-transp' => new ScheduleCalendarTransp($row['transparent']?'transparent':'opaque'), | ||||
]; | ]; | ||||
foreach ($this->propertyMap as $xmlName=>$dbName) { | |||||
foreach ($this->propertyMap as $xmlName => $dbName) { | |||||
$calendar[$xmlName] = $row[$dbName]; | $calendar[$xmlName] = $row[$dbName]; | ||||
} | } | ||||
->from('calendarsubscriptions') | ->from('calendarsubscriptions') | ||||
->where($query->expr()->eq('id', $query->createNamedParameter($subscriptionId))) | ->where($query->expr()->eq('id', $query->createNamedParameter($subscriptionId))) | ||||
->orderBy('calendarorder', 'asc'); | ->orderBy('calendarorder', 'asc'); | ||||
$stmt =$query->execute(); | |||||
$stmt = $query->execute(); | |||||
$row = $stmt->fetch(\PDO::FETCH_ASSOC); | $row = $stmt->fetch(\PDO::FETCH_ASSOC); | ||||
$stmt->closeCursor(); | $stmt->closeCursor(); | ||||
} | } | ||||
$subscription = [ | $subscription = [ | ||||
'id' => $row['id'], | |||||
'uri' => $row['uri'], | |||||
'id' => $row['id'], | |||||
'uri' => $row['uri'], | |||||
'principaluri' => $row['principaluri'], | 'principaluri' => $row['principaluri'], | ||||
'source' => $row['source'], | |||||
'source' => $row['source'], | |||||
'lastmodified' => $row['lastmodified'], | 'lastmodified' => $row['lastmodified'], | ||||
'{' . Plugin::NS_CALDAV . '}supported-calendar-component-set' => new SupportedCalendarComponentSet(['VTODO', 'VEVENT']), | '{' . Plugin::NS_CALDAV . '}supported-calendar-component-set' => new SupportedCalendarComponentSet(['VTODO', 'VEVENT']), | ||||
'{http://sabredav.org/ns}sync-token' => $row['synctoken']?$row['synctoken']:'0', | '{http://sabredav.org/ns}sync-token' => $row['synctoken']?$row['synctoken']:'0', | ||||
]; | ]; | ||||
foreach ($this->subscriptionPropertyMap as $xmlName=>$dbName) { | |||||
foreach ($this->subscriptionPropertyMap as $xmlName => $dbName) { | |||||
if (!is_null($row[$dbName])) { | if (!is_null($row[$dbName])) { | ||||
$subscription[$xmlName] = $row[$dbName]; | $subscription[$xmlName] = $row[$dbName]; | ||||
} | } | ||||
public function createCalendar($principalUri, $calendarUri, array $properties) { | public function createCalendar($principalUri, $calendarUri, array $properties) { | ||||
$values = [ | $values = [ | ||||
'principaluri' => $this->convertPrincipal($principalUri, true), | 'principaluri' => $this->convertPrincipal($principalUri, true), | ||||
'uri' => $calendarUri, | |||||
'synctoken' => 1, | |||||
'transparent' => 0, | |||||
'components' => 'VEVENT,VTODO', | |||||
'displayname' => $calendarUri | |||||
'uri' => $calendarUri, | |||||
'synctoken' => 1, | |||||
'transparent' => 0, | |||||
'components' => 'VEVENT,VTODO', | |||||
'displayname' => $calendarUri | |||||
]; | ]; | ||||
// Default value | // Default value | ||||
$values['transparent'] = (int) ($properties[$transp]->getValue() === 'transparent'); | $values['transparent'] = (int) ($properties[$transp]->getValue() === 'transparent'); | ||||
} | } | ||||
foreach ($this->propertyMap as $xmlName=>$dbName) { | |||||
foreach ($this->propertyMap as $xmlName => $dbName) { | |||||
if (isset($properties[$xmlName])) { | if (isset($properties[$xmlName])) { | ||||
$values[$dbName] = $properties[$xmlName]; | $values[$dbName] = $properties[$xmlName]; | ||||
} | } | ||||
* @param int $calendarType | * @param int $calendarType | ||||
* @return array | * @return array | ||||
*/ | */ | ||||
public function getCalendarObjects($calendarId, $calendarType=self::CALENDAR_TYPE_CALENDAR):array { | |||||
public function getCalendarObjects($calendarId, $calendarType = self::CALENDAR_TYPE_CALENDAR):array { | |||||
$query = $this->db->getQueryBuilder(); | $query = $this->db->getQueryBuilder(); | ||||
$query->select(['id', 'uri', 'lastmodified', 'etag', 'calendarid', 'size', 'componenttype', 'classification']) | $query->select(['id', 'uri', 'lastmodified', 'etag', 'calendarid', 'size', 'componenttype', 'classification']) | ||||
->from('calendarobjects') | ->from('calendarobjects') | ||||
$result = []; | $result = []; | ||||
foreach ($stmt->fetchAll(\PDO::FETCH_ASSOC) as $row) { | foreach ($stmt->fetchAll(\PDO::FETCH_ASSOC) as $row) { | ||||
$result[] = [ | $result[] = [ | ||||
'id' => $row['id'], | |||||
'uri' => $row['uri'], | |||||
'id' => $row['id'], | |||||
'uri' => $row['uri'], | |||||
'lastmodified' => $row['lastmodified'], | 'lastmodified' => $row['lastmodified'], | ||||
'etag' => '"' . $row['etag'] . '"', | |||||
'calendarid' => $row['calendarid'], | |||||
'size' => (int)$row['size'], | |||||
'component' => strtolower($row['componenttype']), | |||||
'classification'=> (int)$row['classification'] | |||||
'etag' => '"' . $row['etag'] . '"', | |||||
'calendarid' => $row['calendarid'], | |||||
'size' => (int)$row['size'], | |||||
'component' => strtolower($row['componenttype']), | |||||
'classification' => (int)$row['classification'] | |||||
]; | ]; | ||||
} | } | ||||
* @param int $calendarType | * @param int $calendarType | ||||
* @return array|null | * @return array|null | ||||
*/ | */ | ||||
public function getCalendarObject($calendarId, $objectUri, $calendarType=self::CALENDAR_TYPE_CALENDAR) { | |||||
public function getCalendarObject($calendarId, $objectUri, $calendarType = self::CALENDAR_TYPE_CALENDAR) { | |||||
$query = $this->db->getQueryBuilder(); | $query = $this->db->getQueryBuilder(); | ||||
$query->select(['id', 'uri', 'lastmodified', 'etag', 'calendarid', 'size', 'calendardata', 'componenttype', 'classification']) | $query->select(['id', 'uri', 'lastmodified', 'etag', 'calendarid', 'size', 'calendardata', 'componenttype', 'classification']) | ||||
->from('calendarobjects') | ->from('calendarobjects') | ||||
} | } | ||||
return [ | return [ | ||||
'id' => $row['id'], | |||||
'uri' => $row['uri'], | |||||
'lastmodified' => $row['lastmodified'], | |||||
'etag' => '"' . $row['etag'] . '"', | |||||
'calendarid' => $row['calendarid'], | |||||
'size' => (int)$row['size'], | |||||
'calendardata' => $this->readBlob($row['calendardata']), | |||||
'component' => strtolower($row['componenttype']), | |||||
'classification'=> (int)$row['classification'] | |||||
'id' => $row['id'], | |||||
'uri' => $row['uri'], | |||||
'lastmodified' => $row['lastmodified'], | |||||
'etag' => '"' . $row['etag'] . '"', | |||||
'calendarid' => $row['calendarid'], | |||||
'size' => (int)$row['size'], | |||||
'calendardata' => $this->readBlob($row['calendardata']), | |||||
'component' => strtolower($row['componenttype']), | |||||
'classification' => (int)$row['classification'] | |||||
]; | ]; | ||||
} | } | ||||
* @param int $calendarType | * @param int $calendarType | ||||
* @return array | * @return array | ||||
*/ | */ | ||||
public function getMultipleCalendarObjects($calendarId, array $uris, $calendarType=self::CALENDAR_TYPE_CALENDAR):array { | |||||
public function getMultipleCalendarObjects($calendarId, array $uris, $calendarType = self::CALENDAR_TYPE_CALENDAR):array { | |||||
if (empty($uris)) { | if (empty($uris)) { | ||||
return []; | return []; | ||||
} | } | ||||
while ($row = $result->fetch()) { | while ($row = $result->fetch()) { | ||||
$objects[] = [ | $objects[] = [ | ||||
'id' => $row['id'], | |||||
'uri' => $row['uri'], | |||||
'id' => $row['id'], | |||||
'uri' => $row['uri'], | |||||
'lastmodified' => $row['lastmodified'], | 'lastmodified' => $row['lastmodified'], | ||||
'etag' => '"' . $row['etag'] . '"', | |||||
'calendarid' => $row['calendarid'], | |||||
'size' => (int)$row['size'], | |||||
'etag' => '"' . $row['etag'] . '"', | |||||
'calendarid' => $row['calendarid'], | |||||
'size' => (int)$row['size'], | |||||
'calendardata' => $this->readBlob($row['calendardata']), | 'calendardata' => $this->readBlob($row['calendardata']), | ||||
'component' => strtolower($row['componenttype']), | |||||
'component' => strtolower($row['componenttype']), | |||||
'classification' => (int)$row['classification'] | 'classification' => (int)$row['classification'] | ||||
]; | ]; | ||||
} | } | ||||
* @param int $calendarType | * @param int $calendarType | ||||
* @return string | * @return string | ||||
*/ | */ | ||||
public function createCalendarObject($calendarId, $objectUri, $calendarData, $calendarType=self::CALENDAR_TYPE_CALENDAR) { | |||||
public function createCalendarObject($calendarId, $objectUri, $calendarData, $calendarType = self::CALENDAR_TYPE_CALENDAR) { | |||||
$extraData = $this->getDenormalizedData($calendarData); | $extraData = $this->getDenormalizedData($calendarData); | ||||
$q = $this->db->getQueryBuilder(); | $q = $this->db->getQueryBuilder(); | ||||
* @param int $calendarType | * @param int $calendarType | ||||
* @return string | * @return string | ||||
*/ | */ | ||||
public function updateCalendarObject($calendarId, $objectUri, $calendarData, $calendarType=self::CALENDAR_TYPE_CALENDAR) { | |||||
public function updateCalendarObject($calendarId, $objectUri, $calendarData, $calendarType = self::CALENDAR_TYPE_CALENDAR) { | |||||
$extraData = $this->getDenormalizedData($calendarData); | $extraData = $this->getDenormalizedData($calendarData); | ||||
$query = $this->db->getQueryBuilder(); | $query = $this->db->getQueryBuilder(); | ||||
$query->update('calendarobjects') | $query->update('calendarobjects') | ||||
* @param int $calendarType | * @param int $calendarType | ||||
* @return void | * @return void | ||||
*/ | */ | ||||
public function deleteCalendarObject($calendarId, $objectUri, $calendarType=self::CALENDAR_TYPE_CALENDAR) { | |||||
public function deleteCalendarObject($calendarId, $objectUri, $calendarType = self::CALENDAR_TYPE_CALENDAR) { | |||||
$data = $this->getCalendarObject($calendarId, $objectUri, $calendarType); | $data = $this->getCalendarObject($calendarId, $objectUri, $calendarType); | ||||
if (is_array($data)) { | if (is_array($data)) { | ||||
if ($calendarType === self::CALENDAR_TYPE_CALENDAR) { | if ($calendarType === self::CALENDAR_TYPE_CALENDAR) { | ||||
* @param int $calendarType | * @param int $calendarType | ||||
* @return array | * @return array | ||||
*/ | */ | ||||
public function calendarQuery($calendarId, array $filters, $calendarType=self::CALENDAR_TYPE_CALENDAR):array { | |||||
public function calendarQuery($calendarId, array $filters, $calendarType = self::CALENDAR_TYPE_CALENDAR):array { | |||||
$componentType = null; | $componentType = null; | ||||
$requirePostFilter = true; | $requirePostFilter = true; | ||||
$timeRange = null; | $timeRange = null; | ||||
* @param integer|null $offset | * @param integer|null $offset | ||||
* @return array | * @return array | ||||
*/ | */ | ||||
public function calendarSearch($principalUri, array $filters, $limit=null, $offset=null) { | |||||
public function calendarSearch($principalUri, array $filters, $limit = null, $offset = null) { | |||||
$calendars = $this->getCalendarsForUser($principalUri); | $calendars = $this->getCalendarsForUser($principalUri); | ||||
$ownCalendars = []; | $ownCalendars = []; | ||||
$sharedCalendars = []; | $sharedCalendars = []; | ||||
* @param int $calendarType | * @param int $calendarType | ||||
* @return array | * @return array | ||||
*/ | */ | ||||
public function getChangesForCalendar($calendarId, $syncToken, $syncLevel, $limit = null, $calendarType=self::CALENDAR_TYPE_CALENDAR) { | |||||
public function getChangesForCalendar($calendarId, $syncToken, $syncLevel, $limit = null, $calendarType = self::CALENDAR_TYPE_CALENDAR) { | |||||
// Current synctoken | // Current synctoken | ||||
$stmt = $this->db->prepare('SELECT `synctoken` FROM `*PREFIX*calendars` WHERE `id` = ?'); | $stmt = $this->db->prepare('SELECT `synctoken` FROM `*PREFIX*calendars` WHERE `id` = ?'); | ||||
$stmt->execute([ $calendarId ]); | $stmt->execute([ $calendarId ]); | ||||
$result = [ | $result = [ | ||||
'syncToken' => $currentToken, | 'syncToken' => $currentToken, | ||||
'added' => [], | |||||
'modified' => [], | |||||
'deleted' => [], | |||||
'added' => [], | |||||
'modified' => [], | |||||
'deleted' => [], | |||||
]; | ]; | ||||
if ($syncToken) { | if ($syncToken) { | ||||
$query = "SELECT `uri`, `operation` FROM `*PREFIX*calendarchanges` WHERE `synctoken` >= ? AND `synctoken` < ? AND `calendarid` = ? AND `calendartype` = ? ORDER BY `synctoken`"; | $query = "SELECT `uri`, `operation` FROM `*PREFIX*calendarchanges` WHERE `synctoken` >= ? AND `synctoken` < ? AND `calendarid` = ? AND `calendartype` = ? ORDER BY `synctoken`"; | ||||
if ($limit>0) { | |||||
$query.= " LIMIT " . (int)$limit; | |||||
if ($limit > 0) { | |||||
$query .= " LIMIT " . (int)$limit; | |||||
} | } | ||||
// Fetching all changes | // Fetching all changes | ||||
->from('calendarsubscriptions') | ->from('calendarsubscriptions') | ||||
->where($query->expr()->eq('principaluri', $query->createNamedParameter($principalUri))) | ->where($query->expr()->eq('principaluri', $query->createNamedParameter($principalUri))) | ||||
->orderBy('calendarorder', 'asc'); | ->orderBy('calendarorder', 'asc'); | ||||
$stmt =$query->execute(); | |||||
$stmt = $query->execute(); | |||||
$subscriptions = []; | $subscriptions = []; | ||||
while ($row = $stmt->fetch(\PDO::FETCH_ASSOC)) { | while ($row = $stmt->fetch(\PDO::FETCH_ASSOC)) { | ||||
$subscription = [ | $subscription = [ | ||||
'id' => $row['id'], | |||||
'uri' => $row['uri'], | |||||
'id' => $row['id'], | |||||
'uri' => $row['uri'], | |||||
'principaluri' => $row['principaluri'], | 'principaluri' => $row['principaluri'], | ||||
'source' => $row['source'], | |||||
'source' => $row['source'], | |||||
'lastmodified' => $row['lastmodified'], | 'lastmodified' => $row['lastmodified'], | ||||
'{' . Plugin::NS_CALDAV . '}supported-calendar-component-set' => new SupportedCalendarComponentSet(['VTODO', 'VEVENT']), | '{' . Plugin::NS_CALDAV . '}supported-calendar-component-set' => new SupportedCalendarComponentSet(['VTODO', 'VEVENT']), | ||||
'{http://sabredav.org/ns}sync-token' => $row['synctoken']?$row['synctoken']:'0', | '{http://sabredav.org/ns}sync-token' => $row['synctoken']?$row['synctoken']:'0', | ||||
]; | ]; | ||||
foreach ($this->subscriptionPropertyMap as $xmlName=>$dbName) { | |||||
foreach ($this->subscriptionPropertyMap as $xmlName => $dbName) { | |||||
if (!is_null($row[$dbName])) { | if (!is_null($row[$dbName])) { | ||||
$subscription[$xmlName] = $row[$dbName]; | $subscription[$xmlName] = $row[$dbName]; | ||||
} | } | ||||
$values = [ | $values = [ | ||||
'principaluri' => $principalUri, | 'principaluri' => $principalUri, | ||||
'uri' => $uri, | |||||
'source' => $properties['{http://calendarserver.org/ns/}source']->getHref(), | |||||
'uri' => $uri, | |||||
'source' => $properties['{http://calendarserver.org/ns/}source']->getHref(), | |||||
'lastmodified' => time(), | 'lastmodified' => time(), | ||||
]; | ]; | ||||
$propertiesBoolean = ['striptodos', 'stripalarms', 'stripattachments']; | $propertiesBoolean = ['striptodos', 'stripalarms', 'stripattachments']; | ||||
foreach ($this->subscriptionPropertyMap as $xmlName=>$dbName) { | |||||
foreach ($this->subscriptionPropertyMap as $xmlName => $dbName) { | |||||
if (array_key_exists($xmlName, $properties)) { | if (array_key_exists($xmlName, $properties)) { | ||||
$values[$dbName] = $properties[$xmlName]; | $values[$dbName] = $properties[$xmlName]; | ||||
if (in_array($dbName, $propertiesBoolean)) { | if (in_array($dbName, $propertiesBoolean)) { | ||||
$propPatch->handle($supportedProperties, function ($mutations) use ($subscriptionId) { | $propPatch->handle($supportedProperties, function ($mutations) use ($subscriptionId) { | ||||
$newValues = []; | $newValues = []; | ||||
foreach ($mutations as $propertyName=>$propertyValue) { | |||||
foreach ($mutations as $propertyName => $propertyValue) { | |||||
if ($propertyName === '{http://calendarserver.org/ns/}source') { | if ($propertyName === '{http://calendarserver.org/ns/}source') { | ||||
$newValues['source'] = $propertyValue->getHref(); | $newValues['source'] = $propertyValue->getHref(); | ||||
} else { | } else { | ||||
$query = $this->db->getQueryBuilder(); | $query = $this->db->getQueryBuilder(); | ||||
$query->update('calendarsubscriptions') | $query->update('calendarsubscriptions') | ||||
->set('lastmodified', $query->createNamedParameter(time())); | ->set('lastmodified', $query->createNamedParameter(time())); | ||||
foreach ($newValues as $fieldName=>$value) { | |||||
foreach ($newValues as $fieldName => $value) { | |||||
$query->set($fieldName, $query->createNamedParameter($value)); | $query->set($fieldName, $query->createNamedParameter($value)); | ||||
} | } | ||||
$query->where($query->expr()->eq('id', $query->createNamedParameter($subscriptionId))) | $query->where($query->expr()->eq('id', $query->createNamedParameter($subscriptionId))) | ||||
} | } | ||||
return [ | return [ | ||||
'uri' => $row['uri'], | |||||
'uri' => $row['uri'], | |||||
'calendardata' => $row['calendardata'], | 'calendardata' => $row['calendardata'], | ||||
'lastmodified' => $row['lastmodified'], | 'lastmodified' => $row['lastmodified'], | ||||
'etag' => '"' . $row['etag'] . '"', | |||||
'size' => (int)$row['size'], | |||||
'etag' => '"' . $row['etag'] . '"', | |||||
'size' => (int)$row['size'], | |||||
]; | ]; | ||||
} | } | ||||
foreach ($stmt->fetchAll(\PDO::FETCH_ASSOC) as $row) { | foreach ($stmt->fetchAll(\PDO::FETCH_ASSOC) as $row) { | ||||
$result[] = [ | $result[] = [ | ||||
'calendardata' => $row['calendardata'], | 'calendardata' => $row['calendardata'], | ||||
'uri' => $row['uri'], | |||||
'uri' => $row['uri'], | |||||
'lastmodified' => $row['lastmodified'], | 'lastmodified' => $row['lastmodified'], | ||||
'etag' => '"' . $row['etag'] . '"', | |||||
'size' => (int)$row['size'], | |||||
'etag' => '"' . $row['etag'] . '"', | |||||
'size' => (int)$row['size'], | |||||
]; | ]; | ||||
} | } | ||||
* @param int $calendarType | * @param int $calendarType | ||||
* @return void | * @return void | ||||
*/ | */ | ||||
protected function addChange($calendarId, $objectUri, $operation, $calendarType=self::CALENDAR_TYPE_CALENDAR) { | |||||
protected function addChange($calendarId, $objectUri, $operation, $calendarType = self::CALENDAR_TYPE_CALENDAR) { | |||||
$table = $calendarType === self::CALENDAR_TYPE_CALENDAR ? 'calendars': 'calendarsubscriptions'; | $table = $calendarType === self::CALENDAR_TYPE_CALENDAR ? 'calendars': 'calendarsubscriptions'; | ||||
$query = $this->db->getQueryBuilder(); | $query = $this->db->getQueryBuilder(); | ||||
$uid = null; | $uid = null; | ||||
$classification = self::CLASSIFICATION_PUBLIC; | $classification = self::CLASSIFICATION_PUBLIC; | ||||
foreach ($vObject->getComponents() as $component) { | foreach ($vObject->getComponents() as $component) { | ||||
if ($component->name!=='VTIMEZONE') { | |||||
if ($component->name !== 'VTIMEZONE') { | |||||
$componentType = $component->name; | $componentType = $component->name; | ||||
$uid = (string)$component->UID; | $uid = (string)$component->UID; | ||||
break; | break; | ||||
'size' => strlen($calendarData), | 'size' => strlen($calendarData), | ||||
'componentType' => $componentType, | 'componentType' => $componentType, | ||||
'firstOccurence' => is_null($firstOccurrence) ? null : max(0, $firstOccurrence), | 'firstOccurence' => is_null($firstOccurrence) ? null : max(0, $firstOccurrence), | ||||
'lastOccurence' => $lastOccurrence, | |||||
'lastOccurence' => $lastOccurrence, | |||||
'uid' => $uid, | 'uid' => $uid, | ||||
'classification' => $classification | 'classification' => $classification | ||||
]; | ]; | ||||
* @param int $calendarType | * @param int $calendarType | ||||
* @return array | * @return array | ||||
*/ | */ | ||||
public function getShares($resourceId, $calendarType=self::CALENDAR_TYPE_CALENDAR) { | |||||
public function getShares($resourceId, $calendarType = self::CALENDAR_TYPE_CALENDAR) { | |||||
return $this->calendarSharingBackend->getShares($resourceId); | return $this->calendarSharingBackend->getShares($resourceId); | ||||
} | } | ||||
* @param string $calendarData | * @param string $calendarData | ||||
* @param int $calendarType | * @param int $calendarType | ||||
*/ | */ | ||||
public function updateProperties($calendarId, $objectUri, $calendarData, $calendarType=self::CALENDAR_TYPE_CALENDAR) { | |||||
public function updateProperties($calendarId, $objectUri, $calendarData, $calendarType = self::CALENDAR_TYPE_CALENDAR) { | |||||
$objectId = $this->getCalendarObjectId($calendarId, $objectUri, $calendarType); | $objectId = $this->getCalendarObjectId($calendarId, $objectUri, $calendarType); | ||||
try { | try { |
* @return array | * @return array | ||||
*/ | */ | ||||
public function getACL() { | public function getACL() { | ||||
$acl = [ | |||||
$acl = [ | |||||
[ | [ | ||||
'privilege' => '{DAV:}read', | 'privilege' => '{DAV:}read', | ||||
'principal' => $this->getOwner(), | 'principal' => $this->getOwner(), | ||||
} | } | ||||
if ($this->getOwner() !== parent::getOwner()) { | if ($this->getOwner() !== parent::getOwner()) { | ||||
$acl[] = [ | |||||
$acl[] = [ | |||||
'privilege' => '{DAV:}read', | 'privilege' => '{DAV:}read', | ||||
'principal' => parent::getOwner(), | 'principal' => parent::getOwner(), | ||||
'protected' => true, | 'protected' => true, |
private $pluginManager; | private $pluginManager; | ||||
/** @var bool */ | /** @var bool */ | ||||
private $returnCachedSubscriptions=false; | |||||
private $returnCachedSubscriptions = false; | |||||
public function __construct(BackendInterface $caldavBackend, $principalInfo) { | public function __construct(BackendInterface $caldavBackend, $principalInfo) { | ||||
parent::__construct($caldavBackend, $principalInfo); | parent::__construct($caldavBackend, $principalInfo); | ||||
* @param integer|null $limit | * @param integer|null $limit | ||||
* @param integer|null $offset | * @param integer|null $offset | ||||
*/ | */ | ||||
public function calendarSearch(array $filters, $limit=null, $offset=null) { | |||||
public function calendarSearch(array $filters, $limit = null, $offset = null) { | |||||
$principalUri = $this->principalInfo['uri']; | $principalUri = $this->principalInfo['uri']; | ||||
return $this->caldavBackend->calendarSearch($principalUri, $filters, $limit, $offset); | return $this->caldavBackend->calendarSearch($principalUri, $filters, $limit, $offset); | ||||
} | } |
* @return array an array of events/journals/todos which are arrays of key-value-pairs | * @return array an array of events/journals/todos which are arrays of key-value-pairs | ||||
* @since 13.0.0 | * @since 13.0.0 | ||||
*/ | */ | ||||
public function search($pattern, array $searchProperties=[], array $options=[], $limit=null, $offset=null) { | |||||
public function search($pattern, array $searchProperties = [], array $options = [], $limit = null, $offset = null) { | |||||
return $this->backend->search($this->calendarInfo, $pattern, | return $this->backend->search($this->calendarInfo, $pattern, | ||||
$searchProperties, $options, $limit, $offset); | $searchProperties, $options, $limit, $offset); | ||||
} | } |
* @package OCA\DAV\CalDAV\Proxy | * @package OCA\DAV\CalDAV\Proxy | ||||
*/ | */ | ||||
class ProxyMapper extends QBMapper { | class ProxyMapper extends QBMapper { | ||||
public const PERMISSION_READ = 1; | |||||
public const PERMISSION_READ = 1; | |||||
public const PERMISSION_WRITE = 2; | public const PERMISSION_WRITE = 2; | ||||
/** | /** |
*/ | */ | ||||
public function send(VEvent $vevent, | public function send(VEvent $vevent, | ||||
string $calendarDisplayName, | string $calendarDisplayName, | ||||
array $users=[]): void; | |||||
array $users = []): void; | |||||
} | } |
*/ | */ | ||||
abstract public function send(VEvent $vevent, | abstract public function send(VEvent $vevent, | ||||
string $calendarDisplayName, | string $calendarDisplayName, | ||||
array $users=[]): void; | |||||
array $users = []): void; | |||||
/** | /** | ||||
* @return string | * @return string |
*/ | */ | ||||
public function send(VEvent $vevent, | public function send(VEvent $vevent, | ||||
string $calendarDisplayName, | string $calendarDisplayName, | ||||
array $users=[]):void { | |||||
array $users = []):void { | |||||
$fallbackLanguage = $this->getFallbackLanguage(); | $fallbackLanguage = $this->getFallbackLanguage(); | ||||
$emailAddressesOfSharees = $this->getEMailAddressesOfAllUsersWithWriteAccessToCalendar($users); | $emailAddressesOfSharees = $this->getEMailAddressesOfAllUsersWithWriteAccessToCalendar($users); |
* @throws \Exception | * @throws \Exception | ||||
*/ | */ | ||||
public function send(VEvent $vevent, | public function send(VEvent $vevent, | ||||
string $calendarDisplayName=null, | |||||
array $users=[]):void { | |||||
string $calendarDisplayName = null, | |||||
array $users = []):void { | |||||
if ($this->config->getAppValue('dav', 'sendEventRemindersPush', 'no') !== 'yes') { | if ($this->config->getAppValue('dav', 'sendEventRemindersPush', 'no') !== 'yes') { | ||||
return; | return; | ||||
} | } |
*/ | */ | ||||
private function getRemindersForVAlarm(VAlarm $valarm, | private function getRemindersForVAlarm(VAlarm $valarm, | ||||
array $objectData, | array $objectData, | ||||
string $eventHash=null, | |||||
string $alarmHash=null, | |||||
bool $isRecurring=false, | |||||
bool $isRecurrenceException=false):array { | |||||
string $eventHash = null, | |||||
string $alarmHash = null, | |||||
bool $isRecurring = false, | |||||
bool $isRecurrenceException = false):array { | |||||
if ($eventHash === null) { | if ($eventHash === null) { | ||||
$eventHash = $this->getEventHash($valarm->parent); | $eventHash = $this->getEventHash($valarm->parent); | ||||
} | } |
* @param String[] $metadata | * @param String[] $metadata | ||||
* @return Array | * @return Array | ||||
*/ | */ | ||||
private function rowToPrincipal(array $row, array $metadata=[]):array { | |||||
private function rowToPrincipal(array $row, array $metadata = []):array { | |||||
return array_merge([ | return array_merge([ | ||||
'uri' => $this->principalPrefix . '/' . $row['backend_id'] . '-' . $row['resource_id'], | 'uri' => $this->principalPrefix . '/' . $row['backend_id'] . '-' . $row['resource_id'], | ||||
'{DAV:}displayname' => $row['displayname'], | '{DAV:}displayname' => $row['displayname'], |
$failed = $this->mailer->send($message); | $failed = $this->mailer->send($message); | ||||
$iTipMessage->scheduleStatus = '1.1; Scheduling message is sent via iMip'; | $iTipMessage->scheduleStatus = '1.1; Scheduling message is sent via iMip'; | ||||
if ($failed) { | if ($failed) { | ||||
$this->logger->error('Unable to deliver message to {failed}', ['app' => 'dav', 'failed' => implode(', ', $failed)]); | |||||
$this->logger->error('Unable to deliver message to {failed}', ['app' => 'dav', 'failed' => implode(', ', $failed)]); | |||||
$iTipMessage->scheduleStatus = '5.0; EMail delivery failed'; | $iTipMessage->scheduleStatus = '5.0; EMail delivery failed'; | ||||
} | } | ||||
} catch (\Exception $ex) { | } catch (\Exception $ex) { |
} | } | ||||
$dtstart = $vevent->DTSTART; | $dtstart = $vevent->DTSTART; | ||||
$dtend = $this->getDTEndFromVEvent($vevent); | |||||
$dtend = $this->getDTEndFromVEvent($vevent); | |||||
$uid = $vevent->UID->getValue(); | $uid = $vevent->UID->getValue(); | ||||
$sequence = isset($vevent->SEQUENCE) ? $vevent->SEQUENCE->getValue() : 0; | $sequence = isset($vevent->SEQUENCE) ? $vevent->SEQUENCE->getValue() : 0; | ||||
$recurrenceId = isset($vevent->{'RECURRENCE-ID'}) ? $vevent->{'RECURRENCE-ID'}->serialize() : ''; | $recurrenceId = isset($vevent->{'RECURRENCE-ID'}) ? $vevent->{'RECURRENCE-ID'}->serialize() : ''; | ||||
'start' => $start, | 'start' => $start, | ||||
'end' => $end, | 'end' => $end, | ||||
], | ], | ||||
'comp-filters' => [], | |||||
'prop-filters' => [], | |||||
'comp-filters' => [], | |||||
'prop-filters' => [], | |||||
], | ], | ||||
[ | [ | ||||
'name' => 'VEVENT', | 'name' => 'VEVENT', | ||||
'is-not-defined' => false, | 'is-not-defined' => false, | ||||
'time-range' => null, | 'time-range' => null, | ||||
'comp-filters' => [], | |||||
'prop-filters' => [ | |||||
'comp-filters' => [], | |||||
'prop-filters' => [ | |||||
[ | [ | ||||
'name' => 'UID', | |||||
'name' => 'UID', | |||||
'is-not-defined' => false, | 'is-not-defined' => false, | ||||
'time-range' => null, | |||||
'text-match' => [ | |||||
'time-range' => null, | |||||
'text-match' => [ | |||||
'value' => $ignoreUID, | 'value' => $ignoreUID, | ||||
'negate-condition' => true, | 'negate-condition' => true, | ||||
'collation' => 'i;octet', | 'collation' => 'i;octet', | ||||
* @return string | * @return string | ||||
*/ | */ | ||||
private function stripOffMailTo(string $email): string { | private function stripOffMailTo(string $email): string { | ||||
if (stripos($email, 'mailto:') === 0) { | |||||
if (stripos($email, 'mailto:') === 0) { | |||||
return substr($email, 7); | return substr($email, 7); | ||||
} | } | ||||
*/ | */ | ||||
public static function xmlDeserialize(Reader $reader) { | public static function xmlDeserialize(Reader $reader) { | ||||
$elems = $reader->parseInnerTree([ | $elems = $reader->parseInnerTree([ | ||||
'{http://nextcloud.com/ns}comp-filter' => 'OCA\\DAV\\CalDAV\\Search\\Xml\\Filter\\CompFilter', | |||||
'{http://nextcloud.com/ns}prop-filter' => 'OCA\\DAV\\CalDAV\\Search\\Xml\\Filter\\PropFilter', | |||||
'{http://nextcloud.com/ns}comp-filter' => 'OCA\\DAV\\CalDAV\\Search\\Xml\\Filter\\CompFilter', | |||||
'{http://nextcloud.com/ns}prop-filter' => 'OCA\\DAV\\CalDAV\\Search\\Xml\\Filter\\PropFilter', | |||||
'{http://nextcloud.com/ns}param-filter' => 'OCA\\DAV\\CalDAV\\Search\\Xml\\Filter\\ParamFilter', | '{http://nextcloud.com/ns}param-filter' => 'OCA\\DAV\\CalDAV\\Search\\Xml\\Filter\\ParamFilter', | ||||
'{http://nextcloud.com/ns}search-term' => 'OCA\\DAV\\CalDAV\\Search\\Xml\\Filter\\SearchTermFilter', | |||||
'{http://nextcloud.com/ns}limit' => 'OCA\\DAV\\CalDAV\\Search\\Xml\\Filter\\LimitFilter', | |||||
'{http://nextcloud.com/ns}offset' => 'OCA\\DAV\\CalDAV\\Search\\Xml\\Filter\\OffsetFilter', | |||||
'{DAV:}prop' => 'Sabre\\Xml\\Element\\KeyValue', | |||||
'{http://nextcloud.com/ns}search-term' => 'OCA\\DAV\\CalDAV\\Search\\Xml\\Filter\\SearchTermFilter', | |||||
'{http://nextcloud.com/ns}limit' => 'OCA\\DAV\\CalDAV\\Search\\Xml\\Filter\\LimitFilter', | |||||
'{http://nextcloud.com/ns}offset' => 'OCA\\DAV\\CalDAV\\Search\\Xml\\Filter\\OffsetFilter', | |||||
'{DAV:}prop' => 'Sabre\\Xml\\Element\\KeyValue', | |||||
]); | ]); | ||||
$newProps = [ | $newProps = [ | ||||
'filters' => [], | |||||
'filters' => [], | |||||
'properties' => [], | 'properties' => [], | ||||
'limit' => null, | |||||
'offset' => null | |||||
'limit' => null, | |||||
'offset' => null | |||||
]; | ]; | ||||
if (!is_array($elems)) { | if (!is_array($elems)) { |
/** | /** | ||||
* @var bool | * @var bool | ||||
*/ | */ | ||||
private $enabled=false; | |||||
private $enabled = false; | |||||
/** | /** | ||||
* @var Server | * @var Server |
} | } | ||||
public function getACL() { | public function getACL() { | ||||
$acl = [ | |||||
$acl = [ | |||||
[ | [ | ||||
'privilege' => '{DAV:}read', | 'privilege' => '{DAV:}read', | ||||
'principal' => $this->getOwner(), | 'principal' => $this->getOwner(), | ||||
} | } | ||||
if ($this->getOwner() !== parent::getOwner()) { | if ($this->getOwner() !== parent::getOwner()) { | ||||
$acl[] = [ | |||||
$acl[] = [ | |||||
'privilege' => '{DAV:}read', | 'privilege' => '{DAV:}read', | ||||
'principal' => parent::getOwner(), | 'principal' => parent::getOwner(), | ||||
'protected' => true, | 'protected' => true, |
$query2 = $this->db->getQueryBuilder(); | $query2 = $this->db->getQueryBuilder(); | ||||
$addressBookOr = $query2->expr()->orX(); | |||||
$addressBookOr = $query2->expr()->orX(); | |||||
foreach ($addressBookIds as $addressBookId) { | foreach ($addressBookIds as $addressBookId) { | ||||
$addressBookOr->add($query2->expr()->eq('cp.addressbookid', $query2->createNamedParameter($addressBookId))); | $addressBookOr->add($query2->expr()->eq('cp.addressbookid', $query2->createNamedParameter($addressBookId))); | ||||
} | } |
$elements = explode(' ', $fullName); | $elements = explode(' ', $fullName); | ||||
$result = ['', '', '', '', '']; | $result = ['', '', '', '', '']; | ||||
if (count($elements) > 2) { | if (count($elements) > 2) { | ||||
$result[0] = implode(' ', array_slice($elements, count($elements)-1)); | |||||
$result[0] = implode(' ', array_slice($elements, count($elements) - 1)); | |||||
$result[1] = $elements[0]; | $result[1] = $elements[0]; | ||||
$result[2] = implode(' ', array_slice($elements, 1, count($elements)-2)); | |||||
$result[2] = implode(' ', array_slice($elements, 1, count($elements) - 2)); | |||||
} elseif (count($elements) === 2) { | } elseif (count($elements) === 2) { | ||||
$result[0] = $elements[1]; | $result[0] = $elements[1]; | ||||
$result[1] = $elements[0]; | $result[1] = $elements[0]; |
*/ | */ | ||||
public function getPluginInfo() { | public function getPluginInfo() { | ||||
return [ | return [ | ||||
'name' => $this->getPluginName(), | |||||
'name' => $this->getPluginName(), | |||||
'description' => 'Return a boolean stating if the vcard have a photo property set or not.' | 'description' => 'Return a boolean stating if the vcard have a photo property set or not.' | ||||
]; | ]; | ||||
} | } |
// Get the xml response | // Get the xml response | ||||
$responseBody = $response->getBodyAsString(); | $responseBody = $response->getBodyAsString(); | ||||
$responseXml = $this->server->xml->parse($responseBody); | |||||
$responseXml = $this->server->xml->parse($responseBody); | |||||
// Reduce the vcards into one string | // Reduce the vcards into one string | ||||
$output = array_reduce($responseXml->getResponses(), function ($vcf, $card) { | $output = array_reduce($responseXml->getResponses(), function ($vcf, $card) { | ||||
*/ | */ | ||||
public function getPluginInfo() { | public function getPluginInfo() { | ||||
return [ | return [ | ||||
'name' => $this->getPluginName(), | |||||
'name' => $this->getPluginName(), | |||||
'description' => 'Intercept a multi-get request and return a single vcf file instead.' | 'description' => 'Intercept a multi-get request and return a single vcf file instead.' | ||||
]; | ]; | ||||
} | } |
return [ | return [ | ||||
'Content-Type' => $type, | 'Content-Type' => $type, | ||||
'body' => $val | |||||
'body' => $val | |||||
]; | ]; | ||||
} catch (\Exception $e) { | } catch (\Exception $e) { | ||||
$this->logger->logException($e, [ | $this->logger->logException($e, [ |
$result[self::PROPERTY_NAME_MENTIONS] = $this->composeMentionsPropertyValue(); | $result[self::PROPERTY_NAME_MENTIONS] = $this->composeMentionsPropertyValue(); | ||||
$unread = null; | $unread = null; | ||||
$user = $this->userSession->getUser(); | |||||
$user = $this->userSession->getUser(); | |||||
if (!is_null($user)) { | if (!is_null($user)) { | ||||
$readUntil = $this->commentsManager->getReadMark( | $readUntil = $this->commentsManager->getReadMark( | ||||
$this->comment->getObjectType(), | $this->comment->getObjectType(), | ||||
return [ | return [ | ||||
self::PROPERTY_NAME_MENTION => [ | self::PROPERTY_NAME_MENTION => [ | ||||
self::PROPERTY_NAME_MENTION_TYPE => $mention['type'], | |||||
self::PROPERTY_NAME_MENTION_ID => $mention['id'], | |||||
self::PROPERTY_NAME_MENTION_TYPE => $mention['type'], | |||||
self::PROPERTY_NAME_MENTION_ID => $mention['id'], | |||||
self::PROPERTY_NAME_MENTION_DISPLAYNAME => $displayName, | self::PROPERTY_NAME_MENTION_DISPLAYNAME => $displayName, | ||||
] | ] | ||||
]; | ]; |
// namespace | // namespace | ||||
public const NS_OWNCLOUD = 'http://owncloud.org/ns'; | public const NS_OWNCLOUD = 'http://owncloud.org/ns'; | ||||
public const REPORT_NAME = '{http://owncloud.org/ns}filter-comments'; | |||||
public const REPORT_PARAM_LIMIT = '{http://owncloud.org/ns}limit'; | |||||
public const REPORT_PARAM_OFFSET = '{http://owncloud.org/ns}offset'; | |||||
public const REPORT_NAME = '{http://owncloud.org/ns}filter-comments'; | |||||
public const REPORT_PARAM_LIMIT = '{http://owncloud.org/ns}limit'; | |||||
public const REPORT_PARAM_OFFSET = '{http://owncloud.org/ns}offset'; | |||||
public const REPORT_PARAM_TIMESTAMP = '{http://owncloud.org/ns}datetime'; | public const REPORT_PARAM_TIMESTAMP = '{http://owncloud.org/ns}datetime'; | ||||
/** @var ICommentsManager */ | /** @var ICommentsManager */ |
* @package OCA\DAV\Comments | * @package OCA\DAV\Comments | ||||
*/ | */ | ||||
class EntityCollection extends RootCollection implements IProperties { | class EntityCollection extends RootCollection implements IProperties { | ||||
public const PROPERTY_NAME_READ_MARKER = '{http://owncloud.org/ns}readMarker'; | |||||
public const PROPERTY_NAME_READ_MARKER = '{http://owncloud.org/ns}readMarker'; | |||||
/** @var string */ | /** @var string */ | ||||
protected $id; | protected $id; |
use Sabre\DAV\ServerPlugin; | use Sabre\DAV\ServerPlugin; | ||||
class CommentPropertiesPlugin extends ServerPlugin { | class CommentPropertiesPlugin extends ServerPlugin { | ||||
public const PROPERTY_NAME_HREF = '{http://owncloud.org/ns}comments-href'; | |||||
public const PROPERTY_NAME_COUNT = '{http://owncloud.org/ns}comments-count'; | |||||
public const PROPERTY_NAME_HREF = '{http://owncloud.org/ns}comments-href'; | |||||
public const PROPERTY_NAME_COUNT = '{http://owncloud.org/ns}comments-count'; | |||||
public const PROPERTY_NAME_UNREAD = '{http://owncloud.org/ns}comments-unread'; | public const PROPERTY_NAME_UNREAD = '{http://owncloud.org/ns}comments-unread'; | ||||
/** @var \Sabre\DAV\Server */ | /** @var \Sabre\DAV\Server */ | ||||
* @return mixed|string | * @return mixed|string | ||||
*/ | */ | ||||
public function getCommentsLink(Node $node) { | public function getCommentsLink(Node $node) { | ||||
$href = $this->server->getBaseUri(); | |||||
$href = $this->server->getBaseUri(); | |||||
$entryPoint = strpos($href, '/remote.php/'); | $entryPoint = strpos($href, '/remote.php/'); | ||||
if ($entryPoint === false) { | if ($entryPoint === false) { | ||||
// in case we end up somewhere else, unexpectedly. | // in case we end up somewhere else, unexpectedly. |
// namespace | // namespace | ||||
public const NS_OWNCLOUD = 'http://owncloud.org/ns'; | public const NS_OWNCLOUD = 'http://owncloud.org/ns'; | ||||
public const REPORT_NAME = '{http://owncloud.org/ns}filter-files'; | |||||
public const REPORT_NAME = '{http://owncloud.org/ns}filter-files'; | |||||
public const SYSTEMTAG_PROPERTYNAME = '{http://owncloud.org/ns}systemtag'; | public const SYSTEMTAG_PROPERTYNAME = '{http://owncloud.org/ns}systemtag'; | ||||
public const CIRCLE_PROPERTYNAME = '{http://owncloud.org/ns}circle'; | public const CIRCLE_PROPERTYNAME = '{http://owncloud.org/ns}circle'; | ||||
* @param string|null $comment | * @param string|null $comment | ||||
* @return Message | * @return Message | ||||
*/ | */ | ||||
private function buildITipResponse(array $row, string $partStat, int $guests=null, | |||||
string $comment=null):Message { | |||||
private function buildITipResponse(array $row, string $partStat, int $guests = null, | |||||
string $comment = null):Message { | |||||
$iTipMessage = new Message(); | $iTipMessage = new Message(); | ||||
$iTipMessage->uid = $row['uid']; | $iTipMessage->uid = $row['uid']; | ||||
$iTipMessage->component = 'VEVENT'; | $iTipMessage->component = 'VEVENT'; |
$shares = []; | $shares = []; | ||||
while ($row = $result->fetch()) { | while ($row = $result->fetch()) { | ||||
$p = $this->principalBackend->getPrincipalByPath($row['principaluri']); | $p = $this->principalBackend->getPrincipalByPath($row['principaluri']); | ||||
$shares[]= [ | |||||
$shares[] = [ | |||||
'href' => "principal:${row['principaluri']}", | 'href' => "principal:${row['principaluri']}", | ||||
'commonName' => isset($p['{DAV:}displayname']) ? $p['{DAV:}displayname'] : '', | 'commonName' => isset($p['{DAV:}displayname']) ? $p['{DAV:}displayname'] : '', | ||||
'status' => 1, | 'status' => 1, |
public static function xmlDeserialize(Reader $reader) { | public static function xmlDeserialize(Reader $reader) { | ||||
$elements = $reader->parseInnerTree([ | $elements = $reader->parseInnerTree([ | ||||
'{' . Plugin::NS_OWNCLOUD. '}set' => 'Sabre\\Xml\\Element\\KeyValue', | |||||
'{' . Plugin::NS_OWNCLOUD. '}set' => 'Sabre\\Xml\\Element\\KeyValue', | |||||
'{' . Plugin::NS_OWNCLOUD . '}remove' => 'Sabre\\Xml\\Element\\KeyValue', | '{' . Plugin::NS_OWNCLOUD . '}remove' => 'Sabre\\Xml\\Element\\KeyValue', | ||||
]); | ]); | ||||
$commonName = '{' . Plugin::NS_OWNCLOUD . '}common-name'; | $commonName = '{' . Plugin::NS_OWNCLOUD . '}common-name'; | ||||
$set[] = [ | $set[] = [ | ||||
'href' => $sharee['{DAV:}href'], | |||||
'href' => $sharee['{DAV:}href'], | |||||
'commonName' => isset($sharee[$commonName]) ? $sharee[$commonName] : null, | 'commonName' => isset($sharee[$commonName]) ? $sharee[$commonName] : null, | ||||
'summary' => isset($sharee[$sumElem]) ? $sharee[$sumElem] : null, | |||||
'readOnly' => !array_key_exists('{' . Plugin::NS_OWNCLOUD . '}read-write', $sharee), | |||||
'summary' => isset($sharee[$sumElem]) ? $sharee[$sumElem] : null, | |||||
'readOnly' => !array_key_exists('{' . Plugin::NS_OWNCLOUD . '}read-write', $sharee), | |||||
]; | ]; | ||||
break; | break; | ||||
$formattedDate = $this->l10n->l('date', $dueDateTime, ['width' => 'medium']); | $formattedDate = $this->l10n->l('date', $dueDateTime, ['width' => 'medium']); | ||||
if ($taskComponent->DUE->hasTime()) { | if ($taskComponent->DUE->hasTime()) { | ||||
$formattedTime = $this->l10n->l('time', $dueDateTime, ['width' => 'short']); | |||||
$formattedTime = $this->l10n->l('time', $dueDateTime, ['width' => 'short']); | |||||
return $this->l10n->t('Due on %s by %s', [$formattedDate, $formattedTime]); | return $this->l10n->t('Due on %s by %s', [$formattedDate, $formattedTime]); | ||||
} | } | ||||
$this->server->xml->expects($this->once()) | $this->server->xml->expects($this->once()) | ||||
->method('parse') | ->method('parse') | ||||
->willReturnCallback(function ($requestBody, $url, &$documentType) { | ->willReturnCallback(function ($requestBody, $url, &$documentType) { | ||||
$documentType = '{http://nextcloud.com/ns}disable-birthday-calendar'; | |||||
$documentType = '{http://nextcloud.com/ns}disable-birthday-calendar'; | |||||
}); | }); | ||||
$this->config->expects($this->never()) | $this->config->expects($this->never()) |
} | } | ||||
public function providesSchedulingData() { | public function providesSchedulingData() { | ||||
$data =<<<EOS | |||||
$data = <<<EOS | |||||
BEGIN:VCALENDAR | BEGIN:VCALENDAR | ||||
VERSION:2.0 | VERSION:2.0 | ||||
PRODID:-//Sabre//Sabre VObject 3.5.0//EN | PRODID:-//Sabre//Sabre VObject 3.5.0//EN | ||||
EOD; | EOD; | ||||
$uriCount = count($uris); | $uriCount = count($uris); | ||||
for ($i=0; $i < $uriCount; $i++) { | |||||
for ($i = 0; $i < $uriCount; $i++) { | |||||
$this->backend->createCalendarObject($calendarId, | $this->backend->createCalendarObject($calendarId, | ||||
$uris[$i], $calData[$i]); | $uris[$i], $calData[$i]); | ||||
} | } |
* @param array $replyTo | * @param array $replyTo | ||||
* @return IMessage | * @return IMessage | ||||
*/ | */ | ||||
private function getMessageMock(string $toMail, IEMailTemplate $templateMock, array $replyTo=null):IMessage { | |||||
private function getMessageMock(string $toMail, IEMailTemplate $templateMock, array $replyTo = null):IMessage { | |||||
$message = $this->createMock(IMessage::class); | $message = $this->createMock(IMessage::class); | ||||
$i = 0; | $i = 0; | ||||
return $vcalendar; | return $vcalendar; | ||||
} | } | ||||
private function setupURLGeneratorMock(int $times=1):void { | |||||
private function setupURLGeneratorMock(int $times = 1):void { | |||||
for ($i = 0; $i < $times; $i++) { | for ($i = 0; $i < $times; $i++) { | ||||
$this->urlGenerator | $this->urlGenerator | ||||
->expects($this->at(8 * $i)) | ->expects($this->at(8 * $i)) |
'is_relative' => false, | 'is_relative' => false, | ||||
'notification_date' => 1465344000, | 'notification_date' => 1465344000, | ||||
'is_repeat_based' => false, | 'is_repeat_based' => false, | ||||
'calendardata' => self::CALENDAR_DATA, | |||||
'calendardata' => self::CALENDAR_DATA, | |||||
'displayname' => 'Displayname 123', | 'displayname' => 'Displayname 123', | ||||
'principaluri' => 'principals/users/user001', | 'principaluri' => 'principals/users/user001', | ||||
], | ], |
->with('principal001', 'contact_birthdays', [ | ->with('principal001', 'contact_birthdays', [ | ||||
'{DAV:}displayname' => 'Contact birthdays', | '{DAV:}displayname' => 'Contact birthdays', | ||||
'{http://apple.com/ns/ical/}calendar-color' => '#E9D859', | '{http://apple.com/ns/ical/}calendar-color' => '#E9D859', | ||||
'components' => 'VEVENT', | |||||
'components' => 'VEVENT', | |||||
]); | ]); | ||||
$this->service->ensureCalendarExists('principal001'); | $this->service->ensureCalendarExists('principal001'); | ||||
} | } |
$this->assertArrayHasKey('lastmodified', $card); | $this->assertArrayHasKey('lastmodified', $card); | ||||
$this->assertArrayHasKey('etag', $card); | $this->assertArrayHasKey('etag', $card); | ||||
$this->assertArrayHasKey('size', $card); | $this->assertArrayHasKey('size', $card); | ||||
$this->assertEquals($this->{ 'vcardTest'.($index+1) }, $card['carddata']); | |||||
$this->assertEquals($this->{ 'vcardTest'.($index + 1) }, $card['carddata']); | |||||
} | } | ||||
// delete the card | // delete the card | ||||
$vCardIds = []; | $vCardIds = []; | ||||
$query = $this->db->getQueryBuilder(); | $query = $this->db->getQueryBuilder(); | ||||
for ($i=0; $i < 3; $i++) { | |||||
for ($i = 0; $i < 3; $i++) { | |||||
$query->insert($this->dbCardsTable) | $query->insert($this->dbCardsTable) | ||||
->values( | ->values( | ||||
[ | [ | ||||
'limit' => ['john', ['FN'], ['limit' => 1], [['uri0', 'John Doe']]], | 'limit' => ['john', ['FN'], ['limit' => 1], [['uri0', 'John Doe']]], | ||||
'limit and offset' => ['john', ['FN'], ['limit' => 1, 'offset' => 1], [['uri1', 'John M. Doe']]], | 'limit and offset' => ['john', ['FN'], ['limit' => 1, 'offset' => 1], [['uri1', 'John M. Doe']]], | ||||
'find "_" escaped' => ['_', ['CLOUD'], [], [['uri2', 'find without options']]], | 'find "_" escaped' => ['_', ['CLOUD'], [], [['uri2', 'find without options']]], | ||||
'find not empty CLOUD' => ['%_%', ['CLOUD'], ['escape_like_param'=>false], [['uri0', 'John Doe'], ['uri2', 'find without options']]], | |||||
'find not empty CLOUD' => ['%_%', ['CLOUD'], ['escape_like_param' => false], [['uri0', 'John Doe'], ['uri2', 'find without options']]], | |||||
]; | ]; | ||||
} | } | ||||
public function testGetContact() { | public function testGetContact() { | ||||
$query = $this->db->getQueryBuilder(); | $query = $this->db->getQueryBuilder(); | ||||
for ($i=0; $i<2; $i++) { | |||||
for ($i = 0; $i < 2; $i++) { | |||||
$query->insert($this->dbCardsTable) | $query->insert($this->dbCardsTable) | ||||
->values( | ->values( | ||||
[ | [ |
$parameters = [ | $parameters = [ | ||||
[ | [ | ||||
'name' => '{http://owncloud.org/ns}limit', | |||||
'name' => '{http://owncloud.org/ns}limit', | |||||
'value' => 5, | 'value' => 5, | ||||
], | ], | ||||
[ | [ | ||||
'name' => '{http://owncloud.org/ns}offset', | |||||
'name' => '{http://owncloud.org/ns}offset', | |||||
'value' => 10, | 'value' => 10, | ||||
], | ], | ||||
[ | [ | ||||
$parameters = [ | $parameters = [ | ||||
[ | [ | ||||
'name' => '{http://owncloud.org/ns}limit', | |||||
'name' => '{http://owncloud.org/ns}limit', | |||||
'value' => 5, | 'value' => 5, | ||||
], | ], | ||||
[ | [ | ||||
'name' => '{http://owncloud.org/ns}offset', | |||||
'name' => '{http://owncloud.org/ns}offset', | |||||
'value' => 10, | 'value' => 10, | ||||
], | ], | ||||
[ | [ |
public function nodeProvider() { | public function nodeProvider() { | ||||
$mocks = []; | $mocks = []; | ||||
foreach (['\OCA\DAV\Connector\Sabre\File', '\OCA\DAV\Connector\Sabre\Directory', '\Sabre\DAV\INode'] as $class) { | foreach (['\OCA\DAV\Connector\Sabre\File', '\OCA\DAV\Connector\Sabre\Directory', '\Sabre\DAV\INode'] as $class) { | ||||
$mocks[] = $this->getMockBuilder($class) | |||||
$mocks[] = $this->getMockBuilder($class) | |||||
->disableOriginalConstructor() | ->disableOriginalConstructor() | ||||
->getMock(); | ->getMock(); | ||||
} | } |
$storage = new Temporary([]); | $storage = new Temporary([]); | ||||
$storage->file_put_contents('file.txt', 'old content'); | $storage->file_put_contents('file.txt', 'old content'); | ||||
$noCreateStorage = new PermissionsMask([ | $noCreateStorage = new PermissionsMask([ | ||||
'storage'=> $storage, | |||||
'mask' => Constants::PERMISSION_ALL - Constants::PERMISSION_CREATE | |||||
'storage' => $storage, | |||||
'mask' => Constants::PERMISSION_ALL - Constants::PERMISSION_CREATE | |||||
]); | ]); | ||||
$this->registerMount($this->user, $noCreateStorage, '/' . $this->user . '/files/root'); | $this->registerMount($this->user, $noCreateStorage, '/' . $this->user . '/files/root'); |
$parameters = [ | $parameters = [ | ||||
[ | [ | ||||
'name' => '{DAV:}prop', | |||||
'name' => '{DAV:}prop', | |||||
'value' => [ | 'value' => [ | ||||
['name' => '{DAV:}getcontentlength', 'value' => ''], | ['name' => '{DAV:}getcontentlength', 'value' => ''], | ||||
['name' => '{http://owncloud.org/ns}size', 'value' => ''], | ['name' => '{http://owncloud.org/ns}size', 'value' => ''], | ||||
], | ], | ||||
], | ], | ||||
[ | [ | ||||
'name' => '{http://owncloud.org/ns}filter-rules', | |||||
'name' => '{http://owncloud.org/ns}filter-rules', | |||||
'value' => [ | 'value' => [ | ||||
['name' => '{http://owncloud.org/ns}systemtag', 'value' => '123'], | ['name' => '{http://owncloud.org/ns}systemtag', 'value' => '123'], | ||||
['name' => '{http://owncloud.org/ns}systemtag', 'value' => '456'], | ['name' => '{http://owncloud.org/ns}systemtag', 'value' => '456'], |
$this->assertSame('awesomeUser', $direct->getUserId()); | $this->assertSame('awesomeUser', $direct->getUserId()); | ||||
$this->assertSame(101, $direct->getFileId()); | $this->assertSame(101, $direct->getFileId()); | ||||
$this->assertSame('superduperlongtoken', $direct->getToken()); | $this->assertSame('superduperlongtoken', $direct->getToken()); | ||||
$this->assertSame(42 + 60*60*8, $direct->getExpiration()); | |||||
$this->assertSame(42 + 60 * 60 * 8, $direct->getExpiration()); | |||||
}); | }); | ||||
$this->urlGenerator->method('getAbsoluteURL') | $this->urlGenerator->method('getAbsoluteURL') |
$tonofnodes = []; | $tonofnodes = []; | ||||
$tonofdata = ""; | $tonofdata = ""; | ||||
for ($i = 0; $i < 101; $i++) { | for ($i = 0; $i < 101; $i++) { | ||||
$thisdata = rand(0,100); // variable length and content | |||||
$thisdata = rand(0,100); // variable length and content | |||||
$tonofdata .= $thisdata; | $tonofdata .= $thisdata; | ||||
array_push($tonofnodes, $this->buildNode($i,$thisdata)); | array_push($tonofnodes, $this->buildNode($i,$thisdata)); | ||||
} | } |
if ($this->util->isMasterKeyEnabled()) { | if ($this->util->isMasterKeyEnabled()) { | ||||
$output->writeln('Use master key to decrypt all files'); | $output->writeln('Use master key to decrypt all files'); | ||||
$user = $this->keyManager->getMasterKeyId(); | $user = $this->keyManager->getMasterKeyId(); | ||||
$password =$this->keyManager->getMasterKeyPassword(); | |||||
$password = $this->keyManager->getMasterKeyPassword(); | |||||
} else { | } else { | ||||
$recoveryKeyId = $this->keyManager->getRecoveryKeyId(); | $recoveryKeyId = $this->keyManager->getRecoveryKeyId(); | ||||
if (!empty($user)) { | if (!empty($user)) { |
protected function encryptUsersFiles($uid, ProgressBar $progress, $userCount) { | protected function encryptUsersFiles($uid, ProgressBar $progress, $userCount) { | ||||
$this->setupUserFS($uid); | $this->setupUserFS($uid); | ||||
$directories = []; | $directories = []; | ||||
$directories[] = '/' . $uid . '/files'; | |||||
$directories[] = '/' . $uid . '/files'; | |||||
while ($root = array_pop($directories)) { | while ($root = array_pop($directories)) { | ||||
$content = $this->rootView->getDirectoryContent($root); | $content = $this->rootView->getDirectoryContent($root); |
* @param View $view | * @param View $view | ||||
*/ | */ | ||||
public function setVersion($path, $version, View $view) { | public function setVersion($path, $version, View $view) { | ||||
$fileInfo= $view->getFileInfo($path); | |||||
$fileInfo = $view->getFileInfo($path); | |||||
if ($fileInfo !== false) { | if ($fileInfo !== false) { | ||||
$cache = $fileInfo->getStorage()->getCache(); | $cache = $fileInfo->getStorage()->getCache(); |
$encryptHomeStorage = $util->shouldEncryptHomeStorage(); | $encryptHomeStorage = $util->shouldEncryptHomeStorage(); | ||||
$parameters = [ | $parameters = [ | ||||
'recoveryEnabled' => $recoveryAdminEnabled, | |||||
'initStatus' => $session->getStatus(), | |||||
'recoveryEnabled' => $recoveryAdminEnabled, | |||||
'initStatus' => $session->getStatus(), | |||||
'encryptHomeStorage' => $encryptHomeStorage, | 'encryptHomeStorage' => $encryptHomeStorage, | ||||
'masterKeyEnabled' => $util->isMasterKeyEnabled(), | |||||
'masterKeyEnabled' => $util->isMasterKeyEnabled(), | |||||
]; | ]; | ||||
return new TemplateResponse('encryption', 'settings-admin', $parameters, ''); | return new TemplateResponse('encryption', 'settings-admin', $parameters, ''); |
<span class="msg"></span> | <span class="msg"></span> | ||||
</p> | </p> | ||||
<?php elseif ($_["recoveryEnabled"] && $_["privateKeySet"] && $_["initialized"] === \OCA\Encryption\Session::INIT_SUCCESSFUL): ?> | |||||
<?php elseif ($_["recoveryEnabled"] && $_["privateKeySet"] && $_["initialized"] === \OCA\Encryption\Session::INIT_SUCCESSFUL): ?> | |||||
<br /> | <br /> | ||||
<p id="userEnableRecovery"> | <p id="userEnableRecovery"> | ||||
<label for="userEnableRecovery"><?php p($l->t("Enable password recovery:")); ?></label> | <label for="userEnableRecovery"><?php p($l->t("Enable password recovery:")); ?></label> |
* test parseHeader() | * test parseHeader() | ||||
*/ | */ | ||||
public function testParseHeader() { | public function testParseHeader() { | ||||
$header= 'HBEGIN:foo:bar:cipher:AES-256-CFB:HEND'; | |||||
$header = 'HBEGIN:foo:bar:cipher:AES-256-CFB:HEND'; | |||||
$result = self::invokePrivate($this->crypt, 'parseHeader', [$header]); | $result = self::invokePrivate($this->crypt, 'parseHeader', [$header]); | ||||
$this->assertTrue(is_array($result)); | $this->assertTrue(is_array($result)); |
$this->view->expects($this->at(0))->method('getDirectoryContent') | $this->view->expects($this->at(0))->method('getDirectoryContent') | ||||
->with('/user1/files')->willReturn( | ->with('/user1/files')->willReturn( | ||||
[ | [ | ||||
['name' => 'foo', 'type'=>'dir'], | |||||
['name' => 'bar', 'type'=>'file'], | |||||
['name' => 'foo', 'type' => 'dir'], | |||||
['name' => 'bar', 'type' => 'file'], | |||||
] | ] | ||||
); | ); | ||||
$this->view->expects($this->at(3))->method('getDirectoryContent') | $this->view->expects($this->at(3))->method('getDirectoryContent') | ||||
->with('/user1/files/foo')->willReturn( | ->with('/user1/files/foo')->willReturn( | ||||
[ | [ | ||||
['name' => 'subfile', 'type'=>'file'] | |||||
['name' => 'subfile', 'type' => 'file'] | |||||
] | ] | ||||
); | ); | ||||
$this->keyStorageMock->expects($this->exactly(2)) | $this->keyStorageMock->expects($this->exactly(2)) | ||||
->method('getUserKey') | ->method('getUserKey') | ||||
->willReturnCallback(function ($uid, $keyID, $encryptionModuleId) { | ->willReturnCallback(function ($uid, $keyID, $encryptionModuleId) { | ||||
if ($keyID=== 'privateKey') { | |||||
if ($keyID === 'privateKey') { | |||||
return ''; | return ''; | ||||
} | } | ||||
return 'key'; | return 'key'; |
$query->insert('federated_reshares') | $query->insert('federated_reshares') | ||||
->values( | ->values( | ||||
[ | [ | ||||
'share_id' => $query->createNamedParameter($shareId), | |||||
'share_id' => $query->createNamedParameter($shareId), | |||||
'remote_id' => $query->createNamedParameter($remoteId), | 'remote_id' => $query->createNamedParameter($remoteId), | ||||
] | ] | ||||
); | ); |
$ocsStatus = isset($status['ocs']); | $ocsStatus = isset($status['ocs']); | ||||
$ocsSuccess = $ocsStatus && ($status['ocs']['meta']['statuscode'] === 100 || $status['ocs']['meta']['statuscode'] === 200); | $ocsSuccess = $ocsStatus && ($status['ocs']['meta']['statuscode'] === 100 || $status['ocs']['meta']['statuscode'] === 200); | ||||
if ($result['success'] && (!$ocsStatus ||$ocsSuccess)) { | |||||
if ($result['success'] && (!$ocsStatus || $ocsSuccess)) { | |||||
$event = new FederatedShareAddedEvent($remote); | $event = new FederatedShareAddedEvent($remote); | ||||
$this->eventDispatcher->dispatchTyped($event); | $this->eventDispatcher->dispatchTyped($event); | ||||
return true; | return true; | ||||
* @return array | * @return array | ||||
* @throws \Exception | * @throws \Exception | ||||
*/ | */ | ||||
protected function tryHttpPostToShareEndpoint($remoteDomain, $urlSuffix, array $fields, $action="share") { | |||||
protected function tryHttpPostToShareEndpoint($remoteDomain, $urlSuffix, array $fields, $action = "share") { | |||||
if ($this->addressHandler->urlContainProtocol($remoteDomain) === false) { | if ($this->addressHandler->urlContainProtocol($remoteDomain) === false) { | ||||
$remoteDomain = 'https://' . $remoteDomain; | $remoteDomain = 'https://' . $remoteDomain; | ||||
} | } |
$query->insert($this->dbTable) | $query->insert($this->dbTable) | ||||
->values( | ->values( | ||||
[ | [ | ||||
'url' => $query->createParameter('url'), | |||||
'url' => $query->createParameter('url'), | |||||
'url_hash' => $query->createParameter('url_hash'), | 'url_hash' => $query->createParameter('url_hash'), | ||||
] | ] | ||||
) | ) |
try { | try { | ||||
$result = $ocsAuthApi->getSharedSecret($url, $token); | $result = $ocsAuthApi->getSharedSecret($url, $token); | ||||
$this->assertTrue($ok); | $this->assertTrue($ok); | ||||
$data = $result->getData(); | |||||
$data = $result->getData(); | |||||
$this->assertSame('secret', $data['sharedSecret']); | $this->assertSame('secret', $data['sharedSecret']); | ||||
} catch (OCSForbiddenException $e) { | } catch (OCSForbiddenException $e) { | ||||
$this->assertFalse($ok); | $this->assertFalse($ok); |
class Application extends App implements IBootstrap { | class Application extends App implements IBootstrap { | ||||
public const APP_ID = 'files'; | public const APP_ID = 'files'; | ||||
public function __construct(array $urlParams=[]) { | |||||
public function __construct(array $urlParams = []) { | |||||
parent::__construct(self::APP_ID, $urlParams); | parent::__construct(self::APP_ID, $urlParams); | ||||
} | } | ||||
protected function formatExecTime() { | protected function formatExecTime() { | ||||
$secs = round($this->execTime); | $secs = round($this->execTime); | ||||
# convert seconds into HH:MM:SS form | # convert seconds into HH:MM:SS form | ||||
return sprintf('%02d:%02d:%02d', ($secs/3600), ($secs/60%60), $secs%60); | |||||
return sprintf('%02d:%02d:%02d', ($secs / 3600), ($secs / 60 % 60), $secs % 60); | |||||
} | } | ||||
/** | /** |
protected function formatExecTime() { | protected function formatExecTime() { | ||||
$secs = round($this->execTime); | $secs = round($this->execTime); | ||||
# convert seconds into HH:MM:SS form | # convert seconds into HH:MM:SS form | ||||
return sprintf('%02d:%02d:%02d', ($secs/3600), ($secs/60%60), $secs%60); | |||||
return sprintf('%02d:%02d:%02d', ($secs / 3600), ($secs / 60 % 60), $secs % 60); | |||||
} | } | ||||
/** | /** |
Helper $activityHelper | Helper $activityHelper | ||||
) { | ) { | ||||
parent::__construct($appName, $request); | parent::__construct($appName, $request); | ||||
$this->appName = $appName; | |||||
$this->request = $request; | |||||
$this->urlGenerator = $urlGenerator; | |||||
$this->l10n = $l10n; | |||||
$this->config = $config; | |||||
$this->appName = $appName; | |||||
$this->request = $request; | |||||
$this->urlGenerator = $urlGenerator; | |||||
$this->l10n = $l10n; | |||||
$this->config = $config; | |||||
$this->eventDispatcher = $eventDispatcher; | $this->eventDispatcher = $eventDispatcher; | ||||
$this->userSession = $userSession; | |||||
$this->appManager = $appManager; | |||||
$this->rootFolder = $rootFolder; | |||||
$this->activityHelper = $activityHelper; | |||||
$this->userSession = $userSession; | |||||
$this->appManager = $appManager; | |||||
$this->rootFolder = $rootFolder; | |||||
$this->activityHelper = $activityHelper; | |||||
} | } | ||||
/** | /** | ||||
* @return string | * @return string | ||||
*/ | */ | ||||
protected function renderScript($appName, $scriptName) { | protected function renderScript($appName, $scriptName) { | ||||
$content = ''; | |||||
$appPath = \OC_App::getAppPath($appName); | |||||
$content = ''; | |||||
$appPath = \OC_App::getAppPath($appName); | |||||
$scriptPath = $appPath . '/' . $scriptName; | $scriptPath = $appPath . '/' . $scriptName; | ||||
if (file_exists($scriptPath)) { | if (file_exists($scriptPath)) { | ||||
// TODO: sanitize path / script name ? | // TODO: sanitize path / script name ? | ||||
$favoritesSublistArray = []; | $favoritesSublistArray = []; | ||||
$navBarPositionPosition = 6; | $navBarPositionPosition = 6; | ||||
$currentCount = 0; | |||||
$currentCount = 0; | |||||
foreach ($favElements['folders'] as $dir) { | foreach ($favElements['folders'] as $dir) { | ||||
$link = $this->urlGenerator->linkToRoute('files.view.index', ['dir' => $dir, 'view' => 'files']); | |||||
$link = $this->urlGenerator->linkToRoute('files.view.index', ['dir' => $dir, 'view' => 'files']); | |||||
$sortingValue = ++$currentCount; | $sortingValue = ++$currentCount; | ||||
$element = [ | |||||
'id' => str_replace('/', '-', $dir), | |||||
'view' => 'files', | |||||
'href' => $link, | |||||
'dir' => $dir, | |||||
'order' => $navBarPositionPosition, | |||||
'folderPosition' => $sortingValue, | |||||
'name' => basename($dir), | |||||
'icon' => 'files', | |||||
$element = [ | |||||
'id' => str_replace('/', '-', $dir), | |||||
'view' => 'files', | |||||
'href' => $link, | |||||
'dir' => $dir, | |||||
'order' => $navBarPositionPosition, | |||||
'folderPosition' => $sortingValue, | |||||
'name' => basename($dir), | |||||
'icon' => 'files', | |||||
'quickaccesselement' => 'true' | 'quickaccesselement' => 'true' | ||||
]; | ]; | ||||
$subcontent = $this->renderScript($subitem['appname'], $subitem['script']); | $subcontent = $this->renderScript($subitem['appname'], $subitem['script']); | ||||
} | } | ||||
$contentItems[$subitem['id']] = [ | $contentItems[$subitem['id']] = [ | ||||
'id' => $subitem['id'], | |||||
'id' => $subitem['id'], | |||||
'content' => $subcontent | 'content' => $subcontent | ||||
]; | ]; | ||||
} | } | ||||
} | } | ||||
$contentItems[$item['id']] = [ | $contentItems[$item['id']] = [ | ||||
'id' => $item['id'], | |||||
'id' => $item['id'], | |||||
'content' => $content | 'content' => $content | ||||
]; | ]; | ||||
} | } | ||||
$this->eventDispatcher->dispatchTyped(new LoadViewer()); | $this->eventDispatcher->dispatchTyped(new LoadViewer()); | ||||
} | } | ||||
$params = []; | |||||
$params['usedSpacePercent'] = (int) $storageInfo['relative']; | |||||
$params['owner'] = $storageInfo['owner'] ?? ''; | |||||
$params['ownerDisplayName'] = $storageInfo['ownerDisplayName'] ?? ''; | |||||
$params['isPublic'] = false; | |||||
$params['allowShareWithLink'] = $this->config->getAppValue('core', 'shareapi_allow_links', 'yes'); | |||||
$params['defaultFileSorting'] = $this->config->getUserValue($user, 'files', 'file_sorting', 'name'); | |||||
$params = []; | |||||
$params['usedSpacePercent'] = (int) $storageInfo['relative']; | |||||
$params['owner'] = $storageInfo['owner'] ?? ''; | |||||
$params['ownerDisplayName'] = $storageInfo['ownerDisplayName'] ?? ''; | |||||
$params['isPublic'] = false; | |||||
$params['allowShareWithLink'] = $this->config->getAppValue('core', 'shareapi_allow_links', 'yes'); | |||||
$params['defaultFileSorting'] = $this->config->getUserValue($user, 'files', 'file_sorting', 'name'); | |||||
$params['defaultFileSortingDirection'] = $this->config->getUserValue($user, 'files', 'file_sorting_direction', 'asc'); | $params['defaultFileSortingDirection'] = $this->config->getUserValue($user, 'files', 'file_sorting_direction', 'asc'); | ||||
$params['showgridview'] = $this->config->getUserValue($user, 'files', 'show_grid', false); | |||||
$params['isIE'] = \OCP\Util::isIE(); | |||||
$showHidden = (bool) $this->config->getUserValue($this->userSession->getUser()->getUID(), 'files', 'show_hidden', false); | |||||
$params['showHiddenFiles'] = $showHidden ? 1 : 0; | |||||
$params['fileNotFound'] = $fileNotFound ? 1 : 0; | |||||
$params['appNavigation'] = $nav; | |||||
$params['appContents'] = $contentItems; | |||||
$params['hiddenFields'] = $event->getHiddenFields(); | |||||
$params['showgridview'] = $this->config->getUserValue($user, 'files', 'show_grid', false); | |||||
$params['isIE'] = \OCP\Util::isIE(); | |||||
$showHidden = (bool) $this->config->getUserValue($this->userSession->getUser()->getUID(), 'files', 'show_hidden', false); | |||||
$params['showHiddenFiles'] = $showHidden ? 1 : 0; | |||||
$params['fileNotFound'] = $fileNotFound ? 1 : 0; | |||||
$params['appNavigation'] = $nav; | |||||
$params['appContents'] = $contentItems; | |||||
$params['hiddenFields'] = $event->getHiddenFields(); | |||||
$response = new TemplateResponse( | $response = new TemplateResponse( | ||||
$this->appName, | $this->appName, | ||||
* @throws \OCP\Files\NotFoundException | * @throws \OCP\Files\NotFoundException | ||||
*/ | */ | ||||
private function redirectToFile($fileId) { | private function redirectToFile($fileId) { | ||||
$uid = $this->userSession->getUser()->getUID(); | |||||
$uid = $this->userSession->getUser()->getUID(); | |||||
$baseFolder = $this->rootFolder->getUserFolder($uid); | $baseFolder = $this->rootFolder->getUserFolder($uid); | ||||
$files = $baseFolder->getById($fileId); | |||||
$params = []; | |||||
$files = $baseFolder->getById($fileId); | |||||
$params = []; | |||||
if (empty($files) && $this->appManager->isEnabledForUser('files_trashbin')) { | if (empty($files) && $this->appManager->isEnabledForUser('files_trashbin')) { | ||||
$baseFolder = $this->rootFolder->get($uid . '/files_trashbin/files/'); | |||||
$files = $baseFolder->getById($fileId); | |||||
$baseFolder = $this->rootFolder->get($uid . '/files_trashbin/files/'); | |||||
$files = $baseFolder->getById($fileId); | |||||
$params['view'] = 'trashbin'; | $params['view'] = 'trashbin'; | ||||
} | } | ||||
return [ | return [ | ||||
'uploadMaxFilesize' => $maxUploadFileSize, | 'uploadMaxFilesize' => $maxUploadFileSize, | ||||
'maxHumanFilesize' => $maxHumanFileSize, | |||||
'maxHumanFilesize' => $maxHumanFileSize, | |||||
'freeSpace' => $storageInfo['free'], | 'freeSpace' => $storageInfo['free'], | ||||
'quota' => $storageInfo['quota'], | 'quota' => $storageInfo['quota'], | ||||
'used' => $storageInfo['used'], | 'used' => $storageInfo['used'], | ||||
'usedSpacePercent' => (int)$storageInfo['relative'], | |||||
'usedSpacePercent' => (int)$storageInfo['relative'], | |||||
'owner' => $storageInfo['owner'], | 'owner' => $storageInfo['owner'], | ||||
'ownerDisplayName' => $storageInfo['ownerDisplayName'], | 'ownerDisplayName' => $storageInfo['ownerDisplayName'], | ||||
'mountType' => $storageInfo['mountType'], | 'mountType' => $storageInfo['mountType'], |
public function __construct($params) { | public function __construct($params) { | ||||
if (isset($params['host']) && isset($params['user']) && isset($params['password'])) { | if (isset($params['host']) && isset($params['user']) && isset($params['password'])) { | ||||
$this->host=$params['host']; | |||||
$this->user=$params['user']; | |||||
$this->password=$params['password']; | |||||
$this->host = $params['host']; | |||||
$this->user = $params['user']; | |||||
$this->password = $params['password']; | |||||
if (isset($params['secure'])) { | if (isset($params['secure'])) { | ||||
$this->secure = $params['secure']; | $this->secure = $params['secure']; | ||||
} else { | } else { | ||||
$this->secure = false; | $this->secure = false; | ||||
} | } | ||||
$this->root=isset($params['root'])?$params['root']:'/'; | |||||
if (! $this->root || $this->root[0]!=='/') { | |||||
$this->root='/'.$this->root; | |||||
$this->root = isset($params['root'])?$params['root']:'/'; | |||||
if (! $this->root || $this->root[0] !== '/') { | |||||
$this->root = '/'.$this->root; | |||||
} | } | ||||
if (substr($this->root, -1) !== '/') { | if (substr($this->root, -1) !== '/') { | ||||
$this->root .= '/'; | $this->root .= '/'; | ||||
* @return string | * @return string | ||||
*/ | */ | ||||
public function constructUrl($path) { | public function constructUrl($path) { | ||||
$url='ftp'; | |||||
$url = 'ftp'; | |||||
if ($this->secure) { | if ($this->secure) { | ||||
$url.='s'; | |||||
$url .= 's'; | |||||
} | } | ||||
$url.='://'.urlencode($this->user).':'.urlencode($this->password).'@'.$this->host.$this->root.$path; | |||||
$url .= '://'.urlencode($this->user).':'.urlencode($this->password).'@'.$this->host.$this->root.$path; | |||||
return $url; | return $url; | ||||
} | } | ||||
case 'c': | case 'c': | ||||
case 'c+': | case 'c+': | ||||
//emulate these | //emulate these | ||||
if (strrpos($path, '.')!==false) { | |||||
$ext=substr($path, strrpos($path, '.')); | |||||
if (strrpos($path, '.') !== false) { | |||||
$ext = substr($path, strrpos($path, '.')); | |||||
} else { | } else { | ||||
$ext=''; | |||||
$ext = ''; | |||||
} | } | ||||
$tmpFile = \OC::$server->getTempManager()->getTemporaryFile(); | $tmpFile = \OC::$server->getTempManager()->getTemporaryFile(); | ||||
if ($this->file_exists($path)) { | if ($this->file_exists($path)) { |
// Register sftp:// | // Register sftp:// | ||||
Stream::register(); | Stream::register(); | ||||
$parsedHost = $this->splitHost($params['host']); | |||||
$parsedHost = $this->splitHost($params['host']); | |||||
$this->host = $parsedHost[0]; | $this->host = $parsedHost[0]; | ||||
$this->port = $parsedHost[1]; | $this->port = $parsedHost[1]; | ||||
/** | /** | ||||
* {@inheritdoc} | * {@inheritdoc} | ||||
*/ | */ | ||||
public function touch($path, $mtime=null) { | |||||
public function touch($path, $mtime = null) { | |||||
try { | try { | ||||
if (!is_null($mtime)) { | if (!is_null($mtime)) { | ||||
return false; | return false; |
* @param Backend $backend | * @param Backend $backend | ||||
*/ | */ | ||||
public function setBackend(Backend $backend) { | public function setBackend(Backend $backend) { | ||||
$this->backend= $backend; | |||||
$this->backend = $backend; | |||||
} | } | ||||
/** | /** |
*/ | */ | ||||
public function getForm() { | public function getForm() { | ||||
$parameters = [ | $parameters = [ | ||||
'encryptionEnabled' => $this->encryptionManager->isEnabled(), | |||||
'visibilityType' => BackendService::VISIBILITY_ADMIN, | |||||
'storages' => $this->globalStoragesService->getStorages(), | |||||
'backends' => $this->backendService->getAvailableBackends(), | |||||
'authMechanisms' => $this->backendService->getAuthMechanisms(), | |||||
'dependencies' => \OCA\Files_External\MountConfig::dependencyMessage($this->backendService->getBackends()), | |||||
'allowUserMounting' => $this->backendService->isUserMountingAllowed(), | |||||
'globalCredentials' => $this->globalAuth->getAuth(''), | |||||
'encryptionEnabled' => $this->encryptionManager->isEnabled(), | |||||
'visibilityType' => BackendService::VISIBILITY_ADMIN, | |||||
'storages' => $this->globalStoragesService->getStorages(), | |||||
'backends' => $this->backendService->getAvailableBackends(), | |||||
'authMechanisms' => $this->backendService->getAuthMechanisms(), | |||||
'dependencies' => \OCA\Files_External\MountConfig::dependencyMessage($this->backendService->getBackends()), | |||||
'allowUserMounting' => $this->backendService->isUserMountingAllowed(), | |||||
'globalCredentials' => $this->globalAuth->getAuth(''), | |||||
'globalCredentialsUid' => '', | 'globalCredentialsUid' => '', | ||||
]; | ]; | ||||
$uid = $this->userSession->getUser()->getUID(); | $uid = $this->userSession->getUser()->getUID(); | ||||
$parameters = [ | $parameters = [ | ||||
'encryptionEnabled' => $this->encryptionManager->isEnabled(), | |||||
'visibilityType' => BackendService::VISIBILITY_PERSONAL, | |||||
'storages' => $this->userGlobalStoragesService->getStorages(), | |||||
'backends' => $this->backendService->getAvailableBackends(), | |||||
'authMechanisms' => $this->backendService->getAuthMechanisms(), | |||||
'dependencies' => \OCA\Files_External\MountConfig::dependencyMessage($this->backendService->getBackends()), | |||||
'allowUserMounting' => $this->backendService->isUserMountingAllowed(), | |||||
'globalCredentials' => $this->globalAuth->getAuth($uid), | |||||
'encryptionEnabled' => $this->encryptionManager->isEnabled(), | |||||
'visibilityType' => BackendService::VISIBILITY_PERSONAL, | |||||
'storages' => $this->userGlobalStoragesService->getStorages(), | |||||
'backends' => $this->backendService->getAvailableBackends(), | |||||
'authMechanisms' => $this->backendService->getAuthMechanisms(), | |||||
'dependencies' => \OCA\Files_External\MountConfig::dependencyMessage($this->backendService->getBackends()), | |||||
'allowUserMounting' => $this->backendService->isUserMountingAllowed(), | |||||
'globalCredentials' => $this->globalAuth->getAuth($uid), | |||||
'globalCredentialsUid' => $uid, | 'globalCredentialsUid' => $uid, | ||||
]; | ]; | ||||
'publickey' => 'MyPublicKey', | 'publickey' => 'MyPublicKey', | ||||
]); | ]); | ||||
$expected = new JSONResponse( | |||||
$expected = new JSONResponse( | |||||
[ | [ | ||||
'data' => [ | 'data' => [ | ||||
'private_key' => 'MyPrivateKey', | 'private_key' => 'MyPrivateKey', |
->with('') | ->with('') | ||||
->willReturn('asdf:asdf'); | ->willReturn('asdf:asdf'); | ||||
$params = [ | $params = [ | ||||
'encryptionEnabled' => false, | |||||
'visibilityType' => BackendService::VISIBILITY_ADMIN, | |||||
'storages' => ['a', 'b', 'c'], | |||||
'backends' => ['d', 'e', 'f'], | |||||
'authMechanisms' => ['g', 'h', 'i'], | |||||
'dependencies' => \OCA\Files_External\MountConfig::dependencyMessage($this->backendService->getBackends()), | |||||
'allowUserMounting' => true, | |||||
'globalCredentials' => 'asdf:asdf', | |||||
'encryptionEnabled' => false, | |||||
'visibilityType' => BackendService::VISIBILITY_ADMIN, | |||||
'storages' => ['a', 'b', 'c'], | |||||
'backends' => ['d', 'e', 'f'], | |||||
'authMechanisms' => ['g', 'h', 'i'], | |||||
'dependencies' => \OCA\Files_External\MountConfig::dependencyMessage($this->backendService->getBackends()), | |||||
'allowUserMounting' => true, | |||||
'globalCredentials' => 'asdf:asdf', | |||||
'globalCredentialsUid' => '', | 'globalCredentialsUid' => '', | ||||
]; | ]; | ||||
$expected = new TemplateResponse('files_external', 'settings', $params, ''); | $expected = new TemplateResponse('files_external', 'settings', $params, ''); |
} | } | ||||
public function testConstructUrl() { | public function testConstructUrl() { | ||||
$config = [ 'host' => 'localhost', | |||||
$config = [ 'host' => 'localhost', | |||||
'user' => 'ftp', | 'user' => 'ftp', | ||||
'password' => 'ftp', | 'password' => 'ftp', | ||||
'root' => '/', | 'root' => '/', |
// this is now more a template now for your private configurations | // this is now more a template now for your private configurations | ||||
return [ | return [ | ||||
'ftp'=>[ | |||||
'run'=>false, | |||||
'host'=>'localhost', | |||||
'user'=>'test', | |||||
'password'=>'test', | |||||
'root'=>'/test', | |||||
'ftp' => [ | |||||
'run' => false, | |||||
'host' => 'localhost', | |||||
'user' => 'test', | |||||
'password' => 'test', | |||||
'root' => '/test', | |||||
], | ], | ||||
'webdav'=>[ | |||||
'run'=>false, | |||||
'host'=>'localhost', | |||||
'user'=>'test', | |||||
'password'=>'test', | |||||
'root'=>'', | |||||
'webdav' => [ | |||||
'run' => false, | |||||
'host' => 'localhost', | |||||
'user' => 'test', | |||||
'password' => 'test', | |||||
'root' => '', | |||||
// wait delay in seconds after write operations | // wait delay in seconds after write operations | ||||
// (only in tests) | // (only in tests) | ||||
// set to higher value for lighttpd webdav | // set to higher value for lighttpd webdav | ||||
'wait'=> 0 | |||||
'wait' => 0 | |||||
], | ], | ||||
'owncloud'=>[ | |||||
'run'=>false, | |||||
'host'=>'localhost/owncloud', | |||||
'user'=>'test', | |||||
'password'=>'test', | |||||
'root'=>'', | |||||
'owncloud' => [ | |||||
'run' => false, | |||||
'host' => 'localhost/owncloud', | |||||
'user' => 'test', | |||||
'password' => 'test', | |||||
'root' => '', | |||||
], | ], | ||||
'swift' => [ | 'swift' => [ | ||||
'run' => false, | 'run' => false, | ||||
//'url' => 'https://identity.api.rackspacecloud.com/v2.0/', //to be used with Rackspace Cloud Files and OpenStack Object Storage | //'url' => 'https://identity.api.rackspacecloud.com/v2.0/', //to be used with Rackspace Cloud Files and OpenStack Object Storage | ||||
//'timeout' => 5 // timeout of HTTP requests in seconds | //'timeout' => 5 // timeout of HTTP requests in seconds | ||||
], | ], | ||||
'smb'=>[ | |||||
'run'=>false, | |||||
'user'=>'test', | |||||
'password'=>'test', | |||||
'host'=>'localhost', | |||||
'share'=>'/test', | |||||
'root'=>'/test/', | |||||
'smb' => [ | |||||
'run' => false, | |||||
'user' => 'test', | |||||
'password' => 'test', | |||||
'host' => 'localhost', | |||||
'share' => '/test', | |||||
'root' => '/test/', | |||||
], | ], | ||||
'amazons3'=>[ | |||||
'run'=>false, | |||||
'key'=>'test', | |||||
'secret'=>'test', | |||||
'bucket'=>'bucket' | |||||
'amazons3' => [ | |||||
'run' => false, | |||||
'key' => 'test', | |||||
'secret' => 'test', | |||||
'bucket' => 'bucket' | |||||
//'hostname' => 'your.host.name', | //'hostname' => 'your.host.name', | ||||
//'port' => '443', | //'port' => '443', | ||||
//'use_ssl' => 'true', | //'use_ssl' => 'true', | ||||
//'test'=>'true', | //'test'=>'true', | ||||
//'timeout'=>20 | //'timeout'=>20 | ||||
], | ], | ||||
'sftp' => [ | |||||
'run'=>false, | |||||
'host'=>'localhost', | |||||
'user'=>'test', | |||||
'password'=>'test', | |||||
'root'=>'/test' | |||||
'sftp' => [ | |||||
'run' => false, | |||||
'host' => 'localhost', | |||||
'user' => 'test', | |||||
'password' => 'test', | |||||
'root' => '/test' | |||||
], | ], | ||||
'sftp_key' => [ | |||||
'run'=>false, | |||||
'host'=>'localhost', | |||||
'user'=>'test', | |||||
'public_key'=>'ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQDJPTvz3OLonF2KSGEKP/nd4CPmRYvemG2T4rIiNYjDj0U5y+2sKEWbjiUlQl2bsqYuVoJ+/UNJlGQbbZ08kQirFeo1GoWBzqioaTjUJfbLN6TzVVKXxR9YIVmH7Ajg2iEeGCndGgbmnPfj+kF9TR9IH8vMVvtubQwf7uEwB0ALhw== phpseclib-generated-key', | |||||
'private_key'=>'test', | |||||
'root'=>'/test' | |||||
'sftp_key' => [ | |||||
'run' => false, | |||||
'host' => 'localhost', | |||||
'user' => 'test', | |||||
'public_key' => 'ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQDJPTvz3OLonF2KSGEKP/nd4CPmRYvemG2T4rIiNYjDj0U5y+2sKEWbjiUlQl2bsqYuVoJ+/UNJlGQbbZ08kQirFeo1GoWBzqioaTjUJfbLN6TzVVKXxR9YIVmH7Ajg2iEeGCndGgbmnPfj+kF9TR9IH8vMVvtubQwf7uEwB0ALhw== phpseclib-generated-key', | |||||
'private_key' => 'test', | |||||
'root' => '/test' | |||||
], | ], | ||||
]; | ]; |
*/ | */ | ||||
[ | [ | ||||
'name' => 'ShareAPI#getShares', | 'name' => 'ShareAPI#getShares', | ||||
'url' => '/api/v1/shares', | |||||
'url' => '/api/v1/shares', | |||||
'verb' => 'GET', | 'verb' => 'GET', | ||||
], | ], | ||||
[ | [ | ||||
'name' => 'ShareAPI#getInheritedShares', | 'name' => 'ShareAPI#getInheritedShares', | ||||
'url' => '/api/v1/shares/inherited', | |||||
'url' => '/api/v1/shares/inherited', | |||||
'verb' => 'GET', | 'verb' => 'GET', | ||||
], | ], | ||||
[ | [ | ||||
'name' => 'ShareAPI#createShare', | 'name' => 'ShareAPI#createShare', | ||||
'url' => '/api/v1/shares', | |||||
'url' => '/api/v1/shares', | |||||
'verb' => 'POST', | 'verb' => 'POST', | ||||
], | ], | ||||
[ | [ | ||||
'name' => 'ShareAPI#pendingShares', | 'name' => 'ShareAPI#pendingShares', | ||||
'url' => '/api/v1/shares/pending', | |||||
'url' => '/api/v1/shares/pending', | |||||
'verb' => 'GET', | 'verb' => 'GET', | ||||
], | ], | ||||
[ | [ | ||||
'name' => 'ShareAPI#getShare', | 'name' => 'ShareAPI#getShare', | ||||
'url' => '/api/v1/shares/{id}', | |||||
'url' => '/api/v1/shares/{id}', | |||||
'verb' => 'GET', | 'verb' => 'GET', | ||||
], | ], | ||||
[ | [ | ||||
'name' => 'ShareAPI#updateShare', | 'name' => 'ShareAPI#updateShare', | ||||
'url' => '/api/v1/shares/{id}', | |||||
'url' => '/api/v1/shares/{id}', | |||||
'verb' => 'PUT', | 'verb' => 'PUT', | ||||
], | ], | ||||
[ | [ | ||||
'name' => 'ShareAPI#deleteShare', | 'name' => 'ShareAPI#deleteShare', | ||||
'url' => '/api/v1/shares/{id}', | |||||
'url' => '/api/v1/shares/{id}', | |||||
'verb' => 'DELETE', | 'verb' => 'DELETE', | ||||
], | ], | ||||
[ | [ | ||||
'name' => 'ShareAPI#acceptShare', | 'name' => 'ShareAPI#acceptShare', | ||||
'url' => '/api/v1/shares/pending/{id}', | |||||
'url' => '/api/v1/shares/pending/{id}', | |||||
'verb' => 'POST', | 'verb' => 'POST', | ||||
], | ], | ||||
/* | /* | ||||
*/ | */ | ||||
[ | [ | ||||
'name' => 'DeletedShareAPI#index', | 'name' => 'DeletedShareAPI#index', | ||||
'url' => '/api/v1/deletedshares', | |||||
'url' => '/api/v1/deletedshares', | |||||
'verb' => 'GET', | 'verb' => 'GET', | ||||
], | ], | ||||
[ | [ | ||||
'name' => 'DeletedShareAPI#undelete', | 'name' => 'DeletedShareAPI#undelete', | ||||
'url' => '/api/v1/deletedshares/{id}', | |||||
'url' => '/api/v1/deletedshares/{id}', | |||||
'verb' => 'POST', | 'verb' => 'POST', | ||||
], | ], | ||||
/* | /* |
//Federated sharing | //Federated sharing | ||||
$res['federation'] = [ | $res['federation'] = [ | ||||
'outgoing' => $this->config->getAppValue('files_sharing', 'outgoing_server2server_share_enabled', 'yes') === 'yes', | |||||
'outgoing' => $this->config->getAppValue('files_sharing', 'outgoing_server2server_share_enabled', 'yes') === 'yes', | |||||
'incoming' => $this->config->getAppValue('files_sharing', 'incoming_server2server_share_enabled', 'yes') === 'yes', | 'incoming' => $this->config->getAppValue('files_sharing', 'incoming_server2server_share_enabled', 'yes') === 'yes', | ||||
'expire_date' => ['enabled' => true] | 'expire_date' => ['enabled' => true] | ||||
]; | ]; |
* @return Mount|null | * @return Mount|null | ||||
* @throws \Doctrine\DBAL\DBALException | * @throws \Doctrine\DBAL\DBALException | ||||
*/ | */ | ||||
public function addShare($remote, $token, $password, $name, $owner, $shareType, $accepted=false, $user = null, $remoteId = -1, $parent = -1) { | |||||
public function addShare($remote, $token, $password, $name, $owner, $shareType, $accepted = false, $user = null, $remoteId = -1, $parent = -1) { | |||||
$user = $user ? $user : $this->uid; | $user = $user ? $user : $this->uid; | ||||
$accepted = $accepted ? IShare::STATUS_ACCEPTED : IShare::STATUS_PENDING; | $accepted = $accepted ? IShare::STATUS_ACCEPTED : IShare::STATUS_PENDING; | ||||
$name = Filesystem::normalizePath('/' . $name); | $name = Filesystem::normalizePath('/' . $name); | ||||
$mountPoint = $tmpMountPointName; | $mountPoint = $tmpMountPointName; | ||||
$hash = md5($tmpMountPointName); | $hash = md5($tmpMountPointName); | ||||
$data = [ | $data = [ | ||||
'remote' => $remote, | |||||
'share_token' => $token, | |||||
'password' => $password, | |||||
'name' => $name, | |||||
'owner' => $owner, | |||||
'user' => $user, | |||||
'mountpoint' => $mountPoint, | |||||
'mountpoint_hash' => $hash, | |||||
'accepted' => $accepted, | |||||
'remote_id' => $remoteId, | |||||
'share_type' => $shareType, | |||||
'remote' => $remote, | |||||
'share_token' => $token, | |||||
'password' => $password, | |||||
'name' => $name, | |||||
'owner' => $owner, | |||||
'user' => $user, | |||||
'mountpoint' => $mountPoint, | |||||
'mountpoint_hash' => $hash, | |||||
'accepted' => $accepted, | |||||
'remote_id' => $remoteId, | |||||
'share_type' => $shareType, | |||||
]; | ]; | ||||
$i = 1; | $i = 1; | ||||
$this->writeShareToDb($remote, $token, $password, $name, $owner, $user, $mountPoint, $hash, $accepted, $remoteId, $parent, $shareType); | $this->writeShareToDb($remote, $token, $password, $name, $owner, $user, $mountPoint, $hash, $accepted, $remoteId, $parent, $shareType); | ||||
$options = [ | $options = [ | ||||
'remote' => $remote, | |||||
'token' => $token, | |||||
'password' => $password, | |||||
'mountpoint' => $mountPoint, | |||||
'owner' => $owner | |||||
'remote' => $remote, | |||||
'token' => $token, | |||||
'password' => $password, | |||||
'mountpoint' => $mountPoint, | |||||
'owner' => $owner | |||||
]; | ]; | ||||
return $this->mountShare($options); | return $this->mountShare($options); | ||||
} | } |
$returnValue = false; | $returnValue = false; | ||||
} | } | ||||
$cache->set($url, $returnValue, 60*60*24); | |||||
$cache->set($url, $returnValue, 60 * 60 * 24); | |||||
return $returnValue; | return $returnValue; | ||||
} | } | ||||
'id' => $notification->getObjectId(), | 'id' => $notification->getObjectId(), | ||||
'name' => $share->getTarget(), | 'name' => $share->getTarget(), | ||||
], | ], | ||||
'user' => [ | |||||
'user' => [ | |||||
'type' => 'user', | 'type' => 'user', | ||||
'id' => $sharer->getUID(), | 'id' => $sharer->getUID(), | ||||
'name' => $sharer->getDisplayName(), | 'name' => $sharer->getDisplayName(), | ||||
'id' => $group->getGID(), | 'id' => $group->getGID(), | ||||
'name' => $group->getDisplayName(), | 'name' => $group->getDisplayName(), | ||||
], | ], | ||||
'user' => [ | |||||
'user' => [ | |||||
'type' => 'user', | 'type' => 'user', | ||||
'id' => $sharer->getUID(), | 'id' => $sharer->getUID(), | ||||
'name' => $sharer->getDisplayName(), | 'name' => $sharer->getDisplayName(), |
* @param string $newPath new path relative to data/user/files | * @param string $newPath new path relative to data/user/files | ||||
*/ | */ | ||||
private static function renameChildren($oldPath, $newPath) { | private static function renameChildren($oldPath, $newPath) { | ||||
$absNewPath = \OC\Files\Filesystem::normalizePath('/' . \OCP\User::getUser() . '/files/' . $newPath); | |||||
$absOldPath = \OC\Files\Filesystem::normalizePath('/' . \OCP\User::getUser() . '/files/' . $oldPath); | |||||
$absNewPath = \OC\Files\Filesystem::normalizePath('/' . \OCP\User::getUser() . '/files/' . $newPath); | |||||
$absOldPath = \OC\Files\Filesystem::normalizePath('/' . \OCP\User::getUser() . '/files/' . $oldPath); | |||||
$mountManager = \OC\Files\Filesystem::getMountManager(); | $mountManager = \OC\Files\Filesystem::getMountManager(); | ||||
$mountedShares = $mountManager->findIn('/' . \OCP\User::getUser() . '/files/' . $oldPath); | $mountedShares = $mountManager->findIn('/' . \OCP\User::getUser() . '/files/' . $oldPath); |
\OC::$server->getConfig()->setAppValue('core', 'shareapi_expire_after_n_days', '7'); | \OC::$server->getConfig()->setAppValue('core', 'shareapi_expire_after_n_days', '7'); | ||||
$this->folder = self::TEST_FOLDER_NAME; | $this->folder = self::TEST_FOLDER_NAME; | ||||
$this->subfolder = '/subfolder_share_api_test'; | |||||
$this->subfolder = '/subfolder_share_api_test'; | |||||
$this->subsubfolder = '/subsubfolder_share_api_test'; | $this->subsubfolder = '/subsubfolder_share_api_test'; | ||||
$this->filename = '/share-api-test.txt'; | $this->filename = '/share-api-test.txt'; | ||||
$share3->setStatus(IShare::STATUS_ACCEPTED); | $share3->setStatus(IShare::STATUS_ACCEPTED); | ||||
$this->shareManager->updateShare($share3); | $this->shareManager->updateShare($share3); | ||||
$testValues=[ | |||||
$testValues = [ | |||||
['query' => $this->folder, | ['query' => $this->folder, | ||||
'expectedResult' => $this->folder . $this->filename], | 'expectedResult' => $this->folder . $this->filename], | ||||
['query' => $this->folder . $this->subfolder, | ['query' => $this->folder . $this->subfolder, |
*/ | */ | ||||
public function createShare($id, $shareType, $sharedWith, $sharedBy, $shareOwner, $path, $permissions, | public function createShare($id, $shareType, $sharedWith, $sharedBy, $shareOwner, $path, $permissions, | ||||
$shareTime, $expiration, $parent, $target, $mail_send, $note = '', $token=null, | |||||
$password=null, $label = '') { | |||||
$shareTime, $expiration, $parent, $target, $mail_send, $note = '', $token = null, | |||||
$password = null, $label = '') { | |||||
$share = $this->getMockBuilder(IShare::class)->getMock(); | $share = $this->getMockBuilder(IShare::class)->getMock(); | ||||
$share->method('getId')->willReturn($id); | $share->method('getId')->willReturn($id); | ||||
$share->method('getShareType')->willReturn($shareType); | $share->method('getShareType')->willReturn($shareType); | ||||
$share->method('getToken')->willReturn($token); | $share->method('getToken')->willReturn($token); | ||||
$share->method('getPassword')->willReturn($password); | $share->method('getPassword')->willReturn($password); | ||||
if ($shareType === IShare::TYPE_USER || | |||||
if ($shareType === IShare::TYPE_USER || | |||||
$shareType === IShare::TYPE_GROUP || | $shareType === IShare::TYPE_GROUP || | ||||
$shareType === IShare::TYPE_LINK) { | $shareType === IShare::TYPE_LINK) { | ||||
$share->method('getFullId')->willReturn('ocinternal:'.$id); | $share->method('getFullId')->willReturn('ocinternal:'.$id); |
$this->collaboratorSearch->expects($this->once()) | $this->collaboratorSearch->expects($this->once()) | ||||
->method('search') | ->method('search') | ||||
->with($search, $expectedShareTypes, $this->anything(), $perPage, $perPage * ($page -1)) | |||||
->with($search, $expectedShareTypes, $this->anything(), $perPage, $perPage * ($page - 1)) | |||||
->willReturn([[], false]); | ->willReturn([[], false]); | ||||
$sharees->expects($this->any()) | $sharees->expects($this->any()) |
parent::setUp(); | parent::setUp(); | ||||
$this->folder = self::TEST_FOLDER_NAME; | $this->folder = self::TEST_FOLDER_NAME; | ||||
$this->subfolder = '/subfolder_share_api_test'; | |||||
$this->subfolder = '/subfolder_share_api_test'; | |||||
$this->subsubfolder = '/subsubfolder_share_api_test'; | $this->subsubfolder = '/subsubfolder_share_api_test'; | ||||
$this->filename = '/share-api-test.txt'; | $this->filename = '/share-api-test.txt'; |
// delete the local folder | // delete the local folder | ||||
/** @var \OC\Files\Storage\Storage $storage */ | /** @var \OC\Files\Storage\Storage $storage */ | ||||
list($storage, $internalPath) = \OC\Files\Filesystem::resolvePath('/' . self::TEST_FILES_SHARING_API_USER2 . '/files/localfolder'); | |||||
list($storage, $internalPath) = \OC\Files\Filesystem::resolvePath('/' . self::TEST_FILES_SHARING_API_USER2 . '/files/localfolder'); | |||||
$storage->rmdir($internalPath); | $storage->rmdir($internalPath); | ||||
//enforce reload of the mount points | //enforce reload of the mount points |
// but the size including mountpoints increases | // but the size including mountpoints increases | ||||
$newRecipientRootInfo = $recipientView->getFileInfo('', true); | $newRecipientRootInfo = $recipientView->getFileInfo('', true); | ||||
$this->assertEquals($oldRecipientSize +3, $newRecipientRootInfo->getSize()); | |||||
$this->assertEquals($oldRecipientSize + 3, $newRecipientRootInfo->getSize()); | |||||
// size of owner's root increases | // size of owner's root increases | ||||
$this->loginAsUser(self::TEST_FILES_SHARING_API_USER2); | $this->loginAsUser(self::TEST_FILES_SHARING_API_USER2); |
$time = $this->timeFactory->getTime(); | $time = $this->timeFactory->getTime(); | ||||
// Never expire dates in future e.g. misconfiguration or negative time | // Never expire dates in future e.g. misconfiguration or negative time | ||||
// adjustment | // adjustment | ||||
if ($time<$timestamp) { | |||||
if ($time < $timestamp) { | |||||
return false; | return false; | ||||
} | } | ||||
$timestamp = substr(pathinfo($parts[0], PATHINFO_EXTENSION), 1); | $timestamp = substr(pathinfo($parts[0], PATHINFO_EXTENSION), 1); | ||||
} | } | ||||
$originalPath = ''; | $originalPath = ''; | ||||
$originalName = substr($entryName, 0, -strlen($timestamp)-2); | |||||
$originalName = substr($entryName, 0, -strlen($timestamp) - 2); | |||||
if (isset($originalLocations[$originalName][$timestamp])) { | if (isset($originalLocations[$originalName][$timestamp])) { | ||||
$originalPath = $originalLocations[$originalName][$timestamp]; | $originalPath = $originalLocations[$originalName][$timestamp]; | ||||
if (substr($originalPath, -1) === '/') { | if (substr($originalPath, -1) === '/') { |
'id' => $query->expr()->literal('file'.$i), | 'id' => $query->expr()->literal('file'.$i), | ||||
'timestamp' => $query->expr()->literal($i), | 'timestamp' => $query->expr()->literal($i), | ||||
'location' => $query->expr()->literal('.'), | 'location' => $query->expr()->literal('.'), | ||||
'user' => $query->expr()->literal('user'.$i%2) | |||||
'user' => $query->expr()->literal('user'.$i % 2) | |||||
])->execute(); | ])->execute(); | ||||
} | } | ||||
$getAllQuery = $this->dbConnection->getQueryBuilder(); | $getAllQuery = $this->dbConnection->getQueryBuilder(); |
public const FAKE_TIME_NOW = 1000000; | public const FAKE_TIME_NOW = 1000000; | ||||
public function expirationData() { | public function expirationData() { | ||||
$today = 100*self::SECONDS_PER_DAY; | |||||
$back10Days = (100-10)*self::SECONDS_PER_DAY; | |||||
$back20Days = (100-20)*self::SECONDS_PER_DAY; | |||||
$back30Days = (100-30)*self::SECONDS_PER_DAY; | |||||
$back35Days = (100-35)*self::SECONDS_PER_DAY; | |||||
$today = 100 * self::SECONDS_PER_DAY; | |||||
$back10Days = (100 - 10) * self::SECONDS_PER_DAY; | |||||
$back20Days = (100 - 20) * self::SECONDS_PER_DAY; | |||||
$back30Days = (100 - 30) * self::SECONDS_PER_DAY; | |||||
$back35Days = (100 - 35) * self::SECONDS_PER_DAY; | |||||
// it should never happen, but who knows :/ | // it should never happen, but who knows :/ | ||||
$ahead100Days = (100+100)*self::SECONDS_PER_DAY; | |||||
$ahead100Days = (100 + 100) * self::SECONDS_PER_DAY; | |||||
return [ | return [ | ||||
// Expiration is disabled - always should return false | // Expiration is disabled - always should return false | ||||
[ 'auto', false ], | [ 'auto', false ], | ||||
[ 'auto,auto', false ], | [ 'auto,auto', false ], | ||||
[ 'auto, auto', false ], | [ 'auto, auto', false ], | ||||
[ 'auto, 3', self::FAKE_TIME_NOW - (3*self::SECONDS_PER_DAY) ], | |||||
[ 'auto, 3', self::FAKE_TIME_NOW - (3 * self::SECONDS_PER_DAY) ], | |||||
[ '5, auto', false ], | [ '5, auto', false ], | ||||
[ '3, 5', self::FAKE_TIME_NOW - (5*self::SECONDS_PER_DAY) ], | |||||
[ '10, 3', self::FAKE_TIME_NOW - (10*self::SECONDS_PER_DAY) ], | |||||
[ '3, 5', self::FAKE_TIME_NOW - (5 * self::SECONDS_PER_DAY) ], | |||||
[ '10, 3', self::FAKE_TIME_NOW - (10 * self::SECONDS_PER_DAY) ], | |||||
]; | ]; | ||||
} | } | ||||
$time = $this->timeFactory->getTime(); | $time = $this->timeFactory->getTime(); | ||||
// Never expire dates in future e.g. misconfiguration or negative time | // Never expire dates in future e.g. misconfiguration or negative time | ||||
// adjustment | // adjustment | ||||
if ($time<$timestamp) { | |||||
if ($time < $timestamp) { | |||||
return false; | return false; | ||||
} | } | ||||
$isValid = false; | $isValid = false; | ||||
\OC::$server->getLogger()->warning( | \OC::$server->getLogger()->warning( | ||||
$minValue . ' is not a valid value for minimal versions retention obligation. Check versions_retention_obligation in your config.php. Falling back to auto.', | $minValue . ' is not a valid value for minimal versions retention obligation. Check versions_retention_obligation in your config.php. Falling back to auto.', | ||||
['app'=>'files_versions'] | |||||
['app' => 'files_versions'] | |||||
); | ); | ||||
} | } | ||||
$isValid = false; | $isValid = false; | ||||
\OC::$server->getLogger()->warning( | \OC::$server->getLogger()->warning( | ||||
$maxValue . ' is not a valid value for maximal versions retention obligation. Check versions_retention_obligation in your config.php. Falling back to auto.', | $maxValue . ' is not a valid value for maximal versions retention obligation. Check versions_retention_obligation in your config.php. Falling back to auto.', | ||||
['app'=>'files_versions'] | |||||
['app' => 'files_versions'] | |||||
); | ); | ||||
} | } | ||||
use OCP\User; | use OCP\User; | ||||
class Storage { | class Storage { | ||||
public const DEFAULTENABLED=true; | |||||
public const DEFAULTMAXSIZE=50; // unit: percentage; 50% of available disk space/quota | |||||
public const DEFAULTENABLED = true; | |||||
public const DEFAULTMAXSIZE = 50; // unit: percentage; 50% of available disk space/quota | |||||
public const VERSIONS_ROOT = 'files_versions/'; | public const VERSIONS_ROOT = 'files_versions/'; | ||||
public const DELETE_TRIGGER_MASTER_REMOVED = 0; | public const DELETE_TRIGGER_MASTER_REMOVED = 0; | ||||
$versionCreated = true; | $versionCreated = true; | ||||
} | } | ||||
$fileToRestore = 'files_versions' . $filename . '.v' . $revision; | |||||
$fileToRestore = 'files_versions' . $filename . '.v' . $revision; | |||||
// Restore encrypted version of the old file for the newly restored file | // Restore encrypted version of the old file for the newly restored file | ||||
// This has to happen manually here since the file is manually copied below | // This has to happen manually here since the file is manually copied below | ||||
$toDelete = []; | $toDelete = []; | ||||
foreach (array_reverse($versions['all']) as $key => $version) { | foreach (array_reverse($versions['all']) as $key => $version) { | ||||
if ((int)$version['version'] <$threshold) { | |||||
if ((int)$version['version'] < $threshold) { | |||||
$toDelete[$key] = $version; | $toDelete[$key] = $version; | ||||
} else { | } else { | ||||
//Versions are sorted by time - nothing mo to iterate. | //Versions are sorted by time - nothing mo to iterate. | ||||
// Check if enough space is available after versions are rearranged. | // Check if enough space is available after versions are rearranged. | ||||
// If not we delete the oldest versions until we meet the size limit for versions, | // If not we delete the oldest versions until we meet the size limit for versions, | ||||
// but always keep the two latest versions | // but always keep the two latest versions | ||||
$numOfVersions = count($allVersions) -2 ; | |||||
$numOfVersions = count($allVersions) - 2 ; | |||||
$i = 0; | $i = 0; | ||||
// sort oldest first and make sure that we start at the first element | // sort oldest first and make sure that we start at the first element | ||||
ksort($allVersions); | ksort($allVersions); |
public const SECONDS_PER_DAY = 86400; //60*60*24 | public const SECONDS_PER_DAY = 86400; //60*60*24 | ||||
public function expirationData() { | public function expirationData() { | ||||
$today = 100*self::SECONDS_PER_DAY; | |||||
$back10Days = (100-10)*self::SECONDS_PER_DAY; | |||||
$back20Days = (100-20)*self::SECONDS_PER_DAY; | |||||
$back30Days = (100-30)*self::SECONDS_PER_DAY; | |||||
$back35Days = (100-35)*self::SECONDS_PER_DAY; | |||||
$today = 100 * self::SECONDS_PER_DAY; | |||||
$back10Days = (100 - 10) * self::SECONDS_PER_DAY; | |||||
$back20Days = (100 - 20) * self::SECONDS_PER_DAY; | |||||
$back30Days = (100 - 30) * self::SECONDS_PER_DAY; | |||||
$back35Days = (100 - 35) * self::SECONDS_PER_DAY; | |||||
// it should never happen, but who knows :/ | // it should never happen, but who knows :/ | ||||
$ahead100Days = (100+100)*self::SECONDS_PER_DAY; | |||||
$ahead100Days = (100 + 100) * self::SECONDS_PER_DAY; | |||||
return [ | return [ | ||||
// Expiration is disabled - always should return false | // Expiration is disabled - always should return false |