Mercurial > hg
comparison hgext/acl.py @ 43077:687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Done with
python3.7 contrib/byteify-strings.py -i $(hg files 'set:mercurial/**.py - mercurial/thirdparty/** + hgext/**.py - hgext/fsmonitor/pywatchman/** - mercurial/__init__.py')
black -l 80 -t py33 -S $(hg files 'set:**.py - mercurial/thirdparty/** - "contrib/python-zstandard/**" - hgext/fsmonitor/pywatchman/**')
# skip-blame mass-reformatting only
Differential Revision: https://phab.mercurial-scm.org/D6972
author | Augie Fackler <augie@google.com> |
---|---|
date | Sun, 06 Oct 2019 09:48:39 -0400 |
parents | 2372284d9457 |
children | 8ff1ecfadcd1 |
comparison
equal
deleted
inserted
replaced
43076:2372284d9457 | 43077:687b865b95ad |
---|---|
230 | 230 |
231 # Note for extension authors: ONLY specify testedwith = 'ships-with-hg-core' for | 231 # Note for extension authors: ONLY specify testedwith = 'ships-with-hg-core' for |
232 # extensions which SHIP WITH MERCURIAL. Non-mainline extensions should | 232 # extensions which SHIP WITH MERCURIAL. Non-mainline extensions should |
233 # be specifying the version(s) of Mercurial they are tested with, or | 233 # be specifying the version(s) of Mercurial they are tested with, or |
234 # leave the attribute unspecified. | 234 # leave the attribute unspecified. |
235 testedwith = 'ships-with-hg-core' | 235 testedwith = b'ships-with-hg-core' |
236 | 236 |
237 configtable = {} | 237 configtable = {} |
238 configitem = registrar.configitem(configtable) | 238 configitem = registrar.configitem(configtable) |
239 | 239 |
240 # deprecated config: acl.config | 240 # deprecated config: acl.config |
241 configitem( | 241 configitem( |
242 'acl', 'config', default=None, | 242 b'acl', b'config', default=None, |
243 ) | 243 ) |
244 configitem( | 244 configitem( |
245 'acl.groups', '.*', default=None, generic=True, | 245 b'acl.groups', b'.*', default=None, generic=True, |
246 ) | 246 ) |
247 configitem( | 247 configitem( |
248 'acl.deny.branches', '.*', default=None, generic=True, | 248 b'acl.deny.branches', b'.*', default=None, generic=True, |
249 ) | 249 ) |
250 configitem( | 250 configitem( |
251 'acl.allow.branches', '.*', default=None, generic=True, | 251 b'acl.allow.branches', b'.*', default=None, generic=True, |
252 ) | 252 ) |
253 configitem( | 253 configitem( |
254 'acl.deny', '.*', default=None, generic=True, | 254 b'acl.deny', b'.*', default=None, generic=True, |
255 ) | 255 ) |
256 configitem( | 256 configitem( |
257 'acl.allow', '.*', default=None, generic=True, | 257 b'acl.allow', b'.*', default=None, generic=True, |
258 ) | 258 ) |
259 configitem( | 259 configitem( |
260 'acl', 'sources', default=lambda: ['serve'], | 260 b'acl', b'sources', default=lambda: [b'serve'], |
261 ) | 261 ) |
262 | 262 |
263 | 263 |
264 def _getusers(ui, group): | 264 def _getusers(ui, group): |
265 | 265 |
266 # First, try to use group definition from section [acl.groups] | 266 # First, try to use group definition from section [acl.groups] |
267 hgrcusers = ui.configlist('acl.groups', group) | 267 hgrcusers = ui.configlist(b'acl.groups', group) |
268 if hgrcusers: | 268 if hgrcusers: |
269 return hgrcusers | 269 return hgrcusers |
270 | 270 |
271 ui.debug('acl: "%s" not defined in [acl.groups]\n' % group) | 271 ui.debug(b'acl: "%s" not defined in [acl.groups]\n' % group) |
272 # If no users found in group definition, get users from OS-level group | 272 # If no users found in group definition, get users from OS-level group |
273 try: | 273 try: |
274 return util.groupmembers(group) | 274 return util.groupmembers(group) |
275 except KeyError: | 275 except KeyError: |
276 raise error.Abort(_("group '%s' is undefined") % group) | 276 raise error.Abort(_(b"group '%s' is undefined") % group) |
277 | 277 |
278 | 278 |
279 def _usermatch(ui, user, usersorgroups): | 279 def _usermatch(ui, user, usersorgroups): |
280 | 280 |
281 if usersorgroups == '*': | 281 if usersorgroups == b'*': |
282 return True | 282 return True |
283 | 283 |
284 for ug in usersorgroups.replace(',', ' ').split(): | 284 for ug in usersorgroups.replace(b',', b' ').split(): |
285 | 285 |
286 if ug.startswith('!'): | 286 if ug.startswith(b'!'): |
287 # Test for excluded user or group. Format: | 287 # Test for excluded user or group. Format: |
288 # if ug is a user name: !username | 288 # if ug is a user name: !username |
289 # if ug is a group name: !@groupname | 289 # if ug is a group name: !@groupname |
290 ug = ug[1:] | 290 ug = ug[1:] |
291 if ( | 291 if ( |
292 not ug.startswith('@') | 292 not ug.startswith(b'@') |
293 and user != ug | 293 and user != ug |
294 or ug.startswith('@') | 294 or ug.startswith(b'@') |
295 and user not in _getusers(ui, ug[1:]) | 295 and user not in _getusers(ui, ug[1:]) |
296 ): | 296 ): |
297 return True | 297 return True |
298 | 298 |
299 # Test for user or group. Format: | 299 # Test for user or group. Format: |
300 # if ug is a user name: username | 300 # if ug is a user name: username |
301 # if ug is a group name: @groupname | 301 # if ug is a group name: @groupname |
302 elif user == ug or ug.startswith('@') and user in _getusers(ui, ug[1:]): | 302 elif ( |
303 user == ug or ug.startswith(b'@') and user in _getusers(ui, ug[1:]) | |
304 ): | |
303 return True | 305 return True |
304 | 306 |
305 return False | 307 return False |
306 | 308 |
307 | 309 |
308 def buildmatch(ui, repo, user, key): | 310 def buildmatch(ui, repo, user, key): |
309 '''return tuple of (match function, list enabled).''' | 311 '''return tuple of (match function, list enabled).''' |
310 if not ui.has_section(key): | 312 if not ui.has_section(key): |
311 ui.debug('acl: %s not enabled\n' % key) | 313 ui.debug(b'acl: %s not enabled\n' % key) |
312 return None | 314 return None |
313 | 315 |
314 pats = [ | 316 pats = [ |
315 pat for pat, users in ui.configitems(key) if _usermatch(ui, user, users) | 317 pat for pat, users in ui.configitems(key) if _usermatch(ui, user, users) |
316 ] | 318 ] |
317 ui.debug( | 319 ui.debug( |
318 'acl: %s enabled, %d entries for user %s\n' % (key, len(pats), user) | 320 b'acl: %s enabled, %d entries for user %s\n' % (key, len(pats), user) |
319 ) | 321 ) |
320 | 322 |
321 # Branch-based ACL | 323 # Branch-based ACL |
322 if not repo: | 324 if not repo: |
323 if pats: | 325 if pats: |
324 # If there's an asterisk (meaning "any branch"), always return True; | 326 # If there's an asterisk (meaning "any branch"), always return True; |
325 # Otherwise, test if b is in pats | 327 # Otherwise, test if b is in pats |
326 if '*' in pats: | 328 if b'*' in pats: |
327 return util.always | 329 return util.always |
328 return lambda b: b in pats | 330 return lambda b: b in pats |
329 return util.never | 331 return util.never |
330 | 332 |
331 # Path-based ACL | 333 # Path-based ACL |
332 if pats: | 334 if pats: |
333 return match.match(repo.root, '', pats) | 335 return match.match(repo.root, b'', pats) |
334 return util.never | 336 return util.never |
335 | 337 |
336 | 338 |
337 def ensureenabled(ui): | 339 def ensureenabled(ui): |
338 """make sure the extension is enabled when used as hook | 340 """make sure the extension is enabled when used as hook |
340 When acl is used through hooks, the extension is never formally loaded and | 342 When acl is used through hooks, the extension is never formally loaded and |
341 enabled. This has some side effect, for example the config declaration is | 343 enabled. This has some side effect, for example the config declaration is |
342 never loaded. This function ensure the extension is enabled when running | 344 never loaded. This function ensure the extension is enabled when running |
343 hooks. | 345 hooks. |
344 """ | 346 """ |
345 if 'acl' in ui._knownconfig: | 347 if b'acl' in ui._knownconfig: |
346 return | 348 return |
347 ui.setconfig('extensions', 'acl', '', source='internal') | 349 ui.setconfig(b'extensions', b'acl', b'', source=b'internal') |
348 extensions.loadall(ui, ['acl']) | 350 extensions.loadall(ui, [b'acl']) |
349 | 351 |
350 | 352 |
351 def hook(ui, repo, hooktype, node=None, source=None, **kwargs): | 353 def hook(ui, repo, hooktype, node=None, source=None, **kwargs): |
352 | 354 |
353 ensureenabled(ui) | 355 ensureenabled(ui) |
354 | 356 |
355 if hooktype not in ['pretxnchangegroup', 'pretxncommit', 'prepushkey']: | 357 if hooktype not in [b'pretxnchangegroup', b'pretxncommit', b'prepushkey']: |
356 raise error.Abort( | 358 raise error.Abort( |
357 _( | 359 _( |
358 'config error - hook type "%s" cannot stop ' | 360 b'config error - hook type "%s" cannot stop ' |
359 'incoming changesets, commits, nor bookmarks' | 361 b'incoming changesets, commits, nor bookmarks' |
360 ) | 362 ) |
361 % hooktype | 363 % hooktype |
362 ) | 364 ) |
363 if hooktype == 'pretxnchangegroup' and source not in ui.configlist( | 365 if hooktype == b'pretxnchangegroup' and source not in ui.configlist( |
364 'acl', 'sources' | 366 b'acl', b'sources' |
365 ): | 367 ): |
366 ui.debug('acl: changes have source "%s" - skipping\n' % source) | 368 ui.debug(b'acl: changes have source "%s" - skipping\n' % source) |
367 return | 369 return |
368 | 370 |
369 user = None | 371 user = None |
370 if source == 'serve' and r'url' in kwargs: | 372 if source == b'serve' and r'url' in kwargs: |
371 url = kwargs[r'url'].split(':') | 373 url = kwargs[r'url'].split(b':') |
372 if url[0] == 'remote' and url[1].startswith('http'): | 374 if url[0] == b'remote' and url[1].startswith(b'http'): |
373 user = urlreq.unquote(url[3]) | 375 user = urlreq.unquote(url[3]) |
374 | 376 |
375 if user is None: | 377 if user is None: |
376 user = procutil.getuser() | 378 user = procutil.getuser() |
377 | 379 |
378 ui.debug('acl: checking access for user "%s"\n' % user) | 380 ui.debug(b'acl: checking access for user "%s"\n' % user) |
379 | 381 |
380 if hooktype == 'prepushkey': | 382 if hooktype == b'prepushkey': |
381 _pkhook(ui, repo, hooktype, node, source, user, **kwargs) | 383 _pkhook(ui, repo, hooktype, node, source, user, **kwargs) |
382 else: | 384 else: |
383 _txnhook(ui, repo, hooktype, node, source, user, **kwargs) | 385 _txnhook(ui, repo, hooktype, node, source, user, **kwargs) |
384 | 386 |
385 | 387 |
386 def _pkhook(ui, repo, hooktype, node, source, user, **kwargs): | 388 def _pkhook(ui, repo, hooktype, node, source, user, **kwargs): |
387 if kwargs[r'namespace'] == 'bookmarks': | 389 if kwargs[r'namespace'] == b'bookmarks': |
388 bookmark = kwargs[r'key'] | 390 bookmark = kwargs[r'key'] |
389 ctx = kwargs[r'new'] | 391 ctx = kwargs[r'new'] |
390 allowbookmarks = buildmatch(ui, None, user, 'acl.allow.bookmarks') | 392 allowbookmarks = buildmatch(ui, None, user, b'acl.allow.bookmarks') |
391 denybookmarks = buildmatch(ui, None, user, 'acl.deny.bookmarks') | 393 denybookmarks = buildmatch(ui, None, user, b'acl.deny.bookmarks') |
392 | 394 |
393 if denybookmarks and denybookmarks(bookmark): | 395 if denybookmarks and denybookmarks(bookmark): |
394 raise error.Abort( | 396 raise error.Abort( |
395 _('acl: user "%s" denied on bookmark "%s"' ' (changeset "%s")') | 397 _( |
398 b'acl: user "%s" denied on bookmark "%s"' | |
399 b' (changeset "%s")' | |
400 ) | |
396 % (user, bookmark, ctx) | 401 % (user, bookmark, ctx) |
397 ) | 402 ) |
398 if allowbookmarks and not allowbookmarks(bookmark): | 403 if allowbookmarks and not allowbookmarks(bookmark): |
399 raise error.Abort( | 404 raise error.Abort( |
400 _( | 405 _( |
401 'acl: user "%s" not allowed on bookmark "%s"' | 406 b'acl: user "%s" not allowed on bookmark "%s"' |
402 ' (changeset "%s")' | 407 b' (changeset "%s")' |
403 ) | 408 ) |
404 % (user, bookmark, ctx) | 409 % (user, bookmark, ctx) |
405 ) | 410 ) |
406 ui.debug( | 411 ui.debug( |
407 'acl: bookmark access granted: "%s" on bookmark "%s"\n' | 412 b'acl: bookmark access granted: "%s" on bookmark "%s"\n' |
408 % (ctx, bookmark) | 413 % (ctx, bookmark) |
409 ) | 414 ) |
410 | 415 |
411 | 416 |
412 def _txnhook(ui, repo, hooktype, node, source, user, **kwargs): | 417 def _txnhook(ui, repo, hooktype, node, source, user, **kwargs): |
413 # deprecated config: acl.config | 418 # deprecated config: acl.config |
414 cfg = ui.config('acl', 'config') | 419 cfg = ui.config(b'acl', b'config') |
415 if cfg: | 420 if cfg: |
416 ui.readconfig( | 421 ui.readconfig( |
417 cfg, | 422 cfg, |
418 sections=[ | 423 sections=[ |
419 'acl.groups', | 424 b'acl.groups', |
420 'acl.allow.branches', | 425 b'acl.allow.branches', |
421 'acl.deny.branches', | 426 b'acl.deny.branches', |
422 'acl.allow', | 427 b'acl.allow', |
423 'acl.deny', | 428 b'acl.deny', |
424 ], | 429 ], |
425 ) | 430 ) |
426 | 431 |
427 allowbranches = buildmatch(ui, None, user, 'acl.allow.branches') | 432 allowbranches = buildmatch(ui, None, user, b'acl.allow.branches') |
428 denybranches = buildmatch(ui, None, user, 'acl.deny.branches') | 433 denybranches = buildmatch(ui, None, user, b'acl.deny.branches') |
429 allow = buildmatch(ui, repo, user, 'acl.allow') | 434 allow = buildmatch(ui, repo, user, b'acl.allow') |
430 deny = buildmatch(ui, repo, user, 'acl.deny') | 435 deny = buildmatch(ui, repo, user, b'acl.deny') |
431 | 436 |
432 for rev in pycompat.xrange(repo[node].rev(), len(repo)): | 437 for rev in pycompat.xrange(repo[node].rev(), len(repo)): |
433 ctx = repo[rev] | 438 ctx = repo[rev] |
434 branch = ctx.branch() | 439 branch = ctx.branch() |
435 if denybranches and denybranches(branch): | 440 if denybranches and denybranches(branch): |
436 raise error.Abort( | 441 raise error.Abort( |
437 _('acl: user "%s" denied on branch "%s"' ' (changeset "%s")') | 442 _(b'acl: user "%s" denied on branch "%s"' b' (changeset "%s")') |
438 % (user, branch, ctx) | 443 % (user, branch, ctx) |
439 ) | 444 ) |
440 if allowbranches and not allowbranches(branch): | 445 if allowbranches and not allowbranches(branch): |
441 raise error.Abort( | 446 raise error.Abort( |
442 _( | 447 _( |
443 'acl: user "%s" not allowed on branch "%s"' | 448 b'acl: user "%s" not allowed on branch "%s"' |
444 ' (changeset "%s")' | 449 b' (changeset "%s")' |
445 ) | 450 ) |
446 % (user, branch, ctx) | 451 % (user, branch, ctx) |
447 ) | 452 ) |
448 ui.debug( | 453 ui.debug( |
449 'acl: branch access granted: "%s" on branch "%s"\n' % (ctx, branch) | 454 b'acl: branch access granted: "%s" on branch "%s"\n' % (ctx, branch) |
450 ) | 455 ) |
451 | 456 |
452 for f in ctx.files(): | 457 for f in ctx.files(): |
453 if deny and deny(f): | 458 if deny and deny(f): |
454 raise error.Abort( | 459 raise error.Abort( |
455 _('acl: user "%s" denied on "%s"' ' (changeset "%s")') | 460 _(b'acl: user "%s" denied on "%s"' b' (changeset "%s")') |
456 % (user, f, ctx) | 461 % (user, f, ctx) |
457 ) | 462 ) |
458 if allow and not allow(f): | 463 if allow and not allow(f): |
459 raise error.Abort( | 464 raise error.Abort( |
460 _('acl: user "%s" not allowed on "%s"' ' (changeset "%s")') | 465 _( |
466 b'acl: user "%s" not allowed on "%s"' | |
467 b' (changeset "%s")' | |
468 ) | |
461 % (user, f, ctx) | 469 % (user, f, ctx) |
462 ) | 470 ) |
463 ui.debug('acl: path access granted: "%s"\n' % ctx) | 471 ui.debug(b'acl: path access granted: "%s"\n' % ctx) |