test-trusted.py
320 lines
| 8.6 KiB
| text/x-python
|
PythonLexer
/ tests / test-trusted.py
|
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 | ||||
|
r28934 | from __future__ import absolute_import, print_function | ||
|
r28913 | |||
|
r3551 | import os | ||
|
r41388 | import sys | ||
|
r28913 | from mercurial import ( | ||
error, | ||||
|
r41388 | pycompat, | ||
|
r28913 | ui as uimod, | ||
util, | ||||
) | ||||
|
r41388 | from mercurial.utils import stringutil | ||
|
r3551 | |||
hgrc = os.environ['HGRCPATH'] | ||||
|
r41388 | f = open(hgrc, 'rb') | ||
|
r5523 | basehgrc = f.read() | ||
f.close() | ||||
|
r3551 | |||
|
r43346 | |||
|
r41388 | def _maybesysstr(v): | ||
if isinstance(v, bytes): | ||||
return pycompat.sysstr(v) | ||||
return pycompat.sysstr(stringutil.pprint(v)) | ||||
|
r43346 | |||
|
r41388 | def bprint(*args, **kwargs): | ||
|
r43346 | print( | ||
*[_maybesysstr(a) for a in args], | ||||
**{k: _maybesysstr(v) for k, v in kwargs.items()} | ||||
) | ||||
|
r41388 | # avoid awkward interleaving with ui object's output | ||
sys.stdout.flush() | ||||
|
r43346 | |||
def testui( | ||||
user=b'foo', | ||||
group=b'bar', | ||||
tusers=(), | ||||
tgroups=(), | ||||
cuser=b'foo', | ||||
cgroup=b'bar', | ||||
debug=False, | ||||
silent=False, | ||||
report=True, | ||||
): | ||||
|
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 | ||||
|
r41388 | f = open(hgrc, 'wb') | ||
|
r5523 | f.write(basehgrc) | ||
|
r41388 | f.write(b'\n[paths]\n') | ||
f.write(b'global = /some/path\n\n') | ||||
|
r3551 | |||
if tusers or tgroups: | ||||
|
r41388 | f.write(b'[trusted]\n') | ||
|
r3551 | if tusers: | ||
|
r41388 | f.write(b'users = %s\n' % b', '.join(tusers)) | ||
|
r3551 | if tgroups: | ||
|
r41388 | f.write(b'groups = %s\n' % b', '.join(tgroups)) | ||
|
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 | ||||
|
r43346 | |||
|
r3551 | util.username = username | ||
def groupname(gid=None): | ||||
if gid is None: | ||||
|
r41388 | return b'bar' | ||
|
r3551 | return group | ||
|
r43346 | |||
|
r3551 | util.groupname = groupname | ||
|
r8657 | def isowner(st): | ||
|
r3677 | return user == cuser | ||
|
r43346 | |||
|
r3677 | util.isowner = isowner | ||
|
r3551 | # try to read everything | ||
|
r43346 | # print '# File belongs to user %s, group %s' % (user, group) | ||
# print '# trusted users = %s; trusted groups = %s' % (tusers, tgroups) | ||||
|
r41388 | kind = (b'different', b'same') | ||
who = (b'', b'user', b'group', b'user and the group') | ||||
|
r43346 | trusted = who[(user in tusers) + 2 * (group in tgroups)] | ||
|
r3551 | if trusted: | ||
|
r41388 | trusted = b', but we trust the ' + trusted | ||
|
r43346 | bprint( | ||
b'# %s user, %s group%s' | ||||
% (kind[user == cuser], kind[group == cgroup], trusted) | ||||
) | ||||
|
r3551 | |||
|
r30559 | u = uimod.ui.load() | ||
|
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. | ||||
|
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') | ||||
|
r3552 | if silent: | ||
return u | ||||
|
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' ') | ||||
|
r43346 | u.config(b'paths', name) # warning with debug=True | ||
|
r41388 | bprint(b'.', end=b' ') | ||
|
r43346 | u.config(b'paths', name, untrusted=True) # no warnings | ||
|
r41388 | bprint(name, b'=', util.pconvert(path)) | ||
|
r28934 | print() | ||
|
r3551 | |||
return u | ||||
|
r43346 | |||
|
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') | ||||
|
r3551 | f.close() | ||
|
r43346 | # print '# Everything is run by user foo, group bar\n' | ||
|
r3551 | |||
# same user, same group | ||||
testui() | ||||
# same user, different group | ||||
|
r41388 | testui(group=b'def') | ||
|
r3551 | # different user, same group | ||
|
r41388 | testui(user=b'abc') | ||
|
r3551 | # ... but we trust the group | ||
|
r41388 | testui(user=b'abc', tgroups=[b'bar']) | ||
|
r3551 | # different user, different group | ||
|
r41388 | testui(user=b'abc', group=b'def') | ||
|
r3551 | # ... but we trust the user | ||
|
r41388 | testui(user=b'abc', group=b'def', tusers=[b'abc']) | ||
|
r3551 | # ... but we trust the group | ||
|
r41388 | testui(user=b'abc', group=b'def', tgroups=[b'def']) | ||
|
r3551 | # ... but we trust the user and the group | ||
|
r41388 | testui(user=b'abc', group=b'def', tusers=[b'abc'], tgroups=[b'def']) | ||
|
r3551 | # ... but we trust all users | ||
|
r41388 | bprint(b'# we trust all users') | ||
testui(user=b'abc', group=b'def', tusers=[b'*']) | ||||
|
r3551 | # ... but we trust all groups | ||
|
r41388 | bprint(b'# we trust all groups') | ||
testui(user=b'abc', group=b'def', tgroups=[b'*']) | ||||
|
r3551 | # ... but we trust the whole universe | ||
|
r41388 | bprint(b'# we trust all users and groups') | ||
testui(user=b'abc', group=b'def', tusers=[b'*'], tgroups=[b'*']) | ||||
|
r3551 | # ... check that users and groups are in different namespaces | ||
|
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']) | ||||
|
r3551 | # ... lists of user names work | ||
|
r41388 | bprint(b"# list of user names") | ||
|
r43346 | testui( | ||
user=b'abc', | ||||
group=b'def', | ||||
tusers=[b'foo', b'xyz', b'abc', b'bleh'], | ||||
tgroups=[b'bar', b'baz', b'qux'], | ||||
) | ||||
|
r3551 | # ... lists of group names work | ||
|
r41388 | bprint(b"# list of group names") | ||
|
r43346 | testui( | ||
user=b'abc', | ||||
group=b'def', | ||||
tusers=[b'foo', b'xyz', b'bleh'], | ||||
tgroups=[b'bar', b'def', b'baz', b'qux'], | ||||
) | ||||
|
r3551 | |||
|
r41388 | bprint(b"# Can't figure out the name of the user running this process") | ||
testui(user=b'abc', group=b'def', cuser=None) | ||||
|
r3552 | |||
|
r41388 | bprint(b"# prints debug warnings") | ||
u = testui(user=b'abc', group=b'def', cuser=b'foo', debug=True) | ||||
|
r3552 | |||
|
r41388 | bprint(b"# report_untrusted enabled without debug hides warnings") | ||
u = testui(user=b'abc', group=b'def', cuser=b'foo', report=False) | ||||
|
r13493 | |||
|
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) | ||||
|
r13493 | |||
|
r41388 | bprint(b"# ui.readconfig sections") | ||
filename = b'foobar' | ||||
f = open(filename, 'wb') | ||||
f.write(b'[foobar]\n') | ||||
f.write(b'baz = quux\n') | ||||
|
r3552 | f.close() | ||
|
r41388 | u.readconfig(filename, sections=[b'foobar']) | ||
bprint(u.config(b'foobar', b'baz')) | ||||
|
r3552 | |||
|
r28934 | print() | ||
|
r41388 | bprint(b"# read trusted, untrusted, new ui, trusted") | ||
|
r30559 | u = uimod.ui.load() | ||
|
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. | ||||
|
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') | ||||
|
r3552 | u.readconfig(filename) | ||
|
r8190 | u2 = u.copy() | ||
|
r43346 | |||
|
r3552 | def username(uid=None): | ||
|
r41388 | return b'foo' | ||
|
r43346 | |||
|
r3552 | util.username = username | ||
|
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)) | ||||
|
r3552 | |||
|
r28934 | print() | ||
|
r41388 | bprint(b"# error handling") | ||
|
r3552 | |||
|
r43346 | |||
|
r26587 | def assertraises(f, exc=error.Abort): | ||
|
r3552 | try: | ||
f() | ||||
|
r25660 | except exc as inst: | ||
|
r41388 | bprint(b'raised', inst.__class__.__name__) | ||
|
r3552 | else: | ||
|
r41388 | bprint(b'no exception?!') | ||
|
r3552 | |||
|
r43346 | |||
|
r41388 | bprint(b"# file doesn't exist") | ||
os.unlink(b'.hg/hgrc') | ||||
assert not os.path.exists(b'.hg/hgrc') | ||||
|
r3552 | testui(debug=True, silent=True) | ||
|
r41388 | testui(user=b'abc', group=b'def', debug=True, silent=True) | ||
|
r3552 | |||
|
r28934 | print() | ||
|
r41388 | bprint(b"# parse error") | ||
f = open(b'.hg/hgrc', 'wb') | ||||
f.write(b'foo') | ||||
|
r3552 | f.close() | ||
|
r8144 | try: | ||
|
r41388 | testui(user=b'abc', group=b'def', silent=True) | ||
|
r46506 | except error.ConfigError as inst: | ||
|
r46500 | bprint(inst.format()) | ||
|
r3552 | |||
|
r8144 | try: | ||
testui(debug=True, silent=True) | ||||
|
r46506 | except error.ConfigError as inst: | ||
|
r46500 | bprint(inst.format()) | ||
|
r31472 | |||
print() | ||||
|
r41388 | bprint(b'# access typed information') | ||
with open(b'.hg/hgrc', 'wb') as f: | ||||
|
r43346 | f.write( | ||
b'''\ | ||||
|
r31472 | [foo] | ||
sub=main | ||||
sub:one=one | ||||
sub:two=two | ||||
path=monty/python | ||||
bool=true | ||||
int=42 | ||||
bytes=81mb | ||||
list=spam,ham,eggs | ||||
|
r43346 | ''' | ||
) | ||||
|
r41388 | u = testui(user=b'abc', group=b'def', cuser=b'foo', silent=True) | ||
|
r43346 | |||
|
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) | ||||
|
r43346 | |||
|
r41388 | bprint(b'# suboptions, trusted and untrusted') | ||
trusted = u.configsuboptions(b'foo', b'sub') | ||||
untrusted = u.configsuboptions(b'foo', b'sub', untrusted=True) | ||||
bprint( | ||||
|
r31472 | (trusted[0], sorted(trusted[1].items())), | ||
|
r43346 | (untrusted[0], sorted(untrusted[1].items())), | ||
) | ||||
|
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') | ||||
|
r43346 | bprint( | ||
u.configbool(b'foo', b'bool'), u.configbool(b'foo', b'bool', untrusted=True) | ||||
) | ||||
|
r41388 | bprint(b'# int, trusted and untrusted') | ||
bprint( | ||||
u.configint(b'foo', b'int', 0), | ||||
|
r43346 | u.configint(b'foo', b'int', 0, untrusted=True), | ||
) | ||||
|
r41388 | bprint(b'# bytes, trusted and untrusted') | ||
bprint( | ||||
u.configbytes(b'foo', b'bytes', 0), | ||||
|
r43346 | u.configbytes(b'foo', b'bytes', 0, untrusted=True), | ||
) | ||||
|
r41388 | bprint(b'# list, trusted and untrusted') | ||
bprint( | ||||
u.configlist(b'foo', b'list', []), | ||||
|
r43346 | u.configlist(b'foo', b'list', [], untrusted=True), | ||
) | ||||