diff options
Diffstat (limited to 'gitosis/test')
-rw-r--r-- | gitosis/test/__init__.py | 0 | ||||
-rw-r--r-- | gitosis/test/test_access.py | 79 | ||||
-rw-r--r-- | gitosis/test/test_group.py | 125 | ||||
-rw-r--r-- | gitosis/test/test_ssh.py | 202 |
4 files changed, 406 insertions, 0 deletions
diff --git a/gitosis/test/__init__.py b/gitosis/test/__init__.py new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/gitosis/test/__init__.py diff --git a/gitosis/test/test_access.py b/gitosis/test/test_access.py new file mode 100644 index 0000000..00b1fe8 --- /dev/null +++ b/gitosis/test/test_access.py @@ -0,0 +1,79 @@ +from nose.tools import eq_ as eq + +from ConfigParser import RawConfigParser + +from gitosis import access + +def test_write_no_simple(): + cfg = RawConfigParser() + eq(access.haveAccess(config=cfg, user='jdoe', mode='writable', path='foo/bar'), + None) + +def test_write_yes_simple(): + cfg = RawConfigParser() + cfg.add_section('group fooers') + cfg.set('group fooers', 'members', 'jdoe') + cfg.set('group fooers', 'writable', 'foo/bar') + eq(access.haveAccess(config=cfg, user='jdoe', mode='writable', path='foo/bar'), + 'foo/bar') + +def test_write_no_simple_wouldHaveReadonly(): + cfg = RawConfigParser() + cfg.add_section('group fooers') + cfg.set('group fooers', 'members', 'jdoe') + cfg.set('group fooers', 'readonly', 'foo/bar') + eq(access.haveAccess(config=cfg, user='jdoe', mode='writable', path='foo/bar'), + None) + +def test_write_yes_map(): + cfg = RawConfigParser() + cfg.add_section('group fooers') + cfg.set('group fooers', 'members', 'jdoe') + cfg.set('group fooers', 'map writable foo/bar', 'quux/thud') + eq(access.haveAccess(config=cfg, user='jdoe', mode='writable', path='foo/bar'), + 'quux/thud') + +def test_write_no_map_wouldHaveReadonly(): + cfg = RawConfigParser() + cfg.add_section('group fooers') + cfg.set('group fooers', 'members', 'jdoe') + cfg.set('group fooers', 'map readonly foo/bar', 'quux/thud') + eq(access.haveAccess(config=cfg, user='jdoe', mode='writable', path='foo/bar'), + None) + +def test_read_no_simple(): + cfg = RawConfigParser() + eq(access.haveAccess(config=cfg, user='jdoe', mode='readonly', path='foo/bar'), + None) + +def test_read_yes_simple(): + cfg = RawConfigParser() + cfg.add_section('group fooers') + cfg.set('group fooers', 'members', 'jdoe') + cfg.set('group fooers', 'readonly', 'foo/bar') + eq(access.haveAccess(config=cfg, user='jdoe', mode='readonly', path='foo/bar'), + 'foo/bar') + +def test_read_yes_simple_wouldHaveWritable(): + cfg = RawConfigParser() + cfg.add_section('group fooers') + cfg.set('group fooers', 'members', 'jdoe') + cfg.set('group fooers', 'writable', 'foo/bar') + eq(access.haveAccess(config=cfg, user='jdoe', mode='readonly', path='foo/bar'), + None) + +def test_read_yes_map(): + cfg = RawConfigParser() + cfg.add_section('group fooers') + cfg.set('group fooers', 'members', 'jdoe') + cfg.set('group fooers', 'map readonly foo/bar', 'quux/thud') + eq(access.haveAccess(config=cfg, user='jdoe', mode='readonly', path='foo/bar'), + 'quux/thud') + +def test_read_yes_map_wouldHaveWritable(): + cfg = RawConfigParser() + cfg.add_section('group fooers') + cfg.set('group fooers', 'members', 'jdoe') + cfg.set('group fooers', 'map writable foo/bar', 'quux/thud') + eq(access.haveAccess(config=cfg, user='jdoe', mode='readonly', path='foo/bar'), + None) diff --git a/gitosis/test/test_group.py b/gitosis/test/test_group.py new file mode 100644 index 0000000..c282661 --- /dev/null +++ b/gitosis/test/test_group.py @@ -0,0 +1,125 @@ +from nose.tools import eq_ as eq, assert_raises + +from ConfigParser import RawConfigParser + +from gitosis import group + +def test_no_emptyConfig(): + cfg = RawConfigParser() + gen = group.getMembership(config=cfg, user='jdoe') + assert_raises(StopIteration, gen.next) + +def test_no_emptyGroup(): + cfg = RawConfigParser() + cfg.add_section('group hackers') + gen = group.getMembership(config=cfg, user='jdoe') + assert_raises(StopIteration, gen.next) + +def test_no_notListed(): + cfg = RawConfigParser() + cfg.add_section('group hackers') + cfg.set('group hackers', 'members', 'wsmith') + gen = group.getMembership(config=cfg, user='jdoe') + assert_raises(StopIteration, gen.next) + +def test_yes_simple(): + cfg = RawConfigParser() + cfg.add_section('group hackers') + cfg.set('group hackers', 'members', 'jdoe') + gen = group.getMembership(config=cfg, user='jdoe') + eq(gen.next(), 'hackers') + assert_raises(StopIteration, gen.next) + +def test_yes_leading(): + cfg = RawConfigParser() + cfg.add_section('group hackers') + cfg.set('group hackers', 'members', 'jdoe wsmith') + gen = group.getMembership(config=cfg, user='jdoe') + eq(gen.next(), 'hackers') + assert_raises(StopIteration, gen.next) + +def test_yes_trailing(): + cfg = RawConfigParser() + cfg.add_section('group hackers') + cfg.set('group hackers', 'members', 'wsmith jdoe') + gen = group.getMembership(config=cfg, user='jdoe') + eq(gen.next(), 'hackers') + assert_raises(StopIteration, gen.next) + +def test_yes_middle(): + cfg = RawConfigParser() + cfg.add_section('group hackers') + cfg.set('group hackers', 'members', 'wsmith jdoe danny') + gen = group.getMembership(config=cfg, user='jdoe') + eq(gen.next(), 'hackers') + assert_raises(StopIteration, gen.next) + +def test_yes_recurse_one(): + cfg = RawConfigParser() + cfg.add_section('group hackers') + cfg.set('group hackers', 'members', 'wsmith @smackers') + cfg.add_section('group smackers') + cfg.set('group smackers', 'members', 'danny jdoe') + gen = group.getMembership(config=cfg, user='jdoe') + eq(gen.next(), 'smackers') + eq(gen.next(), 'hackers') + assert_raises(StopIteration, gen.next) + +def test_yes_recurse_one_ordering(): + cfg = RawConfigParser() + cfg.add_section('group smackers') + cfg.set('group smackers', 'members', 'danny jdoe') + cfg.add_section('group hackers') + cfg.set('group hackers', 'members', 'wsmith @smackers') + gen = group.getMembership(config=cfg, user='jdoe') + eq(gen.next(), 'smackers') + eq(gen.next(), 'hackers') + assert_raises(StopIteration, gen.next) + +def test_yes_recurse_three(): + cfg = RawConfigParser() + cfg.add_section('group hackers') + cfg.set('group hackers', 'members', 'wsmith @smackers') + cfg.add_section('group smackers') + cfg.set('group smackers', 'members', 'danny @snackers') + cfg.add_section('group snackers') + cfg.set('group snackers', 'members', '@whackers foo') + cfg.add_section('group whackers') + cfg.set('group whackers', 'members', 'jdoe') + gen = group.getMembership(config=cfg, user='jdoe') + eq(gen.next(), 'whackers') + eq(gen.next(), 'snackers') + eq(gen.next(), 'smackers') + eq(gen.next(), 'hackers') + assert_raises(StopIteration, gen.next) + +def test_yes_recurse_junk(): + cfg = RawConfigParser() + cfg.add_section('group hackers') + cfg.set('group hackers', 'members', '@notexist @smackers') + cfg.add_section('group smackers') + cfg.set('group smackers', 'members', 'jdoe') + gen = group.getMembership(config=cfg, user='jdoe') + eq(gen.next(), 'smackers') + eq(gen.next(), 'hackers') + assert_raises(StopIteration, gen.next) + +def test_yes_recurse_loop(): + cfg = RawConfigParser() + cfg.add_section('group hackers') + cfg.set('group hackers', 'members', '@smackers') + cfg.add_section('group smackers') + cfg.set('group smackers', 'members', '@hackers jdoe') + gen = group.getMembership(config=cfg, user='jdoe') + eq(gen.next(), 'smackers') + eq(gen.next(), 'hackers') + assert_raises(StopIteration, gen.next) + +def test_no_recurse_loop(): + cfg = RawConfigParser() + cfg.add_section('group hackers') + cfg.set('group hackers', 'members', '@smackers') + cfg.add_section('group smackers') + cfg.set('group smackers', 'members', '@hackers') + gen = group.getMembership(config=cfg, user='jdoe') + assert_raises(StopIteration, gen.next) diff --git a/gitosis/test/test_ssh.py b/gitosis/test/test_ssh.py new file mode 100644 index 0000000..e699506 --- /dev/null +++ b/gitosis/test/test_ssh.py @@ -0,0 +1,202 @@ +from nose.tools import eq_ as eq, assert_raises + +import os, errno +from cStringIO import StringIO + +from gitosis import ssh + +def mkdir(path): + try: + os.mkdir(path) + except OSError, e: + if e.errno == errno.EEXIST: + pass + else: + raise + +def maketemp(): + tmp = os.path.join(os.path.dirname(__file__), 'tmp') + mkdir(tmp) + me = os.path.splitext(os.path.basename(__file__))[0] + tmp = os.path.join(tmp, me) + mkdir(tmp) + return tmp + +def writeFile(path, content): + tmp = '%s.tmp' % path + f = file(tmp, 'w') + try: + f.write(content) + finally: + f.close() + os.rename(tmp, path) + +def _key(s): + return ''.join(s.split('\n')).strip() + +KEY_1 = _key(""" +ssh-rsa +v5XLsUrLsHOKy7Stob1lHZM17YCCNXplcKfbpIztS2PujyixOaBev1ku6H6ny +gUXfuYVzY+PmfTLviSwD3UETxEkR/jlBURACDQARJdUxpgt9XG2Lbs8bhOjonAPapxrH0o +9O8R0Y6Pm1Vh+H2U0B4UBhPgEframpeJYedijBxBV5aq3yUvHkXpcjM/P0gsKqr036k= j +unk@gunk +""") + +KEY_2 = _key(""" +ssh-rsa 4BX2TxZoD3Og2zNjHwaMhVEa5/NLnPcw+Z02TDR0IGJrrqXk7YlfR3oz+Wb/Eb +Ctli20SoWY0Ur8kBEF/xR4hRslZ2U8t0PAJhr8cq5mifhok/gAdckmSzjD67QJ68uZbga8 +ZwIAo7y/BU7cD3Y9UdVZykG34NiijHZLlCBo/TnobXjFIPXvFbfgQ3y8g+akwocFVcQ= f +roop@snoop +""") + +class ReadKeys_Test(object): + def test_empty(self): + tmp = maketemp() + empty = os.path.join(tmp, 'empty') + mkdir(empty) + gen = ssh.readKeys(keydir=empty) + assert_raises(StopIteration, gen.next) + + def test_ignore_dot(self): + tmp = maketemp() + keydir = os.path.join(tmp, 'ignore_dot') + mkdir(keydir) + writeFile(os.path.join(keydir, '.jdoe.pub'), KEY_1+'\n') + gen = ssh.readKeys(keydir=keydir) + assert_raises(StopIteration, gen.next) + + def test_ignore_nonpub(self): + tmp = maketemp() + keydir = os.path.join(tmp, 'ignore_dot') + mkdir(keydir) + writeFile(os.path.join(keydir, 'jdoe.xub'), KEY_1+'\n') + gen = ssh.readKeys(keydir=keydir) + assert_raises(StopIteration, gen.next) + + def test_one(self): + tmp = maketemp() + keydir = os.path.join(tmp, 'one') + mkdir(keydir) + writeFile(os.path.join(keydir, 'jdoe.pub'), KEY_1+'\n') + + gen = ssh.readKeys(keydir=keydir) + eq(gen.next(), ('jdoe', KEY_1)) + assert_raises(StopIteration, gen.next) + + def test_two(self): + tmp = maketemp() + keydir = os.path.join(tmp, 'two') + mkdir(keydir) + writeFile(os.path.join(keydir, 'jdoe.pub'), KEY_1+'\n') + writeFile(os.path.join(keydir, 'wsmith.pub'), KEY_2+'\n') + + gen = ssh.readKeys(keydir=keydir) + got = frozenset(gen) + + eq(got, + frozenset([ + ('jdoe', KEY_1), + ('wsmith', KEY_2), + ])) + +class GenerateAuthorizedKeys_Test(object): + def test_simple(self): + def k(): + yield ('jdoe', KEY_1) + yield ('wsmith', KEY_2) + gen = ssh.generateAuthorizedKeys(k()) + eq(gen.next(), ssh.COMMENT) + eq(gen.next(), ( + 'command="gitosis-serve jdoe",no-port-forwarding,no-X11-f' + +'orwarding,no-agent-forwarding,no-pty %s' % KEY_1)) + eq(gen.next(), ( + 'command="gitosis-serve wsmith",no-port-forwarding,no-X11' + +'-forwarding,no-agent-forwarding,no-pty %s' % KEY_2)) + assert_raises(StopIteration, gen.next) + + +class FilterAuthorizedKeys_Test(object): + def run(self, s): + f = StringIO(s) + lines = ssh.filterAuthorizedKeys(f) + got = ''.join(['%s\n' % line for line in lines]) + return got + + def check_no_change(self, s): + got = self.run(s) + eq(got, s) + + def test_notFiltered_comment(self): + self.check_no_change('#comment\n') + + def test_notFiltered_junk(self): + self.check_no_change('junk\n') + + def test_notFiltered_key(self): + self.check_no_change('%s\n' % KEY_1) + + def test_notFiltered_keyWithCommand(self): + s = '''\ +command="faketosis-serve wsmith",no-port-forwarding,no-X11-forwardin\ +g,no-agent-forwarding,no-pty %(key_1)s +''' % dict(key_1=KEY_1) + self.check_no_change(s) + + + def test_filter_autogeneratedComment_backwardsCompat(self): + got = self.run('### autogenerated by gitosis, DO NOT EDIT\n') + eq(got, '') + + def test_filter_autogeneratedComment_current(self): + got = self.run(ssh.COMMENT+'\n') + eq(got, '') + + def test_filter_simple(self): + s = '''\ +command="gitosis-serve wsmith",no-port-forwarding,no-X11-forwardin\ +g,no-agent-forwarding,no-pty %(key_1)s +''' % dict(key_1=KEY_1) + got = self.run(s) + eq(got, '') + + def test_filter_withPath(self): + s = '''\ +command="/foo/bar/baz/gitosis-serve wsmith",no-port-forwarding,no-X11-forwardin\ +g,no-agent-forwarding,no-pty %(key_1)s +''' % dict(key_1=KEY_1) + got = self.run(s) + eq(got, '') + + +class WriteAuthorizedKeys_Test(object): + def test_simple(self): + tmp = maketemp() + path = os.path.join(tmp, 'authorized_keys') + oldfp = StringIO('''\ +# foo +bar +### autogenerated by gitosis, DO NOT EDIT +command="/foo/bar/baz/gitosis-serve wsmith",no-port-forwarding,\ +no-X11-forwarding,no-agent-forwarding,no-pty %(key_2)s +baz +''' % dict(key_2=KEY_2)) + keydir = os.path.join(tmp, 'one') + mkdir(keydir) + writeFile(os.path.join(keydir, 'jdoe.pub'), KEY_1+'\n') + + ssh.writeAuthorizedKeys( + oldfp=oldfp, newpath=path, keydir=keydir) + + f = file(path) + try: + got = f.read() + finally: + f.close() + + eq(got, '''\ +# foo +bar +baz +### autogenerated by gitosis, DO NOT EDIT +command="gitosis-serve jdoe",no-port-forwarding,\ +no-X11-forwarding,no-agent-forwarding,no-pty %(key_1)s +''' % dict(key_1=KEY_1)) |