* issue #61672: make jenkins_plugin module work in a session when CSRF enabled This commit modifies the signature of `fetch_url` so that a cookie jar can be specified allowing multiple calls to operate with the same session. It uses a similar construct to the `Request` class to initialise the cookie jar if it is not provided. The jenkins_plugin module is modified to create a cookie jar if CSRF is enabled. This cookie jar is then submitted with every call to fetch_url. Also changed is to submit the crumb in the request headers rather than in the data field. This has been tested with Jenkins 2.176. * issue #61672: fix jenkins_script module This commit modifies the jenkins_script module to use the authorization crumb in a session in a similar fashion to the jenkins_plugin change for the same issue.
This commit is contained in:
parent
dfc023209f
commit
76b5b90bd6
3 changed files with 19 additions and 11 deletions
|
@ -1423,7 +1423,7 @@ def url_argument_spec():
|
|||
|
||||
def fetch_url(module, url, data=None, headers=None, method=None,
|
||||
use_proxy=True, force=False, last_mod_time=None, timeout=10,
|
||||
use_gssapi=False, unix_socket=None, ca_path=None):
|
||||
use_gssapi=False, unix_socket=None, ca_path=None, cookies=None):
|
||||
"""Sends a request via HTTP(S) or FTP (needs the module as parameter)
|
||||
|
||||
:arg module: The AnsibleModule (used to get username, password etc. (s.b.).
|
||||
|
@ -1479,7 +1479,8 @@ def fetch_url(module, url, data=None, headers=None, method=None,
|
|||
client_cert = module.params.get('client_cert')
|
||||
client_key = module.params.get('client_key')
|
||||
|
||||
cookies = cookiejar.LWPCookieJar()
|
||||
if not isinstance(cookies, cookiejar.CookieJar):
|
||||
cookies = cookiejar.LWPCookieJar()
|
||||
|
||||
r = None
|
||||
info = dict(url=url, status=-1)
|
||||
|
|
|
@ -264,6 +264,7 @@ state:
|
|||
'''
|
||||
|
||||
from ansible.module_utils.basic import AnsibleModule, to_bytes
|
||||
from ansible.module_utils.six.moves import http_cookiejar as cookiejar
|
||||
from ansible.module_utils.six.moves.urllib.parse import urlencode
|
||||
from ansible.module_utils.urls import fetch_url, url_argument_spec
|
||||
from ansible.module_utils._text import to_native, text_type, binary_type
|
||||
|
@ -287,8 +288,11 @@ class JenkinsPlugin(object):
|
|||
|
||||
# Crumb
|
||||
self.crumb = {}
|
||||
# Cookie jar for crumb session
|
||||
self.cookies = None
|
||||
|
||||
if self._csrf_enabled():
|
||||
self.cookies = cookiejar.LWPCookieJar()
|
||||
self.crumb = self._get_crumb()
|
||||
|
||||
# Get list of installed plugins
|
||||
|
@ -332,7 +336,8 @@ class JenkinsPlugin(object):
|
|||
# Get the URL data
|
||||
try:
|
||||
response, info = fetch_url(
|
||||
self.module, url, timeout=self.timeout, **kwargs)
|
||||
self.module, url, timeout=self.timeout, cookies=self.cookies,
|
||||
headers=self.crumb, **kwargs)
|
||||
|
||||
if info['status'] != 200:
|
||||
self.module.fail_json(msg=msg_status, details=info['msg'])
|
||||
|
@ -405,7 +410,6 @@ class JenkinsPlugin(object):
|
|||
script_data = {
|
||||
'script': install_script
|
||||
}
|
||||
script_data.update(self.crumb)
|
||||
data = urlencode(script_data)
|
||||
|
||||
# Send the installation request
|
||||
|
@ -691,14 +695,12 @@ class JenkinsPlugin(object):
|
|||
def _pm_query(self, action, msg):
|
||||
url = "%s/pluginManager/plugin/%s/%s" % (
|
||||
self.params['url'], self.params['name'], action)
|
||||
data = urlencode(self.crumb)
|
||||
|
||||
# Send the request
|
||||
self._get_url_data(
|
||||
url,
|
||||
msg_status="Plugin not found. %s" % url,
|
||||
msg_exception="%s has failed." % msg,
|
||||
data=data)
|
||||
msg_exception="%s has failed." % msg)
|
||||
|
||||
|
||||
def main():
|
||||
|
|
|
@ -105,6 +105,7 @@ output:
|
|||
import json
|
||||
|
||||
from ansible.module_utils.basic import AnsibleModule
|
||||
from ansible.module_utils.six.moves import http_cookiejar as cookiejar
|
||||
from ansible.module_utils.six.moves.urllib.parse import urlencode
|
||||
from ansible.module_utils.urls import fetch_url
|
||||
from ansible.module_utils._text import to_native
|
||||
|
@ -121,10 +122,11 @@ def is_csrf_protection_enabled(module):
|
|||
return json.loads(content).get('useCrumbs', False)
|
||||
|
||||
|
||||
def get_crumb(module):
|
||||
def get_crumb(module, cookies):
|
||||
resp, info = fetch_url(module,
|
||||
module.params['url'] + '/crumbIssuer/api/json',
|
||||
method='GET')
|
||||
method='GET',
|
||||
cookies=cookies)
|
||||
if info["status"] != 200:
|
||||
module.fail_json(msg="HTTP error " + str(info["status"]) + " " + info["msg"], output='')
|
||||
|
||||
|
@ -163,8 +165,10 @@ def main():
|
|||
script_contents = module.params['script']
|
||||
|
||||
headers = {}
|
||||
cookies = None
|
||||
if is_csrf_protection_enabled(module):
|
||||
crumb = get_crumb(module)
|
||||
cookies = cookiejar.LWPCookieJar()
|
||||
crumb = get_crumb(module, cookies)
|
||||
headers = {crumb['crumbRequestField']: crumb['crumb']}
|
||||
|
||||
resp, info = fetch_url(module,
|
||||
|
@ -172,7 +176,8 @@ def main():
|
|||
data=urlencode({'script': script_contents}),
|
||||
headers=headers,
|
||||
method="POST",
|
||||
timeout=module.params['timeout'])
|
||||
timeout=module.params['timeout'],
|
||||
cookies=cookies)
|
||||
|
||||
if info["status"] != 200:
|
||||
module.fail_json(msg="HTTP error " + str(info["status"]) + " " + info["msg"], output='')
|
||||
|
|
Loading…
Reference in a new issue