Skip to content

Commit

Permalink
issue ansible#61672: make jenkins_plugin module work in a session whe…
Browse files Browse the repository at this point in the history
…n CSRF … (ansible#61673)

* issue ansible#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 ansible#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.
  • Loading branch information
JKDingwall authored and anas-shami committed Sep 23, 2019
1 parent 26106f4 commit 3afcd47
Show file tree
Hide file tree
Showing 3 changed files with 19 additions and 11 deletions.
5 changes: 3 additions & 2 deletions lib/ansible/module_utils/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -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.).
Expand Down Expand Up @@ -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)
Expand Down
12 changes: 7 additions & 5 deletions lib/ansible/modules/web_infrastructure/jenkins_plugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -264,6 +264,7 @@
'''

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
Expand All @@ -287,8 +288,11 @@ def __init__(self, module):

# 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
Expand Down Expand Up @@ -332,7 +336,8 @@ def _get_url_data(
# 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'])
Expand Down Expand Up @@ -405,7 +410,6 @@ def install(self):
script_data = {
'script': install_script
}
script_data.update(self.crumb)
data = urlencode(script_data)

# Send the installation request
Expand Down Expand Up @@ -691,14 +695,12 @@ def _enabling(self, action):
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():
Expand Down
13 changes: 9 additions & 4 deletions lib/ansible/modules/web_infrastructure/jenkins_script.py
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,7 @@
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
Expand All @@ -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='')

Expand Down Expand Up @@ -163,16 +165,19 @@ 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,
module.params['url'] + "/scriptText",
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='')
Expand Down

0 comments on commit 3afcd47

Please sign in to comment.