How to get page from ContentService?

Hi there,

I noticed that PageManager.getPage(pageId) is deprecated and recommended way to replace it is to use ContentService.find()…

So I’m trying to do just that:

// This is a pageId of an existing page
long pageId = 2523153;

// This finds the page just fine
Page pageFromPageManager = pageManager.getPage(pageId);

// This returns always empty optional, why???
Optional<Content> pageFromContentService = contentService.find()
                            .withId(ContentId.of(pageId))
                            .fetch();

This is executed from a job-runner where I’m trying to do some modifications on bunch of pages. I need to get each page, modify the content a bit and then rewrite it. In order to do that I need to get the page itself.

Using PageManager.getPage() returns the Page-instance just fine. However, using ContentService.find() with the same pageId returns always empty optional.

Please advice how ContentService.find() is supposed to be used to get the same page as returned from PageManager???

Thanks.

If I remember correctly PageManager does not care about permissions in general, whereas ContentService does honour permissions. Check what AuthenticatedUserThreadLocal.get() gives you

That is what I also suspect, but the thing is that this code is executed as a scheduled job and the job is launched by the administrator who has full rights to access those pages.

It could well be the reason of the permissions as you mention, BUT if a scheduled job launched by an admin can get the page content, then who can?!? If that is the case, is it the scenario of a scheduled job being able to get paces just mission impossible with ContentService… Pretty poor outcome if that’s the case IMO.

In general for separate threads such as those created for event handling or scheduled jobs, the AuthenticatedUserThreadLocal.get(); will return null since there’s no user authenticated in the context of those threads.
If you have some step to manually start the job you could perhaps in the scheduled job pass in the user and set it “locally” with AuthenticatedUserThreadLocal.set

Hi @PetriJuhaniRiipinen

is your “job user” in confluence-administrators group?, if not add this user to this group. my experience shows that this group is hardcoded in the Confluence and have access to the entire content without permissions (System Administrator and Confluence Administrator rights do not provide this functionality

Cheers

You can also use AuthenticatedUserImpersonator in com.atlassian.confluence.user to wrap your code … of course all of this isn’t in the API packages :blush:

So I guess the user is just empty on your thread and either you have to make sure the user that starts the job gets ‘transferred’ to that thread and has enough permissions or you retrieve a defined user from the confluence-administrators group …

Yep, sounds very much like this is the case here.

Thanks for the ideas everyone.

You can just use the PageService to retrieve the the page.

import com.atlassian.confluence.content.service.PageService;

Page page = pageService.getIdPageLocator​(pageId).getPage(); or
Page page = pageService.getTitleAndSpaceKeyPageLocator(spaceKey, pageTitle).getPage();