From 426edf6ad729ba4ba37aa0a1d6ccbadc5eb965fb Mon Sep 17 00:00:00 2001 From: Ray Greenwell Date: Tue, 25 Jul 2006 19:02:48 +0000 Subject: [PATCH] Moved some of the standard work done by Authenticators into the base class. git-svn-id: svn+ssh://src.earth.threerings.net/narya/trunk@4291 542714f4-19e9-0310-aa3c-eee0fc999fb1 --- .../peer/server/PeerAuthenticator.java | 45 ++++++-- .../presents/server/Authenticator.java | 103 ++++++++++++++---- .../presents/server/DummyAuthenticator.java | 27 +++-- .../threerings/presents/server/Rejector.java | 29 +++-- 4 files changed, 153 insertions(+), 51 deletions(-) diff --git a/src/java/com/threerings/presents/peer/server/PeerAuthenticator.java b/src/java/com/threerings/presents/peer/server/PeerAuthenticator.java index 7727493f6..c3200838e 100644 --- a/src/java/com/threerings/presents/peer/server/PeerAuthenticator.java +++ b/src/java/com/threerings/presents/peer/server/PeerAuthenticator.java @@ -21,6 +21,10 @@ package com.threerings.presents.peer.server; +import com.samskivert.io.PersistenceException; + +import com.samskivert.util.Invoker; + import com.threerings.presents.data.AuthCodes; import com.threerings.presents.net.AuthRequest; @@ -49,22 +53,13 @@ public class PeerAuthenticator extends Authenticator _delegate = delegate; } - @Override // documentation inherited + @Override public void authenticateConnection (AuthingConnection conn) { // if this is a peer server, we check their credentials specially AuthRequest req = conn.getAuthRequest(); if (req.getCredentials() instanceof PeerCreds) { - AuthResponse rsp = new AuthResponse(new AuthResponseData()); - PeerCreds pcreds = (PeerCreds)req.getCredentials(); - if (_peermgr.isAuthenticPeer(pcreds)) { - rsp.getData().code = AuthResponseData.SUCCESS; - } else { - log.warning("Received invalid peer auth request? " + - "[creds=" + pcreds + "]."); - rsp.getData().code = AuthCodes.SERVER_ERROR; - } - connectionWasAuthenticated(conn, rsp); + super.authenticateConnection(conn); } else { // otherwise pass the request on to our delegate @@ -72,6 +67,34 @@ public class PeerAuthenticator extends Authenticator } } + @Override + protected Invoker getInvoker () + { + // The processing of peer authentication happens inline, + // but other authentication will use the _delegate which will + // probably use an Invoker. + return null; + } + + // from abstract Authenticator + protected void processAuthentication ( + AuthingConnection conn, AuthResponse rsp) + throws PersistenceException + { + // here, we are ONLY authenticating peers + AuthRequest req = conn.getAuthRequest(); + PeerCreds pcreds = (PeerCreds) req.getCredentials(); + + if (_peermgr.isAuthenticPeer(pcreds)) { + rsp.getData().code = AuthResponseData.SUCCESS; + + } else { + log.warning("Received invalid peer auth request? " + + "[creds=" + pcreds + "]."); + rsp.getData().code = AuthCodes.SERVER_ERROR; + } + } + protected PeerManager _peermgr; protected Authenticator _delegate; } diff --git a/src/java/com/threerings/presents/server/Authenticator.java b/src/java/com/threerings/presents/server/Authenticator.java index a955a7d9f..0fa20589c 100644 --- a/src/java/com/threerings/presents/server/Authenticator.java +++ b/src/java/com/threerings/presents/server/Authenticator.java @@ -21,12 +21,23 @@ package com.threerings.presents.server; +import java.util.logging.Level; + +import com.samskivert.io.PersistenceException; + +import com.samskivert.util.Invoker; + +import com.threerings.presents.data.AuthCodes; + +import com.threerings.presents.net.AuthRequest; import com.threerings.presents.net.AuthResponse; import com.threerings.presents.net.AuthResponseData; import com.threerings.presents.server.net.AuthingConnection; import com.threerings.presents.server.net.ConnectionManager; +import static com.threerings.presents.Log.log; + /** * The authenticator is a pluggable component of the authentication * framework. The base class handles the basic mechanics of authentication @@ -47,28 +58,27 @@ public abstract class Authenticator /** * Called by the connection management code when an authenticating * connection has received its authentication request from the client. - * This method must return immediately as it is called on the - * connection manager thread. If it is possible to authenticate the - * connection immediately, it may do so, but more likely it will fire - * off a task on the {@link PresentsServer#invoker} to perform the - * authentication. When the authentication is complete, the - * authenticator implementation should call {@link - * #connectionWasAuthenticated}. */ - public abstract void authenticateConnection (AuthingConnection conn); - - /** - * This is called by authenticator implementations when they have - * completed the authentication process. It will deliver the response - * to the user and let the connection manager know to report the - * authentication if it succeeded. - */ - protected void connectionWasAuthenticated ( - final AuthingConnection conn, final AuthResponse rsp) + public void authenticateConnection (final AuthingConnection conn) { - // make double plus extra sure we're on the omgr thread - PresentsServer.omgr.postRunnable(new Runnable() { - public void run () { + final AuthRequest req = conn.getAuthRequest(); + final AuthResponseData rdata = createResponseData(); + final AuthResponse rsp = new AuthResponse(rdata); + + Invoker.Unit unit = new Invoker.Unit("auth:" + req.getCredentials()) { + public boolean invoke() { + try { + processAuthentication(conn, rsp); + + } catch (Exception e) { // Persistence or Runtime + log.log(Level.WARNING, "Error authenticating user " + + "[areq=" + req + "].", e); + rdata.code = AuthCodes.SERVER_ERROR; + } + return true; + } + + public void handleResult () { // stuff a reference to the auth response into the // connection so that we have access to it later in the // authentication process @@ -79,13 +89,62 @@ public abstract class Authenticator // if the authentication request was granted, let the // connection manager know that we just authed - if (AuthResponseData.SUCCESS.equals(rsp.getData().code)) { + if (AuthResponseData.SUCCESS.equals(rdata.code)) { _conmgr.connectionDidAuthenticate(conn); } } - }); + }; + + Invoker invoker = getInvoker(); + if (invoker != null) { + invoker.postUnit(unit); + + } else { + // just process it here + try { + unit.invoke(); + unit.handleResult(); + + } catch (Exception e) { + log.log(Level.WARNING, "Error authenticating user " + + "[areq=" + req + "].", e); + } + } } + /** + * Return the invoker on which to process the authentication, or null + * if the authentication should occur on the calling thread. The default + * implementation returns PresentsServer.invoker. + */ + protected Invoker getInvoker () + { + return PresentsServer.invoker; + } + + /** + * Create a new AuthResponseData instance to use for authenticating + * a connection. + */ + protected AuthResponseData createResponseData () + { + return new AuthResponseData(); + } + + /** + * Process the authentication for the specified connection. + * This method may do database operations if and only if getInvoker() + * returns non-null. The method may return after it has stuffed a valid + * response code in rsp.getData().code. + * + * @param conn The client connection. + * @param rsp The response to the client, which will already contain + * an AuthResponseData created by createResponseDatA(). + */ + protected abstract void processAuthentication ( + AuthingConnection conn, AuthResponse rsp) + throws PersistenceException; + /** The connection manager with which we're working. */ protected ConnectionManager _conmgr; } diff --git a/src/java/com/threerings/presents/server/DummyAuthenticator.java b/src/java/com/threerings/presents/server/DummyAuthenticator.java index 823d10089..deca297b4 100644 --- a/src/java/com/threerings/presents/server/DummyAuthenticator.java +++ b/src/java/com/threerings/presents/server/DummyAuthenticator.java @@ -21,25 +21,34 @@ package com.threerings.presents.server; -import com.threerings.presents.Log; +import com.samskivert.io.PersistenceException; + +import com.samskivert.util.Invoker; + import com.threerings.presents.net.AuthResponse; import com.threerings.presents.net.AuthResponseData; import com.threerings.presents.server.net.AuthingConnection; +import static com.threerings.presents.Log.log; + /** * A simple authenticator implementation that simply accepts all * authentication requests. */ public class DummyAuthenticator extends Authenticator { - /** - * Accept all authentication requests. - */ - public void authenticateConnection (AuthingConnection conn) + @Override + protected Invoker getInvoker () { - Log.info("Accepting request: " + conn.getAuthRequest()); - AuthResponseData rdata = new AuthResponseData(); - rdata.code = AuthResponseData.SUCCESS; - connectionWasAuthenticated(conn, new AuthResponse(rdata)); + return null; // not needed + } + + // from abstract Authenticator + protected void processAuthentication ( + AuthingConnection conn, AuthResponse rsp) + throws PersistenceException + { + log.info("Accepting request: " + conn.getAuthRequest()); + rsp.getData().code = AuthResponseData.SUCCESS; } } diff --git a/src/java/com/threerings/presents/server/Rejector.java b/src/java/com/threerings/presents/server/Rejector.java index 81927b86a..29433df70 100644 --- a/src/java/com/threerings/presents/server/Rejector.java +++ b/src/java/com/threerings/presents/server/Rejector.java @@ -3,14 +3,20 @@ package com.threerings.presents.server; +import java.util.logging.Level; + +import com.samskivert.io.PersistenceException; + +import com.samskivert.util.Invoker; import com.samskivert.util.StringUtil; import com.threerings.util.MessageBundle; -import com.threerings.presents.Log; import com.threerings.presents.net.AuthResponse; import com.threerings.presents.net.AuthResponseData; import com.threerings.presents.server.net.AuthingConnection; +import static com.threerings.presents.Log.log; + /** * A simple server that does nothing more than spit out a canned error * response to everyone who logs in. @@ -51,8 +57,7 @@ public class Rejector extends PresentsServer server.init(); server.run(); } catch (Exception e) { - Log.warning("Unable to initialize server."); - Log.logStackTrace(e); + log.log(Level.WARNING, "Unable to initialize server.", e); } } @@ -62,13 +67,19 @@ public class Rejector extends PresentsServer */ protected class RejectingAuthenticator extends Authenticator { - /** Reject all authentication requests. */ - public void authenticateConnection (AuthingConnection conn) + @Override + protected Invoker getInvoker () { - Log.info("Rejecting request: " + conn.getAuthRequest()); - AuthResponseData rdata = new AuthResponseData(); - rdata.code = _errmsg; - connectionWasAuthenticated(conn, new AuthResponse(rdata)); + return null; + } + + // from abstract Authenticator + protected void processAuthentication ( + AuthingConnection conn, AuthResponse rsp) + throws PersistenceException + { + log.info("Rejecting request: " + conn.getAuthRequest()); + rsp.getData().code = _errmsg; } }