diff --git a/src/java/com/threerings/crowd/server/CrowdClient.java b/src/java/com/threerings/crowd/server/CrowdClient.java index 30cd0a4b8..a4cc348d4 100644 --- a/src/java/com/threerings/crowd/server/CrowdClient.java +++ b/src/java/com/threerings/crowd/server/CrowdClient.java @@ -49,15 +49,6 @@ public class CrowdClient extends PresentsClient } } - // documentation inherited - protected void sessionWillStart () - { - super.sessionWillStart(); - - // configure a specific access controller for the client object - _clobj.setAccessController(CrowdObjectAccess.USER); - } - // documentation inherited protected void sessionWillResume () { diff --git a/src/java/com/threerings/crowd/server/CrowdObjectAccess.java b/src/java/com/threerings/crowd/server/CrowdObjectAccess.java index c15ffb97b..d321e1849 100644 --- a/src/java/com/threerings/crowd/server/CrowdObjectAccess.java +++ b/src/java/com/threerings/crowd/server/CrowdObjectAccess.java @@ -25,13 +25,9 @@ import com.threerings.presents.data.ClientObject; import com.threerings.presents.dobj.AccessController; import com.threerings.presents.dobj.DEvent; import com.threerings.presents.dobj.DObject; -import com.threerings.presents.dobj.InvocationRequestEvent; -import com.threerings.presents.dobj.MessageEvent; -import com.threerings.presents.dobj.NamedEvent; import com.threerings.presents.dobj.Subscriber; +import com.threerings.presents.server.PresentsObjectAccess; -import com.threerings.crowd.Log; -import com.threerings.crowd.data.BodyObject; import com.threerings.crowd.data.PlaceObject; /** @@ -40,76 +36,9 @@ import com.threerings.crowd.data.PlaceObject; public class CrowdObjectAccess { /** - * Our default access controller. Disallows modification of any object - * but allows anyone to subscribe. - */ - public static AccessController DEFAULT = new AccessController() - { - // documentation inherited from interface - public boolean allowSubscribe (DObject object, Subscriber subscriber) - { - // allow anyone to subscribe - return true; - } - - // documentation inherited from interface - public boolean allowDispatch (DObject object, DEvent event) - { - // if the event came from the server, it's cool - if (event.getSourceOid() == -1) { - return true; - - } else { - // if it came from the client, it better be a - // non-modification event - return (event instanceof MessageEvent || - event instanceof InvocationRequestEvent); - } - } - }; - - /** - * Provides access control for user objects. - */ - public static AccessController USER = new AccessController() - { - // documentation inherited from interface - public boolean allowSubscribe (DObject object, Subscriber sub) - { - boolean allowed = true; - // if the subscriber is a client, ensure that they are this - // same user - if (sub instanceof CrowdClient) { - String cluser = ((CrowdClient)sub).getUsername().toString(); - String obuser = ((BodyObject)object).username.toString(); - allowed = obuser.equalsIgnoreCase(cluser); - if (!allowed) { - Log.warning("Refusing BodyObject subscription request " + - "[owner=" + obuser + ", sub=" + sub + "]."); - } - } - return allowed; - } - - // documentation inherited from interface - public boolean allowDispatch (DObject object, DEvent event) - { - // if the event came from the server, it's cool - if (event.getSourceOid() == -1) { - return true; - - } else { - // the client is only allowed to modify the RECEIVERS field - return (event instanceof NamedEvent) && - ((NamedEvent)event).getName().equals(BodyObject.RECEIVERS); - } - } - }; - - /** - * Provides access control for place objects. The default behavior is to - * allow place occupants to subscribe to the place object and to use the - * {@link #DEFAULT} modification policy. + * Provides access control for place objects. The default behavior is to allow place occupants + * to subscribe to the place object and to use the {@link PresentsObjectAccess#DEFAULT} + * modification policy. */ public static AccessController PLACE = new AccessController() { @@ -126,7 +55,7 @@ public class CrowdObjectAccess // documentation inherited from interface public boolean allowDispatch (DObject object, DEvent event) { - return DEFAULT.allowDispatch(object, event); + return PresentsObjectAccess.DEFAULT.allowDispatch(object, event); } }; } diff --git a/src/java/com/threerings/crowd/server/CrowdServer.java b/src/java/com/threerings/crowd/server/CrowdServer.java index dfa458717..dca798b68 100644 --- a/src/java/com/threerings/crowd/server/CrowdServer.java +++ b/src/java/com/threerings/crowd/server/CrowdServer.java @@ -68,9 +68,6 @@ public class CrowdServer extends PresentsServer } }); - // configure the dobject manager with our access controller - omgr.setDefaultAccessController(CrowdObjectAccess.DEFAULT); - // create our body locator _lookup = createBodyLocator(); diff --git a/src/java/com/threerings/presents/peer/server/PeerManager.java b/src/java/com/threerings/presents/peer/server/PeerManager.java index d833e152b..3cd8cfaa0 100644 --- a/src/java/com/threerings/presents/peer/server/PeerManager.java +++ b/src/java/com/threerings/presents/peer/server/PeerManager.java @@ -21,6 +21,7 @@ package com.threerings.presents.peer.server; +import java.net.ConnectException; import java.util.ArrayList; import java.util.Date; import java.util.HashMap; @@ -686,8 +687,12 @@ public class PeerManager // documentation inherited from interface ClientObserver public void clientFailedToLogon (Client client, Exception cause) { - // we'll reconnect at most one minute later in refreshPeers() - log.warning("Peer logon attempt failed " + _record + ": " + cause); + if (cause instanceof ConnectException) { + // we'll reconnect at most one minute later in refreshPeers() + log.info("Peer not online " + _record + ": " + cause.getMessage()); + } else { + log.warning("Peer logon attempt failed " + _record + ": " + cause); + } } // documentation inherited from interface ClientObserver diff --git a/src/java/com/threerings/presents/server/PresentsClient.java b/src/java/com/threerings/presents/server/PresentsClient.java index 37b1dd653..056b9b03d 100644 --- a/src/java/com/threerings/presents/server/PresentsClient.java +++ b/src/java/com/threerings/presents/server/PresentsClient.java @@ -580,6 +580,8 @@ public class PresentsClient */ protected void sessionWillStart () { + // configure a specific access controller for the client object + _clobj.setAccessController(PresentsObjectAccess.CLIENT); } /** diff --git a/src/java/com/threerings/presents/server/PresentsObjectAccess.java b/src/java/com/threerings/presents/server/PresentsObjectAccess.java new file mode 100644 index 000000000..2d76d3ad2 --- /dev/null +++ b/src/java/com/threerings/presents/server/PresentsObjectAccess.java @@ -0,0 +1,99 @@ +// +// $Id$ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2006 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// This library is free software; you can redistribute it and/or modify it +// under the terms of the GNU Lesser General Public License as published +// by the Free Software Foundation; either version 2.1 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.presents.server; + +import com.threerings.presents.Log; +import com.threerings.presents.data.ClientObject; +import com.threerings.presents.dobj.AccessController; +import com.threerings.presents.dobj.DEvent; +import com.threerings.presents.dobj.DObject; +import com.threerings.presents.dobj.InvocationRequestEvent; +import com.threerings.presents.dobj.MessageEvent; +import com.threerings.presents.dobj.NamedEvent; +import com.threerings.presents.dobj.Subscriber; + +/** + * Defines the various object access controllers used by the Presents server. + */ +public class PresentsObjectAccess +{ + /** + * Our default access controller. Disallows modification of any object but allows anyone to + * subscribe. + */ + public static AccessController DEFAULT = new AccessController() + { + // documentation inherited from interface + public boolean allowSubscribe (DObject object, Subscriber subscriber) + { + // allow anyone to subscribe + return true; + } + + // documentation inherited from interface + public boolean allowDispatch (DObject object, DEvent event) + { + // if the event came from the server, it's cool + if (event.getSourceOid() == -1) { + return true; + + } else { + // if it came from the client, it better be a non-modification event + return (event instanceof MessageEvent || event instanceof InvocationRequestEvent); + } + } + }; + + /** + * Provides access control for client objects. + */ + public static AccessController CLIENT = new AccessController() + { + // documentation inherited from interface + public boolean allowSubscribe (DObject object, Subscriber sub) + { + boolean allowed = true; + // if the subscriber is a client, ensure that they are this same user + if (sub instanceof PresentsClient) { + allowed = ((PresentsClient)sub).getClientObject() == object; + if (!allowed) { + Log.warning("Refusing ClientObject subscription request " + + "[obj=" + ((ClientObject)object).who() + ", sub=" + sub + "]."); + } + } + return allowed; + } + + // documentation inherited from interface + public boolean allowDispatch (DObject object, DEvent event) + { + // if the event came from the server, it's cool + if (event.getSourceOid() == -1) { + return true; + } + + // the client is only allowed to modify the RECEIVERS field + return ((event instanceof NamedEvent) && + ((NamedEvent)event).getName().equals(ClientObject.RECEIVERS)); + } + }; +} diff --git a/src/java/com/threerings/presents/server/PresentsServer.java b/src/java/com/threerings/presents/server/PresentsServer.java index 3b8d8b95c..66c513d63 100644 --- a/src/java/com/threerings/presents/server/PresentsServer.java +++ b/src/java/com/threerings/presents/server/PresentsServer.java @@ -32,6 +32,7 @@ import com.threerings.util.signal.SignalManager; import com.threerings.presents.Log; import com.threerings.presents.client.Client; +import com.threerings.presents.dobj.AccessController; import com.threerings.presents.server.net.ConnectionManager; /** @@ -118,6 +119,9 @@ public class PresentsServer // create our distributed object manager omgr = createDObjectManager(); + // configure the dobject manager with our access controller + omgr.setDefaultAccessController(createDefaultObjectAccessController()); + // create and start up our invoker invoker = new PresentsInvoker(omgr); invoker.start(); @@ -167,6 +171,15 @@ public class PresentsServer return new PresentsDObjectMgr(); } + /** + * Defines the default object access policy for all {@link DObject} instances. The default + * default policy is to allow all subscribers but reject all modifications by the client. + */ + protected AccessController createDefaultObjectAccessController () + { + return PresentsObjectAccess.DEFAULT; + } + /** * Returns the port on which the connection manager will listen for * client connections.