Whenever you write code for a filter for MongoDB, you can count on the following variables being pre-defined in the context variable:
This variable will be defined once the first packet has been received from the client. It will contain an object that usually looks like the following, although there may be some variances depending on the client.
{
application: {
name: "robo3t-1.4.2"
},
driver: {
name: "MongoDB Internal Client",
version: "4.2.6-18-g6cdb6ab"
},
os: {
type: "Darwin",
name: "Mac OS X",
architecture: "x86_64",
version: "19.6.0"
}
}
This variable should normally not be modified.
Reject connections from a specific type of client (in a request filter):
if (context.clientInfo && context.clientInfo.driver.name.startsWith("MongoDB Internal")) {
context.result.success = false;
context.result.errorMessage = "Unsupported driver";
context.result.closeConnection = true;
}
This variable will be defined as soon as the authentication process has started, provided of course that the authentication mechanism relies on a user name. This is usually in the second packet sent by the client.
In a request filter, you might for instance supplement a filter for certain users:
if ('fred' === context.username) {
let body = context.packet.getSection(0).getBody();
if ("companies" === body.find) {
body.query.country = 'US';
}
}
This variable is defined at all times, even in connection filters. It contains a Java Socket to the database client.
Reject a connection in a connection filter or request filter:
const clientAddress = context.socket.getRemoteSocketAddress().getAddress().toString();
if ( ! clientAddress.startsWith("123.45.")) {
context.result.success = false;
context.result.errorMessage = "Address is not authorized";
context.result.closeConnection = true;
}
You can use other methods on the socket object, such as close(), but you should expect some error logging if you do. Note that you could theoretically inject data into the socket, or read directly from it, but that should be reserved for advanced users.