jenkins-bot merged this change.

View Change

Approvals: Zhuyifei1999: Looks good to me, approved jenkins-bot: Verified
[bugfix] Use site.userinfo getter instead of site._userinfo within api

- use site.userinfo getter instead of site._userinfo within api which may
cause unexpected results

Request.__init__():
- use str instead of repr when raising Error "attempted as IP"
which is the same in Python 2 and 3
- show the unexpected username with then the warning

CachedRequest._uniquedescriptionstr():
- compare against LoginStatus.AS_USER
- remove max expression because login_status cannot be higher than
LoginStatus.NOT_LOGGED_IN

dry_api_tests.py:
- update test due to the new exception behaviour
- use subTest for each subtest
- additional tests within test_unexpected_user and test_normal

Bug: T243794
Change-Id: I448b851a844ea58351a2a4fed8b16db9855c6eab
---
M pywikibot/data/api.py
M tests/dry_api_tests.py
2 files changed, 38 insertions(+), 38 deletions(-)

diff --git a/pywikibot/data/api.py b/pywikibot/data/api.py
index 0702d38..bbb9b57 100644
--- a/pywikibot/data/api.py
+++ b/pywikibot/data/api.py
@@ -1246,18 +1246,19 @@
# 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('API write action attempted without userinfo')
- assert('name' in self.site._userinfo)
+ try:
+ username = self.site.userinfo['name']
+ except KeyError:
+ raise Error('API write action attempted without user name')

- if 'anon' in self.site._userinfo:
- raise Error('API write action attempted as IP %r'
- % self.site._userinfo['name'])
+ if 'anon' in self.site.userinfo:
+ raise Error("API write action attempted as IP '{}'"
+ .format(username))

- if not self.site.user():
+ if not self.site.user() or self.site.username() != username:
pywikibot.warning(
- 'API write action by unexpected username commenced.\n'
- 'userinfo: %r' % self.site._userinfo)
+ 'API write action by unexpected username {} commenced.\n'
+ 'userinfo: {!r}'.format(username, self.site.userinfo))

# MediaWiki 1.23 allows assertion for any action,
# whereas earlier WMF wikis and others used an extension which
@@ -2176,19 +2177,16 @@
"""
login_status = self.site._loginstatus

- if login_status > pywikibot.site.LoginStatus.NOT_LOGGED_IN and \
- hasattr(self.site, '_userinfo') and \
- 'name' in self.site._userinfo:
+ if login_status >= pywikibot.site.LoginStatus.AS_USER:
# This uses the format of Page.__repr__, without performing
# config.console_encoding as done by Page.__repr__.
# The returned value can't be encoded to anything other than
# ascii otherwise it creates an exception when _create_file_name()
# tries to encode it as utf-8.
- user_key = 'User(User:%s)' % self.site._userinfo['name']
+ user_key = 'User(User:{})'.format(self.site.userinfo['name'])
else:
- user_key = pywikibot.site.LoginStatus(
- max(login_status, pywikibot.site.LoginStatus.NOT_LOGGED_IN))
- user_key = repr(user_key)
+ user_key = repr(pywikibot.site.LoginStatus(
+ pywikibot.site.LoginStatus.NOT_LOGGED_IN))

request_key = repr(sorted(self._encoded_items().items()))
return repr(self.site) + user_key + request_key
diff --git a/tests/dry_api_tests.py b/tests/dry_api_tests.py
index a9a03d3..4d29f85 100644
--- a/tests/dry_api_tests.py
+++ b/tests/dry_api_tests.py
@@ -241,36 +241,38 @@

def test_no_user(self):
"""Test Request object when not a user."""
- site = self.get_site()
+ self.site._userinfo = {}
+ with self.subTest(userinfo=self.site._userinfo):
+ self.assertRaisesRegex(pywikibot.Error,
+ 'API write action attempted without user',
+ Request, site=self.site,
+ parameters={'action': 'edit'})

- del site._userinfo
- self.assertRaisesRegex(pywikibot.Error, ' without userinfo',
- Request, site=site,
- parameters={'action': 'edit'})
-
- site._userinfo = {'name': '1.2.3.4', 'groups': [], 'anon': ''}
-
- # unicode string with "u" is returned with Python 2
- self.assertRaisesRegex(pywikibot.Error, " as IP u?'1.2.3.4'",
- Request, site=site,
- parameters={'action': 'edit'})
+ self.site._userinfo = {'name': '1.2.3.4', 'groups': [], 'anon': ''}
+ with self.subTest(userinfo=self.site._userinfo):
+ self.assertRaisesRegex(pywikibot.Error, " as IP '1.2.3.4'",
+ Request, site=self.site,
+ parameters={'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 = 'myusername'
+ self.site._userinfo = {'name': 'other_username', 'groups': [],
+ 'id': '1'}
+ self.site._username = 'myusername'
# Ignore warning: API write action by unexpected username commenced.
with patch('pywikibot.warning'):
- Request(site=site, parameters={'action': 'edit'})
+ Request(site=self.site, parameters={'action': 'edit'})
+ self.assertNotEqual(self.site.user(), self.site.username())
+ self.assertNotEqual(self.site.userinfo['name'], self.site.username())
+ self.assertFalse(self.site.logged_in())

def test_normal(self):
"""Test Request object when username is correct."""
- site = self.get_site()
- site._userinfo = {'name': 'myusername', 'groups': []}
- site._username = 'myusername'
-
- Request(site=site, parameters={'action': 'edit'})
+ self.site._userinfo = {'name': 'myusername', 'groups': [], 'id': '1'}
+ self.site._username = 'myusername'
+ Request(site=self.site, parameters={'action': 'edit'})
+ self.assertEqual(self.site.user(), self.site.username())
+ self.assertTrue(self.site.logged_in())


class DryMimeTests(TestCase):
@@ -310,7 +312,7 @@
# fake write test needs the config username
site = self.get_site()
site._username = 'myusername'
- site._userinfo = {'name': 'myusername', 'groups': []}
+ site._userinfo = {'name': 'myusername', 'groups': [], 'id': '1'}
parameters = {'action': 'upload', 'file': 'MP_sounds.png',
'filename': join_images_path('MP_sounds.png')}
req = Request(site=site, mime=True, parameters=parameters)

To view, visit change 572484. To unsubscribe, or for help writing mail filters, visit settings.

Gerrit-Project: pywikibot/core
Gerrit-Branch: master
Gerrit-MessageType: merged
Gerrit-Change-Id: I448b851a844ea58351a2a4fed8b16db9855c6eab
Gerrit-Change-Number: 572484
Gerrit-PatchSet: 5
Gerrit-Owner: Xqt <info@gno.de>
Gerrit-Reviewer: D3r1ck <alangiderick@gmail.com>
Gerrit-Reviewer: D3r1ck01 <xsavitar.wiki@aol.com>
Gerrit-Reviewer: Dalba <dalba.wiki@gmail.com>
Gerrit-Reviewer: Dvorapa <dvorapa@seznam.cz>
Gerrit-Reviewer: Framawiki <framawiki@tools.wmflabs.org>
Gerrit-Reviewer: Huji <huji.huji@gmail.com>
Gerrit-Reviewer: JJMC89 <JJMC89.Wikimedia@gmail.com>
Gerrit-Reviewer: Ladsgroup <Ladsgroup@gmail.com>
Gerrit-Reviewer: Legoktm <legoktm@member.fsf.org>
Gerrit-Reviewer: Matěj Suchánek <matejsuchanek97@gmail.com>
Gerrit-Reviewer: Merlijn van Deen <valhallasw@arctus.nl>
Gerrit-Reviewer: Mpaa <mpaa.wiki@gmail.com>
Gerrit-Reviewer: Multichill <maarten@mdammers.nl>
Gerrit-Reviewer: XZise <CommodoreFabianus@gmx.de>
Gerrit-Reviewer: Zhuyifei1999 <zhuyifei1999@gmail.com>
Gerrit-Reviewer: jenkins-bot (75)