forked from Telodendria/Telodendria
Add UserIdParse() and UserIdFree() functions.
The spec says that a username can be either just the localpart, or a localpart and a server. This commit now ensures that the login endpoint actually handles usernames properly by calling the proper parsing functions.
This commit is contained in:
parent
58dae3a0c9
commit
e2806bc810
3 changed files with 94 additions and 4 deletions
|
@ -48,7 +48,7 @@ ROUTE_IMPL(RouteLogin, args)
|
|||
|
||||
char *password;
|
||||
char *type;
|
||||
char *username;
|
||||
UserId *userId = NULL;
|
||||
|
||||
Db *db = args->matrixArgs->db;
|
||||
|
||||
|
@ -160,9 +160,17 @@ ROUTE_IMPL(RouteLogin, args)
|
|||
break;
|
||||
}
|
||||
|
||||
username = JsonValueAsString(val);
|
||||
userId = UserParseId(JsonValueAsString(val),
|
||||
args->matrixArgs->config->serverName);
|
||||
if (!userId)
|
||||
{
|
||||
HttpResponseStatus(args->context, HTTP_BAD_REQUEST);
|
||||
response = MatrixErrorCreate(M_BAD_JSON);
|
||||
break;
|
||||
}
|
||||
|
||||
if (!UserExists(db, username))
|
||||
if (strcmp(userId->server, args->matrixArgs->config->serverName) != 0
|
||||
|| !UserExists(db, userId->localpart))
|
||||
{
|
||||
HttpResponseStatus(args->context, HTTP_FORBIDDEN);
|
||||
response = MatrixErrorCreate(M_FORBIDDEN);
|
||||
|
@ -225,7 +233,7 @@ ROUTE_IMPL(RouteLogin, args)
|
|||
refreshToken = JsonValueAsBoolean(val);
|
||||
}
|
||||
|
||||
user = UserLock(db, username);
|
||||
user = UserLock(db, userId->localpart);
|
||||
|
||||
if (!user)
|
||||
{
|
||||
|
@ -284,6 +292,7 @@ ROUTE_IMPL(RouteLogin, args)
|
|||
break;
|
||||
}
|
||||
|
||||
UserFreeId(userId);
|
||||
JsonFree(request);
|
||||
return response;
|
||||
}
|
||||
|
|
69
src/User.c
69
src/User.c
|
@ -598,3 +598,72 @@ UserDeleteToken(User * user, char *token)
|
|||
|
||||
return 1;
|
||||
}
|
||||
|
||||
UserId *
|
||||
UserParseId(char *id, char *defaultServer)
|
||||
{
|
||||
UserId *userId;
|
||||
|
||||
if (!id)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
id = StrDuplicate(id);
|
||||
if (!id)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
userId = Malloc(sizeof(UserId));
|
||||
if (!userId)
|
||||
{
|
||||
goto finish;
|
||||
}
|
||||
|
||||
/* Fully-qualified user ID */
|
||||
if (*id == '@')
|
||||
{
|
||||
char *localStart = id + 1;
|
||||
char *serverStart = localStart;
|
||||
|
||||
while (*serverStart != ':' && *serverStart != '\0')
|
||||
{
|
||||
serverStart++;
|
||||
}
|
||||
|
||||
if (*serverStart == '\0')
|
||||
{
|
||||
Free(userId);
|
||||
userId = NULL;
|
||||
goto finish;
|
||||
}
|
||||
|
||||
*serverStart = '\0';
|
||||
serverStart++;
|
||||
|
||||
userId->localpart = StrDuplicate(localStart);
|
||||
userId->server = StrDuplicate(serverStart);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Treat it as just a localpart */
|
||||
userId->localpart = StrDuplicate(id);
|
||||
userId->server = StrDuplicate(defaultServer);
|
||||
}
|
||||
|
||||
finish:
|
||||
Free(id);
|
||||
return userId;
|
||||
}
|
||||
|
||||
void
|
||||
UserFreeId(UserId *id)
|
||||
{
|
||||
if (id)
|
||||
{
|
||||
Free(id->localpart);
|
||||
Free(id->server);
|
||||
Free(id);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -42,6 +42,12 @@ typedef struct UserLoginInfo
|
|||
char *refreshToken;
|
||||
} UserLoginInfo;
|
||||
|
||||
typedef struct UserId
|
||||
{
|
||||
char *localpart;
|
||||
char *server;
|
||||
} UserId;
|
||||
|
||||
extern int
|
||||
UserValidate(char *, char *);
|
||||
|
||||
|
@ -93,4 +99,10 @@ extern void
|
|||
extern int
|
||||
UserDeleteToken(User *, char *);
|
||||
|
||||
extern UserId *
|
||||
UserParseId(char *, char *);
|
||||
|
||||
extern void
|
||||
UserFreeId(UserId *);
|
||||
|
||||
#endif /* TELODENDRIA_USER_H */
|
||||
|
|
Loading…
Reference in a new issue