Merge branch 'stable-2.10'
* stable-2.10: Remove 2.9.2 fix from 2.10 release notes Fix SubmoduleOp tests Fix quoted-printable encoding of e-mail addresses Fix incorrect submodule subscriptions Remove 'send email' checkbox from reply box on change screen Update system group documentation Consider rule action while constructing local owners list Increase the size of HTTP passwords Do not throw away random bytes from the CSPRNG Change-Id: I915ebcdcc00028b79277e5213cd5618a07efe01a
This commit is contained in:
commit
ae58426e92
@ -11,35 +11,13 @@ users.
|
|||||||
|
|
||||||
Gerrit comes with the following system groups:
|
Gerrit comes with the following system groups:
|
||||||
|
|
||||||
* Administrators
|
|
||||||
* Anonymous Users
|
* Anonymous Users
|
||||||
* Change Owner
|
* Change Owner
|
||||||
* Non-Interactive Users
|
|
||||||
* Project Owners
|
* Project Owners
|
||||||
* Registered Users
|
* Registered Users
|
||||||
|
|
||||||
The system groups are assigned special access and membership management
|
The system groups are assigned special access and membership management
|
||||||
privileges. The identity of these groups is set in the `system_config`
|
privileges.
|
||||||
table within the database, so the groups can be renamed after installation
|
|
||||||
if desired.
|
|
||||||
|
|
||||||
|
|
||||||
[[administrators]]
|
|
||||||
=== Administrators
|
|
||||||
|
|
||||||
This is the Gerrit "root" identity.
|
|
||||||
|
|
||||||
Users in the 'Administrators' group can perform any action under
|
|
||||||
the Admin menu, to any group or project, without further validation
|
|
||||||
or any other access controls. In most installations only those
|
|
||||||
users who have direct filesystem and database access would be
|
|
||||||
placed into this group.
|
|
||||||
|
|
||||||
Membership in the 'Administrators' group does not imply any other
|
|
||||||
access rights. Administrators do not automatically get code review
|
|
||||||
approval or submit rights in projects. This is a feature designed
|
|
||||||
to permit administrative users to otherwise access Gerrit as any
|
|
||||||
other normal user would, without needing two different accounts.
|
|
||||||
|
|
||||||
|
|
||||||
[[anonymous_users]]
|
[[anonymous_users]]
|
||||||
@ -57,21 +35,6 @@ to grant `Read` access to this group as Gerrit requires an account
|
|||||||
identity for all other operations.
|
identity for all other operations.
|
||||||
|
|
||||||
|
|
||||||
[[non-interactive_users]]
|
|
||||||
=== Non-Interactive Users
|
|
||||||
|
|
||||||
This is an internal user group, members of this group are not expected
|
|
||||||
to perform interactive operations on the Gerrit web front-end.
|
|
||||||
|
|
||||||
However, sometimes such a user may need a separate thread pool in
|
|
||||||
order to prevent it from grabbing threads from the interactive users.
|
|
||||||
|
|
||||||
These users live in a second thread pool, which separates operations
|
|
||||||
made by the non-interactive users from the ones made by the interactive
|
|
||||||
users. This ensures that the interactive users can keep working when
|
|
||||||
resources are tight.
|
|
||||||
|
|
||||||
|
|
||||||
[[project_owners]]
|
[[project_owners]]
|
||||||
=== Project Owners
|
=== Project Owners
|
||||||
|
|
||||||
@ -120,6 +83,59 @@ Registered users are always permitted to make and publish comments
|
|||||||
on any change in any project they have `Read` access to.
|
on any change in any project they have `Read` access to.
|
||||||
|
|
||||||
|
|
||||||
|
== Predefined Groups
|
||||||
|
|
||||||
|
Predefined groups differs from system groups by the fact that they
|
||||||
|
exist in the ACCOUNT_GROUPS table (like normal groups) but predefined groups
|
||||||
|
are created on Gerrit site initialization and unique UUIDs are assigned
|
||||||
|
to those groups. These UUIDs are different on different Gerrit sites.
|
||||||
|
|
||||||
|
Gerrit comes with two predefined groups:
|
||||||
|
|
||||||
|
* Administrators
|
||||||
|
* Non-Interactive Users
|
||||||
|
|
||||||
|
|
||||||
|
[[administrators]]
|
||||||
|
=== Administrators
|
||||||
|
|
||||||
|
This is the Gerrit "root" identity. The capability
|
||||||
|
link:access-control.html#capability_administrateServer['Administrate Server']
|
||||||
|
is assigned to this predefined group on Gerrit site creation.
|
||||||
|
|
||||||
|
Users in the 'Administrators' group can perform any action under
|
||||||
|
the Admin menu, to any group or project, without further validation
|
||||||
|
or any other access controls. In most installations only those
|
||||||
|
users who have direct filesystem and database access would be
|
||||||
|
placed into this group.
|
||||||
|
|
||||||
|
Membership in the 'Administrators' group does not imply any other
|
||||||
|
access rights. Administrators do not automatically get code review
|
||||||
|
approval or submit rights in projects. This is a feature designed
|
||||||
|
to permit administrative users to otherwise access Gerrit as any
|
||||||
|
other normal user would, without needing two different accounts.
|
||||||
|
|
||||||
|
|
||||||
|
[[non-interactive_users]]
|
||||||
|
=== Non-Interactive Users
|
||||||
|
|
||||||
|
This is the Gerrit "batch" identity. The capabilities
|
||||||
|
link:access-control.html#capability_priority['Priority BATCH'] and
|
||||||
|
link:access-control.html#capability_streamEvents['Stream Events']
|
||||||
|
are assigned to this predefined group on Gerrit site creation.
|
||||||
|
|
||||||
|
The members of this group are not expected to perform interactive
|
||||||
|
operations on the Gerrit web front-end.
|
||||||
|
|
||||||
|
However, sometimes such a user may need a separate thread pool in
|
||||||
|
order to prevent it from grabbing threads from the interactive users.
|
||||||
|
|
||||||
|
These users live in a second thread pool, which separates operations
|
||||||
|
made by the non-interactive users from the ones made by the interactive
|
||||||
|
users. This ensures that the interactive users can keep working when
|
||||||
|
resources are tight.
|
||||||
|
|
||||||
|
|
||||||
== Account Groups
|
== Account Groups
|
||||||
|
|
||||||
Account groups contain a list of zero or more user account members,
|
Account groups contain a list of zero or more user account members,
|
||||||
|
@ -269,7 +269,7 @@ Retrieves the HTTP password of an account.
|
|||||||
Content-Type: application/json;charset=UTF-8
|
Content-Type: application/json;charset=UTF-8
|
||||||
|
|
||||||
)]}'
|
)]}'
|
||||||
"ETxgpih8xrNs"
|
"Qmxlc21ydCB1YmVyIGFsbGVzIGluIGRlciBXZWx0IQ"
|
||||||
----
|
----
|
||||||
|
|
||||||
If the account does not have an HTTP password the response is `404 Not Found`.
|
If the account does not have an HTTP password the response is `404 Not Found`.
|
||||||
|
@ -76,8 +76,6 @@ Change Screen
|
|||||||
^^^^^^^^^^^^^
|
^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
|
||||||
* Remove 'send email' checkbox from reply box on change screen.
|
|
||||||
|
|
||||||
* Do not linkify trailing dot or comma in messages.
|
* Do not linkify trailing dot or comma in messages.
|
||||||
+
|
+
|
||||||
As linkifying trailing dots and trailing commas does more harm than
|
As linkifying trailing dots and trailing commas does more harm than
|
||||||
|
@ -45,7 +45,7 @@ public class PutHttpPassword implements RestModifyView<AccountResource, Input> {
|
|||||||
public boolean generate;
|
public boolean generate;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final int LEN = 12;
|
private static final int LEN = 31;
|
||||||
private static final SecureRandom rng;
|
private static final SecureRandom rng;
|
||||||
|
|
||||||
static {
|
static {
|
||||||
@ -126,8 +126,8 @@ public class PutHttpPassword implements RestModifyView<AccountResource, Input> {
|
|||||||
rng.nextBytes(rand);
|
rng.nextBytes(rand);
|
||||||
|
|
||||||
byte[] enc = Base64.encodeBase64(rand, false);
|
byte[] enc = Base64.encodeBase64(rand, false);
|
||||||
StringBuilder r = new StringBuilder(LEN);
|
StringBuilder r = new StringBuilder(enc.length);
|
||||||
for (int i = 0; i < LEN; i++) {
|
for (int i = 0; i < enc.length; i++) {
|
||||||
if (enc[i] == '=') {
|
if (enc[i] == '=') {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -70,6 +70,7 @@ import com.google.gerrit.reviewdb.client.PatchSetInfo;
|
|||||||
import com.google.gerrit.reviewdb.client.Project;
|
import com.google.gerrit.reviewdb.client.Project;
|
||||||
import com.google.gerrit.reviewdb.client.RefNames;
|
import com.google.gerrit.reviewdb.client.RefNames;
|
||||||
import com.google.gerrit.reviewdb.client.RevId;
|
import com.google.gerrit.reviewdb.client.RevId;
|
||||||
|
import com.google.gerrit.reviewdb.client.SubmoduleSubscription;
|
||||||
import com.google.gerrit.reviewdb.server.ReviewDb;
|
import com.google.gerrit.reviewdb.server.ReviewDb;
|
||||||
import com.google.gerrit.server.ApprovalCopier;
|
import com.google.gerrit.server.ApprovalCopier;
|
||||||
import com.google.gerrit.server.ApprovalsUtil;
|
import com.google.gerrit.server.ApprovalsUtil;
|
||||||
@ -607,6 +608,17 @@ public class ReceiveCommits {
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case DELETE:
|
case DELETE:
|
||||||
|
ResultSet<SubmoduleSubscription> submoduleSubscriptions = null;
|
||||||
|
Branch.NameKey projRef = new Branch.NameKey(project.getNameKey(),
|
||||||
|
c.getRefName());
|
||||||
|
try {
|
||||||
|
submoduleSubscriptions =
|
||||||
|
db.submoduleSubscriptions().bySuperProject(projRef);
|
||||||
|
db.submoduleSubscriptions().delete(submoduleSubscriptions);
|
||||||
|
} catch (OrmException e) {
|
||||||
|
log.error("Cannot delete submodule subscription(s) of branch "
|
||||||
|
+ projRef + ": " + submoduleSubscriptions, e);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -15,6 +15,7 @@
|
|||||||
package com.google.gerrit.server.git;
|
package com.google.gerrit.server.git;
|
||||||
|
|
||||||
import com.google.common.base.Strings;
|
import com.google.common.base.Strings;
|
||||||
|
import com.google.common.collect.Lists;
|
||||||
import com.google.gerrit.common.ChangeHooks;
|
import com.google.gerrit.common.ChangeHooks;
|
||||||
import com.google.gerrit.common.Nullable;
|
import com.google.gerrit.common.Nullable;
|
||||||
import com.google.gerrit.reviewdb.client.Account;
|
import com.google.gerrit.reviewdb.client.Account;
|
||||||
@ -233,10 +234,11 @@ public class SubmoduleOp {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// update subscribers of this module
|
// update subscribers of this module
|
||||||
|
List<SubmoduleSubscription> incorrectSubscriptions = Lists.newLinkedList();
|
||||||
for (final SubmoduleSubscription s : subscribers) {
|
for (final SubmoduleSubscription s : subscribers) {
|
||||||
|
try {
|
||||||
if (!updatedSubscribers.add(s.getSuperProject())) {
|
if (!updatedSubscribers.add(s.getSuperProject())) {
|
||||||
log.error("Possible circular subscription involving "
|
log.error("Possible circular subscription involving " + s);
|
||||||
+ s.toString());
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
Map<Branch.NameKey, ObjectId> modules = new HashMap<>(1);
|
Map<Branch.NameKey, ObjectId> modules = new HashMap<>(1);
|
||||||
@ -244,12 +246,24 @@ public class SubmoduleOp {
|
|||||||
|
|
||||||
Map<Branch.NameKey, String> paths = new HashMap<>(1);
|
Map<Branch.NameKey, String> paths = new HashMap<>(1);
|
||||||
paths.put(updatedBranch, s.getPath());
|
paths.put(updatedBranch, s.getPath());
|
||||||
|
|
||||||
try {
|
|
||||||
updateGitlinks(s.getSuperProject(), myRw, modules, paths, msgbuf);
|
updateGitlinks(s.getSuperProject(), myRw, modules, paths, msgbuf);
|
||||||
} catch (SubmoduleException e) {
|
|
||||||
throw e;
|
|
||||||
}
|
}
|
||||||
|
} catch (SubmoduleException e) {
|
||||||
|
log.warn("Cannot update gitlinks for " + s + " due to " + e.getMessage());
|
||||||
|
incorrectSubscriptions.add(s);
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("Cannot update gitlinks for " + s, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!incorrectSubscriptions.isEmpty()) {
|
||||||
|
try {
|
||||||
|
schema.submoduleSubscriptions().delete(incorrectSubscriptions);
|
||||||
|
log.info("Deleted incorrect submodule subscription(s) "
|
||||||
|
+ incorrectSubscriptions);
|
||||||
|
} catch (OrmException e) {
|
||||||
|
log.error("Cannot delete submodule subscription(s) "
|
||||||
|
+ incorrectSubscriptions, e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -366,7 +380,7 @@ public class SubmoduleOp {
|
|||||||
// Recursive call: update subscribers of the subscriber
|
// Recursive call: update subscribers of the subscriber
|
||||||
updateSuperProjects(subscriber, recRw, commitId, msgbuf.toString());
|
updateSuperProjects(subscriber, recRw, commitId, msgbuf.toString());
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
logAndThrowSubmoduleException("Cannot update gitlinks for "
|
throw new SubmoduleException("Cannot update gitlinks for "
|
||||||
+ subscriber.get(), e);
|
+ subscriber.get(), e);
|
||||||
} finally {
|
} finally {
|
||||||
if (recRw != null) {
|
if (recRw != null) {
|
||||||
|
@ -64,23 +64,47 @@ public abstract class EmailHeader {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static boolean needsQuotedPrintableWithinPhrase(final int cp) {
|
||||||
|
switch (cp) {
|
||||||
|
case '!':
|
||||||
|
case '*':
|
||||||
|
case '+':
|
||||||
|
case '-':
|
||||||
|
case '/':
|
||||||
|
case '=':
|
||||||
|
case '_':
|
||||||
|
return false;
|
||||||
|
default:
|
||||||
|
if (('a' <= cp && cp <= 'z')
|
||||||
|
|| ('A' <= cp && cp <= 'Z')
|
||||||
|
|| ('0' <= cp && cp <= '9')) {
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static java.lang.String quotedPrintable(java.lang.String value)
|
static java.lang.String quotedPrintable(java.lang.String value)
|
||||||
throws UnsupportedEncodingException {
|
throws UnsupportedEncodingException {
|
||||||
final StringBuilder r = new StringBuilder();
|
final StringBuilder r = new StringBuilder();
|
||||||
final byte[] encoded = value.getBytes("UTF-8");
|
|
||||||
|
|
||||||
r.append("=?UTF-8?Q?");
|
r.append("=?UTF-8?Q?");
|
||||||
for (byte b : encoded) {
|
for (int i = 0; i < value.length(); i++) {
|
||||||
if (b == ' ') {
|
final int cp = value.codePointAt(i);
|
||||||
|
if (cp == ' ') {
|
||||||
r.append('_');
|
r.append('_');
|
||||||
|
|
||||||
} else if (b == ',' || b == '=' || b == '"' || b == '_' || b < ' ' || '~' <= b) {
|
} else if (needsQuotedPrintableWithinPhrase(cp)) {
|
||||||
|
byte[] buf = new java.lang.String(Character.toChars(cp)).getBytes("UTF-8");
|
||||||
|
for (byte b: buf) {
|
||||||
r.append('=');
|
r.append('=');
|
||||||
r.append(Integer.toHexString((b >>> 4) & 0x0f).toUpperCase());
|
r.append(Integer.toHexString((b >>> 4) & 0x0f).toUpperCase());
|
||||||
r.append(Integer.toHexString(b & 0x0f).toUpperCase());
|
r.append(Integer.toHexString(b & 0x0f).toUpperCase());
|
||||||
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
r.append((char) b);
|
r.append(Character.toChars(cp));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
r.append("?=");
|
r.append("?=");
|
||||||
|
@ -19,12 +19,14 @@ import com.google.gerrit.extensions.restapi.AuthException;
|
|||||||
import com.google.gerrit.extensions.restapi.ResourceConflictException;
|
import com.google.gerrit.extensions.restapi.ResourceConflictException;
|
||||||
import com.google.gerrit.extensions.restapi.Response;
|
import com.google.gerrit.extensions.restapi.Response;
|
||||||
import com.google.gerrit.extensions.restapi.RestModifyView;
|
import com.google.gerrit.extensions.restapi.RestModifyView;
|
||||||
|
import com.google.gerrit.reviewdb.client.SubmoduleSubscription;
|
||||||
import com.google.gerrit.reviewdb.server.ReviewDb;
|
import com.google.gerrit.reviewdb.server.ReviewDb;
|
||||||
import com.google.gerrit.server.IdentifiedUser;
|
import com.google.gerrit.server.IdentifiedUser;
|
||||||
import com.google.gerrit.server.extensions.events.GitReferenceUpdated;
|
import com.google.gerrit.server.extensions.events.GitReferenceUpdated;
|
||||||
import com.google.gerrit.server.git.GitRepositoryManager;
|
import com.google.gerrit.server.git.GitRepositoryManager;
|
||||||
import com.google.gerrit.server.project.DeleteBranch.Input;
|
import com.google.gerrit.server.project.DeleteBranch.Input;
|
||||||
import com.google.gwtorm.server.OrmException;
|
import com.google.gwtorm.server.OrmException;
|
||||||
|
import com.google.gwtorm.server.ResultSet;
|
||||||
import com.google.inject.Inject;
|
import com.google.inject.Inject;
|
||||||
import com.google.inject.Provider;
|
import com.google.inject.Provider;
|
||||||
import com.google.inject.Singleton;
|
import com.google.inject.Singleton;
|
||||||
@ -92,6 +94,9 @@ public class DeleteBranch implements RestModifyView<BranchResource, Input>{
|
|||||||
case FORCED:
|
case FORCED:
|
||||||
referenceUpdated.fire(rsrc.getNameKey(), u);
|
referenceUpdated.fire(rsrc.getNameKey(), u);
|
||||||
hooks.doRefUpdatedHook(rsrc.getBranchKey(), u, identifiedUser.get().getAccount());
|
hooks.doRefUpdatedHook(rsrc.getBranchKey(), u, identifiedUser.get().getAccount());
|
||||||
|
ResultSet<SubmoduleSubscription> submoduleSubscriptions =
|
||||||
|
dbProvider.get().submoduleSubscriptions().bySuperProject(rsrc.getBranchKey());
|
||||||
|
dbProvider.get().submoduleSubscriptions().delete(submoduleSubscriptions);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case REJECTED_CURRENT_BRANCH:
|
case REJECTED_CURRENT_BRANCH:
|
||||||
|
@ -14,6 +14,7 @@
|
|||||||
|
|
||||||
package com.google.gerrit.server.project;
|
package com.google.gerrit.server.project;
|
||||||
|
|
||||||
|
import static com.google.gerrit.common.data.PermissionRule.Action.ALLOW;
|
||||||
import static java.nio.charset.StandardCharsets.UTF_8;
|
import static java.nio.charset.StandardCharsets.UTF_8;
|
||||||
|
|
||||||
import com.google.common.base.Function;
|
import com.google.common.base.Function;
|
||||||
@ -140,7 +141,7 @@ public class ProjectState {
|
|||||||
if (owner != null) {
|
if (owner != null) {
|
||||||
for (PermissionRule rule : owner.getRules()) {
|
for (PermissionRule rule : owner.getRules()) {
|
||||||
GroupReference ref = rule.getGroup();
|
GroupReference ref = rule.getGroup();
|
||||||
if (ref.getUUID() != null) {
|
if (rule.getAction() == ALLOW && ref.getUUID() != null) {
|
||||||
groups.add(ref.getUUID());
|
groups.add(ref.getUUID());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -14,13 +14,10 @@
|
|||||||
|
|
||||||
package com.google.gerrit.server.git;
|
package com.google.gerrit.server.git;
|
||||||
|
|
||||||
|
import static org.easymock.EasyMock.anyObject;
|
||||||
import static org.easymock.EasyMock.capture;
|
import static org.easymock.EasyMock.capture;
|
||||||
import static org.easymock.EasyMock.createNiceMock;
|
|
||||||
import static org.easymock.EasyMock.createStrictMock;
|
|
||||||
import static org.easymock.EasyMock.eq;
|
import static org.easymock.EasyMock.eq;
|
||||||
import static org.easymock.EasyMock.expect;
|
import static org.easymock.EasyMock.expect;
|
||||||
import static org.easymock.EasyMock.replay;
|
|
||||||
import static org.easymock.EasyMock.verify;
|
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.Assert.assertEquals;
|
||||||
|
|
||||||
import com.google.gerrit.common.ChangeHooks;
|
import com.google.gerrit.common.ChangeHooks;
|
||||||
@ -41,6 +38,8 @@ import com.google.gwtorm.server.StandardKeyEncoder;
|
|||||||
import com.google.inject.Provider;
|
import com.google.inject.Provider;
|
||||||
|
|
||||||
import org.easymock.Capture;
|
import org.easymock.Capture;
|
||||||
|
import org.easymock.EasyMock;
|
||||||
|
import org.easymock.IMocksControl;
|
||||||
import org.eclipse.jgit.api.Git;
|
import org.eclipse.jgit.api.Git;
|
||||||
import org.eclipse.jgit.dircache.DirCacheBuilder;
|
import org.eclipse.jgit.dircache.DirCacheBuilder;
|
||||||
import org.eclipse.jgit.dircache.DirCacheEntry;
|
import org.eclipse.jgit.dircache.DirCacheEntry;
|
||||||
@ -75,6 +74,7 @@ public class SubmoduleOpTest extends LocalDiskRepositoryTestCase {
|
|||||||
|
|
||||||
private static final String newLine = System.getProperty("line.separator");
|
private static final String newLine = System.getProperty("line.separator");
|
||||||
|
|
||||||
|
private IMocksControl mockMaker;
|
||||||
private SchemaFactory<ReviewDb> schemaFactory;
|
private SchemaFactory<ReviewDb> schemaFactory;
|
||||||
private SubmoduleSubscriptionAccess subscriptions;
|
private SubmoduleSubscriptionAccess subscriptions;
|
||||||
private ReviewDb schema;
|
private ReviewDb schema;
|
||||||
@ -89,23 +89,22 @@ public class SubmoduleOpTest extends LocalDiskRepositoryTestCase {
|
|||||||
public void setUp() throws Exception {
|
public void setUp() throws Exception {
|
||||||
super.setUp();
|
super.setUp();
|
||||||
|
|
||||||
schemaFactory = createStrictMock(SchemaFactory.class);
|
mockMaker = EasyMock.createStrictControl();
|
||||||
schema = createStrictMock(ReviewDb.class);
|
schemaFactory = mockMaker.createMock(SchemaFactory.class);
|
||||||
subscriptions = createStrictMock(SubmoduleSubscriptionAccess.class);
|
schema = mockMaker.createMock(ReviewDb.class);
|
||||||
urlProvider = createStrictMock(Provider.class);
|
subscriptions = mockMaker.createMock(SubmoduleSubscriptionAccess.class);
|
||||||
repoManager = createStrictMock(GitRepositoryManager.class);
|
urlProvider = mockMaker.createMock(Provider.class);
|
||||||
gitRefUpdated = createStrictMock(GitReferenceUpdated.class);
|
repoManager = mockMaker.createMock(GitRepositoryManager.class);
|
||||||
changeHooks = createNiceMock(ChangeHooks.class);
|
gitRefUpdated = mockMaker.createMock(GitReferenceUpdated.class);
|
||||||
|
changeHooks = mockMaker.createMock(ChangeHooks.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void doReplay() {
|
private void doReplay() {
|
||||||
replay(schemaFactory, schema, subscriptions, urlProvider, repoManager,
|
mockMaker.replay();
|
||||||
gitRefUpdated);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void doVerify() {
|
private void doVerify() {
|
||||||
verify(schemaFactory, schema, subscriptions, urlProvider, repoManager,
|
mockMaker.verify();
|
||||||
gitRefUpdated);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -640,6 +639,8 @@ public class SubmoduleOpTest extends LocalDiskRepositoryTestCase {
|
|||||||
Capture<RefUpdate> ruCapture = new Capture<>();
|
Capture<RefUpdate> ruCapture = new Capture<>();
|
||||||
gitRefUpdated.fire(eq(targetBranchNameKey.getParentKey()),
|
gitRefUpdated.fire(eq(targetBranchNameKey.getParentKey()),
|
||||||
capture(ruCapture));
|
capture(ruCapture));
|
||||||
|
changeHooks.doRefUpdatedHook(eq(targetBranchNameKey),
|
||||||
|
anyObject(RefUpdate.class), EasyMock.<Account>isNull());
|
||||||
|
|
||||||
expect(schema.submoduleSubscriptions()).andReturn(subscriptions);
|
expect(schema.submoduleSubscriptions()).andReturn(subscriptions);
|
||||||
final ResultSet<SubmoduleSubscription> emptySubscriptions =
|
final ResultSet<SubmoduleSubscription> emptySubscriptions =
|
||||||
@ -743,6 +744,8 @@ public class SubmoduleOpTest extends LocalDiskRepositoryTestCase {
|
|||||||
Capture<RefUpdate> ruCapture = new Capture<>();
|
Capture<RefUpdate> ruCapture = new Capture<>();
|
||||||
gitRefUpdated.fire(eq(targetBranchNameKey.getParentKey()),
|
gitRefUpdated.fire(eq(targetBranchNameKey.getParentKey()),
|
||||||
capture(ruCapture));
|
capture(ruCapture));
|
||||||
|
changeHooks.doRefUpdatedHook(eq(targetBranchNameKey),
|
||||||
|
anyObject(RefUpdate.class), EasyMock.<Account>isNull());
|
||||||
|
|
||||||
expect(schema.submoduleSubscriptions()).andReturn(subscriptions);
|
expect(schema.submoduleSubscriptions()).andReturn(subscriptions);
|
||||||
final ResultSet<SubmoduleSubscription> incorrectSubscriptions =
|
final ResultSet<SubmoduleSubscription> incorrectSubscriptions =
|
||||||
|
@ -130,6 +130,12 @@ public class AddressTest {
|
|||||||
assertEquals("=?UTF-8?Q?A_=E2=82=AC_B?= <a@a>", format("A \u20ac B", "a@a"));
|
assertEquals("=?UTF-8?Q?A_=E2=82=AC_B?= <a@a>", format("A \u20ac B", "a@a"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testToHeaderString_NameEmail7() {
|
||||||
|
assertEquals("=?UTF-8?Q?A_=E2=82=AC_B_=28Code_Review=29?= <a@a>",
|
||||||
|
format("A \u20ac B (Code Review)", "a@a"));
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testToHeaderString_Email1() {
|
public void testToHeaderString_Email1() {
|
||||||
assertEquals("a@a", format(null, "a@a"));
|
assertEquals("a@a", format(null, "a@a"));
|
||||||
|
@ -79,11 +79,23 @@ public class RefControlTest {
|
|||||||
public void testOwnerProject() {
|
public void testOwnerProject() {
|
||||||
allow(local, OWNER, ADMIN, "refs/*");
|
allow(local, OWNER, ADMIN, "refs/*");
|
||||||
|
|
||||||
ProjectControl uBlah = util.user(local, DEVS);
|
assertAdminsAreOwnersAndDevsAreNot();
|
||||||
ProjectControl uAdmin = util.user(local, DEVS, ADMIN);
|
}
|
||||||
|
|
||||||
assertFalse("not owner", uBlah.isOwner());
|
@Test
|
||||||
assertTrue("is owner", uAdmin.isOwner());
|
public void testDenyOwnerProject() {
|
||||||
|
allow(local, OWNER, ADMIN, "refs/*");
|
||||||
|
deny(local, OWNER, DEVS, "refs/*");
|
||||||
|
|
||||||
|
assertAdminsAreOwnersAndDevsAreNot();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testBlockOwnerProject() {
|
||||||
|
allow(local, OWNER, ADMIN, "refs/*");
|
||||||
|
block(local, OWNER, DEVS, "refs/*");
|
||||||
|
|
||||||
|
assertAdminsAreOwnersAndDevsAreNot();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@ -527,4 +539,12 @@ public class RefControlTest {
|
|||||||
assertFalse("u can vote -2", range.contains(-2));
|
assertFalse("u can vote -2", range.contains(-2));
|
||||||
assertFalse("u can vote +2", range.contains(2));
|
assertFalse("u can vote +2", range.contains(2));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void assertAdminsAreOwnersAndDevsAreNot() {
|
||||||
|
ProjectControl uBlah = util.user(local, DEVS);
|
||||||
|
ProjectControl uAdmin = util.user(local, DEVS, ADMIN);
|
||||||
|
|
||||||
|
assertFalse("not owner", uBlah.isOwner());
|
||||||
|
assertTrue("is owner", uAdmin.isOwner());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user