Update the ThreadLocal based scopes to use RequestContext.
Bound the ThreadLocalRequestContext module, which makes the CurrentUser available in the Global module. Removed any binding in the scopes that provided the CurrentUser. Updated all of the scopes to propagate the RequestContext. The PerThreadRequestScope.Propagator allows scoping callables to enter a request context. Change-Id: Idf682ed1d7485cf8c9cdd22cd89bfe1ad5296880
This commit is contained in:
@@ -122,7 +122,7 @@ class CommandFactoryProvider implements Provider<CommandFactory> {
|
||||
|
||||
public void setSession(final ServerSession session) {
|
||||
final SshSession s = session.getAttribute(SshSession.KEY);
|
||||
this.ctx = new Context(s, commandLine);
|
||||
this.ctx = sshScope.newContext(s, commandLine);
|
||||
}
|
||||
|
||||
public void start(final Environment env) throws IOException {
|
||||
|
||||
@@ -173,7 +173,7 @@ class DatabasePubKeyAuth implements PublickeyAuthenticator {
|
||||
// session, record a login event in the log and add
|
||||
// a close listener to record a logout event.
|
||||
//
|
||||
Context ctx = new Context(sd, null);
|
||||
Context ctx = sshScope.newContext(sd, null);
|
||||
Context old = sshScope.set(ctx);
|
||||
try {
|
||||
sshLog.onLogin();
|
||||
@@ -185,7 +185,7 @@ class DatabasePubKeyAuth implements PublickeyAuthenticator {
|
||||
new IoFutureListener<IoFuture>() {
|
||||
@Override
|
||||
public void operationComplete(IoFuture future) {
|
||||
final Context ctx = new Context(sd, null);
|
||||
final Context ctx = sshScope.newContext(sd, null);
|
||||
final Context old = sshScope.set(ctx);
|
||||
try {
|
||||
sshLog.onLogout();
|
||||
|
||||
@@ -89,7 +89,7 @@ class NoShell implements Factory<Command> {
|
||||
}
|
||||
|
||||
public void setSession(final ServerSession session) {
|
||||
this.context = new Context(session.getAttribute(SshSession.KEY), "");
|
||||
this.context = sshScope.newContext(session.getAttribute(SshSession.KEY), "");
|
||||
}
|
||||
|
||||
public void start(final Environment env) throws IOException {
|
||||
|
||||
@@ -1,42 +0,0 @@
|
||||
// Copyright (C) 2010 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.sshd;
|
||||
|
||||
import com.google.gerrit.server.CurrentUser;
|
||||
import com.google.gerrit.server.IdentifiedUser;
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.Provider;
|
||||
import com.google.inject.Singleton;
|
||||
|
||||
@Singleton
|
||||
class SshCurrentUserProvider implements Provider<CurrentUser> {
|
||||
private final Provider<SshSession> session;
|
||||
private final Provider<IdentifiedUser> identifiedProvider;
|
||||
|
||||
@Inject
|
||||
SshCurrentUserProvider(Provider<SshSession> s, Provider<IdentifiedUser> p) {
|
||||
session = s;
|
||||
identifiedProvider = p;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CurrentUser get() {
|
||||
final CurrentUser user = session.get().getCurrentUser();
|
||||
if (user instanceof IdentifiedUser) {
|
||||
return identifiedProvider.get();
|
||||
}
|
||||
return session.get().getCurrentUser();
|
||||
}
|
||||
}
|
||||
@@ -1,47 +0,0 @@
|
||||
// Copyright (C) 2010 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.sshd;
|
||||
|
||||
import com.google.gerrit.common.errors.NotSignedInException;
|
||||
import com.google.gerrit.server.CurrentUser;
|
||||
import com.google.gerrit.server.IdentifiedUser;
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.Provider;
|
||||
import com.google.inject.ProvisionException;
|
||||
import com.google.inject.Singleton;
|
||||
|
||||
@Singleton
|
||||
class SshIdentifiedUserProvider implements Provider<IdentifiedUser> {
|
||||
private final Provider<SshSession> session;
|
||||
private final IdentifiedUser.RequestFactory factory;
|
||||
|
||||
@Inject
|
||||
SshIdentifiedUserProvider(Provider<SshSession> s,
|
||||
IdentifiedUser.RequestFactory f) {
|
||||
session = s;
|
||||
factory = f;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IdentifiedUser get() {
|
||||
final CurrentUser user = session.get().getCurrentUser();
|
||||
if (user instanceof IdentifiedUser) {
|
||||
return factory.create(user.getAccessPath(), //
|
||||
((IdentifiedUser) user).getAccountId());
|
||||
}
|
||||
throw new ProvisionException(NotSignedInException.MESSAGE,
|
||||
new NotSignedInException());
|
||||
}
|
||||
}
|
||||
@@ -152,11 +152,6 @@ public class SshModule extends FactoryModule {
|
||||
bind(SocketAddress.class).annotatedWith(RemotePeer.class).toProvider(
|
||||
SshRemotePeerProvider.class).in(SshScope.REQUEST);
|
||||
|
||||
bind(CurrentUser.class).toProvider(SshCurrentUserProvider.class).in(
|
||||
SshScope.REQUEST);
|
||||
bind(IdentifiedUser.class).toProvider(SshIdentifiedUserProvider.class).in(
|
||||
SshScope.REQUEST);
|
||||
|
||||
bind(WorkQueue.Executor.class).annotatedWith(CommandExecutor.class)
|
||||
.toProvider(CommandExecutorProvider.class).in(SshScope.REQUEST);
|
||||
|
||||
|
||||
@@ -14,8 +14,13 @@
|
||||
|
||||
package com.google.gerrit.sshd;
|
||||
|
||||
import com.google.gerrit.server.CurrentUser;
|
||||
import com.google.gerrit.server.IdentifiedUser;
|
||||
import com.google.gerrit.server.RequestCleanup;
|
||||
import com.google.gerrit.server.util.RequestContext;
|
||||
import com.google.gerrit.server.util.ThreadLocalRequestContext;
|
||||
import com.google.gerrit.server.util.ThreadLocalRequestScopePropagator;
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.Key;
|
||||
import com.google.inject.OutOfScopeException;
|
||||
import com.google.inject.Provider;
|
||||
@@ -26,10 +31,10 @@ import java.util.Map;
|
||||
|
||||
/** Guice scopes for state during an SSH connection. */
|
||||
class SshScope {
|
||||
static class Context {
|
||||
private static final Key<RequestCleanup> RC_KEY =
|
||||
Key.get(RequestCleanup.class);
|
||||
private static final Key<RequestCleanup> RC_KEY =
|
||||
Key.get(RequestCleanup.class);
|
||||
|
||||
class Context implements RequestContext {
|
||||
private final RequestCleanup cleanup;
|
||||
private final SshSession session;
|
||||
private final String commandLine;
|
||||
@@ -56,10 +61,6 @@ class SshScope {
|
||||
finished = p.finished;
|
||||
}
|
||||
|
||||
Context(final SshSession s, final String c) {
|
||||
this(s, c, System.currentTimeMillis());
|
||||
}
|
||||
|
||||
String getCommandLine() {
|
||||
return commandLine;
|
||||
}
|
||||
@@ -68,6 +69,16 @@ class SshScope {
|
||||
return session;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CurrentUser getCurrentUser() {
|
||||
final CurrentUser user = session.getCurrentUser();
|
||||
if (user instanceof IdentifiedUser) {
|
||||
return userFactory.create(user.getAccessPath(), //
|
||||
((IdentifiedUser) user).getAccountId());
|
||||
}
|
||||
return user;
|
||||
}
|
||||
|
||||
synchronized <T> T get(Key<T> key, Provider<T> creator) {
|
||||
@SuppressWarnings("unchecked")
|
||||
T t = (T) map.get(key);
|
||||
@@ -100,15 +111,19 @@ class SshScope {
|
||||
}
|
||||
|
||||
static class Propagator extends ThreadLocalRequestScopePropagator<Context> {
|
||||
Propagator() {
|
||||
super(REQUEST, current);
|
||||
private final SshScope sshScope;
|
||||
|
||||
@Inject
|
||||
Propagator(SshScope sshScope, ThreadLocalRequestContext local) {
|
||||
super(REQUEST, current, local);
|
||||
this.sshScope = sshScope;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Context continuingContext(Context ctx) {
|
||||
// The cleanup is not chained, since the RequestScopePropagator executors
|
||||
// the Context's cleanup when finished executing.
|
||||
return new Context(ctx, ctx.getSession(), ctx.getCommandLine());
|
||||
return sshScope.newContinuingContext(ctx);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -123,9 +138,28 @@ class SshScope {
|
||||
return ctx;
|
||||
}
|
||||
|
||||
private final ThreadLocalRequestContext local;
|
||||
private final IdentifiedUser.RequestFactory userFactory;
|
||||
|
||||
@Inject
|
||||
SshScope(ThreadLocalRequestContext local,
|
||||
IdentifiedUser.RequestFactory userFactory) {
|
||||
this.local = local;
|
||||
this.userFactory = userFactory;
|
||||
}
|
||||
|
||||
Context newContext(SshSession session, String commandLine) {
|
||||
return new Context(session, commandLine, System.currentTimeMillis());
|
||||
}
|
||||
|
||||
private Context newContinuingContext(Context ctx) {
|
||||
return new Context(ctx, ctx.getSession(), ctx.getCommandLine());
|
||||
}
|
||||
|
||||
Context set(Context ctx) {
|
||||
Context old = current.get();
|
||||
current.set(ctx);
|
||||
local.setContext(ctx);
|
||||
return old;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user