forked from Telodendria/Telodendria
Finish implementing token refresh.
This implementation just keeps the refresh token and only updates the access token. The spec says that this is allowed. There's really no reason to do this, other than the fact that it's easier.
This commit is contained in:
parent
4b336de171
commit
ff879e715f
2 changed files with 43 additions and 5 deletions
8
TODO.txt
8
TODO.txt
|
@ -13,9 +13,9 @@ Milestone: v0.2.0
|
|||
|
||||
[ ] Abstract /email/requestToken and /msidsn/requestToken
|
||||
|
||||
[ ] User login
|
||||
[ ] User manipulation functions (so we don't use the DB directly)
|
||||
[ ] Refresh tokens
|
||||
[~] User login
|
||||
[x] User manipulation functions (so we don't use the DB directly)
|
||||
[x] Refresh tokens
|
||||
[ ] Logout
|
||||
[ ] Logout all
|
||||
[ ] Login fallback (static HTML page)
|
||||
|
@ -31,6 +31,8 @@ Milestone: v0.2.0
|
|||
[x] Document User
|
||||
[x] Document Str and remove old functions from Util docs.
|
||||
[x] Move docs from Matrix to User for UserValidate
|
||||
[ ] Document HashMapGetKey()
|
||||
[ ] Document new User functions
|
||||
[ ] Document new JSON functions
|
||||
[ ] Document UserInteractiveAuth (move docs from Matrix)
|
||||
|
||||
|
|
|
@ -30,6 +30,8 @@
|
|||
#include <HashMap.h>
|
||||
#include <Str.h>
|
||||
|
||||
#include <User.h>
|
||||
|
||||
ROUTE_IMPL(RouteRefresh, args)
|
||||
{
|
||||
HashMap *request;
|
||||
|
@ -39,15 +41,15 @@ ROUTE_IMPL(RouteRefresh, args)
|
|||
char *refreshToken;
|
||||
|
||||
char *oldAccessToken;
|
||||
char *newAccessToken;
|
||||
UserAccessToken *newAccessToken;
|
||||
char *deviceId;
|
||||
|
||||
Db *db = args->matrixArgs->db;
|
||||
LogConfig *lc = args->matrixArgs->lc;
|
||||
|
||||
User *user = NULL;
|
||||
DbRef *rtRef = NULL;
|
||||
DbRef *oAtRef = NULL;
|
||||
DbRef *nAtRef = NULL;
|
||||
|
||||
if (MATRIX_PATH_PARTS(args->path) > 0)
|
||||
{
|
||||
|
@ -103,24 +105,58 @@ ROUTE_IMPL(RouteRefresh, args)
|
|||
DbUnlock(db, rtRef);
|
||||
DbDelete(db, 3, "tokens", "refresh", refreshToken);
|
||||
|
||||
rtRef = NULL;
|
||||
|
||||
goto finish;
|
||||
}
|
||||
|
||||
/* Get the user associated with the access token and device */
|
||||
user = UserLock(db, JsonValueAsString(HashMapGet(DbJson(oAtRef), "user")));
|
||||
if (!user)
|
||||
{
|
||||
Log(lc, LOG_ERR, "Access token '%s' points to a user that doesn't exist.",
|
||||
oldAccessToken);
|
||||
Log(lc, LOG_WARNING, "This access token will be deleted.");
|
||||
HttpResponseStatus(args->context, HTTP_INTERNAL_SERVER_ERROR);
|
||||
response = MatrixErrorCreate(M_UNKNOWN);
|
||||
|
||||
DbUnlock(db, rtRef);
|
||||
DbDelete(db, 3, "tokens", "refresh", refreshToken);
|
||||
|
||||
DbUnlock(db, oAtRef);
|
||||
DbDelete(db, 3, "tokens", "access", oldAccessToken);
|
||||
|
||||
rtRef = NULL;
|
||||
oAtRef = NULL;
|
||||
|
||||
goto finish;
|
||||
}
|
||||
|
||||
/* Generate a new access token associated with the device and user. */
|
||||
deviceId = JsonValueAsString(HashMapGet(DbJson(oAtRef), "device"));
|
||||
newAccessToken = UserGenerateAccessToken(user, deviceId, 1);
|
||||
UserAccessTokenSave(db, newAccessToken);
|
||||
|
||||
/* Replace old access token in User */
|
||||
JsonValueFree(JsonSet(UserGetDevices(user), JsonValueString(newAccessToken->string), 2, deviceId, "accessToken"));
|
||||
|
||||
/* Delete old access token */
|
||||
DbUnlock(db, oAtRef);
|
||||
DbDelete(db, 3, "tokens", "access", oldAccessToken);
|
||||
|
||||
/* Update the refresh token to point to the new access token */
|
||||
JsonValueFree(HashMapSet(DbJson(rtRef), "refreshes", JsonValueString(StrDuplicate(newAccessToken->string))));
|
||||
|
||||
/* Return the new access token and expiration timestamp to the client */
|
||||
response = HashMapCreate();
|
||||
HashMapSet(response, "access_token", JsonValueString(StrDuplicate(newAccessToken->string)));
|
||||
HashMapSet(response, "expires_in_ms", JsonValueInteger(newAccessToken->lifetime));
|
||||
|
||||
Free(newAccessToken);
|
||||
|
||||
finish:
|
||||
JsonFree(request);
|
||||
DbUnlock(db, rtRef);
|
||||
UserUnlock(user);
|
||||
return response;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue