Implemented bureau authentication

* Token member for bureaus
* Exception type for failed authentication
* Authenticate function
* Bureau id to credentials
* Fixed bad constructor and toString


git-svn-id: svn+ssh://src.earth.threerings.net/narya/trunk@5149 542714f4-19e9-0310-aa3c-eee0fc999fb1
This commit is contained in:
Jamie Doornbos
2008-06-02 04:38:01 +00:00
parent 6c34b9e3ed
commit 69451c5682
5 changed files with 74 additions and 19 deletions
@@ -39,13 +39,10 @@ public class BureauClient extends Client
public function BureauClient (token :String, bureauId :String) public function BureauClient (token :String, bureauId :String)
{ {
super(null); super(null);
_bureauId = bureauId; _bureauId = bureauId;
var creds :BureauCredentials = new BureauCredentials(_bureauId); var creds :BureauCredentials = new BureauCredentials(_bureauId);
creds.sessionToken = token; creds.sessionToken = token;
_creds = creds; _creds = creds;
_ctx = createContext(); _ctx = createContext();
_director = createDirector(); _director = createDirector();
} }
@@ -38,20 +38,26 @@ public class BureauCredentials extends Credentials
*/ */
public var sessionToken :String; public var sessionToken :String;
/**
* The id of the bureau logging in.
*/
public var bureauId :String;
/** /**
* Creates new credentials for a specific bureau. * Creates new credentials for a specific bureau.
*/ */
public function BureauCredentials (token :String) public function BureauCredentials (bureauId :String)
{ {
super(new Name("@@bureau:" + token + "@@")); super(new Name("@@bureau:" + bureauId + "@@"));
sessionToken = token; this.bureauId = bureauId;
} }
/** @inheritDoc */ /** @inheritDoc */
override protected function toStringBuf (buf :StringBuilder) :void override protected function toStringBuf (buf :StringBuilder) :void
{ {
super.toStringBuf(buf); super.toStringBuf(buf);
buf.append(" token=").append(sessionToken); buf.append(" bureauId=").append(bureauId).
append(" token=").append(sessionToken);
} }
// from interface Streamable // from interface Streamable
@@ -59,6 +65,7 @@ public class BureauCredentials extends Credentials
{ {
super.readObject(ins); super.readObject(ins);
sessionToken = (ins.readField(String) as String); sessionToken = (ins.readField(String) as String);
bureauId = (ins.readField(String) as String);
} }
// from interface Streamable // from interface Streamable
@@ -66,6 +73,7 @@ public class BureauCredentials extends Credentials
{ {
super.writeObject(out); super.writeObject(out);
out.writeField(sessionToken); out.writeField(sessionToken);
out.writeField(bureauId);
} }
} }
} }
@@ -41,13 +41,10 @@ public abstract class BureauClient extends Client
public BureauClient (String token, String bureauId, RunQueue runQueue) public BureauClient (String token, String bureauId, RunQueue runQueue)
{ {
super(null, runQueue); super(null, runQueue);
_bureauId = bureauId; _bureauId = bureauId;
BureauCredentials creds = new BureauCredentials(_bureauId); BureauCredentials creds = new BureauCredentials(_bureauId);
creds.sessionToken = token; creds.sessionToken = token;
_creds = creds; _creds = creds;
_ctx = createContext(); _ctx = createContext();
_director = createDirector(); _director = createDirector();
} }
@@ -35,6 +35,20 @@ public class BureauCredentials extends Credentials
*/ */
public String sessionToken; public String sessionToken;
/**
* The id of the bureau logging in.
*/
public String bureauId;
/**
* Test if a given name object matches the name that we generate.
*/
public static boolean isBureau (Name name)
{
String normal = name.getNormal();
return normal.startsWith("@@bureau:") && normal.endsWith("@@");
}
/** /**
* Creates an empty credentials for streaming. Should not be used directly. * Creates an empty credentials for streaming. Should not be used directly.
*/ */
@@ -48,18 +62,14 @@ public class BureauCredentials extends Credentials
public BureauCredentials (String bureauId) public BureauCredentials (String bureauId)
{ {
super(new Name("@@bureau:" + bureauId + "@@")); super(new Name("@@bureau:" + bureauId + "@@"));
this.bureauId = bureauId;
} }
@Override // inherit documentation @Override // inherit documentation
protected void toString (StringBuilder buf) protected void toString (StringBuilder buf)
{ {
super.toString(buf); super.toString(buf);
buf.append(" token=").append(sessionToken); buf.append(" id=").append(bureauId).
} append(" token=").append(sessionToken);
// inherit documentation - from Object
public String toString ()
{
return super.toString() + ", token=" + sessionToken;
} }
} }
@@ -25,6 +25,7 @@ import java.util.Map;
import java.util.Set; import java.util.Set;
import com.threerings.bureau.data.AgentObject; import com.threerings.bureau.data.AgentObject;
import com.threerings.bureau.data.BureauCodes; import com.threerings.bureau.data.BureauCodes;
import com.threerings.bureau.data.BureauCredentials;
import com.threerings.presents.data.ClientObject; import com.threerings.presents.data.ClientObject;
import com.threerings.presents.dobj.RootDObjectManager; import com.threerings.presents.dobj.RootDObjectManager;
import com.threerings.presents.dobj.ObjectDeathListener; import com.threerings.presents.dobj.ObjectDeathListener;
@@ -67,6 +68,21 @@ public class BureauRegistry
String token); String token);
} }
/**
* Thrown when a bureau could not be authenticated.
*/
public static class AuthenticationException extends Exception
{
/**
* Creates a new authentication exception with a message explaining why the client could
* not be authenticated as a bureau.
*/
public AuthenticationException (String message)
{
super(message);
}
}
/** /**
* Creates a new registry, prepared to provide bureau services. * Creates a new registry, prepared to provide bureau services.
*/ */
@@ -101,6 +117,30 @@ public class BureauRegistry
BureauCodes.BUREAU_GROUP); BureauCodes.BUREAU_GROUP);
} }
/**
* Check the credentials to make sure this is one of our bureaus.
*/
public void authenticate (BureauCredentials creds)
throws AuthenticationException
{
Bureau bureau = _bureaus.get(creds.bureauId);
if (bureau == null) {
throw new AuthenticationException(
"Bureau " + creds.bureauId + " not found");
}
if (bureau.clientObj != null) {
throw new AuthenticationException(
"Bureau " + creds.bureauId + " already logged in");
}
if (!bureau.token.equals(creds.sessionToken)) {
throw new AuthenticationException(
"Bureau " + creds.bureauId +
" does not match credentials token");
}
}
/** /**
* Registers a command generator for a given type. When an agent is started and no bureaus are * Registers a command generator for a given type. When an agent is started and no bureaus are
* running, the <code>bureauType</code> is used to determine the <code>CommandGenerator</code> * running, the <code>bureauType</code> is used to determine the <code>CommandGenerator</code>
@@ -155,12 +195,12 @@ public class BureauRegistry
bureau = new Bureau(); bureau = new Bureau();
bureau.bureauId = agent.bureauId; bureau.bureauId = agent.bureauId;
bureau.token = generateToken();
// schedule the bureau to be kicked off // schedule the bureau to be kicked off
String token = generateToken();
bureau.builder = new ProcessBuilder( bureau.builder = new ProcessBuilder(
generator.createCommand( generator.createCommand(
_serverNameAndPort, agent.bureauId, token)); _serverNameAndPort, agent.bureauId, bureau.token));
bureau.builder.redirectErrorStream(true); bureau.builder.redirectErrorStream(true);
@@ -514,6 +554,9 @@ public class BureauRegistry
// non-null once the bureau is scheduled but not yet kicked off // non-null once the bureau is scheduled but not yet kicked off
ProcessBuilder builder; ProcessBuilder builder;
// The token given to this bureau for authentication
String token;
// The bureau's key in the map of bureaus. All requests for this bureau // The bureau's key in the map of bureaus. All requests for this bureau
// with this id should be associated with one instance // with this id should be associated with one instance
String bureauId; String bureauId;