1import netrc, os, unittest, sys, tempfile, textwrap 2from test import support 3 4 5class NetrcTestCase(unittest.TestCase): 6 7 def make_nrc(self, test_data): 8 test_data = textwrap.dedent(test_data) 9 mode = 'w' 10 if sys.platform != 'cygwin': 11 mode += 't' 12 temp_fd, temp_filename = tempfile.mkstemp() 13 with os.fdopen(temp_fd, mode=mode) as fp: 14 fp.write(test_data) 15 self.addCleanup(os.unlink, temp_filename) 16 return netrc.netrc(temp_filename) 17 18 def test_default(self): 19 nrc = self.make_nrc("""\ 20 machine host1.domain.com login log1 password pass1 account acct1 21 default login log2 password pass2 22 """) 23 self.assertEqual(nrc.hosts['host1.domain.com'], 24 ('log1', 'acct1', 'pass1')) 25 self.assertEqual(nrc.hosts['default'], ('log2', None, 'pass2')) 26 27 nrc2 = self.make_nrc(nrc.__repr__()) 28 self.assertEqual(nrc.hosts, nrc2.hosts) 29 30 def test_macros(self): 31 nrc = self.make_nrc("""\ 32 macdef macro1 33 line1 34 line2 35 36 macdef macro2 37 line3 38 line4 39 """) 40 self.assertEqual(nrc.macros, {'macro1': ['line1\n', 'line2\n'], 41 'macro2': ['line3\n', 'line4\n']}) 42 43 def _test_passwords(self, nrc, passwd): 44 nrc = self.make_nrc(nrc) 45 self.assertEqual(nrc.hosts['host.domain.com'], ('log', 'acct', passwd)) 46 47 def test_password_with_leading_hash(self): 48 self._test_passwords("""\ 49 machine host.domain.com login log password #pass account acct 50 """, '#pass') 51 52 def test_password_with_trailing_hash(self): 53 self._test_passwords("""\ 54 machine host.domain.com login log password pass# account acct 55 """, 'pass#') 56 57 def test_password_with_internal_hash(self): 58 self._test_passwords("""\ 59 machine host.domain.com login log password pa#ss account acct 60 """, 'pa#ss') 61 62 def _test_comment(self, nrc, passwd='pass'): 63 nrc = self.make_nrc(nrc) 64 self.assertEqual(nrc.hosts['foo.domain.com'], ('bar', None, passwd)) 65 self.assertEqual(nrc.hosts['bar.domain.com'], ('foo', None, 'pass')) 66 67 def test_comment_before_machine_line(self): 68 self._test_comment("""\ 69 # comment 70 machine foo.domain.com login bar password pass 71 machine bar.domain.com login foo password pass 72 """) 73 74 def test_comment_before_machine_line_no_space(self): 75 self._test_comment("""\ 76 #comment 77 machine foo.domain.com login bar password pass 78 machine bar.domain.com login foo password pass 79 """) 80 81 def test_comment_before_machine_line_hash_only(self): 82 self._test_comment("""\ 83 # 84 machine foo.domain.com login bar password pass 85 machine bar.domain.com login foo password pass 86 """) 87 88 def test_comment_at_end_of_machine_line(self): 89 self._test_comment("""\ 90 machine foo.domain.com login bar password pass # comment 91 machine bar.domain.com login foo password pass 92 """) 93 94 def test_comment_at_end_of_machine_line_no_space(self): 95 self._test_comment("""\ 96 machine foo.domain.com login bar password pass #comment 97 machine bar.domain.com login foo password pass 98 """) 99 100 def test_comment_at_end_of_machine_line_pass_has_hash(self): 101 self._test_comment("""\ 102 machine foo.domain.com login bar password #pass #comment 103 machine bar.domain.com login foo password pass 104 """, '#pass') 105 106 107 @unittest.skipUnless(os.name == 'posix', 'POSIX only test') 108 def test_security(self): 109 # This test is incomplete since we are normally not run as root and 110 # therefore can't test the file ownership being wrong. 111 d = support.TESTFN 112 os.mkdir(d) 113 self.addCleanup(support.rmtree, d) 114 fn = os.path.join(d, '.netrc') 115 with open(fn, 'wt') as f: 116 f.write("""\ 117 machine foo.domain.com login bar password pass 118 default login foo password pass 119 """) 120 with support.EnvironmentVarGuard() as environ: 121 environ.set('HOME', d) 122 os.chmod(fn, 0o600) 123 nrc = netrc.netrc() 124 self.assertEqual(nrc.hosts['foo.domain.com'], 125 ('bar', None, 'pass')) 126 os.chmod(fn, 0o622) 127 self.assertRaises(netrc.NetrcParseError, netrc.netrc) 128 129 def test_file_not_found_in_home(self): 130 d = support.TESTFN 131 os.mkdir(d) 132 self.addCleanup(support.rmtree, d) 133 with support.EnvironmentVarGuard() as environ: 134 environ.set('HOME', d) 135 self.assertRaises(FileNotFoundError, netrc.netrc) 136 137 def test_file_not_found_explicit(self): 138 self.assertRaises(FileNotFoundError, netrc.netrc, 139 file='unlikely_netrc') 140 141 def test_home_not_set(self): 142 fake_home = support.TESTFN 143 os.mkdir(fake_home) 144 self.addCleanup(support.rmtree, fake_home) 145 fake_netrc_path = os.path.join(fake_home, '.netrc') 146 with open(fake_netrc_path, 'w') as f: 147 f.write('machine foo.domain.com login bar password pass') 148 os.chmod(fake_netrc_path, 0o600) 149 150 orig_expanduser = os.path.expanduser 151 called = [] 152 153 def fake_expanduser(s): 154 called.append(s) 155 with support.EnvironmentVarGuard() as environ: 156 environ.set('HOME', fake_home) 157 environ.set('USERPROFILE', fake_home) 158 result = orig_expanduser(s) 159 return result 160 161 with support.swap_attr(os.path, 'expanduser', fake_expanduser): 162 nrc = netrc.netrc() 163 login, account, password = nrc.authenticators('foo.domain.com') 164 self.assertEqual(login, 'bar') 165 166 self.assertTrue(called) 167 168 169if __name__ == "__main__": 170 unittest.main() 171