Searching using the V2 search API permission search filter

Hello,

I am using the v2 search manager to retrieve the content objects within a space. I followed this example in your documents, and the example works fine. However, I have an issue with constructing the SearchFilter object with the SiteSearchPermissionsSearchFilter object.

The example lists this line of code

 SearchFilter searchFilter = SiteSearchPermissionsSearchFilter.getInstance();

and it even clarifies it in the comments:

Please ensure you include com.atlassian.confluence.search.v2.searchfilter.SiteSearchPermissionsSearchFilter in your search. This is a bundled filter that will handle permission checking and content filtering automatically for you.

However, in my implementation getInstance() is already deprecated, and your javadocs mention it here and suggest using the constructor with passing these 4 objects:

SiteSearchPermissionsSearchFilter(UserAccessor, SpacePermissionsFilterDao, SpacePermissionQueryManager, PermissionManager)

So, I tried using the new above constructor, however, I can’t install my plugin mainly because of the SpacePermissionQueryManager.

I get error messages in my logs like osgi constraints, missing requirments, and OBR resolver has 1 unsatisfied requirements for installing etc…

e.g.

Caused by: org.osgi.framework.BundleException: Unresolved constraint in bundle net.myCompany.confluence.plugin.myPlugin [285]: Unable to resolve 285.0: missing requirement [285.0] osgi.wiring.package; (osgi.wiring.package=com.atlassian.confluence.impl.security.query)

I tried every trick I know with modifying my OSGI imports but it won’t work. I did notice in the code that the interface for the SpacePermissionQueryManager is marked with @Internal annotation.

What suggestions are there to implement this permission Search Filter?

A second question, I also tried to experiment with ContentCategorySearchFilter to filter the search to only content objects of pages and blogs (and ignore attachments) but that one is also marked @Internal. How can I add a filter for the search query based on category of content?

Side note: Even when I use the deprecated method getInstance which has no implementation as far as I can see, the searchManager actually returns the correct objects filtered for permissions. Is there a secondary permission manager implemented in the background?

Thanks a lot for your help

1 Like

It may be not very helpful (sorry!) but Confluence itself still uses the deprecated method in 6.9, so maybe it’s not urgent to switch :slight_smile:

IMHO Atlassian uses the @Deprecated and @Experimental annotations without giving much thought to what it means for the users of the API.

I also wanted to use the constructor instead of deprecated getInstance() method, but you can’t solve the issue without doing some funny stuff.

The problem is that the interface SpacePermissionQueryManager is in the package com.atlassian.confluence.impl.security.query. You don’t have access to this class through SpringScanner as the package com.atlassian.confluence.impl.* is excluded.
You can find the exclusion in WEB-INF/lib/confluence-6.X.Y.jar/bootstrapContext.xml as the bean packageScanningConfiguration (the bean is used by the class FelixOsgiContainerManager)

    <!-- configuration shared by the plugin manager during both setup and regular Confluence operation -->
    <bean id="packageScanningConfiguration" class="com.atlassian.confluence.plugin.spring.PackageScannerConfigurationFactory">
        <constructor-arg index="0"> <!-- packageIncludes -->
            [...]
        </constructor-arg>
        <constructor-arg index="1"> <!-- packageExcludes-->
            <list>
                [...]
                <value>com.atlassian.confluence.impl.*</value>
                [...]
            </list>
        </constructor-arg>
        <constructor-arg index="2"> <!-- packageVersions -->
            [...]
        </constructor-arg>
    </bean>

The interesting part is that you have access to the bean spacePermissionQueryManager (the object implementing SpacePermissionQueryManager), but not to the interface class:
You could do

Object x = ContainerManager.getComponent("spacePermissionQueryManager");

but not

SpacePermissionQueryManager x = (SpacePermissionQueryManager) ContainerManager.getComponent("spacePermissionQueryManager")

And to call the constructor without reflection, you need a SpacePermissionQueryManager, not just an Object. You could pass 4 nulls to the constructor :frowning: … (see below)

Side note: Even when I use the deprecated method getInstance which has no implementation as far as I can see, the searchManager actually returns the correct objects filtered for permissions.

SiteSearchPermissionsSearchFilter.getInstace().expand() will invoke for example new SpacePermissionsSearchFilter(null, null). If the fields in SpacePermissionsSearchFilter are null they will be initialized using ContainerManager.getComponent() when they are needed (not in the constructor).

Conclusion:
I’ll use the deprecated getInstance() instead of something like

new SiteSearchPermissionsSearchFilter(null, null, null, null)
1 Like

Thank you for the detailed explanation. Appreciated.