Add param parser and role check.

Signed-off-by: Pol Henarejos <pol.henarejos@cttc.es>
This commit is contained in:
Pol Henarejos
2026-04-26 21:10:47 +02:00
parent c8b5bf8f82
commit a7b143f0d8
2 changed files with 39 additions and 7 deletions

View File

@@ -31,6 +31,7 @@
#define REST_MAX_METHOD_SIZE 8
#define REST_MAX_CONTENT_TYPE_SIZE 64
#define REST_MAX_PATH_SIZE 192
#define REST_MAX_REQUEST_PARAMS 4
typedef enum {
REST_HTTP_UNKNOWN = 0x0,
@@ -64,13 +65,29 @@ typedef enum {
REST_HEADER_TOTAL_COUNT
} rest_header_id_t;
typedef enum {
REST_PARAM_UNKNOWN = 0,
REST_PARAM_INTEGER,
REST_PARAM_STRING
} rest_param_type_t;
typedef struct {
union {
uint32_t int_param;
char *str_param;
} param;
rest_param_type_t type;
} rest_param_t;
typedef struct
{
rest_http_method_t method;
char path[REST_MAX_PATH_SIZE];
const char *body;
size_t body_len;
const char *content_type;
char *headers[REST_HEADER_TOTAL_COUNT];
rest_param_t params[REST_MAX_REQUEST_PARAMS];
} rest_request_t;
typedef struct {
@@ -90,12 +107,7 @@ typedef enum {
REST_ROUTE_REQUIRE_TLS = 0x2,
} rest_route_flags_t;
typedef struct {
rest_http_method_t method;
const char *path;
rest_route_handler_t handler;
rest_route_flags_t flags;
} rest_route_t;
typedef int (*rest_route_param_parser_t)(const char *str, const char *param_str, rest_param_t params_out[REST_MAX_REQUEST_PARAMS]);
typedef enum {
REST_SESSION_ROLE_NONE = 0,
@@ -103,6 +115,16 @@ typedef enum {
REST_SESSION_ROLE_ADMIN = 0x2
} rest_session_role_t;
typedef struct {
rest_http_method_t method;
const char *path;
rest_route_handler_t handler;
rest_route_flags_t flags;
rest_route_param_parser_t param_parser;
rest_session_role_t role; // Minimum required role to access this route (only relevant if REST_ROUTE_REQUIRE_AUTH flag is set)
} rest_route_t;
typedef enum {
REST_SESSION_UNKNOWN = 0,
REST_SESSION_AUTH_PENDING = 0x1,

View File

@@ -695,7 +695,13 @@ void rest_handle_request(rest_conn_t *conn) {
if (routes[i].path == NULL || routes[i].handler == NULL) {
continue;
}
if (strcmp(routes[i].path, request->path) != 0) {
if (routes[i].param_parser != NULL) {
int result = routes[i].param_parser(request->path, routes[i].path, request->params);
if (result < 0) {
continue;
}
}
else if (strcmp(routes[i].path, request->path) != 0) {
continue;
}
if (!(routes[i].method & request->method)) {
@@ -716,6 +722,10 @@ void rest_handle_request(rest_conn_t *conn) {
send_json_error(conn, 401, "authentication_required");
return;
}
if (session->role < routes[i].role) {
send_json_error(conn, 403, "insufficient_privileges");
return;
}
if (session->last_activity_timestamp + REST_SESSION_TIMEOUT_INACTIVITY_MS < board_millis() || session->created_at + REST_SESSION_TIMEOUT_TOTAL_MS < board_millis()) {
session->status = REST_SESSION_EXPIRED;
send_json_error(conn, 401, "session_expired");