To answer your earlier question, the ‘tenant base url’ is https://testtablet.atlassian.net for JIRA and Log in with Atlassian account for Confluence.
I got a trivial add-on working with atlassian-jwt and I think I know what the issue was: we should be providing the addon key as the ‘clientKey’ parameter because that’s what JIRA and Confluence Connect expect the iss
to be. Below is the listing for a minimal add-on (Python 2.7) that pings the REST api and prints the result to show that it was able to authenticate.
It listens on port 5000. You will need to provide a publicly-accessible https url (e.g. the url you get from running ngrok http 5000
) as the first argument.
requirements.txt:
atlassian-jwt==1.6
click==6.7
Flask==0.12
itsdangerous==0.24
Jinja2==2.9.5
MarkupSafe==1.0
PyJWT==1.4.2
requests==2.13.0
Werkzeug==0.11.15
wheel==0.24.0
addon.py:
import sys
import atlassian_jwt
import requests
from flask import Flask, request, jsonify, redirect
ADDON_KEY = "simple-flask-addon"
clients = {}
if __name__ == '__main__':
app = Flask(__name__)
descriptor = {
"key": ADDON_KEY,
"baseUrl": sys.argv[1],
"authentication": {"type": "jwt"},
"scopes": ["READ"],
"lifecycle": {
"installed": "/register",
"enabled": "/ping",
},
}
class SimpleAuthenticator(atlassian_jwt.Authenticator):
def get_shared_secret(self, client_key):
return clients[client_key]['sharedSecret']
auth = SimpleAuthenticator()
@app.route('/', methods=['GET'])
def redirect_to_descriptor():
return redirect('/descriptor')
@app.route('/descriptor', methods=['GET'])
def get_descriptor():
return jsonify(descriptor)
@app.route('/register', methods=['POST'])
def register():
client = request.get_json()
clients[client['clientKey']] = client
return '', 204
@app.route('/ping', methods=['POST'])
def ping():
client_key = auth.authenticate(request.method, request.url, request.headers)
client = clients[client_key]
ping_url = '/rest/api/latest/issue/TEST-2'
jwt_authorization = 'JWT %s' % atlassian_jwt.encode_token('GET', ping_url, ADDON_KEY, client['sharedSecret'])
result = requests.get(client['baseUrl'].rstrip('/') + ping_url, headers={'Authorization': jwt_authorization})
result.raise_for_status()
print '%s - %s' % (result.status_code, result.json())
return '', 204
app.run(debug=True)