1#!/usr/bin/env python 2# 3# mod_authz_svn_tests.py: testing mod_authz_svn 4# 5# Subversion is a tool for revision control. 6# See http://subversion.apache.org for more information. 7# 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 16# 17# http://www.apache.org/licenses/LICENSE-2.0 18# 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 24# under the License. 25###################################################################### 26 27# General modules 28import os, re, logging 29 30logger = logging.getLogger() 31 32# Our testing module 33import svntest 34 35# (abbreviation) 36Skip = svntest.testcase.Skip_deco 37SkipUnless = svntest.testcase.SkipUnless_deco 38XFail = svntest.testcase.XFail_deco 39Issues = svntest.testcase.Issues_deco 40Issue = svntest.testcase.Issue_deco 41Wimp = svntest.testcase.Wimp_deco 42 43ls_of_D_no_H = '''<html><head><title>repos - Revision 1: /A/D</title></head> 44<body> 45 <h2>repos - Revision 1: /A/D</h2> 46 <ul> 47 <li><a href="../">..</a></li> 48 <li><a href="G/">G/</a></li> 49 <li><a href="gamma">gamma</a></li> 50 </ul> 51</body></html>''' 52 53ls_of_D_H = '''<html><head><title>repos - Revision 1: /A/D</title></head> 54<body> 55 <h2>repos - Revision 1: /A/D</h2> 56 <ul> 57 <li><a href="../">..</a></li> 58 <li><a href="G/">G/</a></li> 59 <li><a href="H/">H/</a></li> 60 <li><a href="gamma">gamma</a></li> 61 </ul> 62</body></html>''' 63 64ls_of_H = '''<html><head><title>repos - Revision 1: /A/D/H</title></head> 65<body> 66 <h2>repos - Revision 1: /A/D/H</h2> 67 <ul> 68 <li><a href="../">..</a></li> 69 <li><a href="chi">chi</a></li> 70 <li><a href="omega">omega</a></li> 71 <li><a href="psi">psi</a></li> 72 </ul> 73</body></html>''' 74 75user1 = svntest.main.wc_author 76user1_upper = user1.upper() 77user1_pass = svntest.main.wc_passwd 78user1_badpass = 'XXX' 79assert user1_pass != user1_badpass, "Passwords can't match" 80user2 = svntest.main.wc_author2 81user2_upper = user2.upper() 82user2_pass = svntest.main.wc_passwd 83user2_badpass = 'XXX' 84assert user2_pass != user2_badpass, "Passwords can't match" 85 86def write_authz_file(sbox): 87 svntest.main.write_authz_file(sbox, { 88 '/': '$anonymous = r\n' + 89 'jrandom = rw\n' + 90 'jconstant = rw', 91 '/A/D/H': '$anonymous =\n' + 92 '$authenticated =\n' + 93 'jrandom = rw' 94 }) 95 96def write_authz_file_groups(sbox): 97 authz_name = sbox.authz_name() 98 svntest.main.write_authz_file(sbox,{ 99 '/': '* =', 100 }) 101 102def verify_get(test_area_url, path, user, pw, 103 expected_status, expected_body, headers): 104 import base64 105 106 req_url = test_area_url + path 107 108 h = svntest.main.create_http_connection(req_url, 0) 109 110 if headers is None: 111 headers = {} 112 113 if user and pw: 114 auth_info = user + ':' + pw 115 user_pw = base64.b64encode(auth_info.encode()).decode() 116 headers['Authorization'] = 'Basic ' + user_pw 117 else: 118 auth_info = "anonymous" 119 120 h.request('GET', req_url, None, headers) 121 122 r = h.getresponse() 123 124 actual_status = r.status 125 if expected_status and expected_status != actual_status: 126 127 logger.warn("Expected status '" + str(expected_status) + 128 "' but got '" + str(actual_status) + 129 "' on url '" + req_url + "' (" + 130 auth_info + ").") 131 raise svntest.Failure 132 133 if expected_body: 134 actual_body = r.read() 135 if isinstance(expected_body, str) and not isinstance(actual_body, str): 136 actual_body = actual_body.decode() 137 if expected_body != actual_body: 138 logger.warn("Expected body:") 139 logger.warn(expected_body) 140 logger.warn("But got:") 141 logger.warn(actual_body) 142 logger.warn("on url '" + req_url + "' (" + auth_info + ").") 143 raise svntest.Failure 144 145def verify_gets(test_area_url, tests): 146 for test in tests: 147 verify_get(test_area_url, test['path'], test.get('user'), test.get('pw'), 148 test['status'], test.get('body'), test.get('headers')) 149 150 151###################################################################### 152# Tests 153# 154# Each test must return on success or raise on failure. 155 156 157#---------------------------------------------------------------------- 158 159 160@SkipUnless(svntest.main.is_ra_type_dav) 161def anon(sbox): 162 "test anonymous access" 163 sbox.build(read_only = True, create_wc = False) 164 165 test_area_url = sbox.repo_url.replace('/svn-test-work/local_tmp/repos', 166 '/authz-test-work/anon') 167 168 write_authz_file(sbox) 169 170 anon_tests = ( 171 { 'path': '', 'status': 301 }, 172 { 'path': '/', 'status': 200 }, 173 { 'path': '/repos', 'status': 301 }, 174 { 'path': '/repos/', 'status': 200 }, 175 { 'path': '/repos/A', 'status': 301 }, 176 { 'path': '/repos/A/', 'status': 200 }, 177 { 'path': '/repos/A/D', 'status': 301 }, 178 { 'path': '/repos/A/D/', 'status': 200, 'body': ls_of_D_no_H }, 179 { 'path': '/repos/A/D/gamma', 'status': 200 }, 180 { 'path': '/repos/A/D/H', 'status': 403 }, 181 { 'path': '/repos/A/D/H/', 'status': 403 }, 182 { 'path': '/repos/A/D/H/chi', 'status': 403 }, 183 # auth isn't configured so nothing should change when passing 184 # authn details 185 { 'path': '', 'status': 301, 'user': user1, 'pw': user1_pass}, 186 { 'path': '/', 'status': 200, 'user': user1, 'pw': user1_pass}, 187 { 'path': '/repos', 'status': 301, 'user': user1, 'pw': user1_pass}, 188 { 'path': '/repos/', 'status': 200, 'user': user1, 'pw': user1_pass}, 189 { 'path': '/repos/A', 'status': 301, 'user': user1, 'pw': user1_pass}, 190 { 'path': '/repos/A/', 'status': 200, 'user': user1, 'pw': user1_pass}, 191 { 'path': '/repos/A/D', 'status': 301, 'user': user1, 'pw': user1_pass}, 192 { 'path': '/repos/A/D/', 'status': 200, 'body': ls_of_D_no_H, 193 'user': user1, 'pw': user1_pass}, 194 { 'path': '/repos/A/D/gamma', 'status': 200, 'user': user1, 'pw': user1_pass}, 195 { 'path': '/repos/A/D/H', 'status': 403, 'user': user1, 'pw': user1_pass}, 196 { 'path': '/repos/A/D/H/', 'status': 403, 'user': user1, 'pw': user1_pass}, 197 { 'path': '/repos/A/D/H/chi', 'status': 403, 'user': user1, 'pw': user1_pass}, 198 { 'path': '', 'status': 301, 'user': user1, 'pw': user1_badpass}, 199 { 'path': '/', 'status': 200, 'user': user1, 'pw': user1_badpass}, 200 { 'path': '/repos', 'status': 301, 'user': user1, 'pw': user1_badpass}, 201 { 'path': '/repos/', 'status': 200, 'user': user1, 'pw': user1_badpass}, 202 { 'path': '/repos/A', 'status': 301, 'user': user1, 'pw': user1_badpass}, 203 { 'path': '/repos/A/', 'status': 200, 'user': user1, 'pw': user1_badpass}, 204 { 'path': '/repos/A/D', 'status': 301, 'user': user1, 'pw': user1_badpass}, 205 { 'path': '/repos/A/D/', 'status': 200, 'body': ls_of_D_no_H, 206 'user': user1, 'pw': user1_badpass}, 207 { 'path': '/repos/A/D/gamma', 'status': 200, 'user': user1, 'pw': user1_badpass}, 208 { 'path': '/repos/A/D/H', 'status': 403, 'user': user1, 'pw': user1_badpass}, 209 { 'path': '/repos/A/D/H/', 'status': 403, 'user': user1, 'pw': user1_badpass}, 210 { 'path': '/repos/A/D/H/chi', 'status': 403, 'user': user1, 'pw': user1_badpass}, 211 { 'path': '', 'status': 301, 'user': user2, 'pw': user1_pass}, 212 { 'path': '/', 'status': 200, 'user': user2, 'pw': user1_pass}, 213 { 'path': '/repos', 'status': 301, 'user': user2, 'pw': user1_pass}, 214 { 'path': '/repos/', 'status': 200, 'user': user2, 'pw': user1_pass}, 215 { 'path': '/repos/A', 'status': 301, 'user': user2, 'pw': user1_pass}, 216 { 'path': '/repos/A/', 'status': 200, 'user': user2, 'pw': user1_pass}, 217 { 'path': '/repos/A/D', 'status': 301, 'user': user2, 'pw': user1_pass}, 218 { 'path': '/repos/A/D/', 'status': 200, 'body': ls_of_D_no_H, 219 'user': user2, 'pw': user1_pass}, 220 { 'path': '/repos/A/D/gamma', 'status': 200, 'user': user2, 'pw': user2_pass}, 221 { 'path': '/repos/A/D/H', 'status': 403, 'user': user2, 'pw': user2_pass}, 222 { 'path': '/repos/A/D/H/', 'status': 403, 'user': user2, 'pw': user2_pass}, 223 { 'path': '/repos/A/D/H/chi', 'status': 403, 'user': user2, 'pw': user2_pass}, 224 { 'path': '', 'status': 301, 'user': user2, 'pw': user2_badpass}, 225 { 'path': '/', 'status': 200, 'user': user2, 'pw': user2_badpass}, 226 { 'path': '/repos', 'status': 301, 'user': user2, 'pw': user2_badpass}, 227 { 'path': '/repos/', 'status': 200, 'user': user2, 'pw': user2_badpass}, 228 { 'path': '/repos/A', 'status': 301, 'user': user2, 'pw': user2_badpass}, 229 { 'path': '/repos/A/', 'status': 200, 'user': user2, 'pw': user2_badpass}, 230 { 'path': '/repos/A/D', 'status': 301, 'user': user2, 'pw': user2_badpass}, 231 { 'path': '/repos/A/D/', 'status': 200, 'body': ls_of_D_no_H, 232 'user': user2, 'pw': user2_badpass}, 233 { 'path': '/repos/A/D/gamma', 'status': 200, 'user': user2, 'pw': user2_badpass}, 234 { 'path': '/repos/A/D/H', 'status': 403, 'user': user2, 'pw': user2_badpass}, 235 { 'path': '/repos/A/D/H/', 'status': 403, 'user': user2, 'pw': user2_badpass}, 236 { 'path': '/repos/A/D/H/chi', 'status': 403, 'user': user2, 'pw': user2_badpass}, 237 ) 238 239 verify_gets(test_area_url, anon_tests) 240 241 242@SkipUnless(svntest.main.is_ra_type_dav) 243def mixed(sbox): 244 "test mixed anonymous and authenticated access" 245 sbox.build(read_only = True, create_wc = False) 246 247 test_area_url = sbox.repo_url.replace('/svn-test-work/local_tmp/repos', 248 '/authz-test-work/mixed') 249 250 write_authz_file(sbox) 251 252 mixed_tests = ( 253 { 'path': '', 'status': 301, }, 254 { 'path': '/', 'status': 200, }, 255 { 'path': '/repos', 'status': 301, }, 256 { 'path': '/repos/', 'status': 200, }, 257 { 'path': '/repos/A', 'status': 301, }, 258 { 'path': '/repos/A/', 'status': 200, }, 259 { 'path': '/repos/A/D', 'status': 301, }, 260 { 'path': '/repos/A/D/', 'status': 200, 'body': ls_of_D_no_H, 261 }, 262 { 'path': '/repos/A/D/gamma', 'status': 200, }, 263 { 'path': '/repos/A/D/H', 'status': 401, }, 264 { 'path': '/repos/A/D/H/', 'status': 401, }, 265 { 'path': '/repos/A/D/H/chi', 'status': 401, }, 266 # auth is configured and user1 is allowed access to H 267 { 'path': '', 'status': 301, 'user': user1, 'pw': user1_pass}, 268 { 'path': '/', 'status': 200, 'user': user1, 'pw': user1_pass}, 269 { 'path': '/repos', 'status': 301, 'user': user1, 'pw': user1_pass}, 270 { 'path': '/repos/', 'status': 200, 'user': user1, 'pw': user1_pass}, 271 { 'path': '/repos/A', 'status': 301, 'user': user1, 'pw': user1_pass}, 272 { 'path': '/repos/A/', 'status': 200, 'user': user1, 'pw': user1_pass}, 273 { 'path': '/repos/A/D', 'status': 301, 'user': user1, 'pw': user1_pass}, 274 { 'path': '/repos/A/D/', 'status': 200, 'body': ls_of_D_H, 275 'user': user1, 'pw': user1_pass}, 276 { 'path': '/repos/A/D/gamma', 'status': 200, 'user': user1, 'pw': user1_pass}, 277 { 'path': '/repos/A/D/H', 'status': 301, 'user': user1, 'pw': user1_pass}, 278 { 'path': '/repos/A/D/H/', 'status': 200, 'body': ls_of_H, 'user': user1, 'pw': user1_pass}, 279 { 'path': '/repos/A/D/H/chi', 'status': 200, 'user': user1, 'pw': user1_pass}, 280 # try with the wrong password for user1 281 { 'path': '', 'status': 401, 'user': user1, 'pw': user1_badpass}, 282 { 'path': '/', 'status': 401, 'user': user1, 'pw': user1_badpass}, 283 { 'path': '/repos', 'status': 401, 'user': user1, 'pw': user1_badpass}, 284 { 'path': '/repos/', 'status': 401, 'user': user1, 'pw': user1_badpass}, 285 { 'path': '/repos/A', 'status': 401, 'user': user1, 'pw': user1_badpass}, 286 { 'path': '/repos/A/', 'status': 401, 'user': user1, 'pw': user1_badpass}, 287 { 'path': '/repos/A/D', 'status': 401, 'user': user1, 'pw': user1_badpass}, 288 { 'path': '/repos/A/D/', 'status': 401, 'user': user1, 'pw': user1_badpass}, 289 { 'path': '/repos/A/D/gamma', 'status': 401, 'user': user1, 'pw': user1_badpass}, 290 { 'path': '/repos/A/D/H', 'status': 401, 'user': user1, 'pw': user1_badpass}, 291 { 'path': '/repos/A/D/H/', 'status': 401, 'user': user1, 'pw': user1_badpass}, 292 { 'path': '/repos/A/D/H/chi', 'status': 401, 'user': user1, 'pw': user1_badpass}, 293 # auth is configured and user2 is not allowed access to H 294 { 'path': '', 'status': 301, 'user': user2, 'pw': user2_pass}, 295 { 'path': '/', 'status': 200, 'user': user2, 'pw': user2_pass}, 296 { 'path': '/repos', 'status': 301, 'user': user2, 'pw': user2_pass}, 297 { 'path': '/repos/', 'status': 200, 'user': user2, 'pw': user2_pass}, 298 { 'path': '/repos/A', 'status': 301, 'user': user2, 'pw': user2_pass}, 299 { 'path': '/repos/A/', 'status': 200, 'user': user2, 'pw': user2_pass}, 300 { 'path': '/repos/A/D', 'status': 301, 'user': user2, 'pw': user2_pass}, 301 { 'path': '/repos/A/D/', 'status': 200, 'body': ls_of_D_no_H, 302 'user': user2, 'pw': user2_pass}, 303 { 'path': '/repos/A/D/gamma', 'status': 200, 'user': user2, 'pw': user2_pass}, 304 { 'path': '/repos/A/D/H', 'status': 403, 'user': user2, 'pw': user2_pass}, 305 { 'path': '/repos/A/D/H/', 'status': 403, 'user': user2, 'pw': user2_pass}, 306 { 'path': '/repos/A/D/H/chi', 'status': 403, 'user': user2, 'pw': user2_pass}, 307 # try with the wrong password for user2 308 { 'path': '', 'status': 401, 'user': user2, 'pw': user2_badpass}, 309 { 'path': '/', 'status': 401, 'user': user2, 'pw': user2_badpass}, 310 { 'path': '/repos', 'status': 401, 'user': user2, 'pw': user2_badpass}, 311 { 'path': '/repos/', 'status': 401, 'user': user2, 'pw': user2_badpass}, 312 { 'path': '/repos/A', 'status': 401, 'user': user2, 'pw': user2_badpass}, 313 { 'path': '/repos/A/', 'status': 401, 'user': user2, 'pw': user2_badpass}, 314 { 'path': '/repos/A/D', 'status': 401, 'user': user2, 'pw': user2_badpass}, 315 { 'path': '/repos/A/D/', 'status': 401, 'user': user2, 'pw': user2_badpass}, 316 { 'path': '/repos/A/D/gamma', 'status': 401, 'user': user2, 'pw': user2_badpass}, 317 { 'path': '/repos/A/D/H', 'status': 401, 'user': user2, 'pw': user2_badpass}, 318 { 'path': '/repos/A/D/H/', 'status': 401, 'user': user2, 'pw': user2_badpass}, 319 { 'path': '/repos/A/D/H/chi', 'status': 401, 'user': user2, 'pw': user2_badpass}, 320 ) 321 322 verify_gets(test_area_url, mixed_tests) 323 324@SkipUnless(svntest.main.is_ra_type_dav) 325@XFail(svntest.main.is_httpd_authz_provider_enabled) 326# uses the AuthzSVNNoAuthWhenAnonymousAllowed On directive 327# this is broken with httpd 2.3.x+ since it requires the auth system to accept 328# r->user == NULL and there is a test for this in server/request.c now. It 329# was intended as a workaround for the lack of Satisfy Any in 2.3.x+ which 330# was resolved by httpd with mod_access_compat in 2.3.x+. 331def mixed_noauthwhenanon(sbox): 332 "test mixed with noauthwhenanon directive" 333 sbox.build(read_only = True, create_wc = False) 334 335 test_area_url = sbox.repo_url.replace('/svn-test-work/local_tmp/repos', 336 '/authz-test-work/mixed-noauthwhenanon') 337 338 write_authz_file(sbox) 339 340 noauthwhenanon_tests = ( 341 { 'path': '', 'status': 301, }, 342 { 'path': '/', 'status': 200, }, 343 { 'path': '/repos', 'status': 301, }, 344 { 'path': '/repos/', 'status': 200, }, 345 { 'path': '/repos/A', 'status': 301, }, 346 { 'path': '/repos/A/', 'status': 200, }, 347 { 'path': '/repos/A/D', 'status': 301, }, 348 { 'path': '/repos/A/D/', 'status': 200, 'body': ls_of_D_no_H, 349 }, 350 { 'path': '/repos/A/D/gamma', 'status': 200, }, 351 { 'path': '/repos/A/D/H', 'status': 401, }, 352 { 'path': '/repos/A/D/H/', 'status': 401, }, 353 { 'path': '/repos/A/D/H/chi', 'status': 401, }, 354 # auth is configured and user1 is allowed access to H 355 { 'path': '', 'status': 301, 'user': user1, 'pw': user1_pass}, 356 { 'path': '/', 'status': 200, 'user': user1, 'pw': user1_pass}, 357 { 'path': '/repos', 'status': 301, 'user': user1, 'pw': user1_pass}, 358 { 'path': '/repos/', 'status': 200, 'user': user1, 'pw': user1_pass}, 359 { 'path': '/repos/A', 'status': 301, 'user': user1, 'pw': user1_pass}, 360 { 'path': '/repos/A/', 'status': 200, 'user': user1, 'pw': user1_pass}, 361 { 'path': '/repos/A/D', 'status': 301, 'user': user1, 'pw': user1_pass}, 362 { 'path': '/repos/A/D/', 'status': 200, 'body': ls_of_D_H, 363 'user': user1, 'pw': user1_pass}, 364 { 'path': '/repos/A/D/gamma', 'status': 200, 'user': user1, 'pw': user1_pass}, 365 { 'path': '/repos/A/D/H', 'status': 301, 'user': user1, 'pw': user1_pass}, 366 { 'path': '/repos/A/D/H/', 'status': 200, 'body': ls_of_H, 'user': user1, 'pw': user1_pass}, 367 { 'path': '/repos/A/D/H/chi', 'status': 200, 'user': user1, 'pw': user1_pass}, 368 # try with the wrong password for user1 369 # note that unlike doing this with Satisfy Any this case 370 # actually provides anon access when provided with an invalid 371 # password 372 { 'path': '', 'status': 301, 'user': user1, 'pw': user1_badpass}, 373 { 'path': '/', 'status': 200, 'user': user1, 'pw': user1_badpass}, 374 { 'path': '/repos', 'status': 301, 'user': user1, 'pw': user1_badpass}, 375 { 'path': '/repos/', 'status': 200, 'user': user1, 'pw': user1_badpass}, 376 { 'path': '/repos/A', 'status': 301, 'user': user1, 'pw': user1_badpass}, 377 { 'path': '/repos/A/', 'status': 200, 'user': user1, 'pw': user1_badpass}, 378 { 'path': '/repos/A/D', 'status': 301, 'user': user1, 'pw': user1_badpass}, 379 { 'path': '/repos/A/D/', 'status': 200, 'user': user1, 'pw': user1_badpass}, 380 { 'path': '/repos/A/D/gamma', 'status': 200, 'user': user1, 'pw': user1_badpass}, 381 { 'path': '/repos/A/D/H', 'status': 401, 'user': user1, 'pw': user1_badpass}, 382 { 'path': '/repos/A/D/H/', 'status': 401, 'user': user1, 'pw': user1_badpass}, 383 { 'path': '/repos/A/D/H/chi', 'status': 401, 'user': user1, 'pw': user1_badpass}, 384 # auth is configured and user2 is not allowed access to H 385 { 'path': '', 'status': 301, 'user': user2, 'pw': user2_pass}, 386 { 'path': '/', 'status': 200, 'user': user2, 'pw': user2_pass}, 387 { 'path': '/repos', 'status': 301, 'user': user2, 'pw': user2_pass}, 388 { 'path': '/repos/', 'status': 200, 'user': user2, 'pw': user2_pass}, 389 { 'path': '/repos/A', 'status': 301, 'user': user2, 'pw': user2_pass}, 390 { 'path': '/repos/A/', 'status': 200, 'user': user2, 'pw': user2_pass}, 391 { 'path': '/repos/A/D', 'status': 301, 'user': user2, 'pw': user2_pass}, 392 { 'path': '/repos/A/D/', 'status': 200, 'body': ls_of_D_no_H, 393 'user': user2, 'pw': user2_pass}, 394 { 'path': '/repos/A/D/gamma', 'status': 200, 'user': user2, 'pw': user2_pass}, 395 { 'path': '/repos/A/D/H', 'status': 403, 'user': user2, 'pw': user2_pass}, 396 { 'path': '/repos/A/D/H/', 'status': 403, 'user': user2, 'pw': user2_pass}, 397 { 'path': '/repos/A/D/H/chi', 'status': 403, 'user': user2, 'pw': user2_pass}, 398 # try with the wrong password for user2 399 { 'path': '', 'status': 301, 'user': user2, 'pw': user2_badpass}, 400 { 'path': '/', 'status': 200, 'user': user2, 'pw': user2_badpass}, 401 { 'path': '/repos', 'status': 301, 'user': user2, 'pw': user2_badpass}, 402 { 'path': '/repos/', 'status': 200, 'user': user2, 'pw': user2_badpass}, 403 { 'path': '/repos/A', 'status': 301, 'user': user2, 'pw': user2_badpass}, 404 { 'path': '/repos/A/', 'status': 200, 'user': user2, 'pw': user2_badpass}, 405 { 'path': '/repos/A/D', 'status': 301, 'user': user2, 'pw': user2_badpass}, 406 { 'path': '/repos/A/D/', 'status': 200, 'user': user2, 'pw': user2_badpass}, 407 { 'path': '/repos/A/D/gamma', 'status': 200, 'user': user2, 'pw': user2_badpass}, 408 { 'path': '/repos/A/D/H', 'status': 401, 'user': user2, 'pw': user2_badpass}, 409 { 'path': '/repos/A/D/H/', 'status': 401, 'user': user2, 'pw': user2_badpass}, 410 { 'path': '/repos/A/D/H/chi', 'status': 401, 'user': user2, 'pw': user2_badpass}, 411 ) 412 413 verify_gets(test_area_url, noauthwhenanon_tests) 414 415 416@SkipUnless(svntest.main.is_ra_type_dav) 417def authn(sbox): 418 "test authenticated only access" 419 sbox.build(read_only = True, create_wc = False) 420 421 test_area_url = sbox.repo_url.replace('/svn-test-work/local_tmp/repos', 422 '/authz-test-work/authn') 423 424 write_authz_file(sbox) 425 426 authn_tests = ( 427 { 'path': '', 'status': 401, }, 428 { 'path': '/', 'status': 401, }, 429 { 'path': '/repos', 'status': 401, }, 430 { 'path': '/repos/', 'status': 401, }, 431 { 'path': '/repos/A', 'status': 401, }, 432 { 'path': '/repos/A/', 'status': 401, }, 433 { 'path': '/repos/A/D', 'status': 401, }, 434 { 'path': '/repos/A/D/', 'status': 401, }, 435 { 'path': '/repos/A/D/gamma', 'status': 401, }, 436 { 'path': '/repos/A/D/H', 'status': 401, }, 437 { 'path': '/repos/A/D/H/', 'status': 401, }, 438 { 'path': '/repos/A/D/H/chi', 'status': 401, }, 439 # auth is configured and user1 is allowed access to H 440 { 'path': '', 'status': 301, 'user': user1, 'pw': user1_pass}, 441 { 'path': '/', 'status': 200, 'user': user1, 'pw': user1_pass}, 442 { 'path': '/repos', 'status': 301, 'user': user1, 'pw': user1_pass}, 443 { 'path': '/repos/', 'status': 200, 'user': user1, 'pw': user1_pass}, 444 { 'path': '/repos/A', 'status': 301, 'user': user1, 'pw': user1_pass}, 445 { 'path': '/repos/A/', 'status': 200, 'user': user1, 'pw': user1_pass}, 446 { 'path': '/repos/A/D', 'status': 301, 'user': user1, 'pw': user1_pass}, 447 { 'path': '/repos/A/D/', 'status': 200, 'body': ls_of_D_H, 448 'user': user1, 'pw': user1_pass}, 449 { 'path': '/repos/A/D/gamma', 'status': 200, 'user': user1, 'pw': user1_pass}, 450 { 'path': '/repos/A/D/H', 'status': 301, 'user': user1, 'pw': user1_pass}, 451 { 'path': '/repos/A/D/H/', 'status': 200, 'body': ls_of_H, 'user': user1, 'pw': user1_pass}, 452 { 'path': '/repos/A/D/H/chi', 'status': 200, 'user': user1, 'pw': user1_pass}, 453 # try with upper case username for user1 454 { 'path': '', 'status': 301, 'user': user1_upper, 'pw': user1_pass}, 455 { 'path': '/', 'status': 200, 'user': user1_upper, 'pw': user1_pass}, 456 { 'path': '/repos', 'status': 403, 'user': user1_upper, 'pw': user1_pass}, 457 { 'path': '/repos/', 'status': 403, 'user': user1_upper, 'pw': user1_pass}, 458 { 'path': '/repos/A', 'status': 403, 'user': user1_upper, 'pw': user1_pass}, 459 { 'path': '/repos/A/', 'status': 403, 'user': user1_upper, 'pw': user1_pass}, 460 { 'path': '/repos/A/D', 'status': 403, 'user': user1_upper, 'pw': user1_pass}, 461 { 'path': '/repos/A/D/', 'status': 403, 'user': user1_upper, 'pw': user1_pass}, 462 { 'path': '/repos/A/D/gamma', 'status': 403, 'user': user1_upper, 'pw': user1_pass}, 463 { 'path': '/repos/A/D/H', 'status': 403, 'user': user1_upper, 'pw': user1_pass}, 464 { 'path': '/repos/A/D/H/', 'status': 403, 'user': user1_upper, 'pw': user1_pass}, 465 { 'path': '/repos/A/D/H/chi', 'status': 403, 'user': user1_upper, 'pw': user1_pass}, 466 # try with the wrong password for user1 467 { 'path': '', 'status': 401, 'user': user1, 'pw': user1_badpass}, 468 { 'path': '/', 'status': 401, 'user': user1, 'pw': user1_badpass}, 469 { 'path': '/repos', 'status': 401, 'user': user1, 'pw': user1_badpass}, 470 { 'path': '/repos/', 'status': 401, 'user': user1, 'pw': user1_badpass}, 471 { 'path': '/repos/A', 'status': 401, 'user': user1, 'pw': user1_badpass}, 472 { 'path': '/repos/A/', 'status': 401, 'user': user1, 'pw': user1_badpass}, 473 { 'path': '/repos/A/D', 'status': 401, 'user': user1, 'pw': user1_badpass}, 474 { 'path': '/repos/A/D/', 'status': 401, 'user': user1, 'pw': user1_badpass}, 475 { 'path': '/repos/A/D/gamma', 'status': 401, 'user': user1, 'pw': user1_badpass}, 476 { 'path': '/repos/A/D/H', 'status': 401, 'user': user1, 'pw': user1_badpass}, 477 { 'path': '/repos/A/D/H/', 'status': 401, 'user': user1, 'pw': user1_badpass}, 478 { 'path': '/repos/A/D/H/chi', 'status': 401, 'user': user1, 'pw': user1_badpass}, 479 # auth is configured and user2 is not allowed access to H 480 { 'path': '', 'status': 301, 'user': user2, 'pw': user2_pass}, 481 { 'path': '/', 'status': 200, 'user': user2, 'pw': user2_pass}, 482 { 'path': '/repos', 'status': 301, 'user': user2, 'pw': user2_pass}, 483 { 'path': '/repos/', 'status': 200, 'user': user2, 'pw': user2_pass}, 484 { 'path': '/repos/A', 'status': 301, 'user': user2, 'pw': user2_pass}, 485 { 'path': '/repos/A/', 'status': 200, 'user': user2, 'pw': user2_pass}, 486 { 'path': '/repos/A/D', 'status': 301, 'user': user2, 'pw': user2_pass}, 487 { 'path': '/repos/A/D/', 'status': 200, 'body': ls_of_D_no_H, 488 'user': user2, 'pw': user2_pass}, 489 { 'path': '/repos/A/D/gamma', 'status': 200, 'user': user2, 'pw': user2_pass}, 490 { 'path': '/repos/A/D/H', 'status': 403, 'user': user2, 'pw': user2_pass}, 491 { 'path': '/repos/A/D/H/', 'status': 403, 'user': user2, 'pw': user2_pass}, 492 { 'path': '/repos/A/D/H/chi', 'status': 403, 'user': user2, 'pw': user2_pass}, 493 # try with upper case username for user2 494 { 'path': '', 'status': 301, 'user': user2_upper, 'pw': user2_pass}, 495 { 'path': '/', 'status': 200, 'user': user2_upper, 'pw': user2_pass}, 496 { 'path': '/repos', 'status': 403, 'user': user2_upper, 'pw': user2_pass}, 497 { 'path': '/repos/', 'status': 403, 'user': user2_upper, 'pw': user2_pass}, 498 { 'path': '/repos/A', 'status': 403, 'user': user2_upper, 'pw': user2_pass}, 499 { 'path': '/repos/A/', 'status': 403, 'user': user2_upper, 'pw': user2_pass}, 500 { 'path': '/repos/A/D', 'status': 403, 'user': user2_upper, 'pw': user2_pass}, 501 { 'path': '/repos/A/D/', 'status': 403, 'user': user2_upper, 'pw': user2_pass}, 502 { 'path': '/repos/A/D/gamma', 'status': 403, 'user': user2_upper, 'pw': user2_pass}, 503 { 'path': '/repos/A/D/H', 'status': 403, 'user': user2_upper, 'pw': user2_pass}, 504 { 'path': '/repos/A/D/H/', 'status': 403, 'user': user2_upper, 'pw': user2_pass}, 505 { 'path': '/repos/A/D/H/chi', 'status': 403, 'user': user2_upper, 'pw': user2_pass}, 506 # try with the wrong password for user2 507 { 'path': '', 'status': 401, 'user': user2, 'pw': user2_badpass}, 508 { 'path': '/', 'status': 401, 'user': user2, 'pw': user2_badpass}, 509 { 'path': '/repos', 'status': 401, 'user': user2, 'pw': user2_badpass}, 510 { 'path': '/repos/', 'status': 401, 'user': user2, 'pw': user2_badpass}, 511 { 'path': '/repos/A', 'status': 401, 'user': user2, 'pw': user2_badpass}, 512 { 'path': '/repos/A/', 'status': 401, 'user': user2, 'pw': user2_badpass}, 513 { 'path': '/repos/A/D', 'status': 401, 'user': user2, 'pw': user2_badpass}, 514 { 'path': '/repos/A/D/', 'status': 401, 'user': user2, 'pw': user2_badpass}, 515 { 'path': '/repos/A/D/gamma', 'status': 401, 'user': user2, 'pw': user2_badpass}, 516 { 'path': '/repos/A/D/H', 'status': 401, 'user': user2, 'pw': user2_badpass}, 517 { 'path': '/repos/A/D/H/', 'status': 401, 'user': user2, 'pw': user2_badpass}, 518 { 'path': '/repos/A/D/H/chi', 'status': 401, 'user': user2, 'pw': user2_badpass}, 519 ) 520 521 verify_gets(test_area_url, authn_tests) 522 523@SkipUnless(svntest.main.is_ra_type_dav) 524def authn_anonoff(sbox): 525 "test authenticated only access with anonoff" 526 sbox.build(read_only = True, create_wc = False) 527 528 test_area_url = sbox.repo_url.replace('/svn-test-work/local_tmp/repos', 529 '/authz-test-work/authn-anonoff') 530 531 write_authz_file(sbox) 532 533 anonoff_tests = ( 534 { 'path': '', 'status': 401, }, 535 { 'path': '/', 'status': 401, }, 536 { 'path': '/repos', 'status': 401, }, 537 { 'path': '/repos/', 'status': 401, }, 538 { 'path': '/repos/A', 'status': 401, }, 539 { 'path': '/repos/A/', 'status': 401, }, 540 { 'path': '/repos/A/D', 'status': 401, }, 541 { 'path': '/repos/A/D/', 'status': 401, }, 542 { 'path': '/repos/A/D/gamma', 'status': 401, }, 543 { 'path': '/repos/A/D/H', 'status': 401, }, 544 { 'path': '/repos/A/D/H/', 'status': 401, }, 545 { 'path': '/repos/A/D/H/chi', 'status': 401, }, 546 # auth is configured and user1 is allowed access to H 547 { 'path': '', 'status': 301, 'user': user1, 'pw': user1_pass}, 548 { 'path': '/', 'status': 200, 'user': user1, 'pw': user1_pass}, 549 { 'path': '/repos', 'status': 301, 'user': user1, 'pw': user1_pass}, 550 { 'path': '/repos/', 'status': 200, 'user': user1, 'pw': user1_pass}, 551 { 'path': '/repos/A', 'status': 301, 'user': user1, 'pw': user1_pass}, 552 { 'path': '/repos/A/', 'status': 200, 'user': user1, 'pw': user1_pass}, 553 { 'path': '/repos/A/D', 'status': 301, 'user': user1, 'pw': user1_pass}, 554 { 'path': '/repos/A/D/', 'status': 200, 'body': ls_of_D_H, 555 'user': user1, 'pw': user1_pass}, 556 { 'path': '/repos/A/D/gamma', 'status': 200, 'user': user1, 'pw': user1_pass}, 557 { 'path': '/repos/A/D/H', 'status': 301, 'user': user1, 'pw': user1_pass}, 558 { 'path': '/repos/A/D/H/', 'status': 200, 'body': ls_of_H, 'user': user1, 'pw': user1_pass}, 559 { 'path': '/repos/A/D/H/chi', 'status': 200, 'user': user1, 'pw': user1_pass}, 560 # try with upper case username for user1 561 { 'path': '', 'status': 301, 'user': user1_upper, 'pw': user1_pass}, 562 { 'path': '/', 'status': 200, 'user': user1_upper, 'pw': user1_pass}, 563 { 'path': '/repos', 'status': 403, 'user': user1_upper, 'pw': user1_pass}, 564 { 'path': '/repos/', 'status': 403, 'user': user1_upper, 'pw': user1_pass}, 565 { 'path': '/repos/A', 'status': 403, 'user': user1_upper, 'pw': user1_pass}, 566 { 'path': '/repos/A/', 'status': 403, 'user': user1_upper, 'pw': user1_pass}, 567 { 'path': '/repos/A/D', 'status': 403, 'user': user1_upper, 'pw': user1_pass}, 568 { 'path': '/repos/A/D/', 'status': 403, 'user': user1_upper, 'pw': user1_pass}, 569 { 'path': '/repos/A/D/gamma', 'status': 403, 'user': user1_upper, 'pw': user1_pass}, 570 { 'path': '/repos/A/D/H', 'status': 403, 'user': user1_upper, 'pw': user1_pass}, 571 { 'path': '/repos/A/D/H/', 'status': 403, 'user': user1_upper, 'pw': user1_pass}, 572 { 'path': '/repos/A/D/H/chi', 'status': 403, 'user': user1_upper, 'pw': user1_pass}, 573 # try with the wrong password for user1 574 { 'path': '', 'status': 401, 'user': user1, 'pw': user1_badpass}, 575 { 'path': '/', 'status': 401, 'user': user1, 'pw': user1_badpass}, 576 { 'path': '/repos', 'status': 401, 'user': user1, 'pw': user1_badpass}, 577 { 'path': '/repos/', 'status': 401, 'user': user1, 'pw': user1_badpass}, 578 { 'path': '/repos/A', 'status': 401, 'user': user1, 'pw': user1_badpass}, 579 { 'path': '/repos/A/', 'status': 401, 'user': user1, 'pw': user1_badpass}, 580 { 'path': '/repos/A/D', 'status': 401, 'user': user1, 'pw': user1_badpass}, 581 { 'path': '/repos/A/D/', 'status': 401, 'user': user1, 'pw': user1_badpass}, 582 { 'path': '/repos/A/D/gamma', 'status': 401, 'user': user1, 'pw': user1_badpass}, 583 { 'path': '/repos/A/D/H', 'status': 401, 'user': user1, 'pw': user1_badpass}, 584 { 'path': '/repos/A/D/H/', 'status': 401, 'user': user1, 'pw': user1_badpass}, 585 { 'path': '/repos/A/D/H/chi', 'status': 401, 'user': user1, 'pw': user1_badpass}, 586 # auth is configured and user2 is not allowed access to H 587 { 'path': '', 'status': 301, 'user': user2, 'pw': user2_pass}, 588 { 'path': '/', 'status': 200, 'user': user2, 'pw': user2_pass}, 589 { 'path': '/repos', 'status': 301, 'user': user2, 'pw': user2_pass}, 590 { 'path': '/repos/', 'status': 200, 'user': user2, 'pw': user2_pass}, 591 { 'path': '/repos/A', 'status': 301, 'user': user2, 'pw': user2_pass}, 592 { 'path': '/repos/A/', 'status': 200, 'user': user2, 'pw': user2_pass}, 593 { 'path': '/repos/A/D', 'status': 301, 'user': user2, 'pw': user2_pass}, 594 { 'path': '/repos/A/D/', 'status': 200, 'body': ls_of_D_no_H, 595 'user': user2, 'pw': user2_pass}, 596 { 'path': '/repos/A/D/gamma', 'status': 200, 'user': user2, 'pw': user2_pass}, 597 { 'path': '/repos/A/D/H', 'status': 403, 'user': user2, 'pw': user2_pass}, 598 { 'path': '/repos/A/D/H/', 'status': 403, 'user': user2, 'pw': user2_pass}, 599 { 'path': '/repos/A/D/H/chi', 'status': 403, 'user': user2, 'pw': user2_pass}, 600 # try with upper case username for user2 601 { 'path': '', 'status': 301, 'user': user2_upper, 'pw': user2_pass}, 602 { 'path': '/', 'status': 200, 'user': user2_upper, 'pw': user2_pass}, 603 { 'path': '/repos', 'status': 403, 'user': user2_upper, 'pw': user2_pass}, 604 { 'path': '/repos/', 'status': 403, 'user': user2_upper, 'pw': user2_pass}, 605 { 'path': '/repos/A', 'status': 403, 'user': user2_upper, 'pw': user2_pass}, 606 { 'path': '/repos/A/', 'status': 403, 'user': user2_upper, 'pw': user2_pass}, 607 { 'path': '/repos/A/D', 'status': 403, 'user': user2_upper, 'pw': user2_pass}, 608 { 'path': '/repos/A/D/', 'status': 403, 'user': user2_upper, 'pw': user2_pass}, 609 { 'path': '/repos/A/D/gamma', 'status': 403, 'user': user2_upper, 'pw': user2_pass}, 610 { 'path': '/repos/A/D/H', 'status': 403, 'user': user2_upper, 'pw': user2_pass}, 611 { 'path': '/repos/A/D/H/', 'status': 403, 'user': user2_upper, 'pw': user2_pass}, 612 { 'path': '/repos/A/D/H/chi', 'status': 403, 'user': user2_upper, 'pw': user2_pass}, 613 # try with the wrong password for user2 614 { 'path': '', 'status': 401, 'user': user2, 'pw': user2_badpass}, 615 { 'path': '/', 'status': 401, 'user': user2, 'pw': user2_badpass}, 616 { 'path': '/repos', 'status': 401, 'user': user2, 'pw': user2_badpass}, 617 { 'path': '/repos/', 'status': 401, 'user': user2, 'pw': user2_badpass}, 618 { 'path': '/repos/A', 'status': 401, 'user': user2, 'pw': user2_badpass}, 619 { 'path': '/repos/A/', 'status': 401, 'user': user2, 'pw': user2_badpass}, 620 { 'path': '/repos/A/D', 'status': 401, 'user': user2, 'pw': user2_badpass}, 621 { 'path': '/repos/A/D/', 'status': 401, 'user': user2, 'pw': user2_badpass}, 622 { 'path': '/repos/A/D/gamma', 'status': 401, 'user': user2, 'pw': user2_badpass}, 623 { 'path': '/repos/A/D/H', 'status': 401, 'user': user2, 'pw': user2_badpass}, 624 { 'path': '/repos/A/D/H/', 'status': 401, 'user': user2, 'pw': user2_badpass}, 625 { 'path': '/repos/A/D/H/chi', 'status': 401, 'user': user2, 'pw': user2_badpass}, 626 ) 627 628 verify_gets(test_area_url, anonoff_tests) 629 630@SkipUnless(svntest.main.is_ra_type_dav) 631def authn_lcuser(sbox): 632 "test authenticated only access with lcuser" 633 sbox.build(read_only = True, create_wc = False) 634 635 test_area_url = sbox.repo_url.replace('/svn-test-work/local_tmp/repos', 636 '/authz-test-work/authn-lcuser') 637 638 write_authz_file(sbox) 639 640 lcuser_tests = ( 641 # try with upper case username for user1 (works due to lcuser option) 642 { 'path': '', 'status': 301, 'user': user1_upper, 'pw': user1_pass}, 643 { 'path': '/', 'status': 200, 'user': user1_upper, 'pw': user1_pass}, 644 { 'path': '/repos', 'status': 301, 'user': user1_upper, 'pw': user1_pass}, 645 { 'path': '/repos/', 'status': 200, 'user': user1_upper, 'pw': user1_pass}, 646 { 'path': '/repos/A', 'status': 301, 'user': user1_upper, 'pw': user1_pass}, 647 { 'path': '/repos/A/', 'status': 200, 'user': user1_upper, 'pw': user1_pass}, 648 { 'path': '/repos/A/D', 'status': 301, 'user': user1_upper, 'pw': user1_pass}, 649 { 'path': '/repos/A/D/', 'status': 200, 'body': ls_of_D_H, 650 'user': user1_upper, 'pw': user1_pass}, 651 { 'path': '/repos/A/D/gamma', 'status': 200, 'user': user1_upper, 'pw': user1_pass}, 652 { 'path': '/repos/A/D/H', 'status': 301, 'user': user1_upper, 'pw': user1_pass}, 653 { 'path': '/repos/A/D/H/', 'status': 200, 'body': ls_of_H, 'user': user1_upper, 'pw': user1_pass}, 654 { 'path': '/repos/A/D/H/chi', 'status': 200, 'user': user1_upper, 'pw': user1_pass}, 655 # try with upper case username for user2 (works due to lcuser option) 656 { 'path': '', 'status': 301, 'user': user2_upper, 'pw': user2_pass}, 657 { 'path': '/', 'status': 200, 'user': user2_upper, 'pw': user2_pass}, 658 { 'path': '/repos', 'status': 301, 'user': user2_upper, 'pw': user2_pass}, 659 { 'path': '/repos/', 'status': 200, 'user': user2_upper, 'pw': user2_pass}, 660 { 'path': '/repos/A', 'status': 301, 'user': user2_upper, 'pw': user2_pass}, 661 { 'path': '/repos/A/', 'status': 200, 'user': user2_upper, 'pw': user2_pass}, 662 { 'path': '/repos/A/D', 'status': 301, 'user': user2_upper, 'pw': user2_pass}, 663 { 'path': '/repos/A/D/', 'status': 200, 'body': ls_of_D_no_H, 664 'user': user2_upper, 'pw': user2_pass}, 665 { 'path': '/repos/A/D/gamma', 'status': 200, 'user': user2_upper, 'pw': user2_pass}, 666 { 'path': '/repos/A/D/H', 'status': 403, 'user': user2_upper, 'pw': user2_pass}, 667 { 'path': '/repos/A/D/H/', 'status': 403, 'user': user2_upper, 'pw': user2_pass}, 668 { 'path': '/repos/A/D/H/chi', 'status': 403, 'user': user2_upper, 'pw': user2_pass}, 669 ) 670 671 verify_gets(test_area_url, lcuser_tests) 672 673# authenticated access only by group - a excuse to use AuthzSVNAuthoritative Off 674# this is terribly messed up, Require group runs after mod_authz_svn. 675# so if mod_authz_svn grants the access then it doesn't matter what the group 676# requirement says. If we reject the access then you can use the AuthzSVNAuthoritative Off 677# directive to fall through to the group check. Overall the behavior of setups like this 678# is almost guaranteed to not be what users expect. 679@SkipUnless(svntest.main.is_ra_type_dav) 680def authn_group(sbox): 681 "test authenticated only access via groups" 682 sbox.build(read_only = True, create_wc = False) 683 684 test_area_url = sbox.repo_url.replace('/svn-test-work/local_tmp/repos', 685 '/authz-test-work/authn-group') 686 687 # Can't use write_authz_file() as most tests because we want to deny all 688 # access with mod_authz_svn so the tests fall through to the group handling 689 authz_name = sbox.authz_name() 690 svntest.main.write_authz_file(sbox, { 691 '/': '* =', 692 }) 693 694 group_tests = ( 695 { 'path': '', 'status': 401, }, 696 { 'path': '/', 'status': 401, }, 697 { 'path': '/repos', 'status': 401, }, 698 { 'path': '/repos/', 'status': 401, }, 699 { 'path': '/repos/A', 'status': 401, }, 700 { 'path': '/repos/A/', 'status': 401, }, 701 { 'path': '/repos/A/D', 'status': 401, }, 702 { 'path': '/repos/A/D/', 'status': 401, }, 703 { 'path': '/repos/A/D/gamma', 'status': 401, }, 704 { 'path': '/repos/A/D/H', 'status': 401, }, 705 { 'path': '/repos/A/D/H/', 'status': 401, }, 706 { 'path': '/repos/A/D/H/chi', 'status': 401, }, 707 # auth is configured and user1 is allowed access repo including H 708 { 'path': '', 'status': 301, 'user': user1, 'pw': user1_pass}, 709 { 'path': '/', 'status': 200, 'user': user1, 'pw': user1_pass}, 710 { 'path': '/repos', 'status': 301, 'user': user1, 'pw': user1_pass}, 711 { 'path': '/repos/', 'status': 200, 'user': user1, 'pw': user1_pass}, 712 { 'path': '/repos/A', 'status': 301, 'user': user1, 'pw': user1_pass}, 713 { 'path': '/repos/A/', 'status': 200, 'user': user1, 'pw': user1_pass}, 714 { 'path': '/repos/A/D', 'status': 301, 'user': user1, 'pw': user1_pass}, 715 { 'path': '/repos/A/D/', 'status': 200, 'body': ls_of_D_H, 716 'user': user1, 'pw': user1_pass}, 717 { 'path': '/repos/A/D/gamma', 'status': 200, 'user': user1, 'pw': user1_pass}, 718 { 'path': '/repos/A/D/H', 'status': 301, 'user': user1, 'pw': user1_pass}, 719 { 'path': '/repos/A/D/H/', 'status': 200, 'body': ls_of_H, 'user': user1, 'pw': user1_pass}, 720 { 'path': '/repos/A/D/H/chi', 'status': 200, 'user': user1, 'pw': user1_pass}, 721 ) 722 723 verify_gets(test_area_url, group_tests) 724 725# This test exists to validate our behavior when used with the new authz 726# provider system introduced in httpd 2.3.x. The Satisfy directive 727# determines how older authz hooks are combined and the RequireA(ll|ny) 728# blocks handles how new authz providers are combined. The overall results of 729# all the authz providers (combined per the Require* blocks) are then 730# combined with the other authz hooks via the Satisfy directive. 731# Meaning this test requires that mod_authz_svn says yes and there is 732# either a valid user or the ALLOW header is 1. The header may seem 733# like a silly test but it's easier to excercise than say a host directive 734# in a repeatable test. 735@SkipUnless(svntest.main.is_httpd_authz_provider_enabled) 736def authn_sallrany(sbox): 737 "test satisfy all require any config" 738 sbox.build(read_only = True, create_wc = False) 739 740 test_area_url = sbox.repo_url.replace('/svn-test-work/local_tmp/repos', 741 '/authz-test-work/sallrany') 742 743 write_authz_file(sbox) 744 745 allow_header = { 'ALLOW': '1' } 746 747 sallrany_tests = ( 748 #anon access isn't allowed without ALLOW header 749 { 'path': '', 'status': 401, }, 750 { 'path': '/', 'status': 401, }, 751 { 'path': '/repos', 'status': 401, }, 752 { 'path': '/repos/', 'status': 401, }, 753 { 'path': '/repos/A', 'status': 401, }, 754 { 'path': '/repos/A/', 'status': 401, }, 755 { 'path': '/repos/A/D', 'status': 401, }, 756 { 'path': '/repos/A/D/', 'status': 401, }, 757 { 'path': '/repos/A/D/gamma', 'status': 401, }, 758 { 'path': '/repos/A/D/H', 'status': 401, }, 759 { 'path': '/repos/A/D/H/', 'status': 401, }, 760 { 'path': '/repos/A/D/H/chi', 'status': 401, }, 761 # auth is configured and user1 is allowed access repo including H 762 { 'path': '', 'status': 301, 'user': user1, 'pw': user1_pass}, 763 { 'path': '/', 'status': 200, 'user': user1, 'pw': user1_pass}, 764 { 'path': '/repos', 'status': 301, 'user': user1, 'pw': user1_pass}, 765 { 'path': '/repos/', 'status': 200, 'user': user1, 'pw': user1_pass}, 766 { 'path': '/repos/A', 'status': 301, 'user': user1, 'pw': user1_pass}, 767 { 'path': '/repos/A/', 'status': 200, 'user': user1, 'pw': user1_pass}, 768 { 'path': '/repos/A/D', 'status': 301, 'user': user1, 'pw': user1_pass}, 769 { 'path': '/repos/A/D/', 'status': 200, 'body': ls_of_D_H, 770 'user': user1, 'pw': user1_pass}, 771 { 'path': '/repos/A/D/gamma', 'status': 200, 'user': user1, 'pw': user1_pass}, 772 { 'path': '/repos/A/D/H', 'status': 301, 'user': user1, 'pw': user1_pass}, 773 { 'path': '/repos/A/D/H/', 'status': 200, 'body': ls_of_H, 'user': user1, 'pw': user1_pass}, 774 { 'path': '/repos/A/D/H/chi', 'status': 200, 'user': user1, 'pw': user1_pass}, 775 # try with the wrong password for user1 776 { 'path': '', 'status': 401, 'user': user1, 'pw': user1_badpass}, 777 { 'path': '/', 'status': 401, 'user': user1, 'pw': user1_badpass}, 778 { 'path': '/repos', 'status': 401, 'user': user1, 'pw': user1_badpass}, 779 { 'path': '/repos/', 'status': 401, 'user': user1, 'pw': user1_badpass}, 780 { 'path': '/repos/A', 'status': 401, 'user': user1, 'pw': user1_badpass}, 781 { 'path': '/repos/A/', 'status': 401, 'user': user1, 'pw': user1_badpass}, 782 { 'path': '/repos/A/D', 'status': 401, 'user': user1, 'pw': user1_badpass}, 783 { 'path': '/repos/A/D/', 'status': 401, 'user': user1, 'pw': user1_badpass}, 784 { 'path': '/repos/A/D/gamma', 'status': 401, 'user': user1, 'pw': user1_badpass}, 785 { 'path': '/repos/A/D/H', 'status': 401, 'user': user1, 'pw': user1_badpass}, 786 { 'path': '/repos/A/D/H/', 'status': 401, 'user': user1, 'pw': user1_badpass}, 787 { 'path': '/repos/A/D/H/chi', 'status': 401, 'user': user1, 'pw': user1_badpass}, 788 # auth is configured and user2 is not allowed access to H 789 { 'path': '', 'status': 301, 'user': user2, 'pw': user2_pass}, 790 { 'path': '/', 'status': 200, 'user': user2, 'pw': user2_pass}, 791 { 'path': '/repos', 'status': 301, 'user': user2, 'pw': user2_pass}, 792 { 'path': '/repos/', 'status': 200, 'user': user2, 'pw': user2_pass}, 793 { 'path': '/repos/A', 'status': 301, 'user': user2, 'pw': user2_pass}, 794 { 'path': '/repos/A/', 'status': 200, 'user': user2, 'pw': user2_pass}, 795 { 'path': '/repos/A/D', 'status': 301, 'user': user2, 'pw': user2_pass}, 796 { 'path': '/repos/A/D/', 'status': 200, 'body': ls_of_D_no_H, 797 'user': user2, 'pw': user2_pass}, 798 { 'path': '/repos/A/D/gamma', 'status': 200, 'user': user2, 'pw': user2_pass}, 799 { 'path': '/repos/A/D/H', 'status': 403, 'user': user2, 'pw': user2_pass}, 800 { 'path': '/repos/A/D/H/', 'status': 403, 'user': user2, 'pw': user2_pass}, 801 { 'path': '/repos/A/D/H/chi', 'status': 403, 'user': user2, 'pw': user2_pass}, 802 # try with the wrong password for user2 803 { 'path': '', 'status': 401, 'user': user2, 'pw': user2_badpass}, 804 { 'path': '/', 'status': 401, 'user': user2, 'pw': user2_badpass}, 805 { 'path': '/repos', 'status': 401, 'user': user2, 'pw': user2_badpass}, 806 { 'path': '/repos/', 'status': 401, 'user': user2, 'pw': user2_badpass}, 807 { 'path': '/repos/A', 'status': 401, 'user': user2, 'pw': user2_badpass}, 808 { 'path': '/repos/A/', 'status': 401, 'user': user2, 'pw': user2_badpass}, 809 { 'path': '/repos/A/D', 'status': 401, 'user': user2, 'pw': user2_badpass}, 810 { 'path': '/repos/A/D/', 'status': 401, 'user': user2, 'pw': user2_badpass}, 811 { 'path': '/repos/A/D/gamma', 'status': 401, 'user': user2, 'pw': user2_badpass}, 812 { 'path': '/repos/A/D/H', 'status': 401, 'user': user2, 'pw': user2_badpass}, 813 { 'path': '/repos/A/D/H/', 'status': 401, 'user': user2, 'pw': user2_badpass}, 814 { 'path': '/repos/A/D/H/chi', 'status': 401, 'user': user2, 'pw': user2_badpass}, 815 # anon is allowed with the ALLOW header 816 { 'path': '', 'status': 301, 'headers': allow_header }, 817 { 'path': '/', 'status': 200, 'headers': allow_header }, 818 { 'path': '/repos', 'status': 301, 'headers': allow_header }, 819 { 'path': '/repos/', 'status': 200, 'headers': allow_header }, 820 { 'path': '/repos/A', 'status': 301, 'headers': allow_header }, 821 { 'path': '/repos/A/', 'status': 200, 'headers': allow_header }, 822 { 'path': '/repos/A/D', 'status': 301, 'headers': allow_header }, 823 { 'path': '/repos/A/D/', 'status': 200, 'body': ls_of_D_no_H, 'headers': allow_header }, 824 { 'path': '/repos/A/D/gamma', 'status': 200, 'headers': allow_header }, 825 # these 3 tests return 403 instead of 401 becasue the config allows 826 # the anon user with the ALLOW header without any auth and the old hook 827 # system has no way of knowing it should return 401 since authentication is 828 # configured and can change the behavior. It could decide to return 401 just on 829 # the basis of authentication being configured but then that leaks info in other 830 # cases so it's better for this case to be "broken". 831 { 'path': '/repos/A/D/H', 'status': 403, 'headers': allow_header }, 832 { 'path': '/repos/A/D/H/', 'status': 403, 'headers': allow_header }, 833 { 'path': '/repos/A/D/H/chi', 'status': 403, 'headers': allow_header }, 834 # auth is configured and user1 is allowed access repo including H 835 { 'path': '', 'status': 301, 'user': user1, 'pw': user1_pass, 'headers': allow_header }, 836 { 'path': '/', 'status': 200, 'user': user1, 'pw': user1_pass, 'headers': allow_header }, 837 { 'path': '/repos', 'status': 301, 'user': user1, 'pw': user1_pass, 'headers': allow_header }, 838 { 'path': '/repos/', 'status': 200, 'user': user1, 'pw': user1_pass, 'headers': allow_header }, 839 { 'path': '/repos/A', 'status': 301, 'user': user1, 'pw': user1_pass, 'headers': allow_header }, 840 { 'path': '/repos/A/', 'status': 200, 'user': user1, 'pw': user1_pass, 'headers': allow_header }, 841 { 'path': '/repos/A/D', 'status': 301, 'user': user1, 'pw': user1_pass, 'headers': allow_header }, 842 { 'path': '/repos/A/D/', 'status': 200, 'body': ls_of_D_H, 843 'user': user1, 'pw': user1_pass, 'headers': allow_header }, 844 { 'path': '/repos/A/D/gamma', 'status': 200, 'user': user1, 'pw': user1_pass, 'headers': allow_header }, 845 { 'path': '/repos/A/D/H', 'status': 301, 'user': user1, 'pw': user1_pass, 'headers': allow_header }, 846 { 'path': '/repos/A/D/H/', 'status': 200, 'body': ls_of_H, 'user': user1, 'pw': user1_pass, 'headers': allow_header }, 847 { 'path': '/repos/A/D/H/chi', 'status': 200, 'user': user1, 'pw': user1_pass, 'headers': allow_header }, 848 # try with the wrong password for user1 849 { 'path': '', 'status': 401, 'user': user1, 'pw': user1_badpass, 'headers': allow_header }, 850 { 'path': '/', 'status': 401, 'user': user1, 'pw': user1_badpass, 'headers': allow_header }, 851 { 'path': '/repos', 'status': 401, 'user': user1, 'pw': user1_badpass, 'headers': allow_header }, 852 { 'path': '/repos/', 'status': 401, 'user': user1, 'pw': user1_badpass, 'headers': allow_header }, 853 { 'path': '/repos/A', 'status': 401, 'user': user1, 'pw': user1_badpass, 'headers': allow_header }, 854 { 'path': '/repos/A/', 'status': 401, 'user': user1, 'pw': user1_badpass, 'headers': allow_header }, 855 { 'path': '/repos/A/D', 'status': 401, 'user': user1, 'pw': user1_badpass, 'headers': allow_header }, 856 { 'path': '/repos/A/D/', 'status': 401, 'user': user1, 'pw': user1_badpass, 'headers': allow_header }, 857 { 'path': '/repos/A/D/gamma', 'status': 401, 'user': user1, 'pw': user1_badpass, 'headers': allow_header }, 858 { 'path': '/repos/A/D/H', 'status': 401, 'user': user1, 'pw': user1_badpass, 'headers': allow_header }, 859 { 'path': '/repos/A/D/H/', 'status': 401, 'user': user1, 'pw': user1_badpass, 'headers': allow_header }, 860 { 'path': '/repos/A/D/H/chi', 'status': 401, 'user': user1, 'pw': user1_badpass, 'headers': allow_header }, 861 # auth is configured and user2 is not allowed access to H 862 { 'path': '', 'status': 301, 'user': user2, 'pw': user2_pass, 'headers': allow_header }, 863 { 'path': '/', 'status': 200, 'user': user2, 'pw': user2_pass, 'headers': allow_header }, 864 { 'path': '/repos', 'status': 301, 'user': user2, 'pw': user2_pass, 'headers': allow_header }, 865 { 'path': '/repos/', 'status': 200, 'user': user2, 'pw': user2_pass, 'headers': allow_header }, 866 { 'path': '/repos/A', 'status': 301, 'user': user2, 'pw': user2_pass, 'headers': allow_header }, 867 { 'path': '/repos/A/', 'status': 200, 'user': user2, 'pw': user2_pass, 'headers': allow_header }, 868 { 'path': '/repos/A/D', 'status': 301, 'user': user2, 'pw': user2_pass, 'headers': allow_header }, 869 { 'path': '/repos/A/D/', 'status': 200, 'body': ls_of_D_no_H, 870 'user': user2, 'pw': user2_pass, 'headers': allow_header }, 871 { 'path': '/repos/A/D/gamma', 'status': 200, 'user': user2, 'pw': user2_pass, 'headers': allow_header }, 872 { 'path': '/repos/A/D/H', 'status': 403, 'user': user2, 'pw': user2_pass, 'headers': allow_header }, 873 { 'path': '/repos/A/D/H/', 'status': 403, 'user': user2, 'pw': user2_pass, 'headers': allow_header }, 874 { 'path': '/repos/A/D/H/chi', 'status': 403, 'user': user2, 'pw': user2_pass, 'headers': allow_header }, 875 # try with the wrong password for user2 876 { 'path': '', 'status': 401, 'user': user2, 'pw': user2_badpass, 'headers': allow_header }, 877 { 'path': '/', 'status': 401, 'user': user2, 'pw': user2_badpass, 'headers': allow_header }, 878 { 'path': '/repos', 'status': 401, 'user': user2, 'pw': user2_badpass, 'headers': allow_header }, 879 { 'path': '/repos/', 'status': 401, 'user': user2, 'pw': user2_badpass, 'headers': allow_header }, 880 { 'path': '/repos/A', 'status': 401, 'user': user2, 'pw': user2_badpass, 'headers': allow_header }, 881 { 'path': '/repos/A/', 'status': 401, 'user': user2, 'pw': user2_badpass, 'headers': allow_header }, 882 { 'path': '/repos/A/D', 'status': 401, 'user': user2, 'pw': user2_badpass, 'headers': allow_header }, 883 { 'path': '/repos/A/D/', 'status': 401, 'user': user2, 'pw': user2_badpass, 'headers': allow_header }, 884 { 'path': '/repos/A/D/gamma', 'status': 401, 'user': user2, 'pw': user2_badpass, 'headers': allow_header }, 885 { 'path': '/repos/A/D/H', 'status': 401, 'user': user2, 'pw': user2_badpass, 'headers': allow_header }, 886 { 'path': '/repos/A/D/H/', 'status': 401, 'user': user2, 'pw': user2_badpass, 'headers': allow_header }, 887 { 'path': '/repos/A/D/H/chi', 'status': 401, 'user': user2, 'pw': user2_badpass, 'headers': allow_header }, 888 889 ) 890 891 verify_gets(test_area_url, sallrany_tests) 892 893# See comments on authn_sallrany test for some background on the interaction 894# of Satisfy Any and the newer Require blocks. 895@SkipUnless(svntest.main.is_httpd_authz_provider_enabled) 896def authn_sallrall(sbox): 897 "test satisfy all require all config" 898 sbox.build(read_only = True, create_wc = False) 899 900 test_area_url = sbox.repo_url.replace('/svn-test-work/local_tmp/repos', 901 '/authz-test-work/sallrall') 902 903 write_authz_file(sbox) 904 905 allow_header = { 'ALLOW': '1' } 906 907 sallrall_tests = ( 908 #anon access isn't allowed without ALLOW header 909 { 'path': '', 'status': 403, }, 910 { 'path': '/', 'status': 403, }, 911 { 'path': '/repos', 'status': 403, }, 912 { 'path': '/repos/', 'status': 403, }, 913 { 'path': '/repos/A', 'status': 403, }, 914 { 'path': '/repos/A/', 'status': 403, }, 915 { 'path': '/repos/A/D', 'status': 403, }, 916 { 'path': '/repos/A/D/', 'status': 403, }, 917 { 'path': '/repos/A/D/gamma', 'status': 403, }, 918 { 'path': '/repos/A/D/H', 'status': 403, }, 919 { 'path': '/repos/A/D/H/', 'status': 403, }, 920 { 'path': '/repos/A/D/H/chi', 'status': 403, }, 921 # auth is configured but no access is allowed without the ALLOW header 922 { 'path': '', 'status': 403, 'user': user1, 'pw': user1_pass}, 923 { 'path': '/', 'status': 403, 'user': user1, 'pw': user1_pass}, 924 { 'path': '/repos', 'status': 403, 'user': user1, 'pw': user1_pass}, 925 { 'path': '/repos/', 'status': 403, 'user': user1, 'pw': user1_pass}, 926 { 'path': '/repos/A', 'status': 403, 'user': user1, 'pw': user1_pass}, 927 { 'path': '/repos/A/', 'status': 403, 'user': user1, 'pw': user1_pass}, 928 { 'path': '/repos/A/D', 'status': 403, 'user': user1, 'pw': user1_pass}, 929 { 'path': '/repos/A/D/', 'status': 403, 'user': user1, 'pw': user1_pass}, 930 { 'path': '/repos/A/D/gamma', 'status': 403, 'user': user1, 'pw': user1_pass}, 931 { 'path': '/repos/A/D/H', 'status': 403, 'user': user1, 'pw': user1_pass}, 932 { 'path': '/repos/A/D/H/', 'status': 403, 'user': user1, 'pw': user1_pass}, 933 { 'path': '/repos/A/D/H/chi', 'status': 403, 'user': user1, 'pw': user1_pass}, 934 # try with the wrong password for user1 935 { 'path': '', 'status': 403, 'user': user1, 'pw': user1_badpass}, 936 { 'path': '/', 'status': 403, 'user': user1, 'pw': user1_badpass}, 937 { 'path': '/repos', 'status': 403, 'user': user1, 'pw': user1_badpass}, 938 { 'path': '/repos/', 'status': 403, 'user': user1, 'pw': user1_badpass}, 939 { 'path': '/repos/A', 'status': 403, 'user': user1, 'pw': user1_badpass}, 940 { 'path': '/repos/A/', 'status': 403, 'user': user1, 'pw': user1_badpass}, 941 { 'path': '/repos/A/D', 'status': 403, 'user': user1, 'pw': user1_badpass}, 942 { 'path': '/repos/A/D/', 'status': 403, 'user': user1, 'pw': user1_badpass}, 943 { 'path': '/repos/A/D/gamma', 'status': 403, 'user': user1, 'pw': user1_badpass}, 944 { 'path': '/repos/A/D/H', 'status': 403, 'user': user1, 'pw': user1_badpass}, 945 { 'path': '/repos/A/D/H/', 'status': 403, 'user': user1, 'pw': user1_badpass}, 946 { 'path': '/repos/A/D/H/chi', 'status': 403, 'user': user1, 'pw': user1_badpass}, 947 # auth is configured but no access is allowed without the ALLOW header 948 { 'path': '', 'status': 403, 'user': user2, 'pw': user2_pass}, 949 { 'path': '/', 'status': 403, 'user': user2, 'pw': user2_pass}, 950 { 'path': '/repos', 'status': 403, 'user': user2, 'pw': user2_pass}, 951 { 'path': '/repos/', 'status': 403, 'user': user2, 'pw': user2_pass}, 952 { 'path': '/repos/A', 'status': 403, 'user': user2, 'pw': user2_pass}, 953 { 'path': '/repos/A/', 'status': 403, 'user': user2, 'pw': user2_pass}, 954 { 'path': '/repos/A/D', 'status': 403, 'user': user2, 'pw': user2_pass}, 955 { 'path': '/repos/A/D/', 'status': 403, 'user': user2, 'pw': user2_pass}, 956 { 'path': '/repos/A/D/gamma', 'status': 403, 'user': user2, 'pw': user2_pass}, 957 { 'path': '/repos/A/D/H', 'status': 403, 'user': user2, 'pw': user2_pass}, 958 { 'path': '/repos/A/D/H/', 'status': 403, 'user': user2, 'pw': user2_pass}, 959 { 'path': '/repos/A/D/H/chi', 'status': 403, 'user': user2, 'pw': user2_pass}, 960 # try with the wrong password for user2 961 { 'path': '', 'status': 403, 'user': user2, 'pw': user2_badpass}, 962 { 'path': '/', 'status': 403, 'user': user2, 'pw': user2_badpass}, 963 { 'path': '/repos', 'status': 403, 'user': user2, 'pw': user2_badpass}, 964 { 'path': '/repos/', 'status': 403, 'user': user2, 'pw': user2_badpass}, 965 { 'path': '/repos/A', 'status': 403, 'user': user2, 'pw': user2_badpass}, 966 { 'path': '/repos/A/', 'status': 403, 'user': user2, 'pw': user2_badpass}, 967 { 'path': '/repos/A/D', 'status': 403, 'user': user2, 'pw': user2_badpass}, 968 { 'path': '/repos/A/D/', 'status': 403, 'user': user2, 'pw': user2_badpass}, 969 { 'path': '/repos/A/D/gamma', 'status': 403, 'user': user2, 'pw': user2_badpass}, 970 { 'path': '/repos/A/D/H', 'status': 403, 'user': user2, 'pw': user2_badpass}, 971 { 'path': '/repos/A/D/H/', 'status': 403, 'user': user2, 'pw': user2_badpass}, 972 { 'path': '/repos/A/D/H/chi', 'status': 403, 'user': user2, 'pw': user2_badpass}, 973 # anon is not allowed even with ALLOW header 974 { 'path': '', 'status': 401, 'headers': allow_header }, 975 { 'path': '/', 'status': 401, 'headers': allow_header }, 976 { 'path': '/repos', 'status': 401, 'headers': allow_header }, 977 { 'path': '/repos/', 'status': 401, 'headers': allow_header }, 978 { 'path': '/repos/A', 'status': 401, 'headers': allow_header }, 979 { 'path': '/repos/A/', 'status': 401, 'headers': allow_header }, 980 { 'path': '/repos/A/D', 'status': 401, 'headers': allow_header }, 981 { 'path': '/repos/A/D/', 'status': 401, 'headers': allow_header }, 982 { 'path': '/repos/A/D/gamma', 'status': 401, 'headers': allow_header }, 983 { 'path': '/repos/A/D/H', 'status': 401, 'headers': allow_header }, 984 { 'path': '/repos/A/D/H/', 'status': 401, 'headers': allow_header }, 985 { 'path': '/repos/A/D/H/chi', 'status': 401, 'headers': allow_header }, 986 # auth is configured and user1 is allowed access repo including H 987 { 'path': '', 'status': 301, 'user': user1, 'pw': user1_pass, 'headers': allow_header }, 988 { 'path': '/', 'status': 200, 'user': user1, 'pw': user1_pass, 'headers': allow_header }, 989 { 'path': '/repos', 'status': 301, 'user': user1, 'pw': user1_pass, 'headers': allow_header }, 990 { 'path': '/repos/', 'status': 200, 'user': user1, 'pw': user1_pass, 'headers': allow_header }, 991 { 'path': '/repos/A', 'status': 301, 'user': user1, 'pw': user1_pass, 'headers': allow_header }, 992 { 'path': '/repos/A/', 'status': 200, 'user': user1, 'pw': user1_pass, 'headers': allow_header }, 993 { 'path': '/repos/A/D', 'status': 301, 'user': user1, 'pw': user1_pass, 'headers': allow_header }, 994 { 'path': '/repos/A/D/', 'status': 200, 'body': ls_of_D_H, 995 'user': user1, 'pw': user1_pass, 'headers': allow_header }, 996 { 'path': '/repos/A/D/gamma', 'status': 200, 'user': user1, 'pw': user1_pass, 'headers': allow_header }, 997 { 'path': '/repos/A/D/H', 'status': 301, 'user': user1, 'pw': user1_pass, 'headers': allow_header }, 998 { 'path': '/repos/A/D/H/', 'status': 200, 'body': ls_of_H, 'user': user1, 'pw': user1_pass, 'headers': allow_header }, 999 { 'path': '/repos/A/D/H/chi', 'status': 200, 'user': user1, 'pw': user1_pass, 'headers': allow_header }, 1000 # try with the wrong password for user1 1001 { 'path': '', 'status': 401, 'user': user1, 'pw': user1_badpass, 'headers': allow_header }, 1002 { 'path': '/', 'status': 401, 'user': user1, 'pw': user1_badpass, 'headers': allow_header }, 1003 { 'path': '/repos', 'status': 401, 'user': user1, 'pw': user1_badpass, 'headers': allow_header }, 1004 { 'path': '/repos/', 'status': 401, 'user': user1, 'pw': user1_badpass, 'headers': allow_header }, 1005 { 'path': '/repos/A', 'status': 401, 'user': user1, 'pw': user1_badpass, 'headers': allow_header }, 1006 { 'path': '/repos/A/', 'status': 401, 'user': user1, 'pw': user1_badpass, 'headers': allow_header }, 1007 { 'path': '/repos/A/D', 'status': 401, 'user': user1, 'pw': user1_badpass, 'headers': allow_header }, 1008 { 'path': '/repos/A/D/', 'status': 401, 'user': user1, 'pw': user1_badpass, 'headers': allow_header }, 1009 { 'path': '/repos/A/D/gamma', 'status': 401, 'user': user1, 'pw': user1_badpass, 'headers': allow_header }, 1010 { 'path': '/repos/A/D/H', 'status': 401, 'user': user1, 'pw': user1_badpass, 'headers': allow_header }, 1011 { 'path': '/repos/A/D/H/', 'status': 401, 'user': user1, 'pw': user1_badpass, 'headers': allow_header }, 1012 { 'path': '/repos/A/D/H/chi', 'status': 401, 'user': user1, 'pw': user1_badpass, 'headers': allow_header }, 1013 # auth is configured and user2 is not allowed access to H 1014 { 'path': '', 'status': 301, 'user': user2, 'pw': user2_pass, 'headers': allow_header }, 1015 { 'path': '/', 'status': 200, 'user': user2, 'pw': user2_pass, 'headers': allow_header }, 1016 { 'path': '/repos', 'status': 301, 'user': user2, 'pw': user2_pass, 'headers': allow_header }, 1017 { 'path': '/repos/', 'status': 200, 'user': user2, 'pw': user2_pass, 'headers': allow_header }, 1018 { 'path': '/repos/A', 'status': 301, 'user': user2, 'pw': user2_pass, 'headers': allow_header }, 1019 { 'path': '/repos/A/', 'status': 200, 'user': user2, 'pw': user2_pass, 'headers': allow_header }, 1020 { 'path': '/repos/A/D', 'status': 301, 'user': user2, 'pw': user2_pass, 'headers': allow_header }, 1021 { 'path': '/repos/A/D/', 'status': 200, 'body': ls_of_D_no_H, 1022 'user': user2, 'pw': user2_pass, 'headers': allow_header }, 1023 { 'path': '/repos/A/D/gamma', 'status': 200, 'user': user2, 'pw': user2_pass, 'headers': allow_header }, 1024 { 'path': '/repos/A/D/H', 'status': 403, 'user': user2, 'pw': user2_pass, 'headers': allow_header }, 1025 { 'path': '/repos/A/D/H/', 'status': 403, 'user': user2, 'pw': user2_pass, 'headers': allow_header }, 1026 { 'path': '/repos/A/D/H/chi', 'status': 403, 'user': user2, 'pw': user2_pass, 'headers': allow_header }, 1027 # try with the wrong password for user2 1028 { 'path': '', 'status': 401, 'user': user2, 'pw': user2_badpass, 'headers': allow_header }, 1029 { 'path': '/', 'status': 401, 'user': user2, 'pw': user2_badpass, 'headers': allow_header }, 1030 { 'path': '/repos', 'status': 401, 'user': user2, 'pw': user2_badpass, 'headers': allow_header }, 1031 { 'path': '/repos/', 'status': 401, 'user': user2, 'pw': user2_badpass, 'headers': allow_header }, 1032 { 'path': '/repos/A', 'status': 401, 'user': user2, 'pw': user2_badpass, 'headers': allow_header }, 1033 { 'path': '/repos/A/', 'status': 401, 'user': user2, 'pw': user2_badpass, 'headers': allow_header }, 1034 { 'path': '/repos/A/D', 'status': 401, 'user': user2, 'pw': user2_badpass, 'headers': allow_header }, 1035 { 'path': '/repos/A/D/', 'status': 401, 'user': user2, 'pw': user2_badpass, 'headers': allow_header }, 1036 { 'path': '/repos/A/D/gamma', 'status': 401, 'user': user2, 'pw': user2_badpass, 'headers': allow_header }, 1037 { 'path': '/repos/A/D/H', 'status': 401, 'user': user2, 'pw': user2_badpass, 'headers': allow_header }, 1038 { 'path': '/repos/A/D/H/', 'status': 401, 'user': user2, 'pw': user2_badpass, 'headers': allow_header }, 1039 { 'path': '/repos/A/D/H/chi', 'status': 401, 'user': user2, 'pw': user2_badpass, 'headers': allow_header }, 1040 1041 ) 1042 1043 verify_gets(test_area_url, sallrall_tests) 1044 1045 1046######################################################################## 1047# Run the tests 1048 1049 1050# list all tests here, starting with None: 1051test_list = [ None, 1052 anon, 1053 mixed, 1054 mixed_noauthwhenanon, 1055 authn, 1056 authn_anonoff, 1057 authn_lcuser, 1058 authn_group, 1059 authn_sallrany, 1060 authn_sallrall, 1061 ] 1062serial_only = True 1063 1064if __name__ == '__main__': 1065 svntest.main.run_tests(test_list) 1066 # NOTREACHED 1067 1068 1069### End of file. 1070