How do I authorize a user in the integration tests?

I am trying to use project and repository services inside of my integration tests. For example, creating a new project:

@RunWith(AtlassianPluginsTestRunner.class)
public class MyComponentTest {
    private final ApplicationProperties applicationProperties;
    private final RepositoryService repositoryService;
    private final ProjectService projectService;

    public MyComponentTest(ApplicationProperties applicationProperties, RepositoryService repositoryService, ProjectService projectService){
        this.applicationProperties = applicationProperties;
        this.repositoryService = repositoryService;
        this.projectService = projectService;
    }

    @Test
    public void testSomething(){
        // Error:
        // com.atlassian.bitbucket.AuthorisationException: 
        //   You are not permitted to access this resource
        Project project = projectService.create(
            new ProjectCreateRequest.Builder()
                .name("Project1")
                .key("proj_1")
                .build()
        );
        // Then create repository
        // Finally, do something with the repository and my custom plugin
    }
}

The problem is that I get “com.atlassian.bitbucket.AuthorisationException: You are not permitted to access this resource” exception when creating the project.

If this was Jira, I would be able to solve this by importing JiraAuthenticationContext and calling setLoggedInUser(user). But I am unable to find anything similar for a Bitbucket plugin.

How do I ensure that the user is logged in?

I have found a workaround for this.

It works without a problem if the test is run through the Dev Toolbox test console (e.g. http://localhost:7990/bitbucket/plugins/servlet/it-test-console)

Or when run through curl (e.g. http://localhost:7990/bitbucket/rest/atlassiantestrunner/1.0/runtestfromconsole/it.<path to class>)

But will fail if run through the atlas-integration-test command.

Why?

In Bitbucket, you can authorise resource requests by using the com.atlassian.bitbucket.user.SecurityService component.

Wrap your request with SecurityService.withPermission().call(). This way you also don’t have to impersonate a specific user like you are describing with the JiraAuthenticationContext. Alternatively If you did want to authorise against a specific user then you could use SecurityContext.impersonating().

Example:

securityService.withPermission(Permission.ADMIN, "Useful message").call(() -> projectService.create(....));

Thank you! You have saved my day!

The securityService.withPermission(...).call(() -> ...); did not work, because many services need the current authenticated user. (Consider AuthenticationContext.getCurrentUser()). For example when creating a project, the ProjectService needs the current user to assign them as a project admin.

But, SecurityContext.impersonating() does work. I have ended up doing the following:

import com.atlassian.bitbucket.user.UserService;
import com.atlassian.bitbucket.user.ApplicationUser;
import com.atlassian.bitbucket.user.SecurityService;

...

final ApplicationUser user = userService.findUserByNameOrEmail("admin");
if (user == null) throw new RuntimeException("User not found");
securityService.impersonating(user, "Useful message").call(() -> {
    [... your tests here ...]
    return true;
});

Ah, I didn’t know about some methods requiring a user, good to know.