mirror of
https://github.com/polhenarejos/pico-keys-sdk
synced 2026-05-28 17:11:23 +02:00
Add param parser and role check.
Signed-off-by: Pol Henarejos <pol.henarejos@cttc.es>
This commit is contained in:
@@ -31,6 +31,7 @@
|
|||||||
#define REST_MAX_METHOD_SIZE 8
|
#define REST_MAX_METHOD_SIZE 8
|
||||||
#define REST_MAX_CONTENT_TYPE_SIZE 64
|
#define REST_MAX_CONTENT_TYPE_SIZE 64
|
||||||
#define REST_MAX_PATH_SIZE 192
|
#define REST_MAX_PATH_SIZE 192
|
||||||
|
#define REST_MAX_REQUEST_PARAMS 4
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
REST_HTTP_UNKNOWN = 0x0,
|
REST_HTTP_UNKNOWN = 0x0,
|
||||||
@@ -64,13 +65,29 @@ typedef enum {
|
|||||||
REST_HEADER_TOTAL_COUNT
|
REST_HEADER_TOTAL_COUNT
|
||||||
} rest_header_id_t;
|
} rest_header_id_t;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
REST_PARAM_UNKNOWN = 0,
|
||||||
|
REST_PARAM_INTEGER,
|
||||||
|
REST_PARAM_STRING
|
||||||
|
} rest_param_type_t;
|
||||||
|
|
||||||
typedef struct {
|
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;
|
rest_http_method_t method;
|
||||||
char path[REST_MAX_PATH_SIZE];
|
char path[REST_MAX_PATH_SIZE];
|
||||||
const char *body;
|
const char *body;
|
||||||
size_t body_len;
|
size_t body_len;
|
||||||
const char *content_type;
|
const char *content_type;
|
||||||
char *headers[REST_HEADER_TOTAL_COUNT];
|
char *headers[REST_HEADER_TOTAL_COUNT];
|
||||||
|
rest_param_t params[REST_MAX_REQUEST_PARAMS];
|
||||||
} rest_request_t;
|
} rest_request_t;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
@@ -90,12 +107,7 @@ typedef enum {
|
|||||||
REST_ROUTE_REQUIRE_TLS = 0x2,
|
REST_ROUTE_REQUIRE_TLS = 0x2,
|
||||||
} rest_route_flags_t;
|
} rest_route_flags_t;
|
||||||
|
|
||||||
typedef struct {
|
typedef int (*rest_route_param_parser_t)(const char *str, const char *param_str, rest_param_t params_out[REST_MAX_REQUEST_PARAMS]);
|
||||||
rest_http_method_t method;
|
|
||||||
const char *path;
|
|
||||||
rest_route_handler_t handler;
|
|
||||||
rest_route_flags_t flags;
|
|
||||||
} rest_route_t;
|
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
REST_SESSION_ROLE_NONE = 0,
|
REST_SESSION_ROLE_NONE = 0,
|
||||||
@@ -103,6 +115,16 @@ typedef enum {
|
|||||||
REST_SESSION_ROLE_ADMIN = 0x2
|
REST_SESSION_ROLE_ADMIN = 0x2
|
||||||
} rest_session_role_t;
|
} 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 {
|
typedef enum {
|
||||||
REST_SESSION_UNKNOWN = 0,
|
REST_SESSION_UNKNOWN = 0,
|
||||||
REST_SESSION_AUTH_PENDING = 0x1,
|
REST_SESSION_AUTH_PENDING = 0x1,
|
||||||
|
|||||||
@@ -695,7 +695,13 @@ void rest_handle_request(rest_conn_t *conn) {
|
|||||||
if (routes[i].path == NULL || routes[i].handler == NULL) {
|
if (routes[i].path == NULL || routes[i].handler == NULL) {
|
||||||
continue;
|
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;
|
continue;
|
||||||
}
|
}
|
||||||
if (!(routes[i].method & request->method)) {
|
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");
|
send_json_error(conn, 401, "authentication_required");
|
||||||
return;
|
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()) {
|
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;
|
session->status = REST_SESSION_EXPIRED;
|
||||||
send_json_error(conn, 401, "session_expired");
|
send_json_error(conn, 401, "session_expired");
|
||||||
|
|||||||
Reference in New Issue
Block a user