• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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