import os
import svntest
from svntest.main import write_restrictive_svnserve_conf
from svntest.main import write_authz_file
from svntest.main import server_authz_has_aliases
Item = svntest.wc.StateItem
XFail = svntest.testcase.XFail
Skip = svntest.testcase.Skip
SkipUnless = svntest.testcase.SkipUnless
def authz_open_root(sbox):
"authz issue #2486 - open root"
sbox.build()
write_authz_file(sbox, {"/": "", "/A": "jrandom = rw"})
write_restrictive_svnserve_conf(sbox.repo_dir)
wc_dir = sbox.wc_dir
mu_path = os.path.join(wc_dir, 'A', 'mu')
svntest.main.file_append(mu_path, "hi")
expected_output = svntest.wc.State(wc_dir, {
'A/mu' : Item(verb='Sending'),
})
svntest.actions.run_and_verify_commit(wc_dir,
expected_output,
None,
None,
mu_path)
def authz_open_directory(sbox):
"authz issue #2486 - open directory"
sbox.build()
write_authz_file(sbox, {"/": "*=rw", "/A/B": "*=", "/A/B/E": "jrandom = rw"})
write_restrictive_svnserve_conf(sbox.repo_dir)
wc_dir = sbox.wc_dir
mu_path = os.path.join(wc_dir, 'A', 'mu')
E_path = os.path.join(wc_dir, 'A', 'B', 'E')
svntest.main.run_svn(None, 'mv', mu_path, E_path)
expected_output = svntest.wc.State(wc_dir, {
'A/mu' : Item(verb='Deleting'),
'A/B/E/mu' : Item(verb='Adding'),
})
svntest.actions.run_and_verify_commit(wc_dir,
expected_output,
None,
None,
wc_dir)
def broken_authz_file(sbox):
"broken authz files cause errors"
sbox.build(create_wc = False)
write_authz_file(sbox, {"/": "jrandom = rw # End-line comments disallowed"})
write_restrictive_svnserve_conf(sbox.repo_dir)
exit_code, out, err = svntest.main.run_svn(1,
"delete",
sbox.repo_url + "/A",
"-m", "a log message");
if out:
raise svntest.verify.SVNUnexpectedStdout(out)
if not err:
raise svntest.verify.SVNUnexpectedStderr("Missing stderr")
def authz_read_access(sbox):
"test authz for read operations"
sbox.build(create_wc = False)
root_url = sbox.repo_url
A_url = root_url + '/A'
B_url = A_url + '/B'
C_url = A_url + '/C'
E_url = B_url + '/E'
mu_url = A_url + '/mu'
iota_url = root_url + '/iota'
lambda_url = B_url + '/lambda'
alpha_url = E_url + '/alpha'
D_url = A_url + '/D'
G_url = D_url + '/G'
pi_url = G_url + '/pi'
H_url = D_url + '/H'
chi_url = H_url + '/chi'
if sbox.repo_url.startswith("http"):
expected_err = ".*403 Forbidden.*"
else:
expected_err = ".*svn: Authorization failed.*"
svntest.actions.run_and_verify_svn(None, None, [],
'mkdir',
'-m', 'logmsg',
B_url+'/folder with spaces',
B_url+'/folder with spaces/empty folder')
write_restrictive_svnserve_conf(sbox.repo_dir)
write_authz_file(sbox, { "/": "* = r",
"/A/B": "* =",
"/A/D": "* = rw",
"/A/D/G": ("* = rw\n" +
svntest.main.wc_author + " ="),
"/A/D/H": ("* = \n" +
svntest.main.wc_author + " = rw"),
"/A/B/folder with spaces":
(svntest.main.wc_author + " = r")})
svntest.actions.run_and_verify_svn(None, ["This is the file 'iota'.\n"],
[], 'cat',
iota_url)
svntest.actions.run_and_verify_svn(None, ["This is the file 'chi'.\n"],
[], 'cat',
chi_url)
svntest.actions.run_and_verify_svn(None,
None, expected_err,
'cat',
lambda_url)
svntest.actions.run_and_verify_svn(None,
None, expected_err,
'cat',
alpha_url)
svntest.actions.run_and_verify_svn(None, ["This is the file 'pi'.\n"],
[], 'cat',
pi_url)
svntest.actions.run_and_verify_svn("ls remote root folder",
["A/\n", "iota\n"],
[], 'ls',
root_url)
svntest.actions.run_and_verify_svn(None,
None, svntest.verify.AnyOutput, 'ls',
B_url)
svntest.actions.run_and_verify_svn(None,
None, [], 'ls',
B_url+'/folder with spaces/empty folder')
svntest.actions.run_and_verify_svn(None,
None, expected_err,
'ls',
E_url)
svntest.actions.run_and_verify_svn(None, None, [], 'cp',
iota_url, D_url,
'-m', 'logmsg')
svntest.actions.run_and_verify_svn(None,
None, expected_err,
'cp',
'-m', 'logmsg',
lambda_url, D_url)
svntest.actions.run_and_verify_svn(None, None, [], 'cp',
C_url, D_url,
'-m', 'logmsg')
svntest.actions.run_and_verify_svn(None,
None, expected_err,
'cp',
'-m', 'logmsg',
E_url, D_url)
def authz_write_access(sbox):
"test authz for write operations"
sbox.build(create_wc = False)
write_restrictive_svnserve_conf(sbox.repo_dir)
if sbox.repo_url.startswith('http'):
expected_err = ".*403 Forbidden.*"
else:
expected_err = ".*svn: Access denied.*"
write_authz_file(sbox, { "/": "* = r",
"/A/B": "* = rw",
"/A/C": "* = rw"})
root_url = sbox.repo_url
A_url = root_url + '/A'
B_url = A_url + '/B'
C_url = A_url + '/C'
E_url = B_url + '/E'
mu_url = A_url + '/mu'
iota_url = root_url + '/iota'
lambda_url = B_url + '/lambda'
D_url = A_url + '/D'
svntest.actions.run_and_verify_svn(None,
None, expected_err,
'cp',
'-m', 'logmsg',
lambda_url, D_url)
svntest.actions.run_and_verify_svn(None,
None, expected_err,
'cp',
'-m', 'logmsg',
E_url, D_url)
svntest.actions.run_and_verify_svn(None,
None, expected_err,
'rm',
'-m', 'logmsg',
iota_url)
svntest.actions.run_and_verify_svn(None,
None, expected_err,
'rm',
'-m', 'logmsg',
D_url)
svntest.actions.run_and_verify_svn(None,
None, expected_err,
'mkdir',
'-m', 'logmsg',
A_url+'/newfolder')
svntest.actions.run_and_verify_svn(None,
None, expected_err,
'mv',
'-m', 'logmsg',
mu_url, C_url)
svntest.actions.run_and_verify_svn(None,
None, expected_err,
'mv',
'-m', 'logmsg',
D_url, C_url)
svntest.actions.run_and_verify_svn(None,
None, expected_err,
'mv',
'-m', 'logmsg',
lambda_url, D_url)
svntest.actions.run_and_verify_svn(None,
None, expected_err,
'mv',
'-m', 'logmsg',
B_url, D_url)
def authz_checkout_test(sbox):
"test authz for checkout"
sbox.build(create_wc = False, read_only = True)
local_dir = sbox.wc_dir
write_restrictive_svnserve_conf(sbox.repo_dir)
if sbox.repo_url.startswith('http'):
expected_err = ".*403 Forbidden.*"
else:
expected_err = ".*svn: Authorization failed.*"
write_authz_file(sbox, { "/": "* ="})
svntest.actions.run_and_verify_svn(None, None, expected_err,
'co', sbox.repo_url, local_dir)
write_authz_file(sbox, { "/": "* = r"})
expected_output = svntest.main.greek_state.copy()
expected_output.wc_dir = local_dir
expected_output.tweak(status='A ', contents=None)
expected_wc = svntest.main.greek_state
svntest.actions.run_and_verify_checkout(sbox.repo_url,
local_dir,
expected_output,
expected_wc)
def authz_checkout_and_update_test(sbox):
"test authz for checkout and update"
sbox.build(create_wc = False, read_only = True)
local_dir = sbox.wc_dir
write_restrictive_svnserve_conf(sbox.repo_dir)
write_authz_file(sbox, { "/": "* = r",
"/A/B": "* ="})
expected_output = svntest.main.greek_state.copy()
expected_output.wc_dir = local_dir
expected_output.tweak(status='A ', contents=None)
expected_output.remove('A/B', 'A/B/lambda', 'A/B/E', 'A/B/E/alpha',
'A/B/E/beta', 'A/B/F')
expected_wc = svntest.main.greek_state.copy()
expected_wc.remove('A/B', 'A/B/lambda', 'A/B/E', 'A/B/E/alpha',
'A/B/E/beta', 'A/B/F')
svntest.actions.run_and_verify_checkout(sbox.repo_url, local_dir,
expected_output,
expected_wc)
write_authz_file(sbox, { "/": "* = r"})
expected_output = svntest.wc.State(local_dir, {
'A/B' : Item(status='A '),
'A/B/lambda' : Item(status='A '),
'A/B/E' : Item(status='A '),
'A/B/E/alpha' : Item(status='A '),
'A/B/E/beta' : Item(status='A '),
'A/B/F' : Item(status='A '),
})
expected_wc = svntest.main.greek_state
expected_status = svntest.actions.get_virginal_state(local_dir, 1)
svntest.actions.run_and_verify_update(local_dir,
expected_output,
expected_wc,
expected_status,
None,
None, None,
None, None, 1)
def authz_partial_export_test(sbox):
"test authz for export with unreadable subfolder"
sbox.build(create_wc = False, read_only = True)
local_dir = sbox.wc_dir
svntest.main.safe_rmtree(local_dir)
write_restrictive_svnserve_conf(sbox.repo_dir)
write_authz_file(sbox, { "/": "* = r", "/A/B": "* =" })
expected_output = svntest.main.greek_state.copy()
expected_output.wc_dir = local_dir
expected_output.desc[''] = Item()
expected_output.tweak(status='A ', contents=None)
expected_output.remove('A/B', 'A/B/lambda', 'A/B/E', 'A/B/E/alpha',
'A/B/E/beta', 'A/B/F')
expected_wc = svntest.main.greek_state.copy()
expected_wc.remove('A/B', 'A/B/lambda', 'A/B/E', 'A/B/E/alpha',
'A/B/E/beta', 'A/B/F')
svntest.actions.run_and_verify_export(sbox.repo_url, local_dir,
expected_output,
expected_wc)
def authz_log_and_tracing_test(sbox):
"test authz for log and tracing path changes"
sbox.build()
wc_dir = sbox.wc_dir
write_restrictive_svnserve_conf(sbox.repo_dir)
if sbox.repo_url.startswith('http'):
expected_err = ".*403 Forbidden.*"
else:
expected_err = ".*svn: Authorization failed.*"
write_authz_file(sbox, { "/": "* = rw\n" })
root_url = sbox.repo_url
D_url = root_url + '/A/D'
G_url = D_url + '/G'
rho_path = os.path.join(wc_dir, 'A', 'D', 'G', 'rho')
svntest.main.file_append(rho_path, 'new appended text for rho')
svntest.actions.run_and_verify_svn(None, None, [],
'ci', '-m', 'add file rho', sbox.wc_dir)
svntest.main.file_append(rho_path, 'extra change in rho')
svntest.actions.run_and_verify_svn(None, None, [],
'ci', '-m', 'changed file rho',
sbox.wc_dir)
svntest.actions.run_and_verify_svn(None, None, [], 'cp',
rho_path, D_url,
'-m', 'copy rho to readable area')
if sbox.repo_url.startswith('http'):
expected_err = ".*403 Forbidden.*"
else:
expected_err = ".*svn: Authorization failed.*"
authz = { "/": "* = rw",
"/A/D/G": "* ="}
write_authz_file(sbox, authz)
svntest.actions.run_and_verify_svn(None,
".*(no author).*(no date).*|-+\n|\n", [],
'log', '-r', '2', '--limit', '1',
wc_dir)
if sbox.repo_url.startswith('http'):
expected_err2 = expected_err
else:
expected_err2 = ".*svn: Item is not readable.*"
svntest.actions.run_and_verify_svn(None, None, expected_err2,
'log', rho_path)
svntest.actions.run_and_verify_svn(None,
".*(no author).*(no date).*|-+\n|\n", [],
'log', '-r', '2', '--limit', '1', D_url)
svntest.actions.enable_revprop_changes(sbox.repo_dir)
write_authz_file(sbox, { "/": "* = rw"})
svntest.actions.run_and_verify_svn(
None, None, [], 'ps', '--revprop', '-r1', 'foobar', 'foo bar', sbox.repo_url)
svntest.actions.run_and_verify_log_xml(
expected_revprops=[{'svn:author': svntest.main.wc_author, 'svn:date': '',
'svn:log': 'Log message for revision 1.',
'foobar': 'foo bar'}],
args=['--with-all-revprops', '-r1', sbox.repo_url])
write_authz_file(sbox, authz)
svntest.actions.run_and_verify_log_xml(
expected_revprops=[{'svn:author': svntest.main.wc_author, 'svn:date': ''}],
args=['--with-all-revprops', '-r1', sbox.repo_url])
svntest.actions.run_and_verify_svn(None, None, expected_err,
'cat', '-r', '2', D_url+'/rho')
if sbox.repo_url.startswith('http'):
expected_err2 = expected_err
else:
expected_err2 = ".*svn: Unreadable path encountered; access denied.*"
svntest.actions.run_and_verify_svn(None, None, expected_err2,
'cat', '-r', '2', G_url+'/rho')
svntest.actions.run_and_verify_svn(None, None, expected_err,
'diff', '-r', 'HEAD', G_url+'/rho')
svntest.actions.run_and_verify_svn(None, None, expected_err,
'diff', '-r', '2', D_url+'/rho')
svntest.actions.run_and_verify_svn(None, None, expected_err,
'diff', '-r', '2:4', D_url+'/rho')
def authz_aliases(sbox):
"test authz for aliases"
sbox.build(create_wc = False)
write_restrictive_svnserve_conf(sbox.repo_dir)
if sbox.repo_url.startswith("http"):
expected_err = ".*403 Forbidden.*"
else:
expected_err = ".*svn: Authorization failed.*"
write_authz_file(sbox, { "/" : "* = r",
"/A/B" : "&jray = rw" },
{ "aliases" : 'jray = jrandom' } )
root_url = sbox.repo_url
A_url = root_url + '/A'
B_url = A_url + '/B'
iota_url = root_url + '/iota'
svntest.actions.run_and_verify_svn(None,
None, expected_err,
'cp',
'--username', svntest.main.wc_author2,
'-m', 'logmsg',
iota_url, B_url)
svntest.actions.run_and_verify_svn(None,
None, [],
'cp',
'-m', 'logmsg',
iota_url, B_url)
def authz_validate(sbox):
"test the authz validation rules"
sbox.build(create_wc = False, read_only = True)
write_restrictive_svnserve_conf(sbox.repo_dir)
A_url = sbox.repo_url + '/A'
write_authz_file(sbox, { "/" : "* = r",
"/A/B" : "@undefined_group = rw" })
if sbox.repo_url.startswith("http"):
expected_err = ".*403 Forbidden.*"
elif sbox.repo_url.startswith("svn"):
expected_err = ".*Invalid authz configuration"
else:
expected_err = ".*@undefined_group.*"
svntest.actions.run_and_verify_svn("ls remote folder",
None, expected_err,
'ls',
A_url)
write_authz_file(sbox, { "/" : "* = r" },
{ "groups" : """admins = admin1, admin2, @devs
devs1 = @admins, dev1
devs2 = @admins, dev2
devs = @devs1, dev3, dev4""" })
if sbox.repo_url.startswith("http"):
expected_err = ".*403 Forbidden.*"
elif sbox.repo_url.startswith("svn"):
expected_err = ".*Invalid authz configuration"
else:
expected_err = ".*Circular dependency.*"
svntest.actions.run_and_verify_svn("ls remote folder",
None, expected_err,
'ls',
A_url)
write_authz_file(sbox, { "/" : "* = r" },
{ "groups" : """admins = admin1, admin2
devs1 = @admins, dev1
devs2 = @admins, dev2
users = @devs1, @devs2, user1, user2""" })
svntest.actions.run_and_verify_svn("ls remote folder",
['B/\n', 'C/\n', 'D/\n', 'mu\n'],
[],
'ls',
A_url)
def authz_locking(sbox):
"test authz for locking"
sbox.build()
write_authz_file(sbox, {"/": "", "/A": "jrandom = rw"})
write_restrictive_svnserve_conf(sbox.repo_dir)
if sbox.repo_url.startswith('http'):
expected_err = ".*403 Forbidden.*"
else:
expected_err = ".*svn: Authorization failed.*"
root_url = sbox.repo_url
wc_dir = sbox.wc_dir
iota_url = root_url + '/iota'
iota_path = os.path.join(wc_dir, 'iota')
A_url = root_url + '/A'
mu_path = os.path.join(wc_dir, 'A', 'mu')
svntest.actions.run_and_verify_svn(None,
None, expected_err,
'lock',
'-m', 'lock msg',
iota_url)
svntest.actions.run_and_verify_svn(None,
None, expected_err,
'lock',
'-m', 'lock msg',
iota_path)
svntest.actions.run_and_verify_svn(None,
None, [],
'lock',
'-m', 'lock msg',
mu_path)
svntest.main.file_append(mu_path, "hi")
expected_output = svntest.wc.State(wc_dir, {
'A/mu' : Item(verb='Sending'),
})
svntest.actions.run_and_verify_commit(wc_dir,
expected_output,
[],
None,
mu_path)
def authz_svnserve_anon_access_read(sbox):
"authz issue #2712"
sbox.build(create_wc = False)
svntest.main.safe_rmtree(sbox.wc_dir)
B_path = os.path.join(sbox.wc_dir, 'A', 'B')
other_B_path = B_path + '_other'
B_url = sbox.repo_url + '/A/B'
D_path = os.path.join(sbox.wc_dir, 'A', 'D')
D_url = sbox.repo_url + '/A/D'
write_restrictive_svnserve_conf(sbox.repo_dir, "read")
write_authz_file(sbox, { "/A/B" : "jrandom = rw",
"/A/D" : "* = r" })
svntest.actions.run_and_verify_svn(None, None, [],
'checkout',
B_url, B_path)
svntest.actions.run_and_verify_svn(None, None, [],
'checkout',
D_url, D_path)
svntest.main.safe_rmtree(D_path)
svntest.actions.run_and_verify_svn(None, None, [],
'switch', D_url, B_path)
svntest.actions.run_and_verify_svn(
None, None,
".*Authentication error from server: Username not found.*",
'checkout',
'--non-interactive',
'--username', 'losing_user',
B_url, B_path + '_unsuccessful')
svntest.actions.run_and_verify_svn(None, None, [],
'checkout',
B_url, other_B_path)
other_alpha_path = os.path.join(other_B_path, 'E', 'alpha')
svntest.main.file_append(other_alpha_path, "fish\n")
svntest.actions.run_and_verify_svn(None, None, [],
'commit', '-m', 'log msg',
other_B_path)
svntest.actions.run_and_verify_svn(None, None, [],
'merge', '-c', '2',
B_url, B_path)
def authz_switch_to_directory(sbox):
"switched to directory, no read access on parents"
sbox.build(read_only = True)
write_authz_file(sbox, {"/": "*=rw", "/A/B": "*=", "/A/B/E": "jrandom = rw"})
write_restrictive_svnserve_conf(sbox.repo_dir)
wc_dir = sbox.wc_dir
mu_path = os.path.join(wc_dir, 'A', 'mu')
F_path = os.path.join(wc_dir, 'A', 'B', 'F')
G_path = os.path.join(wc_dir, 'A', 'D', 'G')
svntest.main.run_svn(None, 'switch', sbox.repo_url + "/A/B/E", G_path)
test_list = [ None,
Skip(authz_open_root, svntest.main.is_ra_type_file),
Skip(authz_open_directory, svntest.main.is_ra_type_file),
Skip(broken_authz_file, svntest.main.is_ra_type_file),
Skip(authz_read_access, svntest.main.is_ra_type_file),
Skip(authz_write_access, svntest.main.is_ra_type_file),
Skip(authz_checkout_test, svntest.main.is_ra_type_file),
Skip(authz_log_and_tracing_test, svntest.main.is_ra_type_file),
Skip(authz_checkout_and_update_test,
svntest.main.is_ra_type_file),
Skip(authz_partial_export_test, svntest.main.is_ra_type_file),
SkipUnless(Skip(authz_aliases, svntest.main.is_ra_type_file),
server_authz_has_aliases),
Skip(authz_validate, svntest.main.is_ra_type_file),
Skip(authz_locking, svntest.main.is_ra_type_file),
XFail(SkipUnless(authz_svnserve_anon_access_read,
svntest.main.is_ra_type_svn)),
XFail(Skip(authz_switch_to_directory,
svntest.main.is_ra_type_file)),
]
if __name__ == '__main__':
svntest.main.run_tests(test_list, serial_only = True)