NAME
User
—
Convenience functions for working with
local users.
SYNOPSIS
#include
<User.h>
int
UserValidate
(char
*, char *);
int
UserHistoricalValidate
(char
*, char *);
int
UserExists
(Db
*, char *);
User *
UserCreate
(Db
*, char *,
char *);
User *
UserLock
(Db
*, char *);
User *
UserAuthenticate
(Db
*, char *);
int
UserUnlock
(User
*);
UserLoginInfo *
UserLogin
(User
*, char *,
char *,
char *,
int);
char *
UserGetName
(User
*);
int
UserCheckPassword
(User
*, char *);
int
UserSetPassword
(User
*, char *);
int
UserDeactivate
(User
*);
HashMap *
UserGetDevices
(User
*);
UserAccessToken *
UserGenerateAccessToken
(User
*, char *,
int);
int
UserAccessTokenSave
(Db
*, UserAccessToken
*);
void
UserAccessTokenFree
(UserAccessToken
*);
int
UserDeleteToken
(User
*, char *);
int
UserDeleteTokens
(User
*);
UserId *
UserIdParse
(char
*, char *);
void
UserIdFree
(UserId
*);
DESCRIPTION
The User
API provides a wrapper over the
database and offers an easy way for managing local users. It supports all of
the locking mechanisms that the database does, and provides features for
authenticating local users, among other tasks.
typedef struct UserLoginInfo { UserAccessToken *accessToken; char *refreshToken; } UserLoginInfo; typedef struct UserAccessToken { char *user; char *string; char *deviceId; long lifetime; } UserAccessToken; typedef struct UserId { char *localpart; char *server; } UserId;
UserValidate
()
takes a localpart and domain as separate parameters and validates it against
the rules of the Matrix specification. The reason the domain is required is
because the spec imposes limitations on the length of the user name, and the
longer the domain name is, the shorter the local part can be. This function
is used to ensure that client-provided localparts are valid on this server.
UserHistoricalValidate
()
is called the exact same way, except it is a little more lenient. It is used
to validate user parts on other servers, since some usernames might exist
that are not fully spec compliant, but remain in use due to historical
reasons.
UserExists
()
takes a localpart and checks whether or not it exists in the database.
UserCreate
()
creates a new user. It takes a localpart, which is assumed to be valid, and
a password.
UserLock
()
takes a localpart and obtains a database reference to the user represented
by that localpart. It behaves analogously to
DbLock
(),
and in fact uses it under the hood to ensure that the user can only be
modified by the thread that has locked the user.
UserUnlock
()
returns the user reference back to the database. It uses
DbUnlock
()
under the hood.
UserAuthenticate
()
takes an access token, figures out what user it belongs to, and returns the
reference to that user. This function should be used by most endpoints that
require valid user authentication, since most endpoints are authenticated
via access tokens.
UserLogin
()
is used for logging in a user. It takes the user's password, device ID,
device display name, and a boolean value indicating whether or not the
client supports refresh tokens. This function logs in the user and generates
an access token to be returned to the client.
UserGetName
()
gets the name attached to a user object. It can be used for the few cases
where it's necessary to know the localpart of a user.
UserCheckPassword
()
takes a password and verifies it against a user object. Telodendria does not
store passwords in plain text, so this function hashes the password and and
checks it against what's stored in the database.
UserSetPassword
()
resets the given user's password by hashing a plain text password and
storing it in the database.
UserDeactivate
()
deactivates a user such that it can no longer be used to log in, but the
username is still taken. This is to prevent future users from pretending to
be previous users of a given localpart.
UserGetDevices
()
fetches the devices that belong to the user, in JSON format, identical to
what's stored in the database. In fact, this JSON is still linked to the
database, so it should not be freed with
JsonFree
().
UserAccessTokenGenerate
(),
UserAccessTokenSave
(),
and
UserAccessTokenFree
()
are used for managing individual access tokens on a user. They operate on
the UserAccessToken structure.
UserAccessTokenGenerate
() takes the user localpart
to generate the token for, the device ID, for the token, and a boolean value
indicating whether or not the token should expire.
UserAccessTokenSave
() writes the access token to the
database.
UserDeleteToken
()
and
UserDeleteTokens
()
delete a specific access token/refresh token pair, or all the access and
refresh tokens for a given user, respectively.
UserIdParse
()
parses either a localpart or a fully-qualified Matrix ID.
UserIdFree
()
frees the result of this parsing.
RETURN VALUES
UserValidate
(),
UserHistoricalValidate
(),
UserExists
(), UserUnlock
(),
UserCheckPassword
(),
UserSetPassword
(),
UserDeactivate
(),
UserAccessTokenSave
(),
UserDeleteToken
(), and
UserDeleteTokens
() all return a boolean value.
Non-zero values indicate success, and zero values indicate failure.
UserCreate
(),
UserLock
(), and
UserAuthenticate
() return a pointer to a User, or
NULL if an error occurred.
UserGetName
() returns a pointer to the
string that holds the localpart of the user represented by the given user
pointer. This pointer should not be freed by the caller , as it is used
internally and will be freed when the user is unlocked.
UserLogin
() returns a UserLoginInfo
struct, or NULL
if something goes wrong. All this
information should be returned to the client that is logging in. If the
client doesn't support refresh tokens, then refreshToken will be NULL.
UserGetDevices
() returns a JSON object
that is linked to the database, or NULL if there was an error. The result
should not be freed with JsonFree
() because it is
still directly attached to the database. This object is an exact
representation of what is stored on the disk.
UserAccessTokenGenerate
() generates an
access token structure that should be freed when it is no longer needed, or
NULL
if there was a memory error.
UserIdParse
() returns a UserId structure
that should be freed when it is no longer needed, or
NULL
if there was a memory error.