Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

Code Block
{
	"iss": "client_id_from_atlassian",
	"sub": "flow_id",
	"aud": "https://ihubprod.rixter.net/prod/incoming/token",
	"iat": "currentTimeSeconds",
	"exp": "plus currentTimeSeconds 1200",
	"flow": "flow_id"
}

Output from the signed will be xxxxx.yyyyy.zzzzz

...

Code Block
{
    "grant_type":"urn:ietf:params:oauth:grant-type:jwt-ihub:jwt:bearer",
    "assertion":"{{JWT}}"
}

Replace the {{JWT}} with the signed token from above step.

This URN structure indicates:

  • urn: Namespace denoting a Uniform Resource Name

  • ihub: Identifies the IHub system

  • jwt: Specifies a JSON Web Token (JWT)

  • bearer: Indicates the token type is bearer

Response

If valid it will return a body like below

Code Block
{
	"  access_token": "0AY_VpZg4WI2L0VYjXAc9ccwpNwj2TYbAJ-p_o2pCHHXWGK1N_ADhZ93y0e2REPitoJkbWs-VsEby0pTQXj1tP-5Wh8RTgbqKY343JvMhU_5EKf1vwXA8jUXeANWte-om4yGBIxbI7CUodb1hOfRuIw23RdSHHvvUWsKraffuJ0xpOr5sLTzc3NAdsak4Xjc8IjujDMoHDoEqECzL12CCCrVnkiDuGPN4TNnLbBPnqM91L-6a5WlC-bD3EetEmW7lS3R0GK7HLexgMiAwhKc9EXIaV3v_nwJZp2STQZcxc8Q4YcqCtKgOsSfrPb87MQ3z2FE2sBOmhIziLBS5WifWvYaBhWcyvxifWxj5aw7Ad0GvKRQzsbdP2GwGN385D42jpSupk9oxui84wuq6wr9bRsWagYwQjto-x2y7gZwyrMVyQpBOy_3QhhIY32Xw6vJoOj-2ypRWaIXnhzUyfJkfJv5j_4a8F_grpI9wigVS1X5cdkIBiis-ZuvYvkx8fIJ0nn59bFsomi1qvJ9pMyWByVZ4w2yeyuso7-Q2qRX0jrWbRrOsOMsl5xQoOZYZRm-bFz66ynd-3q50qjcr2QtdQy_ZXcQSZ1bkQjwio7x0jz_Yptn9Bfl2geOeioze__d-_9xd1ZZMwixbYvWuxklh8hvakVyIkc9ZfBMo5dMen6l89Wy0tsq5-65zvB8SZyfk-qikWic_ouVo26kJ1Xe-ni36dxxzoxM-Vu4Wuq3kJ58QhVcUhj9m6zzk866trqqJnx28cBJQ9ofhf8BjcOilO-bt8dJV-ZrRS2-vyFZq9_1d9tvMZe6WJ1JoVbQx7tne_7S8y3Jn2n3Frc18loQ9__Ye_5ic04ed367srWvi-1ojYbOM79hy5mnu2VMU6isFz_hUVqqj5Z-xXZIsQ02vW0g_uIltq85waObt8wYziv4lZU--UUZ1h72McynvY81gqQlB4uVIb6Sp_XprXYtgIOsIYkuQsp7so9ls4Rl7l52Zdkd1W29IF2w",
	"token_type": "Bearer",
	"expires_in": 3599'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiI0ZjAxOWQ0My00OTAwLTNhOTgtYWEwNi00NjE0M2Y0MGMwNjEiLCJzdWIiOiIzNGNkMzNlNC1iNmFhLTQ4MzctODc1Yi03ZWQ4MWFhMzk2ZDYiLCJleHAiOjE3MTkzMTk0MDMsImlhdCI6MTcxOTMxOTA4MX0.jljJZJMcYD4PapgraNXoZZWUYOR3mPcTgpd_CUeeqCU',
  token_type: 'Bearer',
  expires_in: 1719319403
} 

Use the Bearer token

To trigger the flow send the request to https://ihubprod.rixter.net/incoming/webhook/jwt with the http header Authorization: Bearer {{access_token}}

In this call you will include any data that the integration will process.

Example code for trigging flow

Python

Code Block
pip install PyJWT requests cryptography

The private key is stored in a file called privateKey.txt in this example

Expand
titlePython example code
Code Block
import jwt
import requests
import time
import os
from pathlib import Path
import unittest

class TestIncomingJWTIntegration(unittest.TestCase):

    def setUp(self):
        self.timeout = 10  # seconds
        self.maxDiff = None

    def test_should_return_a_valid_bearer(self):
        headers = {
            "alg": "RS256",
            "typ": "JWT"
        }

        current_time = int(time.time())

        payload = {
            'iss': 'copy from trigger page',
            'sub': 'copy from trigger page',
            'aud': 'https://ihubprod.rixter.net/prod/incoming/token',
            'iat': current_time,
            'exp': current_time + 1200
        }

        private_key_path = Path(__file__).parent / 'privateKey.txt'
        with open(private_key_path, 'r') as file:
            private_key = file.read()

        token = jwt.encode(payload, private_key, algorithm='RS256', headers=headers)
        # print('Generated JWT:', token)

        data = {
            "grant_type": "urn:ihub:jwt:bearer",
            "assertion": token
        }

        access_token = None
        # test generate jwt
        try:
            response = requests.post(payload['aud'], json=data, headers={'Content-Type': 'application/json'})
            response.raise_for_status()
            access_token = response.json().get('access_token')
        except requests.exceptions.RequestException as error:
            print('Error:', error.response.json() if error.response else str(error))

        self.assertIsNotNone(access_token)

        # test trigger flow
        incoming_data = {
            "issueKey": "SERVICENOW-1",
            "description": "HEJ",
            "summary": "Ticket from test case"
        }

        try:
            response = requests.post(
                "https://ihubprod.rixter.net/prod/incoming/webhook/jwt",
                json=incoming_data,
                headers={
                    'Content-Type': 'application/json',
                    'Authorization': f'Bearer {access_token}'
                }
            )
            response.raise_for_status()
            print(response.json())
        except requests.exceptions.RequestException as error:
            print('Error:', error.response.json() if error.response else str(error))

if __name__ == '__main__':
    unittest.main()

Javascript

The private key is stored in a file called privateKey.txt in this example

Expand
titleJavascript example code
Code Block
var jwt = require('jsonwebtoken');
const axios = require('axios');
import { expect } from "chai";
const fs = require('fs');
const path = require('path');

describe('Incoming JWT integration test', function() {  // Use function() to access this.timeout
  this.timeout(10000);  // Increase timeout to 10 seconds

  it('should return a valid bearer', async () => {

    const headers = {
      "alg": "RS256",
      "typ": "JWT"
    };

    const currentTime = Math.floor(Date.now() / 1000);

    const payload = {
      iss: 'copy from trigger page',
      sub: 'copy from trigger page',
      aud: 'https://ihubprod.rixter.net/prod/incoming/token',
      iat: currentTime,
      exp: (currentTime + 1200)
    };

    const privateKeyPath = path.join(__dirname, 'privateKey.txt');
    const privateKey = fs.readFileSync(privateKeyPath, 'utf8');

    const token = jwt.sign(payload, privateKey, { algorithm: 'RS256', header: headers });
    //console.log('Generated JWT:', token);

    const data = {
      "grant_type": "urn:ihub:jwt:bearer",
      "assertion": token
    };

    let access_token;
    //test generate jwt
    try {
      const response = await axios.post(payload.aud, data, {
        headers: {
          'Content-Type': 'application/json'
        }
      });
      access_token = response.data.access_token;
    } catch (error) {
      console.error('Error:', error.response ? error.response.data : error.message);
    }
    expect(access_token).not.to.be.equal(undefined);
    //test trigger flow
    const incomingData = {
      "issueKey": "SERVICENOW-1",
      "description": "HEJ",
      "summary":"Ticket from test case"
    };
    try {
      const response = await axios.post("https://ihubprod.rixter.net/prod/incoming/webhook/jwt", incomingData, {
        headers: {
          'Content-Type': 'application/json',
          'Authorization': 'Bearer '+access_token
        }
      });
      console.log(response.data)
    } catch (error) {
      console.error('Error:', error.response ? error.response.data : error.message);
    }

  });
});