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:
parent
4bddf9e12c
commit
cbc9742747
2 changed files with 43 additions and 16 deletions
2
changelogs/fragments/3838-jira-token.yaml
Normal file
2
changelogs/fragments/3838-jira-token.yaml
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
minor_changes:
|
||||||
|
- jira - add support for Bearer token auth (https://github.com/ansible-collections/community.general/pull/3838).
|
|
@ -36,15 +36,22 @@ options:
|
||||||
|
|
||||||
username:
|
username:
|
||||||
type: str
|
type: str
|
||||||
required: true
|
|
||||||
description:
|
description:
|
||||||
- The username to log-in with.
|
- The username to log-in with.
|
||||||
|
- Must be used with I(password). Mutually exclusive with I(token).
|
||||||
|
|
||||||
password:
|
password:
|
||||||
type: str
|
type: str
|
||||||
required: true
|
|
||||||
description:
|
description:
|
||||||
- The password to log-in with.
|
- 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:
|
project:
|
||||||
type: str
|
type: str
|
||||||
|
@ -206,7 +213,7 @@ options:
|
||||||
done.
|
done.
|
||||||
|
|
||||||
notes:
|
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)."
|
- "To use with JIRA Cloud, pass the login e-mail as the I(username) and the API token as I(password)."
|
||||||
|
|
||||||
author:
|
author:
|
||||||
|
@ -408,8 +415,9 @@ class JIRA(StateModuleHelper):
|
||||||
choices=['attach', 'create', 'comment', 'edit', 'update', 'fetch', 'transition', 'link', 'search'],
|
choices=['attach', 'create', 'comment', 'edit', 'update', 'fetch', 'transition', 'link', 'search'],
|
||||||
aliases=['command'], required=True
|
aliases=['command'], required=True
|
||||||
),
|
),
|
||||||
username=dict(type='str', required=True),
|
username=dict(type='str'),
|
||||||
password=dict(type='str', required=True, no_log=True),
|
password=dict(type='str', no_log=True),
|
||||||
|
token=dict(type='str', no_log=True),
|
||||||
project=dict(type='str', ),
|
project=dict(type='str', ),
|
||||||
summary=dict(type='str', ),
|
summary=dict(type='str', ),
|
||||||
description=dict(type='str', ),
|
description=dict(type='str', ),
|
||||||
|
@ -432,6 +440,17 @@ class JIRA(StateModuleHelper):
|
||||||
validate_certs=dict(default=True, type='bool'),
|
validate_certs=dict(default=True, type='bool'),
|
||||||
account_id=dict(type='str'),
|
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=(
|
required_if=(
|
||||||
('operation', 'attach', ['issue', 'attachment']),
|
('operation', 'attach', ['issue', 'attachment']),
|
||||||
('operation', 'create', ['project', 'issuetype', 'summary']),
|
('operation', 'create', ['project', 'issuetype', 'summary']),
|
||||||
|
@ -441,7 +460,6 @@ class JIRA(StateModuleHelper):
|
||||||
('operation', 'link', ['linktype', 'inwardissue', 'outwardissue']),
|
('operation', 'link', ['linktype', 'inwardissue', 'outwardissue']),
|
||||||
('operation', 'search', ['jql']),
|
('operation', 'search', ['jql']),
|
||||||
),
|
),
|
||||||
mutually_exclusive=[('assignee', 'account_id')],
|
|
||||||
supports_check_mode=False
|
supports_check_mode=False
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -642,19 +660,26 @@ class JIRA(StateModuleHelper):
|
||||||
if data and content_type == 'application/json':
|
if data and content_type == 'application/json':
|
||||||
data = json.dumps(data)
|
data = json.dumps(data)
|
||||||
|
|
||||||
|
headers = {}
|
||||||
|
if isinstance(additional_headers, dict):
|
||||||
|
headers = additional_headers.copy()
|
||||||
|
|
||||||
# NOTE: fetch_url uses a password manager, which follows the
|
# NOTE: fetch_url uses a password manager, which follows the
|
||||||
# standard request-then-challenge basic-auth semantics. However as
|
# standard request-then-challenge basic-auth semantics. However as
|
||||||
# JIRA allows some unauthorised operations it doesn't necessarily
|
# JIRA allows some unauthorised operations it doesn't necessarily
|
||||||
# send the challenge, so the request occurs as the anonymous user,
|
# send the challenge, so the request occurs as the anonymous user,
|
||||||
# resulting in unexpected results. To work around this we manually
|
# 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.
|
# the requests as authorized for this user.
|
||||||
|
|
||||||
|
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),
|
auth = to_text(base64.b64encode(to_bytes('{0}:{1}'.format(self.vars.username, self.vars.password),
|
||||||
errors='surrogate_or_strict')))
|
errors='surrogate_or_strict')))
|
||||||
|
|
||||||
headers = {}
|
|
||||||
if isinstance(additional_headers, dict):
|
|
||||||
headers = additional_headers.copy()
|
|
||||||
headers.update({
|
headers.update({
|
||||||
"Content-Type": content_type,
|
"Content-Type": content_type,
|
||||||
"Authorization": "Basic %s" % auth,
|
"Authorization": "Basic %s" % auth,
|
||||||
|
|
Loading…
Reference in a new issue