Skip to content

Commit 4895e65

Browse files
committed
fixup! enh(user_status): set OoO status and message
1 parent 6a174c3 commit 4895e65

4 files changed

Lines changed: 73 additions & 4 deletions

File tree

apps/dav/lib/Service/AbsenceService.php

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,20 +27,33 @@
2727
namespace OCA\DAV\Service;
2828

2929
use InvalidArgumentException;
30+
use OC\AppFramework\Utility\TimeFactory;
31+
use OCA\DAV\CalDAV\CalDavBackend;
32+
use OCA\DAV\CalDAV\Calendar;
33+
use OCA\DAV\CalDAV\CalendarImpl;
3034
use OCA\DAV\Db\Absence;
3135
use OCA\DAV\Db\AbsenceMapper;
36+
use OCA\DAV\ServerFactory;
3237
use OCP\AppFramework\Db\DoesNotExistException;
38+
use OCP\AppFramework\Utility\ITimeFactory;
3339
use OCP\EventDispatcher\IEventDispatcher;
40+
use OCP\IConfig;
3441
use OCP\IUserManager;
3542
use OCP\User\Events\OutOfOfficeChangedEvent;
3643
use OCP\User\Events\OutOfOfficeClearedEvent;
3744
use OCP\User\Events\OutOfOfficeScheduledEvent;
45+
use Sabre\DAV\Exception\NotFound;
46+
use Sabre\VObject\Component\VCalendar;
47+
use Sabre\VObject\Component\VTimeZone;
3848

3949
class AbsenceService {
4050
public function __construct(
4151
private AbsenceMapper $absenceMapper,
4252
private IEventDispatcher $eventDispatcher,
4353
private IUserManager $userManager,
54+
private ITimeFactory $timeFactory,
55+
private ServerFactory $serverFactory,
56+
private IConfig $appConfig,
4457
) {
4558
}
4659

@@ -117,5 +130,50 @@ public function getAbsence(string $userId): ?Absence {
117130
return null;
118131
}
119132
}
133+
134+
public function isInEffect(Absence $absence): bool {
135+
$principal = "principals/users/" . $absence->getUserId();
136+
$invitationServer = $this->serverFactory->createInviationResponseServer(false);
137+
$server = $invitationServer->getServer();
138+
139+
/** @var \OCA\DAV\CalDAV\Plugin $caldavPlugin */
140+
$caldavPlugin = $server->getPlugin('caldav');
141+
$calendarHomePath = $caldavPlugin->getCalendarHomeForPrincipal($principal);
142+
try {
143+
$calendarHome = $server->tree->getNodeForPath($calendarHomePath);
144+
$uri = $this->appConfig->getUserValue($absence->getUserId(), 'dav', 'defaultCalendar', CalDavBackend::PERSONAL_CALENDAR_URI);
145+
$calendarNode = $calendarHome->getChild($uri);
146+
} catch (NotFound $e) {
147+
return false;
148+
}
149+
150+
if (!($calendarNode instanceof Calendar)) {
151+
$this->logger->warning('Personal calendar node is not a calendar');
152+
return false;
153+
}
154+
if ($calendarNode->isDeleted()) {
155+
$this->logger->warning('Personal calendar has been deleted');
156+
return false;
157+
}
158+
159+
$tz = $calendarNode->getProperties([])['{urn:ietf:params:xml:ns:caldav}calendar-timezone'] ?? null;
160+
if($tz === null) {
161+
// Do the comparison without a tz
162+
$absenceStart = new \DateTime($absence->getFirstDay());
163+
$absenceEnd = new \DateTime($absence->getLastDay());
164+
$now = $this->timeFactory->getTime();
165+
return $absenceStart->getTimestamp() <= $now && $absenceEnd->getTimestamp() >= $now;
166+
}
167+
168+
/** @var VCalendar $vtimezoneObj */
169+
$vtimezoneObj = Reader::read($tz);
170+
/** @var VTimeZone $vtimezone */
171+
$vtimezone = $vtimezoneObj->VTIMEZONE;
172+
$calendarTimeZone = $vtimezone->getTimeZone();
173+
$absenceStart = new \DateTime($absence->getFirstDay(), $calendarTimeZone);
174+
$absenceEnd = new \DateTime($absence->getLastDay(), $calendarTimeZone);
175+
$now = $this->timeFactory->getTime();
176+
return $absenceStart->getTimestamp() <= $now && $absenceEnd->getTimestamp() >= $now;
177+
}
120178
}
121179

apps/user_status/lib/Service/StatusService.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,7 @@ public function findByUserId(string $userId): UserStatus {
151151
// It doesn't matter if we have calendar events if an absence is registered
152152
// A user can be OOO while not having declined a calendar event during that time
153153
$absenceStatus = $this->absenceService->getAbsence($userId);
154-
if(!empty($absenceStatus)) {
154+
if(!empty($absenceStatus) && $this->absenceService->isInEffect($absenceStatus)) {
155155
$status = $this->setUserStatus($userId, IUserStatus::DND, IUserStatus::MESSAGE_AVAILABILITY, true, $absenceStatus->getStatus());
156156
return $this->processStatus($status);
157157
}

apps/user_status/tests/Unit/Service/StatusServiceTest.php

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1005,7 +1005,7 @@ public function testFindByUserIdUserDefinedAndPersistent(): void {
10051005
$this->assertEquals($status, $this->service->findByUserId('admin'));
10061006
}
10071007

1008-
public function testFindByUserIdAbsence(): void {
1008+
public function testFindByUserIdAbsenceInEffect(): void {
10091009
$oldStatus = new UserStatus();
10101010
$oldStatus->setIsUserDefined(true);
10111011
$oldStatus->setStatus(IUserStatus::ONLINE);
@@ -1025,6 +1025,10 @@ public function testFindByUserIdAbsence(): void {
10251025
$this->absenceStatusService->expects(self::once())
10261026
->method('getAbsence')
10271027
->willReturn($absence);
1028+
$this->absenceStatusService->expects(self::once())
1029+
->method('isInEffect')
1030+
->with($absence)
1031+
->willReturn(true);
10281032
$this->predefinedStatusService->expects(self::once())
10291033
->method('isValidId')
10301034
->with($newStatus->getMessageId())

lib/private/User/AvailabilityCoordinator.php

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828

2929
use JsonException;
3030
use OCA\DAV\Db\AbsenceMapper;
31+
use OCA\DAV\Service\AbsenceService;
3132
use OCP\AppFramework\Db\DoesNotExistException;
3233
use OCP\ICache;
3334
use OCP\ICacheFactory;
@@ -41,7 +42,7 @@ class AvailabilityCoordinator implements IAvailabilityCoordinator {
4142

4243
public function __construct(
4344
ICacheFactory $cacheFactory,
44-
private AbsenceMapper $absenceMapper,
45+
private AbsenceService $absenceService,
4546
private LoggerInterface $logger,
4647
) {
4748
$this->cache = $cacheFactory->createLocal('OutOfOfficeData');
@@ -99,13 +100,19 @@ public function getCurrentOutOfOfficeData(IUser $user): ?IOutOfOfficeData {
99100
}
100101

101102
try {
102-
$absenceData = $this->absenceMapper->findByUserId($user->getUID());
103+
$absenceData = $this->absenceService->getAbsence($user->getUID());
103104
} catch (DoesNotExistException $e) {
104105
return null;
105106
}
106107

108+
// no matter if it's in effect or not, let's cache it
107109
$data = $absenceData->toOutOufOfficeData($user);
108110
$this->setCachedOutOfOfficeData($data);
111+
112+
if(!$this->absenceService->isInEffect($absenceData)) {
113+
return null;
114+
}
115+
109116
return $data;
110117
}
111118
}

0 commit comments

Comments
 (0)