Cannot Create group via Forge app

I’m trying to create a Group in Jira and Confluence via Forge.

Here is some snippet for that:

    const payload = {
        name: name
    }

    console.log('[GROUP CREATING] ' + JSON.stringify(payload))

    var response
    if(isJira) { // Jira
      response = await api.asApp().requestJira(route`/rest/api/3/group`, {
        method: 'POST',
        headers: {
          Accept: 'application/json',
          'Content-Type': 'application/json',
        },
        body: JSON.stringify(payload),
      });
    } else { // confluence
      response = await api.asApp().requestConfluence(route`/wiki/rest/api/group`, {
        method: 'POST',
        headers: {
          Accept: 'application/json',
          'Content-Type': 'application/json',
        },
        body: JSON.stringify(payload),
      });
    }
    
      const responseBody = await response.json()
      if (!response.ok) {
        console.log('[GROUP CREATING] failed')
        console.error(responseBody)
        return null
      } else {
        console.log('[GROUP CREATING] done')
        console.debug(responseBody)
        return responseBody.groupId
      }

Here are permissions from manifest (I have already tried recommended, granular and both):

permissions:
  scopes:
    - write:confluence-groups
    - manage:jira-configuration
    - write:confluence-space
    - read:space.permission:confluence
    - write:space.permission:confluence
    - read:jira-work
    - write:jira-work
    - read:confluence-space.summary
    - read:group:jira
    - write:group:jira
    - read:group:confluence
    - write:group:confluence

And here is the response from Jira and Confluence on it:

// Jira
{
  errorMessages: [
    'An error occurred: com.atlassian.idp.client.exceptions.AuthorizationException: {"schemas":["urn:ietf:params:scim:api:messages:2.0:Error"],"status":"403","detail":"You do not have permission to make this request.","errorType":"InsufficientPermissions","message":"You do not have permission to make this request."}'
  ],
  errors: {}
}

// Confluence 
{
  statusCode: 500,
  message: 'com.netflix.hystrix.exception.HystrixRuntimeException: CreateGroupIdentityPlatformCommand failed and no fallback available.'
}

P.S. With the same app I can create Project/Space and do a lot of other thing, however it fails on group creating

Regards, Roman

2 Likes

According to the doc:
https://developer.atlassian.com/cloud/confluence/rest/api-group-group/#api-wiki-rest-api-group-post

Permissions required : User must be a site admin.

So either you should use asUser() instead of asApp() or your app needs to be a site admin (scary).

But the fact that the doc also says:

Connect apps cannot access this REST resource.

I’m uncertain if the api call will work in Forge…

1 Like

Hi @danielwester
and thank you for the prompt answer!

Hm…Grant app site admin is also an option. Cause it’s custom development for a particular client.
Unfortunately, I do not know where to change it. Can you suggest how to do that?

The app already has access to create groups (granted by ‘manage:jira-configuration’)

I also tried to do it via ‘asUser()’, however got

{
  message: 'Authentication required',
  name: 'NEEDS_AUTHENTICATION_ERR',
  stack: ''
}

Seems I need to grant the app to do actions on behalf of me.
How to make it? The last time I clicked smth like that was fired by UI forge’s element, now app w/o any UI.

P.S. I can create groups via REST client

Ok,
By adding an empty UI block I was asked to Allow access to the app to make calls as me.

However, this workaround hasn’t worked. The following error message returned (after allowing access) on the call ‘asUser’:

{
  message: 'Authentication required',
  name: 'NEEDS_AUTHENTICATION_ERR',
  stack: ''
}

:frowning:

Hi @RomaBubyakin,

I’ve just tried this and I can confirm that I’ve been able to create a group.

I’ve tried this in Confluence using asUser and here is my code:

const createGroup = async (value) => {

  const bodyData = {
      name: "ForgeGroup"
  }

  console.log(bodyData);

  const res = await api
    .asUser()
    .requestConfluence(route`/wiki/rest/api/group`, {
      method: "POST",
      body: JSON.stringify(bodyData)
    });

  console.log(`Response: ${res.status} ${res.statusText}`);
  console.log(await res.json());

And the corresponding output in the forge tunnel console:

INFO    05:19:40.011  0f3932111cd03e65  { name: 'ForgeGroup' }
INFO    05:19:42.733  0f3932111cd03e65  Response: 201 Created
INFO    05:19:42.733  0f3932111cd03e65  {
  type: 'group',
  name: 'forgegroup',
  id: 'e5ea7c12-40ef-4343-9222-b19f4712b28c',
  _links: {
    self: 'https://<site>.atlassian.net/wiki/rest/experimental/group/forgegroup',
    base: 'https://<site>.atlassian.net/wiki',
    context: '/wiki'

These are the scopes of the app (note that I also have the read:confluence-groups one because I’m also requesting a GET /wiki/rest/api/group in the same app but that can be removed if the app doesn’t require that:

permissions:
  scopes:
    - 'write:confluence-groups'
    - 'read:confluence-groups'

I’m not really sure about what might be happening here, but I would suggest trying to isolate the issue by running a new app with just the required method and scopes and make sure that it’s deployed and installed with those scopes. Or maybe try to uninstall (forge uninstall) and re-install the app.

Caterina

2 Likes

Hi @ccurti,
Thank you for the response!
The stand-alone app works well. However, in my application, it does not work.

I supposed it’s related to
Note: This [api.asUser()] context method is only available in modules that support the UI kit. (link)

In my use case group should be created on issue transition.
It means:

  • I cannot do it with asApp() because of an internal bug
  • I cannot do it with asUser() as well because issue transition is not a direct UI interaction
  • Doing it via basic auth is also not a good decision, because of adding site admin credentials to the source code

:frowning:

I made it with a Basic Auth request as a temporary, but working solution.
So plugin installation will require an additional step to add a personal token to store it securely.