File hg-r36753.patch of Package mercurial.7756
# HG changeset patch
# User Gregory Szorc <gregory.szorc@gmail.com>
# Date 1519181619 28800
# Tue Feb 20 18:53:39 2018 -0800
# Branch stable
# Node ID 742ce6fbc109cc1d0944292e73fcaa1c7291b90d
# Parent bbd4027b019b07a83fd7d76ee81c8f152f7916df
wireproto: move command permissions dict out of hgweb_mod
The operation type associated with wire protocol commands is supposed
to be defined in a dictionary so it can be used for permissions
checking.
Since this metadata is closely associated with wire protocol commands
themselves, it makes sense to define it in the same module where
wire protocol commands are defined.
This commit moves hgweb_mod.perms to wireproto.PERMISSIONS and
updates most references in the code to use the new home. The old
symbol remains an alias for the new symbol. Tests pass with the
code pointing at the old symbol. So this should be API compatible
for extensions.
As part of the code move, we split up the assignment to the dict
so it is next to the @wireprotocommand. This reinforces that a
@wireprotocommand should have an entry in this dict.
In the future, we'll want to declare permissions as part of the
@wireprotocommand decorator. But this isn't appropriate for the
stable branch.
---
hgext/largefiles/uisetup.py | 7 +++----
mercurial/hgweb/hgweb_mod.py | 12 +++---------
mercurial/wireproto.py | 12 ++++++++++++
3 files changed, 18 insertions(+), 13 deletions(-)
--- a/hgext/largefiles/uisetup.py
+++ b/hgext/largefiles/uisetup.py
@@ -12,7 +12,6 @@ from __future__ import absolute_import
from mercurial.i18n import _
from mercurial.hgweb import (
- hgweb_mod,
webcommands,
)
@@ -177,9 +176,9 @@ def uisetup(ui):
# make putlfile behave the same as push and {get,stat}lfile behave
# the same as pull w.r.t. permissions checks
- hgweb_mod.perms['putlfile'] = 'push'
- hgweb_mod.perms['getlfile'] = 'pull'
- hgweb_mod.perms['statlfile'] = 'pull'
+ wireproto.permissions['putlfile'] = 'push'
+ wireproto.permissions['getlfile'] = 'pull'
+ wireproto.permissions['statlfile'] = 'pull'
extensions.wrapfunction(webcommands, 'decodepath', overrides.decodepath)
--- a/mercurial/hgweb/hgweb_mod.py
+++ b/mercurial/hgweb/hgweb_mod.py
@@ -35,6 +35,7 @@ from .. import (
templater,
ui as uimod,
util,
+ wireproto,
)
from . import (
@@ -44,15 +45,8 @@ from . import (
wsgicgi,
)
-perms = {
- 'changegroup': 'pull',
- 'changegroupsubset': 'pull',
- 'getbundle': 'pull',
- 'stream_out': 'pull',
- 'listkeys': 'pull',
- 'unbundle': 'push',
- 'pushkey': 'push',
-}
+# Aliased for API compatibility.
+perms = wireproto.permissions
archivespecs = util.sortdict((
('zip', ('application/zip', 'zip', '.zip', None)),
--- a/mercurial/wireproto.py
+++ b/mercurial/wireproto.py
@@ -661,6 +661,11 @@ def supportedcompengines(ui, proto, role
# list of commands
commands = {}
+# Maps wire protocol name to operation type. This is used for permissions
+# checking. All defined @wireiprotocommand should have an entry in this
+# dict.
+permissions = {}
+
def wireprotocommand(name, args=''):
"""decorator for wire protocol command"""
def register(func):
@@ -792,12 +797,14 @@ def _capabilities(repo, proto):
def capabilities(repo, proto):
return ' '.join(_capabilities(repo, proto))
+permissions['changegroup'] = 'pull'
@wireprotocommand('changegroup', 'roots')
def changegroup(repo, proto, roots):
nodes = decodelist(roots)
cg = changegroupmod.changegroup(repo, nodes, 'serve')
return streamres(reader=cg, v1compressible=True)
+permissions['changegroupsubset'] = 'pull'
@wireprotocommand('changegroupsubset', 'bases heads')
def changegroupsubset(repo, proto, bases, heads):
bases = decodelist(bases)
@@ -811,6 +818,7 @@ def debugwireargs(repo, proto, one, two,
opts = options('debugwireargs', ['three', 'four'], others)
return repo.debugwireargs(one, two, **opts)
+permissions['getbundle'] = 'pull'
@wireprotocommand('getbundle', '*')
def getbundle(repo, proto, others):
opts = options('getbundle', gboptsmap.keys(), others)
@@ -875,6 +883,7 @@ def hello(repo, proto):
'''
return "capabilities: %s\n" % (capabilities(repo, proto))
+permissions['listkeys'] = 'pull'
@wireprotocommand('listkeys', 'namespace')
def listkeys(repo, proto, namespace):
d = repo.listkeys(encoding.tolocal(namespace)).items()
@@ -896,6 +905,7 @@ def lookup(repo, proto, key):
def known(repo, proto, nodes, others):
return ''.join(b and "1" or "0" for b in repo.known(decodelist(nodes)))
+permissions['pushkey'] = 'push'
@wireprotocommand('pushkey', 'namespace key old new')
def pushkey(repo, proto, namespace, key, old, new):
# compatibility with pre-1.8 clients which were accidentally
@@ -928,6 +938,7 @@ def pushkey(repo, proto, namespace, key,
encoding.tolocal(old), new)
return '%s\n' % int(r)
+permissions['stream_out'] = 'pull'
@wireprotocommand('stream_out')
def stream(repo, proto):
'''If the server supports streaming clone, it advertises the "stream"
@@ -950,6 +961,7 @@ def stream(repo, proto):
except error.LockError:
return '2\n'
+permissions['unbundle'] = 'push'
@wireprotocommand('unbundle', 'heads')
def unbundle(repo, proto, heads):
their_heads = decodelist(heads)