Add group sharing migration Migrate all userstags/v9.0beta1
@@ -11,16 +11,13 @@ | |||
/apps*/* | |||
!/apps/dav | |||
!/apps/files | |||
!/apps/files_encryption | |||
!/apps/federation | |||
!/apps/encryption | |||
!/apps/encryption_dummy | |||
!/apps/files_external | |||
!/apps/files_sharing | |||
!/apps/files_trashbin | |||
!/apps/files_versions | |||
!/apps/user_ldap | |||
!/apps/user_webdavauth | |||
!/apps/provisioning_api | |||
!/apps/systemtags | |||
/apps/files_external/3rdparty/irodsphp/PHPUnitTest |
@@ -24,9 +24,11 @@ use OCA\DAV\CardDAV\ContactsManager; | |||
use OCA\DAV\CardDAV\SyncJob; | |||
use OCA\DAV\CardDAV\SyncService; | |||
use OCA\DAV\HookManager; | |||
use OCA\Dav\Migration\MigrateAddressbooks; | |||
use \OCP\AppFramework\App; | |||
use OCP\AppFramework\IAppContainer; | |||
use OCP\Contacts\IManager; | |||
use OCP\IUser; | |||
class Application extends App { | |||
@@ -73,6 +75,14 @@ class Application extends App { | |||
return new \OCA\DAV\CardDAV\CardDavBackend($db, $principal, $logger); | |||
}); | |||
$container->registerService('MigrateAddressbooks', function($c) { | |||
/** @var IAppContainer $c */ | |||
$db = $c->getServer()->getDatabaseConnection(); | |||
return new MigrateAddressbooks( | |||
$db, | |||
$c->query('CardDavBackend') | |||
); | |||
}); | |||
} | |||
/** | |||
@@ -100,4 +110,20 @@ class Application extends App { | |||
$jl->add(new SyncJob()); | |||
} | |||
public function migrateAddressbooks() { | |||
try { | |||
$migration = $this->getContainer()->query('MigrateAddressbooks'); | |||
$migration->setup(); | |||
$userManager = $this->getContainer()->getServer()->getUserManager(); | |||
$userManager->callForAllUsers(function($user) use($migration) { | |||
/** @var IUser $user */ | |||
$migration->migrateForUser($user->getUID()); | |||
}); | |||
} catch (\Exception $ex) { | |||
$this->getContainer()->getServer()->getLogger()->logException($ex); | |||
} | |||
} | |||
} |
@@ -23,3 +23,4 @@ use OCA\Dav\AppInfo\Application; | |||
$app = new Application(); | |||
$app->setupCron(); | |||
$app->migrateAddressbooks(); |
@@ -22,6 +22,7 @@ | |||
use OCA\Dav\AppInfo\Application; | |||
use OCA\DAV\Command\CreateAddressBook; | |||
use OCA\DAV\Command\CreateCalendar; | |||
use OCA\Dav\Command\MigrateAddressbooks; | |||
use OCA\DAV\Command\SyncSystemAddressBook; | |||
$config = \OC::$server->getConfig(); | |||
@@ -37,3 +38,10 @@ $app = new Application(); | |||
$application->add(new CreateAddressBook($userManager, $groupManager, $dbConnection, $logger)); | |||
$application->add(new CreateCalendar($userManager, $dbConnection)); | |||
$application->add(new SyncSystemAddressBook($app->getSyncService())); | |||
// the occ tool is *for now* only available in debug mode for developers to test | |||
if ($config->getSystemValue('debug', false)){ | |||
$app = new \OCA\Dav\AppInfo\Application(); | |||
$migration = $app->getContainer()->query('MigrateAddressbooks'); | |||
$application->add(new MigrateAddressbooks($userManager, $migration)); | |||
} |
@@ -88,7 +88,7 @@ class CreateAddressBook extends Command { | |||
); | |||
$name = $input->getArgument('name'); | |||
$carddav = new CardDavBackend($this->dbConnection, $principalBackend); | |||
$carddav = new CardDavBackend($this->dbConnection, $principalBackend, $this->logger); | |||
$carddav->createAddressBook("principals/users/$user", $name, []); | |||
} | |||
} |
@@ -0,0 +1,65 @@ | |||
<?php | |||
namespace OCA\Dav\Command; | |||
use OCP\IUser; | |||
use OCP\IUserManager; | |||
use Symfony\Component\Console\Command\Command; | |||
use Symfony\Component\Console\Helper\ProgressBar; | |||
use Symfony\Component\Console\Input\InputArgument; | |||
use Symfony\Component\Console\Input\InputInterface; | |||
use Symfony\Component\Console\Output\OutputInterface; | |||
class MigrateAddressbooks extends Command { | |||
/** @var IUserManager */ | |||
protected $userManager; | |||
/** @var \OCA\Dav\Migration\MigrateAddressbooks */ | |||
private $service; | |||
/** | |||
* @param IUserManager $userManager | |||
* @param \OCA\Dav\Migration\MigrateAddressbooks $service | |||
*/ | |||
function __construct(IUserManager $userManager, | |||
\OCA\Dav\Migration\MigrateAddressbooks $service | |||
) { | |||
parent::__construct(); | |||
$this->userManager = $userManager; | |||
$this->service = $service; | |||
} | |||
protected function configure() { | |||
$this | |||
->setName('dav:migrate-addressbooks') | |||
->setDescription('Migrate addressbooks from the contacts app to core') | |||
->addArgument('user', | |||
InputArgument::OPTIONAL, | |||
'User for whom all addressbooks will be migrated'); | |||
} | |||
protected function execute(InputInterface $input, OutputInterface $output) { | |||
$this->service->setup(); | |||
$user = $input->getArgument('user'); | |||
if (!is_null($user)) { | |||
if (!$this->userManager->userExists($user)) { | |||
throw new \InvalidArgumentException("User <$user> in unknown."); | |||
} | |||
$output->writeln("Start migration for $user"); | |||
$this->service->migrateForUser($user); | |||
} | |||
$output->writeln("Start migration of all known users ..."); | |||
$p = new ProgressBar($output); | |||
$p->start(); | |||
$this->userManager->callForAllUsers(function($user) use ($p) { | |||
$p->advance(); | |||
/** @var IUser $user */ | |||
$this->service->migrateForUser($user->getUID()); | |||
}); | |||
$p->finish(); | |||
$output->writeln(''); | |||
} | |||
} |
@@ -53,7 +53,6 @@ class SyncSystemAddressBook extends Command { | |||
* @param OutputInterface $output | |||
*/ | |||
protected function execute(InputInterface $input, OutputInterface $output) { | |||
$output->writeln('Syncing users ...'); | |||
$progress = new ProgressBar($output); | |||
$progress->start(); |
@@ -0,0 +1,118 @@ | |||
<?php | |||
namespace OCA\Dav\Migration; | |||
use OCA\DAV\CardDAV\AddressBook; | |||
use OCA\DAV\CardDAV\CardDavBackend; | |||
use OCP\IConfig; | |||
use OCP\IDBConnection; | |||
use OCP\ILogger; | |||
use Sabre\CardDAV\Plugin; | |||
use Symfony\Component\Console\Command\Command; | |||
use Symfony\Component\Console\Input\InputArgument; | |||
use Symfony\Component\Console\Input\InputInterface; | |||
use Symfony\Component\Console\Output\OutputInterface; | |||
class MigrateAddressbooks { | |||
/** @var \OCP\IDBConnection */ | |||
protected $dbConnection; | |||
/** @var CardDavBackend */ | |||
private $backend; | |||
/** | |||
* @param IDBConnection $dbConnection | |||
* @param IConfig $config | |||
* @param ILogger $logger | |||
*/ | |||
function __construct(IDBConnection $dbConnection, | |||
CardDavBackend $backend | |||
) { | |||
$this->dbConnection = $dbConnection; | |||
$this->backend = $backend; | |||
} | |||
private function verifyPreconditions() { | |||
if (!$this->dbConnection->tableExists('contacts_addressbooks')) { | |||
throw new \DomainException('Contacts tables are missing. Nothing to do.'); | |||
} | |||
} | |||
/** | |||
* @param string $user | |||
*/ | |||
public function migrateForUser($user) { | |||
// get all addressbooks of that user | |||
$query = $this->dbConnection->getQueryBuilder(); | |||
$books = $query->select()->from('contacts_addressbooks') | |||
->where($query->expr()->eq('user', $query->createNamedParameter($user))) | |||
->execute() | |||
->fetchAll(); | |||
$principal = "principals/users/$user"; | |||
foreach($books as $book) { | |||
$knownBooks = $this->backend->getAddressBooksByUri($principal, $book['uri']); | |||
if (!is_null($knownBooks)) { | |||
continue; | |||
} | |||
$newId = $this->backend->createAddressBook($principal, $book['uri'], [ | |||
'{DAV:}displayname' => $book['displayname'], | |||
'{' . Plugin::NS_CARDDAV . '}addressbook-description' => $book['description'] | |||
]); | |||
$this->migrateBook($book['id'], $newId); | |||
$this->migrateShares($book['id'], $newId); | |||
} | |||
} | |||
public function setup() { | |||
$this->verifyPreconditions(); | |||
} | |||
/** | |||
* @param int $addressBookId | |||
* @param int $newAddressBookId | |||
*/ | |||
private function migrateBook($addressBookId, $newAddressBookId) { | |||
$query = $this->dbConnection->getQueryBuilder(); | |||
$cards = $query->select()->from('contacts_cards') | |||
->where($query->expr()->eq('addressbookid', $query->createNamedParameter($addressBookId))) | |||
->execute() | |||
->fetchAll(); | |||
foreach ($cards as $card) { | |||
$this->backend->createCard($newAddressBookId, $card['uri'], $card['carddata']); | |||
} | |||
} | |||
/** | |||
* @param int $addressBookId | |||
* @param int $newAddressBookId | |||
*/ | |||
private function migrateShares($addressBookId, $newAddressBookId) { | |||
$query = $this->dbConnection->getQueryBuilder(); | |||
$shares = $query->select()->from('share') | |||
->where($query->expr()->eq('item_source', $query->createNamedParameter($addressBookId))) | |||
->andWhere($query->expr()->eq('item_type', $query->expr()->literal('addressbook'))) | |||
->andWhere($query->expr()->in('share_type', [ $query->expr()->literal(0), $query->expr()->literal(1)])) | |||
->execute() | |||
->fetchAll(); | |||
$add = array_map(function($s) { | |||
$prefix = 'principal:principals/users/'; | |||
if ($s['share_type'] === 1) { | |||
$prefix = 'principal:principals/groups/'; | |||
} | |||
return [ | |||
'href' => $prefix . $s['share_with'] | |||
]; | |||
}, $shares); | |||
$newAddressBook = $this->backend->getAddressBookById($newAddressBookId); | |||
$book = new AddressBook($this->backend, $newAddressBook); | |||
$this->backend->updateShares($book, $add, []); | |||
} | |||
} |