3
# svnauthz_tests.py: testing the 'svnauthz' tool.
5
# Subversion is a tool for revision control.
6
# See http://subversion.apache.org for more information.
8
# ====================================================================
9
# Licensed to the Apache Software Foundation (ASF) under one
10
# or more contributor license agreements. See the NOTICE file
11
# distributed with this work for additional information
12
# regarding copyright ownership. The ASF licenses this file
13
# to you under the Apache License, Version 2.0 (the
14
# "License"); you may not use this file except in compliance
15
# with the License. You may obtain a copy of the License at
17
# http://www.apache.org/licenses/LICENSE-2.0
19
# Unless required by applicable law or agreed to in writing,
20
# software distributed under the License is distributed on an
21
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
22
# KIND, either express or implied. See the License for the
23
# specific language governing permissions and limitations
25
######################################################################
33
from svntest import wc
36
Skip = svntest.testcase.Skip_deco
37
SkipUnless = svntest.testcase.SkipUnless_deco
38
XFail = svntest.testcase.XFail_deco
39
Issues = svntest.testcase.Issues_deco
40
Issue = svntest.testcase.Issue_deco
41
Wimp = svntest.testcase.Wimp_deco
42
Item = svntest.wc.StateItem
44
# Run svnauthz commands on commit
45
hook_template = """import sys,os,subprocess
48
fp = open(os.path.join(sys.argv[1], 'hooks.log'), 'wb')
49
def output_command(fp, cmd, opt):
50
command = [svnauthz_bin, cmd, '-t', sys.argv[2], sys.argv[1]] + opt
51
process = subprocess.Popen(command, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=False, bufsize=-1)
52
(output, errors) = process.communicate()
53
status = process.returncode
56
fp.write("Exit %%d\\n" %% status)
59
for (svnauthz_cmd, svnauthz_opt) in %s:
60
output_command(fp, svnauthz_cmd, svnauthz_opt.split())
63
#----------------------------------------------------------------------
64
def verify_logfile(logfilename, expected_data, delete_log=True):
65
if os.path.exists(logfilename):
66
fp = open(logfilename)
68
raise svntest.verify.SVNUnexpectedOutput("hook logfile %s not found"\
71
actual_data = fp.readlines()
74
os.unlink(logfilename)
75
svntest.verify.compare_and_display_lines('wrong hook logfile content',
77
expected_data, actual_data)
79
#----------------------------------------------------------------------
81
# Note we don't test various different validation failures, the
82
# validation is actually just done when the file is loaded and
83
# the library tests for the config file parser and the authz
84
# parser already validate various failures that return errors.
86
def svnauthz_validate_file_test(sbox):
87
"test 'svnauthz validate' on files"
90
(authz_fd, authz_path) = tempfile.mkstemp()
91
authz_content = "[/]\n* = rw\n"
92
svntest.main.file_write(authz_path, authz_content)
95
svntest.actions.run_and_verify_svnauthz("Valid authz file", None, None,
96
0, False, "validate", authz_path)
98
# Invalid authz file, expect exit code 1, we found the file loaded it
100
svntest.main.file_write(authz_path, 'x\n')
101
svntest.actions.run_and_verify_svnauthz("Invalid authz file", None, None,
102
1, False, "validate", authz_path)
104
# Non-existant authz file
105
# exit code 2, operational error since we can't test the file.
107
os.remove(authz_path)
108
svntest.actions.run_and_verify_svnauthz("Non-existant authz file", None,
109
None, 2, False, "validate",
112
@SkipUnless(svntest.main.is_ra_type_file)
113
def svnauthz_validate_repo_test(sbox):
114
"test 'svnauthz validate' on urls"
118
repo_url = sbox.repo_url
120
authz_content = "[/]\n* = rw\n"
122
# build an authz file and commit it to the repo
123
authz_path = os.path.join(wc_dir, 'A', 'authz')
124
svntest.main.file_write(authz_path, authz_content)
125
svntest.main.run_svn(None, 'add', authz_path)
126
expected_output = wc.State(wc_dir, {'A/authz' : Item(verb='Adding')})
127
expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
128
expected_status.add({
129
'A/authz' : Item(status=' ', wc_rev=2),
131
if svntest.actions.run_and_verify_commit(wc_dir, expected_output,
132
expected_status, None, wc_dir):
133
raise svntest.Failure
135
# Valid authz url (file stored in repo)
136
authz_url = repo_url + '/A/authz'
137
svntest.actions.run_and_verify_svnauthz("Valid authz url", None, None,
138
0, False, "validate", authz_url)
140
# Invalid authz url (again use the iota file in the repo)
141
# expect exit code 1, we found the file loaded it but found an error
142
iota_url = repo_url + '/iota'
143
svntest.actions.run_and_verify_svnauthz("Invalid authz url", None, None,
144
1, False, "validate", iota_url)
146
# Non-existant authz url
147
# exit code 2, operational error since we can't test the file.
148
svntest.actions.run_and_verify_svnauthz("Non-existant authz file", None,
149
None, 2, False, "validate",
152
def svnauthz_validate_txn_test(sbox):
153
"test 'svnauthz validate --transaction'"
157
repo_dir = sbox.repo_dir
159
logfilepath = os.path.join(repo_dir, 'hooks.log')
160
pre_commit_hook = svntest.main.get_pre_commit_hook_path(repo_dir)
161
hook_instance = hook_template % (repr(svntest.main.svnauthz_binary),
162
repr([('validate', 'A/authz')]))
163
svntest.main.create_python_hook_script(pre_commit_hook, hook_instance)
165
# Create an authz file
166
authz_content = "[/]\n* = rw\n"
167
authz_path = os.path.join(wc_dir, 'A/authz')
168
svntest.main.file_write(authz_path, authz_content)
169
svntest.main.run_svn(None, 'add', authz_path)
171
# commit a valid authz file, and check the hook's logfile
172
expected_output = wc.State(wc_dir, {'A/authz' : Item(verb='Adding')})
173
expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
174
expected_status.add({
175
'A/authz' : Item(status=' ', wc_rev=2),
177
if svntest.actions.run_and_verify_commit(wc_dir, expected_output,
178
expected_status, None, wc_dir):
179
raise svntest.Failure
180
expected_data = ['Exit 0\n']
181
verify_logfile(logfilepath, expected_data)
183
# Add an invalid line to the authz file.
184
svntest.main.file_append(authz_path, 'x')
185
expected_output = wc.State(wc_dir, {'A/authz' : Item(verb='Sending')})
186
expected_status.tweak('A/authz', status=' ', wc_rev=3)
187
if svntest.actions.run_and_verify_commit(wc_dir, expected_output,
188
expected_status, None, wc_dir):
189
raise svntest.Failure
190
expected_data = svntest.verify.RegexOutput(".*?Error parsing authz file: '.*?'",
192
verify_logfile(logfilepath, expected_data, delete_log=False)
193
# Check the logfile that our Exit was 1 too
194
expected_data = svntest.verify.ExpectedOutput("Exit 1\n", match_all=False)
195
verify_logfile(logfilepath, expected_data)
197
# Validate a file that doesn't exist and make sure we're exiting with 2.
198
hook_instance = hook_template % (repr(svntest.main.svnauthz_binary),
199
repr([('validate', 'zilch')]))
200
svntest.main.create_python_hook_script(pre_commit_hook, hook_instance)
201
svntest.main.file_append(authz_path, 'x')
202
expected_status.tweak('A/authz', status=' ', wc_rev=4)
203
if svntest.actions.run_and_verify_commit(wc_dir, expected_output,
204
expected_status, None, wc_dir):
205
raise svntest.Failure
206
expected_data = svntest.verify.ExpectedOutput("Exit 2\n", match_all=False)
207
verify_logfile(logfilepath, expected_data)
209
def svnauthz_accessof_file_test(sbox):
210
"test 'svnauthz accessof' on files"
212
# build an authz file
213
(authz_fd, authz_path) = tempfile.mkstemp()
214
authz_content = "[/]\ngroucho = \ngallagher = rw\n* = r\n" + \
215
"[/bios]\n* = rw\n" + \
216
"[comedy:/jokes]\ngroucho = rw\n" + \
217
"[slapstick:/jokes]\n* =\n"
218
svntest.main.file_write(authz_path, authz_content)
220
# Anonymous access with no path, and no repository should be rw
221
# since it returns the highest level of access granted anywhere.
222
# So /bios being rw for everyone means this will be rw.
223
svntest.actions.run_and_verify_svnauthz("Anonymous access", ["rw\n"], None,
224
0, False, "accessof", authz_path)
226
# Anonymous access on /jokes should be r, no repo so won't match
227
# the slapstick:/jokes section.
228
svntest.actions.run_and_verify_svnauthz("Anonymous access on path",
229
["r\n"], None, 0, False, "accessof",
230
authz_path, "--path", "/jokes")
232
# Anonymous access on /jokes on slapstick repo should be no
233
svntest.actions.run_and_verify_svnauthz("Anonymous access on path with repo",
234
["no\n"], None, 0, False, "accessof",
235
authz_path, "--path", "/jokes",
236
"--repository", "slapstick")
238
# User access with no path, and no repository should be rw
239
# since it returns the h ighest level of access anywhere.
240
# So /bios being rw for everyone means this will be rw.
241
svntest.actions.run_and_verify_svnauthz("User access", ["rw\n"], None,
242
0, False, "accessof", authz_path,
243
"--username", "groucho")
245
# User groucho specified on /jokes with no repo, will not match any of the
246
# repo specific sections, so is r since everyone has read access.
247
svntest.actions.run_and_verify_svnauthz("User access on path", ["r\n"], None,
248
0, False, "accessof", authz_path,
249
"--path", "/jokes", "--username",
252
# User groucho specified on /jokes with the repo comedy will be rw
253
svntest.actions.run_and_verify_svnauthz("User access on path with repo",
254
["rw\n"], None, 0, False, "accessof",
255
authz_path, "--path", "/jokes",
256
"--username", "groucho",
257
"--repository", "comedy")
260
os.remove(authz_path)
262
@SkipUnless(svntest.main.is_ra_type_file)
263
def svnauthz_accessof_repo_test(sbox):
264
"test 'svnauthz accessof' on urls"
268
repo_url = sbox.repo_url
270
authz_content = "[/]\ngroucho = \ngallagher = rw\n* = r\n" + \
271
"[/bios]\n* = rw\n" + \
272
"[comedy:/jokes]\ngroucho = rw\n" + \
273
"[slapstick:/jokes]\n* =\n"
275
# build an authz file and commit it to the repo
276
authz_path = os.path.join(wc_dir, 'A', 'authz')
277
svntest.main.file_write(authz_path, authz_content)
278
svntest.main.run_svn(None, 'add', authz_path)
279
expected_output = wc.State(wc_dir, {'A/authz' : Item(verb='Adding')})
280
expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
281
expected_status.add({
282
'A/authz' : Item(status=' ', wc_rev=2),
284
if svntest.actions.run_and_verify_commit(wc_dir, expected_output,
285
expected_status, None, wc_dir):
286
raise svntest.Failure
288
# Anonymous access with no path, and no repository should be rw
289
# since it returns the highest level of access granted anywhere.
290
# So /bios being rw for everyone means this will be rw.
291
authz_url = repo_url + "/A/authz"
292
svntest.actions.run_and_verify_svnauthz("Anonymous access", ["rw\n"], None,
293
0, False, "accessof", authz_url)
295
# Anonymous access on /jokes should be r, no repo so won't match
296
# the slapstick:/jokes section.
297
svntest.actions.run_and_verify_svnauthz("Anonymous access on path",
298
["r\n"], None, 0, False, "accessof",
299
authz_url, "--path", "/jokes")
301
# Anonymous access on /jokes on slapstick repo should be no
302
svntest.actions.run_and_verify_svnauthz("Anonymous access on path with repo",
303
["no\n"], None, 0, False, "accessof",
304
authz_url, "--path", "/jokes",
305
"--repository", "slapstick")
307
# User access with no path, and no repository should be rw
308
# since it returns the h ighest level of access anywhere.
309
# So /bios being rw for everyone means this will be rw.
310
svntest.actions.run_and_verify_svnauthz("User access", ["rw\n"], None,
311
0, False, "accessof", authz_url,
312
"--username", "groucho")
314
# User groucho specified on /jokes with no repo, will not match any of the
315
# repo specific sections, so is r since everyone has read access.
316
svntest.actions.run_and_verify_svnauthz("User access on path", ["r\n"], None,
317
0, False, "accessof", authz_url,
318
"--path", "/jokes", "--username",
321
# User groucho specified on /jokes with the repo comedy will be rw
322
svntest.actions.run_and_verify_svnauthz("User access on path with repo",
323
["rw\n"], None, 0, False, "accessof",
324
authz_url, "--path", "/jokes",
325
"--username", "groucho",
326
"--repository", "comedy")
328
def svnauthz_accessof_groups_file_test(sbox):
329
"test 'svnauthz accessof --groups-file' on files"
331
# build an authz file
332
(authz_fd, authz_path) = tempfile.mkstemp()
333
authz_content = "[/]\n@musicians = rw\n@comedians = \n" + \
334
"[comedy:/jokes]\n@musicians = \n@comedians = r\n"
335
svntest.main.file_write(authz_path, authz_content)
337
# build a groups file
338
(groups_fd, groups_path) = tempfile.mkstemp()
339
groups_content = "[groups]\nmusicians=stafford\ncomedians=groucho\n"
340
svntest.main.file_write(groups_path, groups_content)
342
# Anonymous access with no path, and no repository should be no
343
# since it returns the highest level of access granted anywhere.
344
svntest.actions.run_and_verify_svnauthz("Anonymous access", ["no\n"], None,
345
0, False, "accessof", authz_path,
346
"--groups-file", groups_path)
348
# User stafford (@musicians) access with no path, and no repository should
349
# be no since it returns the highest level of access granted anywhere.
350
svntest.actions.run_and_verify_svnauthz("Group 1 access",
352
0, False, "accessof", authz_path,
353
"--groups-file", groups_path,
354
"--username", "stafford")
356
# User groucho (@comedians) access with no path, and no repository should
357
# be no since it returns the highest level of access granted anywhere.
358
svntest.actions.run_and_verify_svnauthz("Group 2 access",
360
0, False, "accessof", authz_path,
361
"--groups-file", groups_path,
362
"--username", "groucho")
364
# Anonymous access specified on /jokes with the repo comedy will be no.
365
svntest.actions.run_and_verify_svnauthz("Anonymous access on path with repo",
366
["no\n"], None, 0, False,
367
"accessof", authz_path,
368
"--groups-file", groups_path,
370
"--repository", "comedy")
372
# User stafford (@musicians) specified on /jokes with the repo comedy
374
svntest.actions.run_and_verify_svnauthz("Group 1 access on path with repo",
376
0, False, "accessof", authz_path,
377
"--groups-file", groups_path,
379
"--repository", "comedy",
380
"--username", "stafford")
382
# User groucho (@comedians) specified on /jokes with the repo
384
svntest.actions.run_and_verify_svnauthz("Group 2 access on path with repo",
386
0, False, "accessof", authz_path,
387
"--groups-file", groups_path,
389
"--repository", "comedy",
390
"--username", "groucho")
393
os.remove(authz_path)
395
os.remove(groups_path)
397
@SkipUnless(svntest.main.is_ra_type_file)
398
def svnauthz_accessof_groups_repo_test(sbox):
399
"test 'svnauthz accessof --groups-file' on urls"
403
repo_url = sbox.repo_url
405
authz_content = "[/]\n@musicians = rw\n@comedians = \n" + \
406
"[comedy:/jokes]\n@musicians = \n@comedians = r\n"
408
groups_content = "[groups]\nmusicians=stafford\ncomedians=groucho\n"
410
# build authz and groups files and commit them to the repo
411
authz_path = os.path.join(wc_dir, 'A', 'authz')
412
groups_path = os.path.join(wc_dir, 'A', 'groups')
413
svntest.main.file_write(authz_path, authz_content)
414
svntest.main.file_write(groups_path, groups_content)
415
svntest.main.run_svn(None, 'add', authz_path, groups_path)
416
expected_output = wc.State(wc_dir, {
417
'A/authz' : Item(verb='Adding'),
418
'A/groups' : Item(verb='Adding'),
420
expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
421
expected_status.add({
422
'A/authz' : Item(status=' ', wc_rev=2),
423
'A/groups' : Item(status=' ', wc_rev=2),
426
if svntest.actions.run_and_verify_commit(wc_dir, expected_output,
427
expected_status, None, wc_dir):
428
raise svntest.Failure
430
# Anonymous access with no path, and no repository should be no
431
# since it returns the highest level of access granted anywhere.
432
authz_url = repo_url + "/A/authz"
433
groups_url = repo_url + "/A/groups"
434
svntest.actions.run_and_verify_svnauthz("Anonymous access", ["no\n"], None,
435
0, False, "accessof", authz_url,
436
"--groups-file", groups_url)
438
# User stafford (@musicians) access with no path, and no repository should
439
# be no since it returns the highest level of access granted anywhere.
440
svntest.actions.run_and_verify_svnauthz("Group 1 access",
442
0, False, "accessof", authz_url,
443
"--groups-file", groups_url,
444
"--username", "stafford")
446
# User groucho (@comedians) access with no path, and no repository should
447
# be no since it returns the highest level of access granted anywhere.
448
svntest.actions.run_and_verify_svnauthz("Group 2 access",
450
0, False, "accessof", authz_url,
451
"--groups-file", groups_url,
452
"--username", "groucho")
454
# Anonymous access specified on /jokes with the repo comedy will be no.
455
svntest.actions.run_and_verify_svnauthz("Anonymous access on path with repo",
456
["no\n"], None, 0, False,
457
"accessof", authz_url,
458
"--groups-file", groups_url,
460
"--repository", "comedy")
462
# User stafford (@musicians) specified on /jokes with the repo comedy
464
svntest.actions.run_and_verify_svnauthz("Group 1 access on path with repo",
466
0, False, "accessof", authz_url,
467
"--groups-file", groups_url,
469
"--repository", "comedy",
470
"--username", "stafford")
472
# User groucho (@comedians) specified on /jokes with the repo
474
svntest.actions.run_and_verify_svnauthz("Group 2 access on path with repo",
476
0, False, "accessof", authz_url,
477
"--groups-file", groups_url,
479
"--repository", "comedy",
480
"--username", "groucho")
482
def svnauthz_accessof_is_file_test(sbox):
483
"test 'svnauthz accessof --is' on files"
485
# build an authz file
486
(authz_fd, authz_path) = tempfile.mkstemp()
487
authz_content = "[/]\ngroucho = \ngallagher = rw\n* = r\n" + \
488
"[/bios]\n* = rw\n" + \
489
"[comedy:/jokes]\ngroucho = rw\n" + \
490
"[slapstick:/jokes]\n* =\n"
491
svntest.main.file_write(authz_path, authz_content)
493
# Test an invalid --is option, should get an error message and exit code
495
expected_output = svntest.verify.RegexOutput(
496
".*'x' is not a valid argument for --is", match_all=False
498
svntest.actions.run_and_verify_svnauthz("--is x fails", None,
499
expected_output, 2, False,
500
"accessof", authz_path, "--is", "x")
502
# Anonymous access with no path, and no repository should be rw
503
# since it returns the highest level of access granted anywhere.
504
# So /bios being rw for everyone means this will be rw.
505
# Test --is rw returns 0.
506
svntest.actions.run_and_verify_svnauthz("Anonymous access --is rw", None,
507
None, 0, False, "accessof",
508
authz_path, "--is", "rw")
509
# Test --is r returns 3.
510
svntest.actions.run_and_verify_svnauthz("Anonymous access --is r", None,
511
None, 3, False, "accessof",
512
authz_path, "--is", "r")
513
# Test --is no returns 3.
514
svntest.actions.run_and_verify_svnauthz("Anonymous access --is no", None,
515
None, 3, False, "accessof",
516
authz_path, "--is", "no")
518
# Anonymous access on /jokes should be r, no repo so won't match
519
# the slapstick:/jokes section.
520
# Test --is r returns 0.
521
svntest.actions.run_and_verify_svnauthz("Anonymous access on path --is r",
522
None, None, 0, False, "accessof",
523
authz_path, "--path", "/jokes",
525
# Test --is rw returns 3.
526
svntest.actions.run_and_verify_svnauthz("Anonymous access on path --is r",
527
None, None, 3, False, "accessof",
528
authz_path, "--path", "/jokes",
530
# Test --is no returns 3.
531
svntest.actions.run_and_verify_svnauthz("Anonymous access on path --is r",
532
None, None, 3, False, "accessof",
533
authz_path, "--path", "/jokes",
536
# Anonymous access on /jokes on slapstick repo should be no
537
# Test --is no returns 0.
538
svntest.actions.run_and_verify_svnauthz("Anon access on path w/ repo --is no",
539
None, None, 0, False, "accessof",
540
authz_path, "--path", "/jokes",
541
"--repository", "slapstick",
543
# Test --is rw returns 3.
544
svntest.actions.run_and_verify_svnauthz("Anon access on path w/ repo --is no",
545
None, None, 3, False, "accessof",
546
authz_path, "--path", "/jokes",
547
"--repository", "slapstick",
549
# Test --is r returns 3.
550
svntest.actions.run_and_verify_svnauthz("Anon access on path w/ repo --is no",
551
None, None, 3, False, "accessof",
552
authz_path, "--path", "/jokes",
553
"--repository", "slapstick",
556
# User access with no path, and no repository should be rw
557
# since it returns the h ighest level of access anywhere.
558
# So /bios being rw for everyone means this will be rw.
559
# Test --is rw returns 0.
560
svntest.actions.run_and_verify_svnauthz("User access --is rw", None, None,
561
0, False, "accessof", authz_path,
562
"--username", "groucho", "--is",
564
# Test --is r returns 3.
565
svntest.actions.run_and_verify_svnauthz("User access --is r", None, None,
566
3, False, "accessof", authz_path,
567
"--username", "groucho", "--is",
569
# Test --is no returns 3.
570
svntest.actions.run_and_verify_svnauthz("User access --is no", None, None,
571
3, False, "accessof", authz_path,
572
"--username", "groucho", "--is",
575
# User groucho specified on /jokes with no repo, will not match any of the
576
# repo specific sections, so is r since everyone has read access.
577
# Test --is r returns 0.
578
svntest.actions.run_and_verify_svnauthz("User access on path --is r", None,
579
None, 0, False, "accessof",
580
authz_path, "--path", "/jokes",
581
"--username", "groucho", "--is", "r")
582
# Test --is rw returns 3.
583
svntest.actions.run_and_verify_svnauthz("User access on path --is rw", None,
584
None, 3, False, "accessof",
585
authz_path, "--path", "/jokes",
586
"--username", "groucho",
588
# Test --is no returns 3.
589
svntest.actions.run_and_verify_svnauthz("User access on path --is no", None,
590
None, 3, False, "accessof",
591
authz_path, "--path", "/jokes",
592
"--username", "groucho",
595
# User groucho specified on /jokes with the repo comedy will be rw
596
# Test --is rw returns 0.
597
svntest.actions.run_and_verify_svnauthz("User access on path w/ repo --is rw",
598
None, None, 0, False, "accessof",
599
authz_path, "--path", "/jokes",
600
"--username", "groucho",
601
"--repository", "comedy", "--is",
603
# Test --is r returns 3.
604
svntest.actions.run_and_verify_svnauthz("User access on path w/ repo --is r",
605
None, None, 3, False, "accessof",
606
authz_path, "--path", "/jokes",
607
"--username", "groucho",
608
"--repository", "comedy", "--is",
610
# Test --is no returns 3.
611
svntest.actions.run_and_verify_svnauthz("User access on path w/ repo --is no",
612
None, None, 3, False, "accessof",
613
authz_path, "--path", "/jokes",
614
"--username", "groucho",
615
"--repository", "comedy", "--is",
618
# Add an invalid line to the authz file
619
svntest.main.file_append(authz_path, "x\n")
620
# Check that --is returns 1 when the syntax is invalid with a file..
621
expected_out = svntest.verify.RegexOutput(
622
".*Error while parsing config file:",
625
svntest.actions.run_and_verify_svnauthz("--is with invalid authz file",
626
None, expected_out, 1, False,
627
"accessof", authz_path, "--path",
628
"/jokes", "--username", "groucho",
629
"--repository", "comedy", "--is",
633
os.remove(authz_path)
635
@SkipUnless(svntest.main.is_ra_type_file)
636
def svnauthz_accessof_is_repo_test(sbox):
637
"test 'svnauthz accessof --is' on files and urls"
641
repo_url = sbox.repo_url
643
authz_content = "[/]\ngroucho = \ngallagher = rw\n* = r\n" + \
644
"[/bios]\n* = rw\n" + \
645
"[comedy:/jokes]\ngroucho = rw\n" + \
646
"[slapstick:/jokes]\n* =\n"
648
# build an authz file and commit it to the repo
649
authz_path = os.path.join(wc_dir, 'A', 'authz')
650
svntest.main.file_write(authz_path, authz_content)
651
svntest.main.run_svn(None, 'add', authz_path)
652
expected_output = wc.State(wc_dir, {'A/authz' : Item(verb='Adding')})
653
expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
654
expected_status.add({
655
'A/authz' : Item(status=' ', wc_rev=2),
657
if svntest.actions.run_and_verify_commit(wc_dir, expected_output,
658
expected_status, None, wc_dir):
659
raise svntest.Failure
661
# Test an invalid --is option, should get an error message and exit code
663
authz_url = repo_url + "/A/authz"
664
expected_output = svntest.verify.RegexOutput(
665
".*'x' is not a valid argument for --is", match_all=False
667
svntest.actions.run_and_verify_svnauthz("--is x fails", None,
668
expected_output, 2, False,
669
"accessof", authz_url, "--is", "x")
671
# Anonymous access with no path, and no repository should be rw
672
# since it returns the highest level of access granted anywhere.
673
# So /bios being rw for everyone means this will be rw.
674
# Test --is rw returns 0.
675
svntest.actions.run_and_verify_svnauthz("Anonymous access --is rw", None,
676
None, 0, False, "accessof",
677
authz_url, "--is", "rw")
678
# Test --is r returns 3.
679
svntest.actions.run_and_verify_svnauthz("Anonymous access --is r", None,
680
None, 3, False, "accessof",
681
authz_url, "--is", "r")
682
# Test --is no returns 3.
683
svntest.actions.run_and_verify_svnauthz("Anonymous access --is no", None,
684
None, 3, False, "accessof",
685
authz_url, "--is", "no")
687
# Anonymous access on /jokes should be r, no repo so won't match
688
# the slapstick:/jokes section.
689
# Test --is r returns 0.
690
svntest.actions.run_and_verify_svnauthz("Anonymous access on path --is r",
691
None, None, 0, False, "accessof",
692
authz_url, "--path", "/jokes",
694
# Test --is rw returns 3.
695
svntest.actions.run_and_verify_svnauthz("Anonymous access on path --is r",
696
None, None, 3, False, "accessof",
697
authz_url, "--path", "/jokes",
699
# Test --is no returns 3.
700
svntest.actions.run_and_verify_svnauthz("Anonymous access on path --is r",
701
None, None, 3, False, "accessof",
702
authz_url, "--path", "/jokes",
705
# Anonymous access on /jokes on slapstick repo should be no
706
# Test --is no returns 0.
707
svntest.actions.run_and_verify_svnauthz("Anon access on path w/ repo --is no",
708
None, None, 0, False, "accessof",
709
authz_url, "--path", "/jokes",
710
"--repository", "slapstick",
712
# Test --is rw returns 3.
713
svntest.actions.run_and_verify_svnauthz("Anon access on path w/ repo --is no",
714
None, None, 3, False, "accessof",
715
authz_url, "--path", "/jokes",
716
"--repository", "slapstick",
718
# Test --is r returns 3.
719
svntest.actions.run_and_verify_svnauthz("Anon access on path w/ repo --is no",
720
None, None, 3, False, "accessof",
721
authz_url, "--path", "/jokes",
722
"--repository", "slapstick",
725
# User access with no path, and no repository should be rw
726
# since it returns the h ighest level of access anywhere.
727
# So /bios being rw for everyone means this will be rw.
728
# Test --is rw returns 0.
729
svntest.actions.run_and_verify_svnauthz("User access --is rw", None, None,
730
0, False, "accessof", authz_url,
731
"--username", "groucho", "--is",
733
# Test --is r returns 3.
734
svntest.actions.run_and_verify_svnauthz("User access --is r", None, None,
735
3, False, "accessof", authz_url,
736
"--username", "groucho", "--is",
738
# Test --is no returns 3.
739
svntest.actions.run_and_verify_svnauthz("User access --is no", None, None,
740
3, False, "accessof", authz_url,
741
"--username", "groucho", "--is",
744
# User groucho specified on /jokes with no repo, will not match any of the
745
# repo specific sections, so is r since everyone has read access.
746
# Test --is r returns 0.
747
svntest.actions.run_and_verify_svnauthz("User access on path --is r", None,
748
None, 0, False, "accessof",
749
authz_url, "--path", "/jokes",
750
"--username", "groucho", "--is", "r")
751
# Test --is rw returns 3.
752
svntest.actions.run_and_verify_svnauthz("User access on path --is rw", None,
753
None, 3, False, "accessof",
754
authz_url, "--path", "/jokes",
755
"--username", "groucho",
757
# Test --is no returns 3.
758
svntest.actions.run_and_verify_svnauthz("User access on path --is no", None,
759
None, 3, False, "accessof",
760
authz_url, "--path", "/jokes",
761
"--username", "groucho",
764
# User groucho specified on /jokes with the repo comedy will be rw
765
# Test --is rw returns 0.
766
svntest.actions.run_and_verify_svnauthz("User access on path w/ repo --is rw",
767
None, None, 0, False, "accessof",
768
authz_url, "--path", "/jokes",
769
"--username", "groucho",
770
"--repository", "comedy", "--is",
772
# Test --is r returns 3.
773
svntest.actions.run_and_verify_svnauthz("User access on path w/ repo --is r",
774
None, None, 3, False, "accessof",
775
authz_url, "--path", "/jokes",
776
"--username", "groucho",
777
"--repository", "comedy", "--is",
779
# Test --is no returns 3.
780
svntest.actions.run_and_verify_svnauthz("User access on path w/ repo --is no",
781
None, None, 3, False, "accessof",
782
authz_url, "--path", "/jokes",
783
"--username", "groucho",
784
"--repository", "comedy", "--is",
787
# Add an invalid line to the authz file
788
svntest.main.file_append(authz_path, "x\n")
789
expected_output = wc.State(wc_dir, {'A/authz' : Item(verb='Sending')})
790
expected_status.tweak('A/authz', wc_rev=3)
791
if svntest.actions.run_and_verify_commit(wc_dir, expected_output,
792
expected_status, None, wc_dir):
793
raise svntest.Failure
795
# Check that --is returns 1 when the syntax is invalid with a url.
796
expected_out = svntest.verify.RegexOutput(
797
".*Error while parsing config file:",
800
svntest.actions.run_and_verify_svnauthz("--is with invalid authz url",
801
None, expected_out, 1, False,
802
"accessof", authz_url, "--path",
803
"/jokes", "--username", "groucho",
804
"--repository", "comedy", "--is",
807
def svnauthz_accessof_txn_test(sbox):
808
"test 'svnauthz accessof --transaction'"
812
repo_dir = sbox.repo_dir
814
logfilepath = os.path.join(repo_dir, 'hooks.log')
815
pre_commit_hook = svntest.main.get_pre_commit_hook_path(repo_dir)
816
hook_instance = hook_template % (repr(svntest.main.svnauthz_binary),
818
'--is rw A/authz')]))
819
svntest.main.create_python_hook_script(pre_commit_hook, hook_instance)
821
# Create an authz file
822
authz_content = "[/]\n* = rw\n"
823
authz_path = os.path.join(wc_dir, 'A/authz')
824
svntest.main.file_write(authz_path, authz_content)
825
svntest.main.run_svn(None, 'add', authz_path)
827
# Only really testing the exit value code paths.
829
# commit a valid authz file, and run --is rw which is true.
830
# Should get an exit of 0.
831
expected_output = wc.State(wc_dir, {'A/authz' : Item(verb='Adding')})
832
expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
833
expected_status.add({
834
'A/authz' : Item(status=' ', wc_rev=2),
836
if svntest.actions.run_and_verify_commit(wc_dir, expected_output,
837
expected_status, None, wc_dir):
838
raise svntest.Failure
839
expected_data = ['Exit 0\n']
840
verify_logfile(logfilepath, expected_data)
842
# commit a valid authz file, and run --is r which is false
843
# Should get an exit of 3.
844
hook_instance = hook_template % (repr(svntest.main.svnauthz_binary),
847
svntest.main.create_python_hook_script(pre_commit_hook, hook_instance)
848
expected_output = wc.State(wc_dir, {'A/authz' : Item(verb='Sending')})
849
expected_status.tweak('A/authz', status=' ', wc_rev=3)
850
svntest.main.file_append(authz_path, "groucho = r\n")
851
if svntest.actions.run_and_verify_commit(wc_dir, expected_output,
852
expected_status, None, wc_dir):
853
raise svntest.Failure
854
expected_data = svntest.verify.ExpectedOutput('Exit 3\n', match_all=False)
855
verify_logfile(logfilepath, expected_data)
857
# break the authz file with a non-existant group and check for an exit 1.
858
expected_status.tweak('A/authz', status=' ', wc_rev=4)
859
svntest.main.file_append(authz_path, "@friends = rw\n")
860
if svntest.actions.run_and_verify_commit(wc_dir, expected_output,
861
expected_status, None, wc_dir):
862
raise svntest.Failure
863
expected_data = svntest.verify.ExpectedOutput('Exit 1\n', match_all=False)
864
verify_logfile(logfilepath, expected_data)
866
# break the authz file with a non-existant gropu and check for an exit 2.
867
expected_output = wc.State(wc_dir, {'A/authz' : Item(verb='Deleting')})
868
expected_status.remove('A/authz')
869
svntest.main.run_svn(None, 'rm', authz_path)
870
if svntest.actions.run_and_verify_commit(wc_dir, expected_output,
871
expected_status, None, wc_dir):
872
raise svntest.Failure
873
expected_data = svntest.verify.ExpectedOutput('Exit 2\n', match_all=False)
874
verify_logfile(logfilepath, expected_data)
876
def svnauthz_compat_mode_file_test(sbox):
877
"test 'svnauthz-validate' compatability mode file"
880
# Create an authz file
881
(authz_fd, authz_path) = tempfile.mkstemp()
882
authz_content = "[/]\n* = rw\n"
883
svntest.main.file_write(authz_path, authz_content)
885
# Check a valid file.
886
svntest.actions.run_and_verify_svnauthz("svnauthz-validate on file",
890
# Check an invalid file.
891
svntest.main.file_append(authz_path, "x\n")
892
svntest.actions.run_and_verify_svnauthz("svnauthz-validate on invalid file",
898
os.remove(authz_path)
900
# Check a non-existant file.
901
svntest.actions.run_and_verify_svnauthz(
902
"svnauthz-validate on non-existant file", None, None, 2, True,
907
@SkipUnless(svntest.main.is_ra_type_file)
908
def svnauthz_compat_mode_repo_test(sbox):
909
"test 'svnauthz-validate' compatability mode url"
913
repo_url = sbox.repo_url
915
# Create an authz file
916
authz_content = "[/]\n* = rw\n"
917
authz_path = os.path.join(wc_dir, 'A/authz')
918
svntest.main.file_write(authz_path, authz_content)
919
authz_url = repo_url + '/A/authz'
921
# Commit the file and check a URL
922
svntest.main.run_svn(None, 'add', authz_path)
923
expected_output = wc.State(wc_dir, {'A/authz' : Item(verb='Adding')})
924
expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
925
expected_status.add({
926
'A/authz' : Item(status=' ', wc_rev=2),
928
if svntest.actions.run_and_verify_commit(wc_dir, expected_output,
929
expected_status, None, wc_dir):
930
raise svntest.Failure
931
svntest.actions.run_and_verify_svnauthz("svnauthz-validate on url",
935
# Check an invalid url.
936
svntest.main.file_append(authz_path, "x\n")
937
expected_output = wc.State(wc_dir, {'A/authz' : Item(verb='Sending')})
938
expected_status.tweak('A/authz', status=' ', wc_rev=3)
939
if svntest.actions.run_and_verify_commit(wc_dir, expected_output,
940
expected_status, None, wc_dir):
941
raise svntest.Failure
942
svntest.actions.run_and_verify_svnauthz("svnauthz-validate on invalid file",
946
# Check a non-existant url.
947
# Exit code really should be 2 since this is an operational error.
948
svntest.actions.run_and_verify_svnauthz(
949
"svnauthz-validate on non-existant file", None, None, 2, True,
953
########################################################################
957
# list all tests here, starting with None:
959
svnauthz_validate_file_test,
960
svnauthz_validate_repo_test,
961
svnauthz_validate_txn_test,
962
svnauthz_accessof_file_test,
963
svnauthz_accessof_repo_test,
964
svnauthz_accessof_groups_file_test,
965
svnauthz_accessof_groups_repo_test,
966
svnauthz_accessof_is_file_test,
967
svnauthz_accessof_is_repo_test,
968
svnauthz_accessof_txn_test,
969
svnauthz_compat_mode_file_test,
970
svnauthz_compat_mode_repo_test,
973
if __name__ == '__main__':
974
svntest.main.run_tests(test_list)