From c56f72b09f1a7f20da2920fae134f76902d2fd76 Mon Sep 17 00:00:00 2001 From: Bruce Zu Date: Thu, 28 Aug 2014 17:21:39 +0800 Subject: [PATCH] Fix: permission on user specific reference name cannot work In ExpandParameters.match() the parameter 'ref' may also contain "${username}", e.g. in ProjectControl.canPerformOnAnyRef() the call on controlForRef() puts in a access section name, in this case 'ref' also need evaluation before doing next match, else it will not be matched and that section is skipped in preparing RefControl.relevant, as a result when a user has PUSH power *only* on that section, Gerrit will reject any upload request from this user. Fixed. evaluate any per-user ref in ExpandParameters.match(). Change-Id: I42c8e15d147eb4ad031b929cf51ccfc1e17a16e3 --- .../server/project/RefPatternMatcher.java | 17 ++++++++++++++--- .../gerrit/server/project/RefControlTest.java | 7 +++++++ 2 files changed, 21 insertions(+), 3 deletions(-) diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/project/RefPatternMatcher.java b/gerrit-server/src/main/java/com/google/gerrit/server/project/RefPatternMatcher.java index dcf684198f..d882e0dac1 100644 --- a/gerrit-server/src/main/java/com/google/gerrit/server/project/RefPatternMatcher.java +++ b/gerrit-server/src/main/java/com/google/gerrit/server/project/RefPatternMatcher.java @@ -110,13 +110,24 @@ public abstract class RefPatternMatcher { u = username; } - RefPatternMatcher next = - getMatcher(template.replace(Collections.singletonMap("username", u))); - return next != null && next.match(ref, username); + RefPatternMatcher next = getMatcher(expand(template, u)); + return next != null ? next.match(expand(ref, u), username) : false; } boolean matchPrefix(String ref) { return ref.startsWith(prefix); } + + private String expand(String parameterizedRef, String userName) { + if (parameterizedRef.contains("${")) { + return expand(new ParameterizedString(parameterizedRef), userName); + } + return parameterizedRef; + } + + private String expand(ParameterizedString parameterizedRef, String userName) { + return parameterizedRef.replace(Collections.singletonMap("username", + userName)); + } } } diff --git a/gerrit-server/src/test/java/com/google/gerrit/server/project/RefControlTest.java b/gerrit-server/src/test/java/com/google/gerrit/server/project/RefControlTest.java index 54765ac558..74156dd226 100644 --- a/gerrit-server/src/test/java/com/google/gerrit/server/project/RefControlTest.java +++ b/gerrit-server/src/test/java/com/google/gerrit/server/project/RefControlTest.java @@ -255,6 +255,13 @@ public class RefControlTest { u.controlForRef("refs/heads/master").canUpload()); } + @Test + public void testUsernamePatternCanUploadToAnyRef() { + grant(local, PUSH, REGISTERED_USERS, "refs/heads/users/${username}/*"); + ProjectControl u = util.user(local, "a-registered-user"); + assertTrue("can upload", u.canPushToAtLeastOneRef() == Capable.OK); + } + @Test public void testUsernamePatternNonRegex() { grant(local, READ, DEVS, "refs/sb/${username}/heads/*");