1
0
Fork 0
mirror of https://github.com/ansible-collections/community.general.git synced 2024-09-14 20:13:21 +02:00

jira - Add support for Bearer token auth (#3838)

* jira - Add support for Bearer token auth

* jira - Add support for Bearer token auth

* added changelog fragment

Co-authored-by: Felix Fontein <felix@fontein.de>

* fix indent issue

* fix overindent

* jira - Add support for Bearer token auth

* jira - Add support for Bearer token auth

* added changelog fragment

* minor doc fix to be clearer.

Be clear about the exclusivity between username and token
as well as password and token.

* Update changelogs/fragments/3838-jira-token.yaml

Co-authored-by: Felix Fontein <felix@fontein.de>

* Update plugins/modules/web_infrastructure/jira.py

Co-authored-by: Felix Fontein <felix@fontein.de>

* Update plugins/modules/web_infrastructure/jira.py

Co-authored-by: Felix Fontein <felix@fontein.de>

Co-authored-by: Felix Fontein <felix@fontein.de>
This commit is contained in:
Kambiz Aghaiepour 2021-12-09 15:24:24 -05:00 committed by GitHub
parent 4bddf9e12c
commit cbc9742747
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 43 additions and 16 deletions

View file

@ -0,0 +1,2 @@
minor_changes:
- jira - add support for Bearer token auth (https://github.com/ansible-collections/community.general/pull/3838).

View file

@ -36,15 +36,22 @@ options:
username:
type: str
required: true
description:
- The username to log-in with.
- Must be used with I(password). Mutually exclusive with I(token).
password:
type: str
required: true
description:
- The password to log-in with.
- Must be used with I(username). Mutually exclusive with I(token).
token:
type: str
description:
- The personal access token to log-in with.
- Mutually exclusive with I(username) and I(password).
version_added: 4.2.0
project:
type: str
@ -206,7 +213,7 @@ options:
done.
notes:
- "Currently this only works with basic-auth."
- "Currently this only works with basic-auth, or tokens."
- "To use with JIRA Cloud, pass the login e-mail as the I(username) and the API token as I(password)."
author:
@ -408,8 +415,9 @@ class JIRA(StateModuleHelper):
choices=['attach', 'create', 'comment', 'edit', 'update', 'fetch', 'transition', 'link', 'search'],
aliases=['command'], required=True
),
username=dict(type='str', required=True),
password=dict(type='str', required=True, no_log=True),
username=dict(type='str'),
password=dict(type='str', no_log=True),
token=dict(type='str', no_log=True),
project=dict(type='str', ),
summary=dict(type='str', ),
description=dict(type='str', ),
@ -432,6 +440,17 @@ class JIRA(StateModuleHelper):
validate_certs=dict(default=True, type='bool'),
account_id=dict(type='str'),
),
mutually_exclusive=[
['username', 'token'],
['password', 'token'],
['assignee', 'account_id'],
],
required_together=[
['username', 'password'],
],
required_one_of=[
['username', 'token'],
],
required_if=(
('operation', 'attach', ['issue', 'attachment']),
('operation', 'create', ['project', 'issuetype', 'summary']),
@ -441,7 +460,6 @@ class JIRA(StateModuleHelper):
('operation', 'link', ['linktype', 'inwardissue', 'outwardissue']),
('operation', 'search', ['jql']),
),
mutually_exclusive=[('assignee', 'account_id')],
supports_check_mode=False
)
@ -642,23 +660,30 @@ class JIRA(StateModuleHelper):
if data and content_type == 'application/json':
data = json.dumps(data)
headers = {}
if isinstance(additional_headers, dict):
headers = additional_headers.copy()
# NOTE: fetch_url uses a password manager, which follows the
# standard request-then-challenge basic-auth semantics. However as
# JIRA allows some unauthorised operations it doesn't necessarily
# send the challenge, so the request occurs as the anonymous user,
# resulting in unexpected results. To work around this we manually
# inject the basic-auth header up-front to ensure that JIRA treats
# inject the auth header up-front to ensure that JIRA treats
# the requests as authorized for this user.
auth = to_text(base64.b64encode(to_bytes('{0}:{1}'.format(self.vars.username, self.vars.password),
errors='surrogate_or_strict')))
headers = {}
if isinstance(additional_headers, dict):
headers = additional_headers.copy()
headers.update({
"Content-Type": content_type,
"Authorization": "Basic %s" % auth,
})
if self.vars.token is not None:
headers.update({
"Content-Type": content_type,
"Authorization": "Bearer %s" % self.vars.token,
})
else:
auth = to_text(base64.b64encode(to_bytes('{0}:{1}'.format(self.vars.username, self.vars.password),
errors='surrogate_or_strict')))
headers.update({
"Content-Type": content_type,
"Authorization": "Basic %s" % auth,
})
response, info = fetch_url(
self.module, url, data=data, method=method, timeout=self.vars.timeout, headers=headers