Can one access users address books in background jobs?

Hello,

Is it possible to access users’ address books in a background job?

I would like to do so, in order to keep contact pictures in sync with external sources (downloading from social networks in my case, see #1580).

Here is what I tried so far:

Running $this->manager->getUserAddressBooks(); returns only the system address book if executed by a background job. So I tried one layer below, using the CardDavBackend $this->davBackend->getUsersOwnAddressBooks("principals/users/$user");, which seemed to work but only returned the books as array. I don’t know how to transform it into a full IAddressBook. Maybe the ContactsManager-function “getUserAddressBooks” needs to be extended by a variable (userid)? This smells like opening a data security issue, though.

Much better would be to run background jobs as user. Is there a way to do so?

Alright, I discovered there is an IAddressBookProvider in v19 - awesome!

@ChristophWurst, can you help me on how to use it? I tried:

use OCA\DAV\CardDAV\Integration\IAddressBookProvider;

/** @var IAddressBookProvider */
private  $addressBookProvider;

public function __construct(...IAddressBookProvider $addressBookProvider)

But it gives me the error message

Could not resolve addressBookProvider! Class addressBookProvider does not exist

Trace

#0 /var/www/nextcloud/lib/private/AppFramework/Utility/SimpleContainer.php(116): OC\AppFramework\Utility\SimpleContainer->resolve('addressBookProv...')

#1 /var/www/nextcloud/lib/private/ServerContainer.php(149): OC\AppFramework\Utility\SimpleContainer->query(‘addressBookProv…’, true)

#2 /var/www/nextcloud/lib/private/AppFramework/DependencyInjection/DIContainer.php(388): OC\ServerContainer->query(‘addressBookProv…’, true)

#3 /var/www/nextcloud/lib/private/AppFramework/Utility/SimpleContainer.php(78): OC\AppFramework\DependencyInjection\DIContainer->query(‘addressBookProv…’)

#4 /var/www/nextcloud/lib/private/AppFramework/Utility/SimpleContainer.php(101): OC\AppFramework\Utility\SimpleContainer->buildClass(Object(ReflectionClass))

#5 /var/www/nextcloud/lib/private/AppFramework/Utility/SimpleContainer.php(116): OC\AppFramework\Utility\SimpleContainer->resolve(‘OCA\Contacts\Co…’)

#6 /var/www/nextcloud/lib/private/AppFramework/DependencyInjection/DIContainer.php(414): OC\AppFramework\Utility\SimpleContainer->query(‘OCA\Contacts\Co…’)

#7 /var/www/nextcloud/lib/private/AppFramework/DependencyInjection/DIContainer.php(385): OC\AppFramework\DependencyInjection\DIContainer->queryNoFallback(‘OCA\Contacts\Co…’)

#8 /var/www/nextcloud/lib/private/AppFramework/App.php(124): OC\AppFramework\DependencyInjection\DIContainer->query(‘OCA\Contacts\Co…’)

#9 /var/www/nextcloud/lib/private/AppFramework/Routing/RouteActionHandler.php(47): OC\AppFramework\App::main(‘OCA\Contacts\Co…’, ‘updateAddressbo…’, Object(OC\AppFramework\DependencyInjection\DIContainer), Array)

#10 [internal function]: OC\AppFramework\Routing\RouteActionHandler->__invoke(Array)

#11 /var/www/nextcloud/lib/private/Route/Router.php(297): call_user_func(Object(OC\AppFramework\Routing\RouteActionHandler), Array)

#12 /var/www/nextcloud/lib/base.php(1007): OC\Route\Router->match(’/apps/contacts/…’)

#13 /var/www/nextcloud/index.php(37): OC::handleRequest()

#14 {main}

What am I doing wrong?

Remove the variadic ... before the type hint so it becomes

public function __construct(IAddressBookProvider $addressBookProvider)

Sorry, my post was not clear. I clipped the other parameters and have it exactly like that. Do you know why I am getting the error message?

here is a more complete snipped:

namespace OCA\Contacts\Controller;

use OCP\AppFramework\ApiController;
use OCP\AppFramework\Http;
use OCP\AppFramework\Http\DataResponse;
use OCP\AppFramework\Http\JSONResponse;
use OCP\AppFramework\Http\TemplateResponse;
use OCP\IConfig;
use OCP\Contacts\IManager;
use OCP\IAddressBook;
use OCP\L10N\IFactory;
use OCP\IRequest;
use OCP\Util;

use OCA\DAV\CardDAV\Integration\IAddressBookProvider;

class SocialApiController extends ApiController {

	protected $appName;

	/** @var IFactory */
	private  $languageFactory;
	/** @var IManager */
	private  $manager;
	/** @var IConfig */
	private  $config;

	public function __construct(string $AppName,
					IRequest $request,
					IManager $manager,
					IConfig $config,
					IFactory $languageFactory,
					IAddressBookProvider $addressBookProvider) {

I am using @skjnldsv 's development environment, running Nextcloud 19.0.0 beta 6. The files are present in server/apps/dav/lib/CardDAV/Integration (IAddressBookProvider.php).

If someone has the same question: I was not successful with the IAddressBookProvider, so I manually registered the AddressBooks:

protected function registerAddressbooks($user, IManager $manager) {
	$cm = new ContactsManager($this->davBackend, $this->l10n);
	$cm->setupContactsProvider($manager, $user, $this->urlGen);
	//FIXME: would be better with: davBackend->getUsersOwnAddressBooks (no shared or system address books)
}

It’s not optimal, as I cannot filter out system or shared ones that easy - but it’s doing its job.

Leaving this topic open in the hope for a better solution…