NAME
Uia
—
User Interactive Authentication
API.
SYNOPSIS
#include
<Uia.h>
UiaStage *
UiaStageBuild
(char
*, HashMap *);
Array *
UiaDummyFlow
(void);
void
UiaCleanup
(MatrixHttpHandlerArgs
*);
int
UiaComplete
(Array
*, HttpServerContext
*, Db *,
HashMap *,
HashMap **,
TelodendriaConfig *);
void
UiaFlowsFree
(Array
*);
DESCRIPTION
Uia
takes care of all the logic for
performing user interactive authentication as defined by the Matrix
specification. API endpoints that require authentication via user
interactive authentication build up flows and any necessary parameters, and
pass them into
UiaComplete
(),
which validates auth
objects and maintains session
state to track the progress of a client through the user interactive
authentication flows. The idea is that an API endpoint will not progress
until user interactive authentication has succeeded.
Uia
makes it easy for the numerous API endpoints
that utilize this authentication mechanism to implement it.
UiaStageBuild
()
builds a single stage. A stage consists of a string identifying its type,
which is used to instruct the client as to what should be done, and
parameters, which is a JSON object that contains implementation-specific
parameters for completing the stage. This function takes those two
parameters in that order.
UiaDummyFlow
()
builds a flow that consists only of a dummy stage. This is useful when an
endpoint is required to use user interactive authentication, but doesn't
actually want to require the user to do anything. Since the dummy flow is a
pretty common flow, it seemed sensible to have a function for it. Other
flows are built by the caller that wishes to perform user interactive
authentication.
UiaCleanup
()
should be called periodically to purge old sessions. Session are only valid
for a few minutes after their last access. After that, they should be purged
so the database doesn't fill up with session files. This function is
specifically designed to be called via
Cron(3).
UiaComplete
()
does the bulk of the work for user interactive authentication. It takes many
paramters:
- An array of arrays of stages. Stages should be created with
UiaStageBuild
(), and then put into an array to create a flow. Those flows should then be put into an array and passed as this paramter. Do note that because of the loose typing of Telodendria's Array API, it is very easy to make mistakes here; if you are implementing a new route that requires user interactive authentication, then refer to an existing route so you can see how it works. - An HTTP server context. This is required to set the response headers in the event of an error.
- The database where user interactive authentication sessons are persisted.
- The JSON request body that contains the client's
auth
object, which will be read, parsed, and handled as appropriate. - A pointer to a pointer where a JSON response can be placed if necessary.
If
UiaComplete
() encounters a client error, such as a failure to authenticate, or outstanding stages that have not been completed, it will place a JSON response here that is expected to be returned to the client. This response will include a description of all the flows, stages, and their parameters. - A valid Telodendria configuration structure, because a few values are read from the configuration during certain stages of the authentication.
UiaFlowsFree
()
frees an array of flows, as described above. Even though the caller
constructs this array, it is convenient to free it in its entirety in a
single function call.
RETURN VALUES
UiaStageBuild
() returns an opaque
structure that represents a user interactive authentication stage, and any
parameters the client needs to complete it. It may return NULL if there is
an error allocating memory.
UiaDummyFlow
() returns an array that
represents a dummy authentication flow, or NULL if it could not allocate
memory for it.
UiaComplete
() returns an integer less than
zero if it experiences an internal failure, such as a failure to allocate
memory, or a corrupted database. It returns 0 if the client has remaining
stages to complete. In this case, it will have set the response headers and
the passed response pointer, so the caller should immediately return the
response to the client. This function returns 1 if the user has successfully
completed all stages. Only in this case shall the caller proceed with its
logic.