140 lines
3.6 KiB
Python
140 lines
3.6 KiB
Python
#!/usr/bin/env python3
|
|
|
|
# Copyright: (c) 2019, Alexandre Iooss <erdnaxe@crans.org>
|
|
# GNU General Public License v3.0+
|
|
|
|
"""
|
|
This module simulate the edition of a MoinMoin wiki page
|
|
|
|
Example:
|
|
moinmoin_page:
|
|
url: https://wiki.crans.org/WikiErdnaxe
|
|
user: WikiErdnaxe
|
|
password: HoTuNeMeConnaisPas
|
|
content: "{{ lookup('template', 'mapage.j2') }}"
|
|
revision_comment: Bip bip
|
|
"""
|
|
|
|
import re
|
|
import urllib.error
|
|
import urllib.parse
|
|
import urllib.request
|
|
|
|
from ansible.module_utils.basic import AnsibleModule
|
|
|
|
|
|
def login(url, user, password):
|
|
"""
|
|
Log in and return session cookie or None if failed
|
|
|
|
:param url: random wiki url (not root page)
|
|
:param user: wiki user
|
|
:param password: user's password
|
|
:return: session cookie
|
|
"""
|
|
# Send a HTTP POST request
|
|
data = urllib.parse.urlencode({
|
|
'action': 'login',
|
|
'login': 'Connexion',
|
|
'name': user,
|
|
'password': password
|
|
}).encode()
|
|
req = urllib.request.Request(url, data)
|
|
try:
|
|
response = urllib.request.urlopen(req)
|
|
cookie = response.getheader('set-cookie')
|
|
except urllib.error.HTTPError as e:
|
|
# If 404, then also return header
|
|
cookie = e.getheader('set-cookie')
|
|
|
|
# Check that authentication worked
|
|
assert cookie, 'server did not return a session cookie'
|
|
return cookie
|
|
|
|
|
|
def edit_ticket(url, cookie):
|
|
"""
|
|
Return edition ticket of url
|
|
|
|
:param url: page to edit
|
|
:param cookie: session cookie
|
|
:return: edit ticket
|
|
"""
|
|
# Send request with session cookie
|
|
suffix = "?action=edit&editor=text"
|
|
req = urllib.request.Request(url + suffix)
|
|
req.add_header("Cookie", cookie)
|
|
content = urllib.request.urlopen(req).read().decode('utf-8')
|
|
|
|
# Search for ticket
|
|
search = re.search('name=\"ticket\" value=\"([^\"]*)\"', content)
|
|
assert search, 'no edit ticket was found'
|
|
return search.group(1)
|
|
|
|
|
|
def edit(url, user, password, content, revision_comment):
|
|
"""
|
|
Edit a MoinMoin wiki page
|
|
|
|
:param url: page to edit
|
|
:param user: wiki user
|
|
:param password: user's password
|
|
:param content: content to place on this page
|
|
:param revision_comment: revision comment
|
|
"""
|
|
# Connect and get edit ticket
|
|
cookie = login(url, user, password)
|
|
ticket = edit_ticket(url, cookie)
|
|
|
|
# Create request and send
|
|
data = {
|
|
'button_save': 'Enregistrer les modifications',
|
|
'category': '',
|
|
'comment': revision_comment.encode("utf-8"),
|
|
'savetext': content.encode("utf-8"),
|
|
'action': 'edit',
|
|
'ticket': ticket
|
|
}
|
|
req = urllib.request.Request(url, urllib.parse.urlencode(data).encode())
|
|
req.add_header("Cookie", cookie)
|
|
urllib.request.urlopen(req)
|
|
|
|
|
|
def run_module():
|
|
# Define arguments that should be passed
|
|
module_args = {
|
|
'url': {'type': 'str', 'required': True},
|
|
'user': {'type': 'str', 'required': True},
|
|
'password': {'type': 'str', 'required': True},
|
|
'content': {'type': 'str', 'required': True},
|
|
'revision_comment': {'type': 'str', 'required': True},
|
|
}
|
|
|
|
# Define arguments that are returned
|
|
result = {
|
|
'changed': False,
|
|
}
|
|
|
|
# Our AnsibleModule
|
|
module = AnsibleModule(
|
|
argument_spec=module_args,
|
|
supports_check_mode=True
|
|
)
|
|
|
|
# TODO: get current wiki page and compare
|
|
result['changed'] = True
|
|
|
|
# If not is check mode and page need to change, then update page
|
|
if not module.check_mode and result['changed']:
|
|
edit(**module.params)
|
|
|
|
module.exit_json(**result)
|
|
|
|
|
|
def main():
|
|
run_module()
|
|
|
|
|
|
if __name__ == '__main__':
|
|
main()
|