Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
61 changes: 36 additions & 25 deletions apps/dav/lib/CardDAV/CardDavBackend.php
Original file line number Diff line number Diff line change
Expand Up @@ -648,23 +648,26 @@ public function getMultipleCards($addressBookId, array $uris) {
* @param mixed $addressBookId
* @param string $cardUri
* @param string $cardData
* @param bool $checkAlreadyExists
* @return string
*/
public function createCard($addressBookId, $cardUri, $cardData) {
public function createCard($addressBookId, $cardUri, $cardData, bool $checkAlreadyExists = true) {
$etag = md5($cardData);
$uid = $this->getUID($cardData);

$q = $this->db->getQueryBuilder();
$q->select('uid')
->from($this->dbCardsTable)
->where($q->expr()->eq('addressbookid', $q->createNamedParameter($addressBookId)))
->andWhere($q->expr()->eq('uid', $q->createNamedParameter($uid)))
->setMaxResults(1);
$result = $q->execute();
$count = (bool)$result->fetchOne();
$result->closeCursor();
if ($count) {
throw new \Sabre\DAV\Exception\BadRequest('VCard object with uid already exists in this addressbook collection.');
if ($checkAlreadyExists) {
$q = $this->db->getQueryBuilder();
$q->select('uid')
->from($this->dbCardsTable)
->where($q->expr()->eq('addressbookid', $q->createNamedParameter($addressBookId)))
->andWhere($q->expr()->eq('uid', $q->createNamedParameter($uid)))
->setMaxResults(1);
$result = $q->executeQuery();
$count = (bool)$result->fetchOne();
$result->closeCursor();
if ($count) {
throw new \Sabre\DAV\Exception\BadRequest('VCard object with uid already exists in this addressbook collection.');
}
}

$query = $this->db->getQueryBuilder();
Expand Down Expand Up @@ -1268,21 +1271,29 @@ protected function updateProperties($addressBookId, $cardUri, $vCardSerialized)
]
);

foreach ($vCard->children() as $property) {
if (!in_array($property->name, self::$indexProperties)) {
continue;
}
$preferred = 0;
foreach ($property->parameters as $parameter) {
if ($parameter->name === 'TYPE' && strtoupper($parameter->getValue()) === 'PREF') {
$preferred = 1;
break;

$this->db->beginTransaction();

try {
foreach ($vCard->children() as $property) {
if (!in_array($property->name, self::$indexProperties)) {
continue;
}
$preferred = 0;
foreach ($property->parameters as $parameter) {
if ($parameter->name === 'TYPE' && strtoupper($parameter->getValue()) === 'PREF') {
$preferred = 1;
break;
}
}
$query->setParameter('name', $property->name);
$query->setParameter('value', mb_strcut($property->getValue(), 0, 254));
$query->setParameter('preferred', $preferred);
$query->execute();
}
$query->setParameter('name', $property->name);
$query->setParameter('value', mb_strcut($property->getValue(), 0, 254));
$query->setParameter('preferred', $preferred);
$query->execute();
$this->db->commit();
} catch (\Exception $e) {
$this->db->rollBack();
}
}

Expand Down
4 changes: 2 additions & 2 deletions apps/dav/lib/CardDAV/SyncService.php
Original file line number Diff line number Diff line change
Expand Up @@ -265,12 +265,12 @@ public function updateUser(IUser $user) {
$userId = $user->getUID();

$cardId = "$name:$userId.vcf";
$card = $this->backend->getCard($addressBookId, $cardId);
if ($user->isEnabled()) {
$card = $this->backend->getCard($addressBookId, $cardId);
if ($card === false) {
$vCard = $this->converter->createCardFromUser($user);
if ($vCard !== null) {
$this->backend->createCard($addressBookId, $cardId, $vCard->serialize());
$this->backend->createCard($addressBookId, $cardId, $vCard->serialize(), false);
}
} else {
$vCard = $this->converter->createCardFromUser($user);
Expand Down
12 changes: 7 additions & 5 deletions apps/dav/lib/HookManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -105,10 +105,7 @@ public function setup() {
$this->postDeleteUser(['uid' => $uid]);
});
\OC::$server->getUserManager()->listen('\OC\User', 'postUnassignedUserId', [$this, 'postUnassignedUserId']);
Util::connectHook('OC_User',
'changeUser',
$this,
'changeUser');
Util::connectHook('OC_User', 'changeUser', $this, 'changeUser');
}

public function postCreateUser($params) {
Expand Down Expand Up @@ -164,7 +161,12 @@ public function postUnassignedUserId($uid) {

public function changeUser($params) {
$user = $params['user'];
$this->syncService->updateUser($user);
$feature = $params['feature'];
// This case is already covered by the account manager firing up a signal
// later on
if ($feature !== 'eMailAddress' && $feature !== 'displayName') {
$this->syncService->updateUser($user);
}
}

public function firstLogin(IUser $user = null) {
Expand Down
18 changes: 9 additions & 9 deletions lib/private/Accounts/AccountManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -269,12 +269,15 @@ protected function sanitizeWebsite(IAccountProperty $property, bool $throwOnData
}
}

protected function updateUser(IUser $user, array $data, bool $throwOnData = false): array {
$oldUserData = $this->getUser($user, false);
protected function updateUser(IUser $user, array $data, ?array $oldUserData, bool $throwOnData = false): array {
if ($oldUserData === null) {
$oldUserData = $this->getUser($user, false);
}

$updated = true;

if ($oldUserData !== $data) {
$this->updateExistingUser($user, $data);
$this->updateExistingUser($user, $data, $oldUserData);
} else {
// nothing needs to be done if new and old data set are the same
$updated = false;
Expand Down Expand Up @@ -601,12 +604,9 @@ protected function importFromJson(string $json, string $userId): ?array {
}

/**
* update existing user in accounts table
*
* @param IUser $user
* @param array $data
* Update existing user in accounts table
*/
protected function updateExistingUser(IUser $user, array $data): void {
protected function updateExistingUser(IUser $user, array $data, array $oldData): void {
$uid = $user->getUID();
$jsonEncodedData = $this->prepareJson($data);
$query = $this->connection->getQueryBuilder();
Expand Down Expand Up @@ -820,7 +820,7 @@ public function updateAccount(IAccount $account): void {
];
}

$this->updateUser($account->getUser(), $data, true);
$this->updateUser($account->getUser(), $data, $oldData, true);
$this->internalCache->set($account->getUser()->getUID(), $account);
}
}
9 changes: 3 additions & 6 deletions tests/lib/Accounts/AccountManagerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -424,7 +424,7 @@ protected function populateOrUpdate(): void {
],
];
foreach ($users as $userInfo) {
$this->invokePrivate($this->accountManager, 'updateUser', [$userInfo['user'], $userInfo['data'], false]);
$this->invokePrivate($this->accountManager, 'updateUser', [$userInfo['user'], $userInfo['data'], null, false]);
}
}

Expand Down Expand Up @@ -466,9 +466,6 @@ public function testUpdateUser($newData, $oldData, $insertNew, $updateExisting)
/** @var IUser $user */
$user = $this->createMock(IUser::class);

// FIXME: should be an integration test instead of this abomination
$accountManager->expects($this->once())->method('getUser')->with($user)->willReturn($oldData);

if ($updateExisting) {
$accountManager->expects($this->once())->method('updateExistingUser')
->with($user, $newData);
Expand Down Expand Up @@ -497,10 +494,10 @@ function ($eventName, $event) use ($user, $newData) {
);
}

$this->invokePrivate($accountManager, 'updateUser', [$user, $newData]);
$this->invokePrivate($accountManager, 'updateUser', [$user, $newData, $oldData]);
}

public function dataTrueFalse() {
public function dataTrueFalse(): array {
return [
#$newData | $oldData | $insertNew | $updateExisting
[['myProperty' => ['value' => 'newData']], ['myProperty' => ['value' => 'oldData']], false, true],
Expand Down