Skip to main content

Checking permissions

On the server

Permission handlers are a type of custom Express middleware. They fetch permissions from the database and add them to the incoming request. Optionally, they check whether a specific permissions is present, and automatically return the UNAUTHORIZED status code in the negative case.

Permissions fetchers

Handlers named with[Entity]Permissions (e.g. withThreadPermissions, withBoardPermissions) are "permission fetchers". They extract the appropriate entity id from the request, fetch the corresponding permissions, and add them to the request object under the key current[Entity]Permissions.

Example:

// Update thread route
router.patch(
"threads/:thread_id",
ensureLoggedIn,
withThreadPermissions,
async (req, res) => {
const { currentThreadPermissions } = req;
// currentThreadPermissions now contains the permissions the user has for the thread with id `thread_id`.
}
);
warning

If the route has no :thread_id param, the withThreadPermissions handler will throw an error.

Generic permission checkers

Handlers named ensure[Entity]Permission (e.g. ensureThreadPermission, ensureBoardPermission) are generic permission checkers. Each of these handlers takes a permission as an argument, and checks that the user has the permission for the given entity. If the permission is not found, the appropriate UNAUTHORIZED status code is automatically returned.

Like permission fetchers, permission checkers add a list of the user's permissions to the request object under the key current[Entity]Permissions.

Example:

// Create new thread on a board
router.post(
"boards/:board_id",
ensureLoggedIn,
ensureBoardPermission(BoardPermissions.createThread),
async (req, res, next) => {
// If this handler is reached, the user has the `createThread` permission for the board with id `board_i`.
// If ensureBoardPermission fails, a response with status 403 is automatically sent back.
}
);
warning

If the route has no :board_id param, the ensureBoardPermission handler will throw an error.

Complex permission checkers

When checking for the simple existance of a permission is not enough, we can create a permission checker with more specific logic. These handlers are usually named ensure[Condition] (e.g. ensureLoggedIn, ensureBoardAccess). Their semantic is the same as generic permission checkers.

Example:

router.get("feeds/boards/:board_id", ensureBoardAccess, async (req, res) => {
// If this handler is reached, the user has permission to access the board with id `board_id`.
// If ensureBoardAccess fails, a response with status 403 is automatically sent back.
});

On the client

Each board's metadata includes the user's permission for the board and all threads and posts contained within. See the boards/{board_id} endpoint for details.

TODO

Create documentation about checking permissions on the client and add a link here.