jenkins-bot has submitted this change and it was merged.

Change subject: Client side write API assert and warning
......................................................................


Client side write API assert and warning

If the username is not present or is a IP address, raise
an error without sending a request to the server.

Warn if the site user is not a config specified username.

Change-Id: I5074bdb14c1cdc37e2ac2b5a71887c1b699f95b4
---
M pywikibot/data/api.py
M tests/dry_api_tests.py
2 files changed, 57 insertions(+), 2 deletions(-)

Approvals:
  John Vandenberg: Looks good to me, but someone else must approve
  XZise: Looks good to me, approved
  jenkins-bot: Verified



diff --git a/pywikibot/data/api.py b/pywikibot/data/api.py
index 741a75b..bc3c42a 100644
--- a/pywikibot/data/api.py
+++ b/pywikibot/data/api.py
@@ -25,7 +25,7 @@
 
 import pywikibot
 from pywikibot import config, login
-from pywikibot.tools import MediaWikiVersion, deprecated, itergroup
+from pywikibot.tools import MediaWikiVersion, deprecated, itergroup, ip
 from pywikibot.exceptions import (
     Server504Error, Server414Error, FatalServerError, Error
 )
@@ -800,6 +800,22 @@
             "wbcreateclaim", "wbremoveclaims", "wbsetclaimvalue",
             "wbsetreference", "wbremovereferences"
         )
+        # Client side verification that the request is being performed
+        # by a logged in user, and warn if it isn't a config username.
+        if self.write:
+            if not hasattr(self.site, "_userinfo"):
+                raise Error(u"API write action attempted without userinfo")
+            assert('name' in self.site._userinfo)
+
+            if ip.is_IP(self.site._userinfo['name']):
+                raise Error(u"API write action attempted as IP %r"
+                            % self.site._userinfo['name'])
+
+            if not self.site.user():
+                pywikibot.warning(
+                    u"API write action by unexpected username commenced.\n"
+                    u"userinfo: %r" % self.site._userinfo)
+
         # MediaWiki 1.23 allows assertion for any action,
         # whereas earlier WMF wikis and others used an extension which
         # could only allow assert for action=edit.
diff --git a/tests/dry_api_tests.py b/tests/dry_api_tests.py
index eb260c1..fa78901 100644
--- a/tests/dry_api_tests.py
+++ b/tests/dry_api_tests.py
@@ -180,6 +180,40 @@
         self.assertEqual(en_user_path, ar_user_path)
 
 
+class DryWriteAssertTests(DefaultDrySiteTestCase):
+
+    """Test client site write assert."""
+
+    def test_no_user(self):
+        """Test Request object when not a user."""
+        site = self.get_site()
+
+        del site._userinfo
+        self.assertRaisesRegex(pywikibot.Error, ' without userinfo',
+                               Request, site=site, action='edit')
+
+        site._userinfo = {'name': '1.2.3.4', 'groups': []}
+
+        self.assertRaisesRegex(pywikibot.Error, " as IP '1.2.3.4'",
+                               Request, site=site, action='edit')
+
+    def test_unexpected_user(self):
+        """Test Request object when username is not correct."""
+        site = self.get_site()
+        site._userinfo = {'name': 'other_username', 'groups': []}
+        site._username[0] = 'myusername'
+
+        Request(site=site, action='edit')
+
+    def test_normal(self):
+        """Test Request object when username is correct."""
+        site = self.get_site()
+        site._userinfo = {'name': 'myusername', 'groups': []}
+        site._username[0] = 'myusername'
+
+        Request(site=site, action='edit')
+
+
 class DryMimeTests(TestCase):
 
     """Test MIME request handling without a real site."""
@@ -197,6 +231,7 @@
         self.assertEqual(file_content, submsg.get_payload(decode=True))
 
     def test_mime_file_container(self):
+        """Test Request._build_mime_request encodes binary."""
         local_filename = os.path.join(_images_dir, 'MP_sounds.png')
         with open(local_filename, 'rb') as f:
             file_content = f.read()
@@ -213,7 +248,11 @@
 
     def test_upload_object(self):
         """Test Request object prepared to upload."""
-        req = Request(site=self.get_site(), action="upload",
+        # fake write test needs the config username
+        site = self.get_site()
+        site._username[0] = 'myusername'
+        site._userinfo = {'name': 'myusername', 'groups': []}
+        req = Request(site=site, action="upload",
                       file='MP_sounds.png', mime=True,
                       filename=os.path.join(_images_dir, 'MP_sounds.png'))
         self.assertEqual(req.mime, True)

-- 
To view, visit https://gerrit.wikimedia.org/r/186152
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings

Gerrit-MessageType: merged
Gerrit-Change-Id: I5074bdb14c1cdc37e2ac2b5a71887c1b699f95b4
Gerrit-PatchSet: 3
Gerrit-Project: pywikibot/core
Gerrit-Branch: master
Gerrit-Owner: John Vandenberg <[email protected]>
Gerrit-Reviewer: John Vandenberg <[email protected]>
Gerrit-Reviewer: Ladsgroup <[email protected]>
Gerrit-Reviewer: Merlijn van Deen <[email protected]>
Gerrit-Reviewer: Mpaa <[email protected]>
Gerrit-Reviewer: XZise <[email protected]>
Gerrit-Reviewer: jenkins-bot <>

_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to