Support HTTP authentication for replication
Gerrit now supports HTTP Basic and Digest authentication when a remote http:// URL is configured for replication. The password can be supplied by secure.config. Change-Id: Id1277ba8d9a8653f1b2f94d8b5fe94323623c5c5 Signed-off-by: Shawn O. Pearce <sop@google.com>
This commit is contained in:
parent
4a11a38b0b
commit
7929d874a0
|
@ -1945,6 +1945,9 @@ Sample `etc/secure.config`:
|
|||
|
||||
[sendemail]
|
||||
smtpPass = sp@m
|
||||
|
||||
[remote "bar"]
|
||||
password = s3kr3t
|
||||
----
|
||||
|
||||
File `etc/replication.config`
|
||||
|
|
|
@ -194,6 +194,24 @@ By default, replicates without group control, i.e replicates
|
|||
everything to all remotes.
|
||||
|
||||
|
||||
[[secure_config]]File `secure.config`
|
||||
-----------------------------------------------
|
||||
|
||||
The optional file `'$site_path'/secure.config` is a Git-style config
|
||||
file that provides secure values that should not be world-readable,
|
||||
such as passwords. Passwords for HTTP remotes can be obtained from
|
||||
this file.
|
||||
|
||||
[[remote.name.username]]remote.<name>.username::
|
||||
+
|
||||
Username to use for HTTP authentication on this remote, if not given
|
||||
in the URL.
|
||||
|
||||
[[remote.name.password]]remote.<name>.password::
|
||||
+
|
||||
Password to use for HTTP authentication on this remote.
|
||||
|
||||
|
||||
[[ssh_config]]File `~/.ssh/config`
|
||||
----------------------------------
|
||||
|
||||
|
|
|
@ -19,7 +19,6 @@ import static com.google.inject.Scopes.SINGLETON;
|
|||
import com.google.gerrit.common.data.ApprovalTypes;
|
||||
import com.google.gerrit.lifecycle.LifecycleListener;
|
||||
import com.google.gerrit.lifecycle.LifecycleModule;
|
||||
import com.google.gerrit.reviewdb.AccountGroup;
|
||||
import com.google.gerrit.reviewdb.AuthType;
|
||||
import com.google.gerrit.reviewdb.Project;
|
||||
import com.google.gerrit.server.AnonymousUser;
|
||||
|
@ -35,12 +34,11 @@ import com.google.gerrit.server.account.AccountInfoCacheFactory;
|
|||
import com.google.gerrit.server.account.DefaultRealm;
|
||||
import com.google.gerrit.server.account.EmailExpander;
|
||||
import com.google.gerrit.server.account.GroupCacheImpl;
|
||||
import com.google.gerrit.server.account.GroupInfoCacheFactory;
|
||||
import com.google.gerrit.server.account.GroupIncludeCacheImpl;
|
||||
import com.google.gerrit.server.account.GroupInfoCacheFactory;
|
||||
import com.google.gerrit.server.account.Realm;
|
||||
import com.google.gerrit.server.auth.ldap.LdapModule;
|
||||
import com.google.gerrit.server.cache.CachePool;
|
||||
import com.google.gerrit.server.config.SitePaths;
|
||||
import com.google.gerrit.server.events.EventFactory;
|
||||
import com.google.gerrit.server.git.ChangeMergeQueue;
|
||||
import com.google.gerrit.server.git.GitRepositoryManager;
|
||||
|
@ -50,6 +48,7 @@ import com.google.gerrit.server.git.PushAllProjectsOp;
|
|||
import com.google.gerrit.server.git.PushReplication;
|
||||
import com.google.gerrit.server.git.ReloadSubmitQueueOp;
|
||||
import com.google.gerrit.server.git.ReplicationQueue;
|
||||
import com.google.gerrit.server.git.SecureCredentialsProvider;
|
||||
import com.google.gerrit.server.git.TransferConfig;
|
||||
import com.google.gerrit.server.git.WorkQueue;
|
||||
import com.google.gerrit.server.mail.EmailSender;
|
||||
|
@ -68,16 +67,13 @@ import com.google.gerrit.server.tools.ToolsCatalog;
|
|||
import com.google.gerrit.server.util.IdGenerator;
|
||||
import com.google.gerrit.server.workflow.FunctionState;
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.TypeLiteral;
|
||||
|
||||
import org.apache.velocity.app.Velocity;
|
||||
import org.apache.velocity.runtime.RuntimeConstants;
|
||||
|
||||
import org.eclipse.jgit.lib.Config;
|
||||
import org.eclipse.jgit.lib.PersonIdent;
|
||||
|
||||
import java.util.Properties;
|
||||
import java.util.Set;
|
||||
|
||||
|
||||
/** Starts global state with standard dependencies. */
|
||||
|
@ -173,6 +169,7 @@ public class GerritGlobalModule extends FactoryModule {
|
|||
bind(TransferConfig.class);
|
||||
|
||||
bind(ReplicationQueue.class).to(PushReplication.class).in(SINGLETON);
|
||||
factory(SecureCredentialsProvider.Factory.class);
|
||||
factory(PushAllProjectsOp.Factory.class);
|
||||
|
||||
bind(MergeQueue.class).to(ChangeMergeQueue.class).in(SINGLETON);
|
||||
|
|
|
@ -15,8 +15,8 @@
|
|||
package com.google.gerrit.server.git;
|
||||
|
||||
import com.google.gerrit.reviewdb.Project;
|
||||
import com.google.gerrit.reviewdb.ReviewDb;
|
||||
import com.google.gerrit.reviewdb.Project.NameKey;
|
||||
import com.google.gerrit.reviewdb.ReviewDb;
|
||||
import com.google.gerrit.server.project.NoSuchProjectException;
|
||||
import com.google.gerrit.server.project.ProjectControl;
|
||||
import com.google.gwtorm.client.OrmException;
|
||||
|
@ -34,6 +34,7 @@ import org.eclipse.jgit.lib.Constants;
|
|||
import org.eclipse.jgit.lib.NullProgressMonitor;
|
||||
import org.eclipse.jgit.lib.Ref;
|
||||
import org.eclipse.jgit.lib.Repository;
|
||||
import org.eclipse.jgit.transport.CredentialsProvider;
|
||||
import org.eclipse.jgit.transport.FetchConnection;
|
||||
import org.eclipse.jgit.transport.PushResult;
|
||||
import org.eclipse.jgit.transport.RefSpec;
|
||||
|
@ -70,6 +71,7 @@ class PushOp implements ProjectRunnable {
|
|||
private final SchemaFactory<ReviewDb> schema;
|
||||
private final PushReplication.ReplicationConfig pool;
|
||||
private final RemoteConfig config;
|
||||
private final CredentialsProvider credentialsProvider;
|
||||
|
||||
private final Set<String> delta = new HashSet<String>();
|
||||
private final Project.NameKey projectName;
|
||||
|
@ -88,11 +90,13 @@ class PushOp implements ProjectRunnable {
|
|||
@Inject
|
||||
PushOp(final GitRepositoryManager grm, final SchemaFactory<ReviewDb> s,
|
||||
final PushReplication.ReplicationConfig p, final RemoteConfig c,
|
||||
final SecureCredentialsProvider.Factory cpFactory,
|
||||
@Assisted final Project.NameKey d, @Assisted final URIish u) {
|
||||
repoManager = grm;
|
||||
schema = s;
|
||||
pool = p;
|
||||
config = c;
|
||||
credentialsProvider = cpFactory.create(c.getName());
|
||||
projectName = d;
|
||||
uri = u;
|
||||
}
|
||||
|
@ -249,6 +253,7 @@ class PushOp implements ProjectRunnable {
|
|||
private PushResult pushVia(final Transport tn) throws IOException,
|
||||
NotSupportedException, TransportException {
|
||||
tn.applyConfig(config);
|
||||
tn.setCredentialsProvider(credentialsProvider);
|
||||
|
||||
final List<RemoteRefUpdate> todo = generateUpdates(tn);
|
||||
if (todo.isEmpty()) {
|
||||
|
|
|
@ -0,0 +1,92 @@
|
|||
// Copyright (C) 2011 The Android Open Source Project
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package com.google.gerrit.server.git;
|
||||
|
||||
import com.google.gerrit.server.config.GerritServerConfig;
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.assistedinject.Assisted;
|
||||
|
||||
import org.eclipse.jgit.errors.UnsupportedCredentialItem;
|
||||
import org.eclipse.jgit.lib.Config;
|
||||
import org.eclipse.jgit.transport.CredentialItem;
|
||||
import org.eclipse.jgit.transport.CredentialsProvider;
|
||||
import org.eclipse.jgit.transport.URIish;
|
||||
|
||||
/** Looks up a remote's password in secure.config. */
|
||||
public class SecureCredentialsProvider extends CredentialsProvider {
|
||||
public interface Factory {
|
||||
SecureCredentialsProvider create(String remoteName);
|
||||
}
|
||||
|
||||
private final String cfgUser;
|
||||
private final String cfgPass;
|
||||
|
||||
@Inject
|
||||
SecureCredentialsProvider(@GerritServerConfig Config cfg,
|
||||
@Assisted String remoteName) {
|
||||
cfgUser = cfg.getString("remote", remoteName, "username");
|
||||
cfgPass = cfg.getString("remote", remoteName, "password");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isInteractive() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supports(CredentialItem... items) {
|
||||
for (CredentialItem i : items) {
|
||||
if (i instanceof CredentialItem.Username) {
|
||||
continue;
|
||||
} else if (i instanceof CredentialItem.Password) {
|
||||
continue;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean get(URIish uri, CredentialItem... items)
|
||||
throws UnsupportedCredentialItem {
|
||||
String username = uri.getUser();
|
||||
if (username == null) {
|
||||
username = cfgUser;
|
||||
}
|
||||
if (username == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
String password = uri.getPass();
|
||||
if (password == null) {
|
||||
password = cfgPass;
|
||||
}
|
||||
if (password == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (CredentialItem i : items) {
|
||||
if (i instanceof CredentialItem.Username) {
|
||||
((CredentialItem.Username) i).setValue(username);
|
||||
} else if (i instanceof CredentialItem.Password) {
|
||||
((CredentialItem.Password) i).setValue(password.toCharArray());
|
||||
} else {
|
||||
throw new UnsupportedCredentialItem(uri, i.getPromptText());
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue