test-trusted.py
288 lines
| 8.9 KiB
| text/x-python
|
PythonLexer
/ tests / test-trusted.py
Alexis S. L. Carvalho
|
r3551 | # Since it's not easy to write a test that portably deals | ||
# with files from different users/groups, we cheat a bit by | ||||
# monkey-patching some functions in the util module | ||||
Pulkit Goyal
|
r28934 | from __future__ import absolute_import, print_function | ||
Pulkit Goyal
|
r28913 | |||
Alexis S. L. Carvalho
|
r3551 | import os | ||
Augie Fackler
|
r41388 | import sys | ||
Pulkit Goyal
|
r28913 | from mercurial import ( | ||
error, | ||||
Augie Fackler
|
r41388 | pycompat, | ||
Pulkit Goyal
|
r28913 | ui as uimod, | ||
util, | ||||
) | ||||
Augie Fackler
|
r41388 | from mercurial.utils import stringutil | ||
Alexis S. L. Carvalho
|
r3551 | |||
hgrc = os.environ['HGRCPATH'] | ||||
Augie Fackler
|
r41388 | f = open(hgrc, 'rb') | ||
Alexis S. L. Carvalho
|
r5523 | basehgrc = f.read() | ||
f.close() | ||||
Alexis S. L. Carvalho
|
r3551 | |||
Augie Fackler
|
r41388 | def _maybesysstr(v): | ||
if isinstance(v, bytes): | ||||
return pycompat.sysstr(v) | ||||
return pycompat.sysstr(stringutil.pprint(v)) | ||||
def bprint(*args, **kwargs): | ||||
print(*[_maybesysstr(a) for a in args], | ||||
**{k: _maybesysstr(v) for k, v in kwargs.items()}) | ||||
# avoid awkward interleaving with ui object's output | ||||
sys.stdout.flush() | ||||
def testui(user=b'foo', group=b'bar', tusers=(), tgroups=(), | ||||
cuser=b'foo', cgroup=b'bar', debug=False, silent=False, | ||||
Ry4an Brase
|
r13493 | report=True): | ||
Alexis S. L. Carvalho
|
r3551 | # user, group => owners of the file | ||
# tusers, tgroups => trusted users/groups | ||||
# cuser, cgroup => user/group of the current process | ||||
# write a global hgrc with the list of trusted users/groups and | ||||
# some setting so that we can be sure it was read | ||||
Augie Fackler
|
r41388 | f = open(hgrc, 'wb') | ||
Alexis S. L. Carvalho
|
r5523 | f.write(basehgrc) | ||
Augie Fackler
|
r41388 | f.write(b'\n[paths]\n') | ||
f.write(b'global = /some/path\n\n') | ||||
Alexis S. L. Carvalho
|
r3551 | |||
if tusers or tgroups: | ||||
Augie Fackler
|
r41388 | f.write(b'[trusted]\n') | ||
Alexis S. L. Carvalho
|
r3551 | if tusers: | ||
Augie Fackler
|
r41388 | f.write(b'users = %s\n' % b', '.join(tusers)) | ||
Alexis S. L. Carvalho
|
r3551 | if tgroups: | ||
Augie Fackler
|
r41388 | f.write(b'groups = %s\n' % b', '.join(tgroups)) | ||
Alexis S. L. Carvalho
|
r3551 | f.close() | ||
# override the functions that give names to uids and gids | ||||
def username(uid=None): | ||||
if uid is None: | ||||
return cuser | ||||
return user | ||||
util.username = username | ||||
def groupname(gid=None): | ||||
if gid is None: | ||||
Augie Fackler
|
r41388 | return b'bar' | ||
Alexis S. L. Carvalho
|
r3551 | return group | ||
util.groupname = groupname | ||||
Martin Geisler
|
r8657 | def isowner(st): | ||
Alexis S. L. Carvalho
|
r3677 | return user == cuser | ||
util.isowner = isowner | ||||
Alexis S. L. Carvalho
|
r3551 | # try to read everything | ||
#print '# File belongs to user %s, group %s' % (user, group) | ||||
#print '# trusted users = %s; trusted groups = %s' % (tusers, tgroups) | ||||
Augie Fackler
|
r41388 | kind = (b'different', b'same') | ||
who = (b'', b'user', b'group', b'user and the group') | ||||
Alexis S. L. Carvalho
|
r3551 | trusted = who[(user in tusers) + 2*(group in tgroups)] | ||
if trusted: | ||||
Augie Fackler
|
r41388 | trusted = b', but we trust the ' + trusted | ||
bprint(b'# %s user, %s group%s' % (kind[user == cuser], | ||||
kind[group == cgroup], | ||||
trusted)) | ||||
Alexis S. L. Carvalho
|
r3551 | |||
Yuya Nishihara
|
r30559 | u = uimod.ui.load() | ||
Boris Feld
|
r34859 | # disable the configuration registration warning | ||
# | ||||
# the purpose of this test is to check the old behavior, not to validate the | ||||
# behavior from registered item. so we silent warning related to unregisted | ||||
# config. | ||||
Augie Fackler
|
r41388 | u.setconfig(b'devel', b'warn-config-unknown', False, b'test') | ||
u.setconfig(b'devel', b'all-warnings', False, b'test') | ||||
u.setconfig(b'ui', b'debug', pycompat.bytestr(bool(debug))) | ||||
u.setconfig(b'ui', b'report_untrusted', pycompat.bytestr(bool(report))) | ||||
u.readconfig(b'.hg/hgrc') | ||||
Alexis S. L. Carvalho
|
r3552 | if silent: | ||
return u | ||||
Augie Fackler
|
r41388 | bprint(b'trusted') | ||
for name, path in u.configitems(b'paths'): | ||||
bprint(b' ', name, b'=', util.pconvert(path)) | ||||
bprint(b'untrusted') | ||||
for name, path in u.configitems(b'paths', untrusted=True): | ||||
bprint(b'.', end=b' ') | ||||
u.config(b'paths', name) # warning with debug=True | ||||
bprint(b'.', end=b' ') | ||||
u.config(b'paths', name, untrusted=True) # no warnings | ||||
bprint(name, b'=', util.pconvert(path)) | ||||
Pulkit Goyal
|
r28934 | print() | ||
Alexis S. L. Carvalho
|
r3551 | |||
return u | ||||
Augie Fackler
|
r41388 | os.mkdir(b'repo') | ||
os.chdir(b'repo') | ||||
os.mkdir(b'.hg') | ||||
f = open(b'.hg/hgrc', 'wb') | ||||
f.write(b'[paths]\n') | ||||
f.write(b'local = /another/path\n\n') | ||||
Alexis S. L. Carvalho
|
r3551 | f.close() | ||
#print '# Everything is run by user foo, group bar\n' | ||||
# same user, same group | ||||
testui() | ||||
# same user, different group | ||||
Augie Fackler
|
r41388 | testui(group=b'def') | ||
Alexis S. L. Carvalho
|
r3551 | # different user, same group | ||
Augie Fackler
|
r41388 | testui(user=b'abc') | ||
Alexis S. L. Carvalho
|
r3551 | # ... but we trust the group | ||
Augie Fackler
|
r41388 | testui(user=b'abc', tgroups=[b'bar']) | ||
Alexis S. L. Carvalho
|
r3551 | # different user, different group | ||
Augie Fackler
|
r41388 | testui(user=b'abc', group=b'def') | ||
Alexis S. L. Carvalho
|
r3551 | # ... but we trust the user | ||
Augie Fackler
|
r41388 | testui(user=b'abc', group=b'def', tusers=[b'abc']) | ||
Alexis S. L. Carvalho
|
r3551 | # ... but we trust the group | ||
Augie Fackler
|
r41388 | testui(user=b'abc', group=b'def', tgroups=[b'def']) | ||
Alexis S. L. Carvalho
|
r3551 | # ... but we trust the user and the group | ||
Augie Fackler
|
r41388 | testui(user=b'abc', group=b'def', tusers=[b'abc'], tgroups=[b'def']) | ||
Alexis S. L. Carvalho
|
r3551 | # ... but we trust all users | ||
Augie Fackler
|
r41388 | bprint(b'# we trust all users') | ||
testui(user=b'abc', group=b'def', tusers=[b'*']) | ||||
Alexis S. L. Carvalho
|
r3551 | # ... but we trust all groups | ||
Augie Fackler
|
r41388 | bprint(b'# we trust all groups') | ||
testui(user=b'abc', group=b'def', tgroups=[b'*']) | ||||
Alexis S. L. Carvalho
|
r3551 | # ... but we trust the whole universe | ||
Augie Fackler
|
r41388 | bprint(b'# we trust all users and groups') | ||
testui(user=b'abc', group=b'def', tusers=[b'*'], tgroups=[b'*']) | ||||
Alexis S. L. Carvalho
|
r3551 | # ... check that users and groups are in different namespaces | ||
Augie Fackler
|
r41388 | bprint(b"# we don't get confused by users and groups with the same name") | ||
testui(user=b'abc', group=b'def', tusers=[b'def'], tgroups=[b'abc']) | ||||
Alexis S. L. Carvalho
|
r3551 | # ... lists of user names work | ||
Augie Fackler
|
r41388 | bprint(b"# list of user names") | ||
testui(user=b'abc', group=b'def', tusers=[b'foo', b'xyz', b'abc', b'bleh'], | ||||
tgroups=[b'bar', b'baz', b'qux']) | ||||
Alexis S. L. Carvalho
|
r3551 | # ... lists of group names work | ||
Augie Fackler
|
r41388 | bprint(b"# list of group names") | ||
testui(user=b'abc', group=b'def', tusers=[b'foo', b'xyz', b'bleh'], | ||||
tgroups=[b'bar', b'def', b'baz', b'qux']) | ||||
Alexis S. L. Carvalho
|
r3551 | |||
Augie Fackler
|
r41388 | bprint(b"# Can't figure out the name of the user running this process") | ||
testui(user=b'abc', group=b'def', cuser=None) | ||||
Alexis S. L. Carvalho
|
r3552 | |||
Augie Fackler
|
r41388 | bprint(b"# prints debug warnings") | ||
u = testui(user=b'abc', group=b'def', cuser=b'foo', debug=True) | ||||
Alexis S. L. Carvalho
|
r3552 | |||
Augie Fackler
|
r41388 | bprint(b"# report_untrusted enabled without debug hides warnings") | ||
u = testui(user=b'abc', group=b'def', cuser=b'foo', report=False) | ||||
Ry4an Brase
|
r13493 | |||
Augie Fackler
|
r41388 | bprint(b"# report_untrusted enabled with debug shows warnings") | ||
u = testui(user=b'abc', group=b'def', cuser=b'foo', debug=True, report=False) | ||||
Ry4an Brase
|
r13493 | |||
Augie Fackler
|
r41388 | bprint(b"# ui.readconfig sections") | ||
filename = b'foobar' | ||||
f = open(filename, 'wb') | ||||
f.write(b'[foobar]\n') | ||||
f.write(b'baz = quux\n') | ||||
Alexis S. L. Carvalho
|
r3552 | f.close() | ||
Augie Fackler
|
r41388 | u.readconfig(filename, sections=[b'foobar']) | ||
bprint(u.config(b'foobar', b'baz')) | ||||
Alexis S. L. Carvalho
|
r3552 | |||
Pulkit Goyal
|
r28934 | print() | ||
Augie Fackler
|
r41388 | bprint(b"# read trusted, untrusted, new ui, trusted") | ||
Yuya Nishihara
|
r30559 | u = uimod.ui.load() | ||
Boris Feld
|
r34859 | # disable the configuration registration warning | ||
# | ||||
# the purpose of this test is to check the old behavior, not to validate the | ||||
# behavior from registered item. so we silent warning related to unregisted | ||||
# config. | ||||
Augie Fackler
|
r41388 | u.setconfig(b'devel', b'warn-config-unknown', False, b'test') | ||
u.setconfig(b'devel', b'all-warnings', False, b'test') | ||||
u.setconfig(b'ui', b'debug', b'on') | ||||
Alexis S. L. Carvalho
|
r3552 | u.readconfig(filename) | ||
Matt Mackall
|
r8190 | u2 = u.copy() | ||
Alexis S. L. Carvalho
|
r3552 | def username(uid=None): | ||
Augie Fackler
|
r41388 | return b'foo' | ||
Alexis S. L. Carvalho
|
r3552 | util.username = username | ||
Augie Fackler
|
r41388 | u2.readconfig(b'.hg/hgrc') | ||
bprint(b'trusted:') | ||||
bprint(u2.config(b'foobar', b'baz')) | ||||
bprint(b'untrusted:') | ||||
bprint(u2.config(b'foobar', b'baz', untrusted=True)) | ||||
Alexis S. L. Carvalho
|
r3552 | |||
Pulkit Goyal
|
r28934 | print() | ||
Augie Fackler
|
r41388 | bprint(b"# error handling") | ||
Alexis S. L. Carvalho
|
r3552 | |||
Pierre-Yves David
|
r26587 | def assertraises(f, exc=error.Abort): | ||
Alexis S. L. Carvalho
|
r3552 | try: | ||
f() | ||||
Gregory Szorc
|
r25660 | except exc as inst: | ||
Augie Fackler
|
r41388 | bprint(b'raised', inst.__class__.__name__) | ||
Alexis S. L. Carvalho
|
r3552 | else: | ||
Augie Fackler
|
r41388 | bprint(b'no exception?!') | ||
Alexis S. L. Carvalho
|
r3552 | |||
Augie Fackler
|
r41388 | bprint(b"# file doesn't exist") | ||
os.unlink(b'.hg/hgrc') | ||||
assert not os.path.exists(b'.hg/hgrc') | ||||
Alexis S. L. Carvalho
|
r3552 | testui(debug=True, silent=True) | ||
Augie Fackler
|
r41388 | testui(user=b'abc', group=b'def', debug=True, silent=True) | ||
Alexis S. L. Carvalho
|
r3552 | |||
Pulkit Goyal
|
r28934 | print() | ||
Augie Fackler
|
r41388 | bprint(b"# parse error") | ||
f = open(b'.hg/hgrc', 'wb') | ||||
f.write(b'foo') | ||||
Alexis S. L. Carvalho
|
r3552 | f.close() | ||
Gregory Szorc
|
r41638 | # This is a hack to remove b'' prefixes from ParseError.__bytes__ on | ||
# Python 3. | ||||
def normalizeparseerror(e): | ||||
if pycompat.ispy3: | ||||
args = [a.decode('utf-8') for a in e.args] | ||||
else: | ||||
args = e.args | ||||
return error.ParseError(*args) | ||||
Matt Mackall
|
r8144 | try: | ||
Augie Fackler
|
r41388 | testui(user=b'abc', group=b'def', silent=True) | ||
Gregory Szorc
|
r25660 | except error.ParseError as inst: | ||
Gregory Szorc
|
r41638 | bprint(normalizeparseerror(inst)) | ||
Alexis S. L. Carvalho
|
r3552 | |||
Matt Mackall
|
r8144 | try: | ||
testui(debug=True, silent=True) | ||||
Gregory Szorc
|
r25660 | except error.ParseError as inst: | ||
Gregory Szorc
|
r41638 | bprint(normalizeparseerror(inst)) | ||
Martijn Pieters
|
r31472 | |||
print() | ||||
Augie Fackler
|
r41388 | bprint(b'# access typed information') | ||
with open(b'.hg/hgrc', 'wb') as f: | ||||
f.write(b'''\ | ||||
Martijn Pieters
|
r31472 | [foo] | ||
sub=main | ||||
sub:one=one | ||||
sub:two=two | ||||
path=monty/python | ||||
bool=true | ||||
int=42 | ||||
bytes=81mb | ||||
list=spam,ham,eggs | ||||
''') | ||||
Augie Fackler
|
r41388 | u = testui(user=b'abc', group=b'def', cuser=b'foo', silent=True) | ||
Matt Harbison
|
r31857 | def configpath(section, name, default=None, untrusted=False): | ||
path = u.configpath(section, name, default, untrusted) | ||||
if path is None: | ||||
return None | ||||
return util.pconvert(path) | ||||
Augie Fackler
|
r41388 | bprint(b'# suboptions, trusted and untrusted') | ||
trusted = u.configsuboptions(b'foo', b'sub') | ||||
untrusted = u.configsuboptions(b'foo', b'sub', untrusted=True) | ||||
bprint( | ||||
Martijn Pieters
|
r31472 | (trusted[0], sorted(trusted[1].items())), | ||
(untrusted[0], sorted(untrusted[1].items()))) | ||||
Augie Fackler
|
r41388 | bprint(b'# path, trusted and untrusted') | ||
bprint(configpath(b'foo', b'path'), configpath(b'foo', b'path', untrusted=True)) | ||||
bprint(b'# bool, trusted and untrusted') | ||||
bprint(u.configbool(b'foo', b'bool'), | ||||
u.configbool(b'foo', b'bool', untrusted=True)) | ||||
bprint(b'# int, trusted and untrusted') | ||||
bprint( | ||||
u.configint(b'foo', b'int', 0), | ||||
u.configint(b'foo', b'int', 0, untrusted=True)) | ||||
bprint(b'# bytes, trusted and untrusted') | ||||
bprint( | ||||
u.configbytes(b'foo', b'bytes', 0), | ||||
u.configbytes(b'foo', b'bytes', 0, untrusted=True)) | ||||
bprint(b'# list, trusted and untrusted') | ||||
bprint( | ||||
u.configlist(b'foo', b'list', []), | ||||
u.configlist(b'foo', b'list', [], untrusted=True)) | ||||