Add a little more to the svn_rangelist_intersect test to test the
[svn.git] / subversion / tests / cmdline / authz_tests.py
blobd9e5cb42eca8551d03ad4da3848283e241123197
1 #!/usr/bin/env python
3 # authz_tests.py: testing authentication.
5 # Subversion is a tool for revision control.
6 # See http://subversion.tigris.org for more information.
8 # ====================================================================
9 # Copyright (c) 2000-2006 CollabNet. All rights reserved.
11 # This software is licensed as described in the file COPYING, which
12 # you should have received as part of this distribution. The terms
13 # are also available at http://subversion.tigris.org/license-1.html.
14 # If newer versions of this license are posted there, you may use a
15 # newer version instead, at your option.
17 ######################################################################
19 # General modules
20 import os
22 # Our testing module
23 import svntest
25 from svntest.main import write_restrictive_svnserve_conf
26 from svntest.main import write_authz_file
27 from svntest.main import server_authz_has_aliases
29 # (abbreviation)
30 Item = svntest.wc.StateItem
31 XFail = svntest.testcase.XFail
32 Skip = svntest.testcase.Skip
33 SkipUnless = svntest.testcase.SkipUnless
35 ######################################################################
36 # Tests
38 # Each test must return on success or raise on failure.
41 #----------------------------------------------------------------------
43 # regression test for issue #2486 - part 1: open_root
45 def authz_open_root(sbox):
46 "authz issue #2486 - open root"
48 sbox.build()
50 write_authz_file(sbox, {"/": "", "/A": "jrandom = rw"})
52 write_restrictive_svnserve_conf(sbox.repo_dir)
54 # we have write access in folder /A, but not in root. Test on too
55 # restrictive access needed in open_root by modifying a file in /A
56 wc_dir = sbox.wc_dir
58 mu_path = os.path.join(wc_dir, 'A', 'mu')
59 svntest.main.file_append(mu_path, "hi")
61 # Create expected output tree.
62 expected_output = svntest.wc.State(wc_dir, {
63 'A/mu' : Item(verb='Sending'),
66 # Commit the one file.
67 svntest.actions.run_and_verify_commit(wc_dir,
68 expected_output,
69 None,
70 None,
71 mu_path)
73 #----------------------------------------------------------------------
75 # regression test for issue #2486 - part 2: open_directory
77 def authz_open_directory(sbox):
78 "authz issue #2486 - open directory"
80 sbox.build()
82 write_authz_file(sbox, {"/": "*=rw", "/A/B": "*=", "/A/B/E": "jrandom = rw"})
84 write_restrictive_svnserve_conf(sbox.repo_dir)
86 # we have write access in folder /A/B/E, but not in /A/B. Test on too
87 # restrictive access needed in open_directory by moving file /A/mu to
88 # /A/B/E
89 wc_dir = sbox.wc_dir
91 mu_path = os.path.join(wc_dir, 'A', 'mu')
92 E_path = os.path.join(wc_dir, 'A', 'B', 'E')
94 svntest.main.run_svn(None, 'mv', mu_path, E_path)
96 # Create expected output tree.
97 expected_output = svntest.wc.State(wc_dir, {
98 'A/mu' : Item(verb='Deleting'),
99 'A/B/E/mu' : Item(verb='Adding'),
102 # Commit the working copy.
103 svntest.actions.run_and_verify_commit(wc_dir,
104 expected_output,
105 None,
106 None,
107 wc_dir)
109 def broken_authz_file(sbox):
110 "broken authz files cause errors"
112 sbox.build(create_wc = False)
114 # No characters but 'r', 'w', and whitespace are allowed as a value
115 # in an authz rule.
116 write_authz_file(sbox, {"/": "jrandom = rw # End-line comments disallowed"})
118 write_restrictive_svnserve_conf(sbox.repo_dir)
120 out, err = svntest.main.run_svn(1,
121 "delete",
122 sbox.repo_url + "/A",
123 "-m", "a log message");
124 if out:
125 raise svntest.verify.SVNUnexpectedStdout(out)
126 if not err:
127 raise svntest.verify.SVNUnexpectedStderr("Missing stderr")
129 # test whether read access is correctly granted and denied
130 def authz_read_access(sbox):
131 "test authz for read operations"
133 sbox.build(create_wc = False)
135 root_url = sbox.repo_url
136 A_url = root_url + '/A'
137 B_url = A_url + '/B'
138 C_url = A_url + '/C'
139 E_url = B_url + '/E'
140 mu_url = A_url + '/mu'
141 iota_url = root_url + '/iota'
142 lambda_url = B_url + '/lambda'
143 alpha_url = E_url + '/alpha'
144 D_url = A_url + '/D'
145 G_url = D_url + '/G'
146 pi_url = G_url + '/pi'
147 H_url = D_url + '/H'
148 chi_url = H_url + '/chi'
150 if sbox.repo_url.startswith("http"):
151 expected_err = ".*403 Forbidden.*"
152 else:
153 expected_err = ".*svn: Authorization failed.*"
155 # create some folders with spaces in their names
156 svntest.actions.run_and_verify_svn(None, None, [],
157 'mkdir',
158 '-m', 'logmsg',
159 B_url+'/folder with spaces',
160 B_url+'/folder with spaces/empty folder')
162 write_restrictive_svnserve_conf(sbox.repo_dir)
164 write_authz_file(sbox, { "/": "* = r",
165 "/A/B": "* =",
166 "/A/D": "* = rw",
167 "/A/D/G": ("* = rw\n" +
168 svntest.main.wc_author + " ="),
169 "/A/D/H": ("* = \n" +
170 svntest.main.wc_author + " = rw"),
171 "/A/B/folder with spaces":
172 (svntest.main.wc_author + " = r")})
174 # read a remote file
175 svntest.actions.run_and_verify_svn(None, ["This is the file 'iota'.\n"],
176 [], 'cat',
177 iota_url)
179 # read a remote file, readably by user specific exception
180 svntest.actions.run_and_verify_svn(None, ["This is the file 'chi'.\n"],
181 [], 'cat',
182 chi_url)
184 # read a remote file, unreadable: should fail
185 svntest.actions.run_and_verify_svn(None,
186 None, expected_err,
187 'cat',
188 lambda_url)
190 # read a remote file, unreadable through recursion: should fail
191 svntest.actions.run_and_verify_svn(None,
192 None, expected_err,
193 'cat',
194 alpha_url)
196 # read a remote file, user specific authorization is ignored because * = rw
197 svntest.actions.run_and_verify_svn(None, ["This is the file 'pi'.\n"],
198 [], 'cat',
199 pi_url)
200 # open a remote folder(ls)
201 svntest.actions.run_and_verify_svn("ls remote root folder",
202 ["A/\n", "iota\n"],
203 [], 'ls',
204 root_url)
206 # open a remote folder(ls), unreadable: should fail
207 svntest.actions.run_and_verify_svn(None,
208 None, svntest.verify.AnyOutput, 'ls',
209 B_url)
211 # open a remote folder(ls) with spaces, should succeed
212 svntest.actions.run_and_verify_svn(None,
213 None, [], 'ls',
214 B_url+'/folder with spaces/empty folder')
216 # open a remote folder(ls), unreadable through recursion: should fail
217 svntest.actions.run_and_verify_svn(None,
218 None, expected_err,
219 'ls',
220 E_url)
222 # copy a remote file
223 svntest.actions.run_and_verify_svn(None, None, [], 'cp',
224 iota_url, D_url,
225 '-m', 'logmsg')
227 # copy a remote file, source is unreadable: should fail
228 svntest.actions.run_and_verify_svn(None,
229 None, expected_err,
230 'cp',
231 '-m', 'logmsg',
232 lambda_url, D_url)
234 # copy a remote folder
235 svntest.actions.run_and_verify_svn(None, None, [], 'cp',
236 C_url, D_url,
237 '-m', 'logmsg')
239 # copy a remote folder, source is unreadable: should fail
240 svntest.actions.run_and_verify_svn(None,
241 None, expected_err,
242 'cp',
243 '-m', 'logmsg',
244 E_url, D_url)
246 # test whether write access is correctly granted and denied
247 def authz_write_access(sbox):
248 "test authz for write operations"
250 sbox.build(create_wc = False)
252 write_restrictive_svnserve_conf(sbox.repo_dir)
254 if sbox.repo_url.startswith('http'):
255 expected_err = ".*403 Forbidden.*"
256 else:
257 expected_err = ".*svn: Access denied.*"
259 write_authz_file(sbox, { "/": "* = r",
260 "/A/B": "* = rw",
261 "/A/C": "* = rw"})
263 root_url = sbox.repo_url
264 A_url = root_url + '/A'
265 B_url = A_url + '/B'
266 C_url = A_url + '/C'
267 E_url = B_url + '/E'
268 mu_url = A_url + '/mu'
269 iota_url = root_url + '/iota'
270 lambda_url = B_url + '/lambda'
271 D_url = A_url + '/D'
273 # copy a remote file, target is readonly: should fail
274 svntest.actions.run_and_verify_svn(None,
275 None, expected_err,
276 'cp',
277 '-m', 'logmsg',
278 lambda_url, D_url)
280 # copy a remote folder, target is readonly: should fail
281 svntest.actions.run_and_verify_svn(None,
282 None, expected_err,
283 'cp',
284 '-m', 'logmsg',
285 E_url, D_url)
287 # delete a file, target is readonly: should fail
288 svntest.actions.run_and_verify_svn(None,
289 None, expected_err,
290 'rm',
291 '-m', 'logmsg',
292 iota_url)
294 # delete a folder, target is readonly: should fail
295 svntest.actions.run_and_verify_svn(None,
296 None, expected_err,
297 'rm',
298 '-m', 'logmsg',
299 D_url)
301 # create a folder, target is readonly: should fail
302 svntest.actions.run_and_verify_svn(None,
303 None, expected_err,
304 'mkdir',
305 '-m', 'logmsg',
306 A_url+'/newfolder')
308 # move a remote file, source is readonly: should fail
309 svntest.actions.run_and_verify_svn(None,
310 None, expected_err,
311 'mv',
312 '-m', 'logmsg',
313 mu_url, C_url)
315 # move a remote folder, source is readonly: should fail
316 svntest.actions.run_and_verify_svn(None,
317 None, expected_err,
318 'mv',
319 '-m', 'logmsg',
320 D_url, C_url)
322 # move a remote file, target is readonly: should fail
323 svntest.actions.run_and_verify_svn(None,
324 None, expected_err,
325 'mv',
326 '-m', 'logmsg',
327 lambda_url, D_url)
329 # move a remote folder, target is readonly: should fail
330 svntest.actions.run_and_verify_svn(None,
331 None, expected_err,
332 'mv',
333 '-m', 'logmsg',
334 B_url, D_url)
336 #----------------------------------------------------------------------
338 def authz_checkout_test(sbox):
339 "test authz for checkout"
341 sbox.build(create_wc = False, read_only = True)
342 local_dir = sbox.wc_dir
344 write_restrictive_svnserve_conf(sbox.repo_dir)
346 # 1st part: disable all read access, checkout should fail
348 # write an authz file with *= on /
349 if sbox.repo_url.startswith('http'):
350 expected_err = ".*403 Forbidden.*"
351 else:
352 expected_err = ".*svn: Authorization failed.*"
354 write_authz_file(sbox, { "/": "* ="})
356 # checkout a working copy, should fail
357 svntest.actions.run_and_verify_svn(None, None, expected_err,
358 'co', sbox.repo_url, local_dir)
360 # 2nd part: now enable read access
362 write_authz_file(sbox, { "/": "* = r"})
364 # checkout a working copy, should succeed because we have read access
365 expected_output = svntest.main.greek_state.copy()
366 expected_output.wc_dir = local_dir
367 expected_output.tweak(status='A ', contents=None)
369 expected_wc = svntest.main.greek_state
371 svntest.actions.run_and_verify_checkout(sbox.repo_url,
372 local_dir,
373 expected_output,
374 expected_wc)
376 def authz_checkout_and_update_test(sbox):
377 "test authz for checkout and update"
379 sbox.build(create_wc = False, read_only = True)
380 local_dir = sbox.wc_dir
382 write_restrictive_svnserve_conf(sbox.repo_dir)
384 # 1st part: disable read access on folder A/B, checkout should not
385 # download this folder
387 # write an authz file with *= on /A/B
388 write_authz_file(sbox, { "/": "* = r",
389 "/A/B": "* ="})
391 # checkout a working copy, should not dl /A/B
392 expected_output = svntest.main.greek_state.copy()
393 expected_output.wc_dir = local_dir
394 expected_output.tweak(status='A ', contents=None)
395 expected_output.remove('A/B', 'A/B/lambda', 'A/B/E', 'A/B/E/alpha',
396 'A/B/E/beta', 'A/B/F')
398 expected_wc = svntest.main.greek_state.copy()
399 expected_wc.remove('A/B', 'A/B/lambda', 'A/B/E', 'A/B/E/alpha',
400 'A/B/E/beta', 'A/B/F')
402 svntest.actions.run_and_verify_checkout(sbox.repo_url, local_dir,
403 expected_output,
404 expected_wc)
406 # 2nd part: now enable read access
408 # write an authz file with *=r on /
409 write_authz_file(sbox, { "/": "* = r"})
411 # update the working copy, should download /A/B because we now have read
412 # access
413 expected_output = svntest.wc.State(local_dir, {
414 'A/B' : Item(status='A '),
415 'A/B/lambda' : Item(status='A '),
416 'A/B/E' : Item(status='A '),
417 'A/B/E/alpha' : Item(status='A '),
418 'A/B/E/beta' : Item(status='A '),
419 'A/B/F' : Item(status='A '),
422 expected_wc = svntest.main.greek_state
423 expected_status = svntest.actions.get_virginal_state(local_dir, 1)
425 svntest.actions.run_and_verify_update(local_dir,
426 expected_output,
427 expected_wc,
428 expected_status,
429 None,
430 None, None,
431 None, None, 1)
433 def authz_partial_export_test(sbox):
434 "test authz for export with unreadable subfolder"
436 sbox.build(create_wc = False, read_only = True)
437 local_dir = sbox.wc_dir
439 # cleanup remains of a previous test run.
440 svntest.main.safe_rmtree(local_dir)
442 write_restrictive_svnserve_conf(sbox.repo_dir)
444 # 1st part: disable read access on folder A/B, export should not
445 # download this folder
447 # write an authz file with *= on /A/B
448 write_authz_file(sbox, { "/": "* = r", "/A/B": "* =" })
450 # export a working copy, should not dl /A/B
451 expected_output = svntest.main.greek_state.copy()
452 expected_output.wc_dir = local_dir
453 expected_output.desc[''] = Item()
454 expected_output.tweak(status='A ', contents=None)
455 expected_output.remove('A/B', 'A/B/lambda', 'A/B/E', 'A/B/E/alpha',
456 'A/B/E/beta', 'A/B/F')
458 expected_wc = svntest.main.greek_state.copy()
459 expected_wc.remove('A/B', 'A/B/lambda', 'A/B/E', 'A/B/E/alpha',
460 'A/B/E/beta', 'A/B/F')
462 svntest.actions.run_and_verify_export(sbox.repo_url, local_dir,
463 expected_output,
464 expected_wc)
466 #----------------------------------------------------------------------
468 def authz_log_and_tracing_test(sbox):
469 "test authz for log and tracing path changes"
471 sbox.build()
472 wc_dir = sbox.wc_dir
474 write_restrictive_svnserve_conf(sbox.repo_dir)
476 # write an authz file with *=rw on /
477 if sbox.repo_url.startswith('http'):
478 expected_err = ".*403 Forbidden.*"
479 else:
480 expected_err = ".*svn: Authorization failed.*"
482 write_authz_file(sbox, { "/": "* = rw\n" })
484 root_url = sbox.repo_url
485 D_url = root_url + '/A/D'
486 G_url = D_url + '/G'
488 # check if log doesn't spill any info on which you don't have read access
489 rho_path = os.path.join(wc_dir, 'A', 'D', 'G', 'rho')
490 svntest.main.file_append(rho_path, 'new appended text for rho')
492 svntest.actions.run_and_verify_svn(None, None, [],
493 'ci', '-m', 'add file rho', sbox.wc_dir)
495 svntest.main.file_append(rho_path, 'extra change in rho')
497 svntest.actions.run_and_verify_svn(None, None, [],
498 'ci', '-m', 'changed file rho',
499 sbox.wc_dir)
501 # copy a remote file
502 svntest.actions.run_and_verify_svn(None, None, [], 'cp',
503 rho_path, D_url,
504 '-m', 'copy rho to readable area')
506 # now disable read access on the first version of rho, keep the copy in
507 # /A/D readable.
508 if sbox.repo_url.startswith('http'):
509 expected_err = ".*403 Forbidden.*"
510 else:
511 expected_err = ".*svn: Authorization failed.*"
513 authz = { "/": "* = rw",
514 "/A/D/G": "* ="}
515 write_authz_file(sbox, authz)
517 ## log
519 # changed file in this rev. is not readable anymore, so author and date
520 # should be hidden, like this:
521 # r2 | (no author) | (no date) | 1 line
522 svntest.actions.run_and_verify_svn(None,
523 ".*(no author).*(no date).*|-+\n|\n", [],
524 'log', '-r', '2', '--limit', '1',
525 wc_dir)
527 if sbox.repo_url.startswith('http'):
528 expected_err2 = expected_err
529 else:
530 expected_err2 = ".*svn: Item is not readable.*"
532 # if we do the same thing directly on the unreadable file, we get:
533 # svn: Item is not readable
534 svntest.actions.run_and_verify_svn(None, None, expected_err2,
535 'log', rho_path)
537 # while the HEAD rev of the copy is readable in /A/D, its parent in
538 # /A/D/G is not, so don't spill any info there either.
539 svntest.actions.run_and_verify_svn(None,
540 ".*(no author).*(no date).*|-+\n|\n", [],
541 'log', '-r', '2', '--limit', '1', D_url)
543 # Test that only author/date are shown for partially visible revisions.
544 svntest.actions.enable_revprop_changes(sbox.repo_dir)
545 write_authz_file(sbox, { "/": "* = rw"})
546 svntest.actions.run_and_verify_svn(
547 None, None, [], # message, expected_stdout, expected_stderr
548 'ps', '--revprop', '-r1', 'foobar', 'foo bar', sbox.repo_url)
549 svntest.actions.run_and_verify_log_xml(
550 expected_revprops=[{'svn:author': svntest.main.wc_author, 'svn:date': '',
551 'svn:log': 'Log message for revision 1.',
552 'foobar': 'foo bar'}],
553 args=['--with-all-revprops', '-r1', sbox.repo_url])
554 write_authz_file(sbox, authz)
555 svntest.actions.run_and_verify_log_xml(
556 expected_revprops=[{'svn:author': svntest.main.wc_author, 'svn:date': ''}],
557 args=['--with-all-revprops', '-r1', sbox.repo_url])
560 ## cat
562 # now see if we can look at the older version of rho
563 svntest.actions.run_and_verify_svn(None, None, expected_err,
564 'cat', '-r', '2', D_url+'/rho')
566 if sbox.repo_url.startswith('http'):
567 expected_err2 = expected_err
568 else:
569 expected_err2 = ".*svn: Unreadable path encountered; access denied.*"
571 svntest.actions.run_and_verify_svn(None, None, expected_err2,
572 'cat', '-r', '2', G_url+'/rho')
574 ## diff
576 # we shouldn't see the diff of a file in an unreadable path
577 svntest.actions.run_and_verify_svn(None, None, expected_err,
578 'diff', '-r', 'HEAD', G_url+'/rho')
580 svntest.actions.run_and_verify_svn(None, None, expected_err,
581 'diff', '-r', '2', D_url+'/rho')
583 svntest.actions.run_and_verify_svn(None, None, expected_err,
584 'diff', '-r', '2:4', D_url+'/rho')
586 # test whether read access is correctly granted and denied
587 def authz_aliases(sbox):
588 "test authz for aliases"
590 sbox.build(create_wc = False)
592 write_restrictive_svnserve_conf(sbox.repo_dir)
594 if sbox.repo_url.startswith("http"):
595 expected_err = ".*403 Forbidden.*"
596 else:
597 expected_err = ".*svn: Authorization failed.*"
599 write_authz_file(sbox, { "/" : "* = r",
600 "/A/B" : "&jray = rw" },
601 { "aliases" : 'jray = jrandom' } )
603 root_url = sbox.repo_url
604 A_url = root_url + '/A'
605 B_url = A_url + '/B'
606 iota_url = root_url + '/iota'
608 # copy a remote file, target is readonly for jconstant: should fail
609 svntest.actions.run_and_verify_svn(None,
610 None, expected_err,
611 'cp',
612 '--username', svntest.main.wc_author2,
613 '-m', 'logmsg',
614 iota_url, B_url)
616 # try the same action, but as user jray (alias of jrandom), should work.
617 svntest.actions.run_and_verify_svn(None,
618 None, [],
619 'cp',
620 '-m', 'logmsg',
621 iota_url, B_url)
623 def authz_validate(sbox):
624 "test the authz validation rules"
626 sbox.build(create_wc = False, read_only = True)
628 write_restrictive_svnserve_conf(sbox.repo_dir)
630 A_url = sbox.repo_url + '/A'
632 # If any of the validate rules fail, the authz isn't loaded so there's no
633 # access at all to the repository.
635 # Test 1: Undefined group
636 write_authz_file(sbox, { "/" : "* = r",
637 "/A/B" : "@undefined_group = rw" })
639 if sbox.repo_url.startswith("http"):
640 expected_err = ".*403 Forbidden.*"
641 else:
642 expected_err = ".*@undefined_group.*"
644 # validation of this authz file should fail, so no repo access
645 svntest.actions.run_and_verify_svn("ls remote folder",
646 None, expected_err,
647 'ls',
648 A_url)
650 # Test 2: Circular dependency
651 write_authz_file(sbox, { "/" : "* = r" },
652 { "groups" : """admins = admin1, admin2, @devs
653 devs1 = @admins, dev1
654 devs2 = @admins, dev2
655 devs = @devs1, dev3, dev4""" })
657 if sbox.repo_url.startswith("http"):
658 expected_err = ".*403 Forbidden.*"
659 else:
660 expected_err = ".*Circular dependency.*"
662 # validation of this authz file should fail, so no repo access
663 svntest.actions.run_and_verify_svn("ls remote folder",
664 None, expected_err,
665 'ls',
666 A_url)
668 # Test 3: Group including other group 2 times (issue 2684)
669 write_authz_file(sbox, { "/" : "* = r" },
670 { "groups" : """admins = admin1, admin2
671 devs1 = @admins, dev1
672 devs2 = @admins, dev2
673 users = @devs1, @devs2, user1, user2""" })
675 # validation of this authz file should fail, so no repo access
676 svntest.actions.run_and_verify_svn("ls remote folder",
677 ['B/\n', 'C/\n', 'D/\n', 'mu\n'],
679 'ls',
680 A_url)
682 # test locking/unlocking with authz
683 def authz_locking(sbox):
684 "test authz for locking"
686 sbox.build()
688 write_authz_file(sbox, {"/": "", "/A": "jrandom = rw"})
689 write_restrictive_svnserve_conf(sbox.repo_dir)
691 if sbox.repo_url.startswith('http'):
692 expected_err = ".*403 Forbidden.*"
693 else:
694 expected_err = ".*svn: Authorization failed.*"
696 root_url = sbox.repo_url
697 wc_dir = sbox.wc_dir
698 iota_url = root_url + '/iota'
699 iota_path = os.path.join(wc_dir, 'iota')
700 A_url = root_url + '/A'
701 mu_path = os.path.join(wc_dir, 'A', 'mu')
703 # lock a file url, target is readonly: should fail
704 svntest.actions.run_and_verify_svn(None,
705 None, expected_err,
706 'lock',
707 '-m', 'lock msg',
708 iota_url)
710 # lock a file path, target is readonly: should fail
711 svntest.actions.run_and_verify_svn(None,
712 None, expected_err,
713 'lock',
714 '-m', 'lock msg',
715 iota_path)
717 # Test for issue 2700: we have write access in folder /A, but not in root.
718 # Get a lock on /A/mu and try to commit it.
720 # lock a file path, target is writeable: should succeed
721 svntest.actions.run_and_verify_svn(None,
722 None, [],
723 'lock',
724 '-m', 'lock msg',
725 mu_path)
727 svntest.main.file_append(mu_path, "hi")
729 expected_output = svntest.wc.State(wc_dir, {
730 'A/mu' : Item(verb='Sending'),
733 svntest.actions.run_and_verify_commit(wc_dir,
734 expected_output,
736 None,
737 mu_path)
739 # test for issue #2712: if anon-access == read, svnserve should also check
740 # authz to determine whether a checkout/update is actually allowed for
741 # anonymous users, and, if not, attempt authentication.
742 def authz_svnserve_anon_access_read(sbox):
743 "authz issue #2712"
745 sbox.build(create_wc = False)
746 svntest.main.safe_rmtree(sbox.wc_dir)
747 B_path = os.path.join(sbox.wc_dir, 'A', 'B')
748 other_B_path = B_path + '_other'
749 B_url = sbox.repo_url + '/A/B'
750 D_path = os.path.join(sbox.wc_dir, 'A', 'D')
751 D_url = sbox.repo_url + '/A/D'
753 # We want a svnserve.conf with anon-access = read.
754 write_restrictive_svnserve_conf(sbox.repo_dir, "read")
756 # Give jrandom read access to /A/B. Anonymous users can only
757 # access /A/D.
758 write_authz_file(sbox, { "/A/B" : "jrandom = rw",
759 "/A/D" : "* = r" })
761 # Perform a checkout of /A/B, expecting to see no errors.
762 svntest.actions.run_and_verify_svn(None, None, [],
763 'checkout',
764 B_url, B_path)
766 # Anonymous users should be able to check out /A/D.
767 svntest.actions.run_and_verify_svn(None, None, [],
768 'checkout',
769 D_url, D_path)
771 # Now try a switch.
772 svntest.main.safe_rmtree(D_path)
773 svntest.actions.run_and_verify_svn(None, None, [],
774 'switch', D_url, B_path)
776 # Check out /A/B with an unknown username, expect error.
777 svntest.actions.run_and_verify_svn(
778 None, None,
779 ".*Authentication error from server: Username not found.*",
780 'checkout',
781 '--non-interactive',
782 '--username', 'losing_user',
783 B_url, B_path + '_unsuccessful')
785 # Check out a second copy of /A/B, make changes for later merge.
786 svntest.actions.run_and_verify_svn(None, None, [],
787 'checkout',
788 B_url, other_B_path)
789 other_alpha_path = os.path.join(other_B_path, 'E', 'alpha')
790 svntest.main.file_append(other_alpha_path, "fish\n")
791 svntest.actions.run_and_verify_svn(None, None, [],
792 'commit', '-m', 'log msg',
793 other_B_path)
795 # Now try to merge. This is an atypical merge, since our "branch"
796 # is not really a branch (it's the same URL), but we only care about
797 # authz here, not the semantics of the merge. (Merges had been
798 # failing in authz, for the reasons summarized in
799 # http://subversion.tigris.org/issues/show_bug.cgi?id=2712#desc13.)
800 svntest.actions.run_and_verify_svn(None, None, [],
801 'merge', '-c', '2',
802 B_url, B_path)
804 def authz_switch_to_directory(sbox):
805 "switched to directory, no read access on parents"
807 sbox.build(read_only = True)
809 write_authz_file(sbox, {"/": "*=rw", "/A/B": "*=", "/A/B/E": "jrandom = rw"})
811 write_restrictive_svnserve_conf(sbox.repo_dir)
813 wc_dir = sbox.wc_dir
814 mu_path = os.path.join(wc_dir, 'A', 'mu')
815 F_path = os.path.join(wc_dir, 'A', 'B', 'F')
816 G_path = os.path.join(wc_dir, 'A', 'D', 'G')
818 # Switch /A/B/E to /A/B/F.
819 svntest.main.run_svn(None, 'switch', sbox.repo_url + "/A/B/E", G_path)
821 ########################################################################
822 # Run the tests
824 # list all tests here, starting with None:
825 test_list = [ None,
826 Skip(authz_open_root, svntest.main.is_ra_type_file),
827 Skip(authz_open_directory, svntest.main.is_ra_type_file),
828 Skip(broken_authz_file, svntest.main.is_ra_type_file),
829 Skip(authz_read_access, svntest.main.is_ra_type_file),
830 Skip(authz_write_access, svntest.main.is_ra_type_file),
831 Skip(authz_checkout_test, svntest.main.is_ra_type_file),
832 Skip(authz_log_and_tracing_test, svntest.main.is_ra_type_file),
833 Skip(authz_checkout_and_update_test,
834 svntest.main.is_ra_type_file),
835 Skip(authz_partial_export_test, svntest.main.is_ra_type_file),
836 SkipUnless(Skip(authz_aliases, svntest.main.is_ra_type_file),
837 server_authz_has_aliases),
838 Skip(authz_validate, svntest.main.is_ra_type_file),
839 Skip(authz_locking, svntest.main.is_ra_type_file),
840 XFail(SkipUnless(authz_svnserve_anon_access_read,
841 svntest.main.is_ra_type_svn)),
842 XFail(Skip(authz_switch_to_directory,
843 svntest.main.is_ra_type_file)),
846 if __name__ == '__main__':
847 svntest.main.run_tests(test_list, serial_only = True)
848 # NOTREACHED
851 ### End of file.