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