mirror of
https://github.com/storytold/artcraft.git
synced 2026-11-05 17:58:55 +00:00
new endpoint
This commit is contained in:
1 parent
50d31cffd8
commit
d9151b9fc8
9 files changed
+546
-2
No files matched your search
+146
@@ -0,0 +1,146 @@
|
||||
{
|
||||
"db_name": "MySQL",
|
||||
"query": "\nSELECT\n uir.id,\n uir.impersonator_user_token as `impersonator_user_token: UserToken`,\n impersonator.username as impersonator_username,\n impersonator.display_name as impersonator_display_name,\n uir.impersonated_user_token as `impersonated_user_token: UserToken`,\n impersonated.username as impersonated_username,\n impersonated.display_name as impersonated_display_name,\n uir.is_redeemed as `is_redeemed: bool`,\n (uir.expires_at < NOW()) as `is_expired: bool`,\n uir.expires_at,\n uir.created_at,\n uir.updated_at\nFROM user_impersonation_requests uir\nJOIN users impersonator ON impersonator.token = uir.impersonator_user_token\nJOIN users impersonated ON impersonated.token = uir.impersonated_user_token\nWHERE uir.id < ?\nORDER BY uir.id DESC\nLIMIT ?\n ",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
"ordinal": 0,
|
||||
"name": "id",
|
||||
"type_info": {
|
||||
"type": "LongLong",
|
||||
"flags": "NOT_NULL | UNSIGNED | AUTO_INCREMENT | BINARY",
|
||||
"char_set": 63,
|
||||
"max_size": 20
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 1,
|
||||
"name": "impersonator_user_token: UserToken",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "NOT_NULL | MULTIPLE_KEY | BINARY | NO_DEFAULT_VALUE",
|
||||
"char_set": 224,
|
||||
"max_size": 128
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 2,
|
||||
"name": "impersonator_username",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "NOT_NULL | UNIQUE_KEY | BINARY | NO_DEFAULT_VALUE",
|
||||
"char_set": 224,
|
||||
"max_size": 80
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 3,
|
||||
"name": "impersonator_display_name",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "NOT_NULL | BINARY | NO_DEFAULT_VALUE",
|
||||
"char_set": 224,
|
||||
"max_size": 80
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 4,
|
||||
"name": "impersonated_user_token: UserToken",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "NOT_NULL | MULTIPLE_KEY | BINARY | NO_DEFAULT_VALUE",
|
||||
"char_set": 224,
|
||||
"max_size": 128
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 5,
|
||||
"name": "impersonated_username",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "NOT_NULL | UNIQUE_KEY | BINARY | NO_DEFAULT_VALUE",
|
||||
"char_set": 224,
|
||||
"max_size": 80
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 6,
|
||||
"name": "impersonated_display_name",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "NOT_NULL | BINARY | NO_DEFAULT_VALUE",
|
||||
"char_set": 224,
|
||||
"max_size": 80
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 7,
|
||||
"name": "is_redeemed: bool",
|
||||
"type_info": {
|
||||
"type": "Tiny",
|
||||
"flags": "NOT_NULL | BINARY",
|
||||
"char_set": 63,
|
||||
"max_size": 1
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 8,
|
||||
"name": "is_expired: bool",
|
||||
"type_info": {
|
||||
"type": "LongLong",
|
||||
"flags": "NOT_NULL | BINARY",
|
||||
"char_set": 63,
|
||||
"max_size": 1
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 9,
|
||||
"name": "expires_at",
|
||||
"type_info": {
|
||||
"type": "Timestamp",
|
||||
"flags": "NOT_NULL | BINARY | TIMESTAMP | NO_DEFAULT_VALUE",
|
||||
"char_set": 63,
|
||||
"max_size": 19
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 10,
|
||||
"name": "created_at",
|
||||
"type_info": {
|
||||
"type": "Timestamp",
|
||||
"flags": "NOT_NULL | BINARY | TIMESTAMP",
|
||||
"char_set": 63,
|
||||
"max_size": 19
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 11,
|
||||
"name": "updated_at",
|
||||
"type_info": {
|
||||
"type": "Timestamp",
|
||||
"flags": "NOT_NULL | BINARY | TIMESTAMP",
|
||||
"char_set": 63,
|
||||
"max_size": 19
|
||||
}
|
||||
}
|
||||
],
|
||||
"parameters": {
|
||||
"Right": 2
|
||||
},
|
||||
"nullable": [
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false
|
||||
]
|
||||
},
|
||||
"hash": "5d45897a5d4c326c8d17f105cae81db7f5878c197b55e8ea61c225e739d11234"
|
||||
}
|
||||
+146
@@ -0,0 +1,146 @@
|
||||
{
|
||||
"db_name": "MySQL",
|
||||
"query": "\nSELECT\n uir.id,\n uir.impersonator_user_token as `impersonator_user_token: UserToken`,\n impersonator.username as impersonator_username,\n impersonator.display_name as impersonator_display_name,\n uir.impersonated_user_token as `impersonated_user_token: UserToken`,\n impersonated.username as impersonated_username,\n impersonated.display_name as impersonated_display_name,\n uir.is_redeemed as `is_redeemed: bool`,\n (uir.expires_at < NOW()) as `is_expired: bool`,\n uir.expires_at,\n uir.created_at,\n uir.updated_at\nFROM user_impersonation_requests uir\nJOIN users impersonator ON impersonator.token = uir.impersonator_user_token\nJOIN users impersonated ON impersonated.token = uir.impersonated_user_token\nORDER BY uir.id DESC\nLIMIT ?\n ",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
"ordinal": 0,
|
||||
"name": "id",
|
||||
"type_info": {
|
||||
"type": "LongLong",
|
||||
"flags": "NOT_NULL | UNSIGNED | AUTO_INCREMENT | BINARY",
|
||||
"char_set": 63,
|
||||
"max_size": 20
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 1,
|
||||
"name": "impersonator_user_token: UserToken",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "NOT_NULL | MULTIPLE_KEY | BINARY | NO_DEFAULT_VALUE",
|
||||
"char_set": 224,
|
||||
"max_size": 128
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 2,
|
||||
"name": "impersonator_username",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "NOT_NULL | UNIQUE_KEY | BINARY | NO_DEFAULT_VALUE",
|
||||
"char_set": 224,
|
||||
"max_size": 80
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 3,
|
||||
"name": "impersonator_display_name",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "NOT_NULL | BINARY | NO_DEFAULT_VALUE",
|
||||
"char_set": 224,
|
||||
"max_size": 80
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 4,
|
||||
"name": "impersonated_user_token: UserToken",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "NOT_NULL | MULTIPLE_KEY | BINARY | NO_DEFAULT_VALUE",
|
||||
"char_set": 224,
|
||||
"max_size": 128
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 5,
|
||||
"name": "impersonated_username",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "NOT_NULL | UNIQUE_KEY | BINARY | NO_DEFAULT_VALUE",
|
||||
"char_set": 224,
|
||||
"max_size": 80
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 6,
|
||||
"name": "impersonated_display_name",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "NOT_NULL | BINARY | NO_DEFAULT_VALUE",
|
||||
"char_set": 224,
|
||||
"max_size": 80
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 7,
|
||||
"name": "is_redeemed: bool",
|
||||
"type_info": {
|
||||
"type": "Tiny",
|
||||
"flags": "NOT_NULL | BINARY",
|
||||
"char_set": 63,
|
||||
"max_size": 1
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 8,
|
||||
"name": "is_expired: bool",
|
||||
"type_info": {
|
||||
"type": "LongLong",
|
||||
"flags": "NOT_NULL | BINARY",
|
||||
"char_set": 63,
|
||||
"max_size": 1
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 9,
|
||||
"name": "expires_at",
|
||||
"type_info": {
|
||||
"type": "Timestamp",
|
||||
"flags": "NOT_NULL | BINARY | TIMESTAMP | NO_DEFAULT_VALUE",
|
||||
"char_set": 63,
|
||||
"max_size": 19
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 10,
|
||||
"name": "created_at",
|
||||
"type_info": {
|
||||
"type": "Timestamp",
|
||||
"flags": "NOT_NULL | BINARY | TIMESTAMP",
|
||||
"char_set": 63,
|
||||
"max_size": 19
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 11,
|
||||
"name": "updated_at",
|
||||
"type_info": {
|
||||
"type": "Timestamp",
|
||||
"flags": "NOT_NULL | BINARY | TIMESTAMP",
|
||||
"char_set": 63,
|
||||
"max_size": 19
|
||||
}
|
||||
}
|
||||
],
|
||||
"parameters": {
|
||||
"Right": 1
|
||||
},
|
||||
"nullable": [
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false
|
||||
]
|
||||
},
|
||||
"hash": "e72b3dfdd9df4ee10a696faa4dfc3fb8addc9d2b88017f503c339fb616bef6f1"
|
||||
}
|
||||
+95
@@ -0,0 +1,95 @@
|
||||
use chrono::{DateTime, Utc};
|
||||
use sqlx::MySqlPool;
|
||||
|
||||
use tokens::tokens::users::UserToken;
|
||||
|
||||
pub struct UserImpersonationRequestListItem {
|
||||
pub id: u64,
|
||||
pub impersonator_user_token: UserToken,
|
||||
pub impersonator_username: String,
|
||||
pub impersonator_display_name: String,
|
||||
pub impersonated_user_token: UserToken,
|
||||
pub impersonated_username: String,
|
||||
pub impersonated_display_name: String,
|
||||
pub is_redeemed: bool,
|
||||
pub is_expired: bool,
|
||||
pub expires_at: DateTime<Utc>,
|
||||
pub created_at: DateTime<Utc>,
|
||||
pub updated_at: DateTime<Utc>,
|
||||
}
|
||||
|
||||
pub struct ListUserImpersonationRequestsArgs<'a> {
|
||||
pub maybe_cursor_id: Option<u64>,
|
||||
pub limit: u32,
|
||||
pub mysql_pool: &'a MySqlPool,
|
||||
}
|
||||
|
||||
pub async fn list_user_impersonation_requests(
|
||||
args: ListUserImpersonationRequestsArgs<'_>,
|
||||
) -> Result<Vec<UserImpersonationRequestListItem>, sqlx::Error> {
|
||||
|
||||
let limit = args.limit as i64;
|
||||
|
||||
let items = match args.maybe_cursor_id {
|
||||
Some(cursor_id) => {
|
||||
sqlx::query_as!(
|
||||
UserImpersonationRequestListItem,
|
||||
r#"
|
||||
SELECT
|
||||
uir.id,
|
||||
uir.impersonator_user_token as `impersonator_user_token: UserToken`,
|
||||
impersonator.username as impersonator_username,
|
||||
impersonator.display_name as impersonator_display_name,
|
||||
uir.impersonated_user_token as `impersonated_user_token: UserToken`,
|
||||
impersonated.username as impersonated_username,
|
||||
impersonated.display_name as impersonated_display_name,
|
||||
uir.is_redeemed as `is_redeemed: bool`,
|
||||
(uir.expires_at < NOW()) as `is_expired: bool`,
|
||||
uir.expires_at,
|
||||
uir.created_at,
|
||||
uir.updated_at
|
||||
FROM user_impersonation_requests uir
|
||||
JOIN users impersonator ON impersonator.token = uir.impersonator_user_token
|
||||
JOIN users impersonated ON impersonated.token = uir.impersonated_user_token
|
||||
WHERE uir.id < ?
|
||||
ORDER BY uir.id DESC
|
||||
LIMIT ?
|
||||
"#,
|
||||
cursor_id as u64,
|
||||
limit,
|
||||
)
|
||||
.fetch_all(args.mysql_pool)
|
||||
.await?
|
||||
}
|
||||
None => {
|
||||
sqlx::query_as!(
|
||||
UserImpersonationRequestListItem,
|
||||
r#"
|
||||
SELECT
|
||||
uir.id,
|
||||
uir.impersonator_user_token as `impersonator_user_token: UserToken`,
|
||||
impersonator.username as impersonator_username,
|
||||
impersonator.display_name as impersonator_display_name,
|
||||
uir.impersonated_user_token as `impersonated_user_token: UserToken`,
|
||||
impersonated.username as impersonated_username,
|
||||
impersonated.display_name as impersonated_display_name,
|
||||
uir.is_redeemed as `is_redeemed: bool`,
|
||||
(uir.expires_at < NOW()) as `is_expired: bool`,
|
||||
uir.expires_at,
|
||||
uir.created_at,
|
||||
uir.updated_at
|
||||
FROM user_impersonation_requests uir
|
||||
JOIN users impersonator ON impersonator.token = uir.impersonator_user_token
|
||||
JOIN users impersonated ON impersonated.token = uir.impersonated_user_token
|
||||
ORDER BY uir.id DESC
|
||||
LIMIT ?
|
||||
"#,
|
||||
limit,
|
||||
)
|
||||
.fetch_all(args.mysql_pool)
|
||||
.await?
|
||||
}
|
||||
};
|
||||
|
||||
Ok(items)
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
pub mod insert_user_impersonation_request;
|
||||
pub mod list_user_impersonation_requests;
|
||||
pub mod list_user_impersonation_requests_for_user;
|
||||
pub mod lookup_user_impersonation_request;
|
||||
pub mod mark_impersonation_token_as_redeemed;
|
||||
@@ -87,6 +87,7 @@ use crate::http_server::endpoints::media_files::upsert_upload::write_scene_file:
|
||||
use crate::http_server::endpoints::model_download::enqueue_gptsovits_model_download_handler::*;
|
||||
use crate::http_server::endpoints::moderation::user_feature_flags::edit_user_feature_flags_handler::*;
|
||||
use crate::http_server::endpoints::moderation::user_sessions::moderator_list_user_session_impersonation_requests_for_user_handler::*;
|
||||
use crate::http_server::endpoints::moderation::user_sessions::moderator_list_user_session_impersonation_requests_handler::*;
|
||||
use crate::http_server::endpoints::moderation::user_sessions::moderator_user_session_impersonation_request_handler::*;
|
||||
use crate::http_server::endpoints::prompts::get_prompt_handler::*;
|
||||
use artcraft_api_defs::common::responses::job_details::JobDetailsLipsyncRequest;
|
||||
@@ -510,6 +511,7 @@ use crate::http_server::endpoints::media_files::list::list_batch_generated_redux
|
||||
crate::http_server::endpoints::moderation::wallets::moderator_create_wallet_for_user_handler::moderator_create_wallet_for_user_handler,
|
||||
crate::http_server::endpoints::moderation::wallets::moderator_get_wallet_handler::moderator_get_wallet_handler,
|
||||
crate::http_server::endpoints::moderation::user_sessions::moderator_list_user_session_impersonation_requests_for_user_handler::moderator_list_user_session_impersonation_requests_for_user_handler,
|
||||
crate::http_server::endpoints::moderation::user_sessions::moderator_list_user_session_impersonation_requests_handler::moderator_list_user_session_impersonation_requests_handler,
|
||||
crate::http_server::endpoints::moderation::user_sessions::moderator_user_session_impersonation_request_handler::moderator_user_session_impersonation_request_handler,
|
||||
// Credits
|
||||
crate::http_server::endpoints::credits::get_session_credits_handler::get_session_credits_handler,
|
||||
@@ -596,6 +598,7 @@ use crate::http_server::endpoints::media_files::list::list_batch_generated_redux
|
||||
WeightsDefaultCoverInfo,
|
||||
|
||||
// Endpoint API types
|
||||
AllImpersonationRequestResponse,
|
||||
AppStateError,
|
||||
AppStateLegacyPermissionFlags,
|
||||
AppStatePermissions,
|
||||
@@ -889,6 +892,8 @@ use crate::http_server::endpoints::media_files::list::list_batch_generated_redux
|
||||
ListFeaturedWeightsError,
|
||||
ListFeaturedWeightsQueryParams,
|
||||
ListFeaturedWeightsSuccessResponse,
|
||||
ListAllImpersonationRequestsQueryParams,
|
||||
ListAllImpersonationRequestsSuccessResponse,
|
||||
ListImpersonationRequestsPathInfo,
|
||||
ListImpersonationRequestsQueryParams,
|
||||
ListUserImpersonationRequestsSuccessResponse,
|
||||
|
||||
+1
@@ -1,2 +1,3 @@
|
||||
pub mod moderator_list_user_session_impersonation_requests_for_user_handler;
|
||||
pub mod moderator_list_user_session_impersonation_requests_handler;
|
||||
pub mod moderator_user_session_impersonation_request_handler;
|
||||
+1
-1
@@ -64,7 +64,7 @@ pub struct UserImpersonationRequestResponse {
|
||||
#[utoipa::path(
|
||||
get,
|
||||
tag = "Moderation",
|
||||
path = "/v1/moderation/user_sessions/impersonation_requests/{user_token}",
|
||||
path = "/v1/moderation/user_sessions/impersonation_requests/user/{user_token}",
|
||||
params(
|
||||
ListImpersonationRequestsQueryParams,
|
||||
),
|
||||
|
||||
+145
@@ -0,0 +1,145 @@
|
||||
use std::sync::Arc;
|
||||
|
||||
use actix_web::web::{Json, Query};
|
||||
use actix_web::{web, HttpRequest};
|
||||
use chrono::{DateTime, Utc};
|
||||
use log::warn;
|
||||
use utoipa::{IntoParams, ToSchema};
|
||||
|
||||
use mysql_queries::queries::user_impersonation_requests::list_user_impersonation_requests::{
|
||||
list_user_impersonation_requests, ListUserImpersonationRequestsArgs,
|
||||
};
|
||||
use tokens::tokens::users::UserToken;
|
||||
|
||||
use crate::http_server::common_responses::advanced_common_web_error::AdvancedCommonWebError;
|
||||
use crate::http_server::web_utils::user_session::require_moderator::{
|
||||
require_moderator, UseDatabase,
|
||||
};
|
||||
use crate::state::server_state::ServerState;
|
||||
|
||||
const CURSOR_NAME: &str = "modallimp";
|
||||
const DEFAULT_LIMIT: u32 = 50;
|
||||
const MAX_LIMIT: u32 = 1000;
|
||||
|
||||
// --- Request ---
|
||||
|
||||
#[derive(Deserialize, ToSchema, IntoParams)]
|
||||
pub struct ListAllImpersonationRequestsQueryParams {
|
||||
pub cursor: Option<String>,
|
||||
pub limit: Option<u32>,
|
||||
}
|
||||
|
||||
// --- Response ---
|
||||
|
||||
#[derive(Serialize, ToSchema)]
|
||||
pub struct ListAllImpersonationRequestsSuccessResponse {
|
||||
pub success: bool,
|
||||
pub impersonation_requests: Vec<AllImpersonationRequestResponse>,
|
||||
pub maybe_cursor: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Serialize, ToSchema)]
|
||||
pub struct AllImpersonationRequestResponse {
|
||||
pub impersonator_user_token: UserToken,
|
||||
pub impersonator_username: String,
|
||||
pub impersonator_display_name: String,
|
||||
pub impersonated_user_token: UserToken,
|
||||
pub impersonated_username: String,
|
||||
pub impersonated_display_name: String,
|
||||
pub is_redeemed: bool,
|
||||
pub is_expired: bool,
|
||||
pub expires_at: DateTime<Utc>,
|
||||
pub created_at: DateTime<Utc>,
|
||||
pub updated_at: DateTime<Utc>,
|
||||
}
|
||||
|
||||
// --- Handler ---
|
||||
|
||||
/// List all impersonation requests (not scoped to a user). Moderators only.
|
||||
#[utoipa::path(
|
||||
get,
|
||||
tag = "Moderation",
|
||||
path = "/v1/moderation/user_sessions/impersonation_requests/list",
|
||||
params(
|
||||
ListAllImpersonationRequestsQueryParams,
|
||||
),
|
||||
responses(
|
||||
(status = 200, description = "Success", body = ListAllImpersonationRequestsSuccessResponse),
|
||||
(status = 401, description = "Unauthorized"),
|
||||
(status = 500, description = "Server error"),
|
||||
),
|
||||
)]
|
||||
pub async fn moderator_list_user_session_impersonation_requests_handler(
|
||||
http_request: HttpRequest,
|
||||
query: Query<ListAllImpersonationRequestsQueryParams>,
|
||||
server_state: web::Data<Arc<ServerState>>,
|
||||
) -> Result<Json<ListAllImpersonationRequestsSuccessResponse>, AdvancedCommonWebError> {
|
||||
|
||||
let _user_session = require_moderator(
|
||||
&http_request,
|
||||
&server_state,
|
||||
UseDatabase::GrabNewConnection,
|
||||
).await.map_err(|err| {
|
||||
warn!("Moderator check failed: {:?}", err);
|
||||
AdvancedCommonWebError::NotAuthorized
|
||||
})?;
|
||||
|
||||
let limit = query.limit
|
||||
.unwrap_or(DEFAULT_LIMIT)
|
||||
.min(MAX_LIMIT);
|
||||
|
||||
let maybe_cursor_id = match &query.cursor {
|
||||
None => None,
|
||||
Some(cursor_str) => {
|
||||
let decoded = server_state.opaque_cursors
|
||||
.decode_cursor_expecting_name(CURSOR_NAME, cursor_str)
|
||||
.map_err(|err| {
|
||||
warn!("Failed to decode cursor: {:?}", err);
|
||||
AdvancedCommonWebError::BadInputWithSimpleMessage(
|
||||
"Invalid cursor".to_string())
|
||||
})?;
|
||||
decoded.last_id
|
||||
}
|
||||
};
|
||||
|
||||
let records = list_user_impersonation_requests(
|
||||
ListUserImpersonationRequestsArgs {
|
||||
maybe_cursor_id,
|
||||
limit,
|
||||
mysql_pool: &server_state.mysql_pool,
|
||||
},
|
||||
).await.map_err(|err| {
|
||||
warn!("Failed to list impersonation requests: {:?}", err);
|
||||
AdvancedCommonWebError::from_error(err)
|
||||
})?;
|
||||
|
||||
let maybe_cursor = records.last().map(|last| {
|
||||
server_state.opaque_cursors
|
||||
.encode_last_id_cursor(CURSOR_NAME, last.id)
|
||||
}).transpose().map_err(|err| {
|
||||
warn!("Failed to encode cursor: {:?}", err);
|
||||
AdvancedCommonWebError::server_error_with_message("Failed to encode cursor")
|
||||
})?;
|
||||
|
||||
let impersonation_requests = records.into_iter().map(|r| {
|
||||
AllImpersonationRequestResponse {
|
||||
impersonator_user_token: r.impersonator_user_token,
|
||||
impersonator_username: r.impersonator_username,
|
||||
impersonator_display_name: r.impersonator_display_name,
|
||||
impersonated_user_token: r.impersonated_user_token,
|
||||
impersonated_username: r.impersonated_username,
|
||||
impersonated_display_name: r.impersonated_display_name,
|
||||
is_redeemed: r.is_redeemed,
|
||||
is_expired: r.is_expired,
|
||||
expires_at: r.expires_at,
|
||||
created_at: r.created_at,
|
||||
updated_at: r.updated_at,
|
||||
}
|
||||
}).collect();
|
||||
|
||||
Ok(Json(ListAllImpersonationRequestsSuccessResponse {
|
||||
success: true,
|
||||
impersonation_requests,
|
||||
maybe_cursor,
|
||||
}))
|
||||
}
|
||||
+6
-1
@@ -37,6 +37,7 @@ use crate::http_server::endpoints::moderation::user::moderator_user_lookup_handl
|
||||
use crate::http_server::endpoints::moderation::alerts::moderation_send_alert_handler::moderation_send_alert_handler;
|
||||
use crate::http_server::endpoints::moderation::user_feature_flags::edit_user_feature_flags_handler::edit_user_feature_flags_handler;
|
||||
use crate::http_server::endpoints::moderation::user_sessions::moderator_list_user_session_impersonation_requests_for_user_handler::moderator_list_user_session_impersonation_requests_for_user_handler;
|
||||
use crate::http_server::endpoints::moderation::user_sessions::moderator_list_user_session_impersonation_requests_handler::moderator_list_user_session_impersonation_requests_handler;
|
||||
use crate::http_server::endpoints::moderation::user_sessions::moderator_user_session_impersonation_request_handler::moderator_user_session_impersonation_request_handler;
|
||||
|
||||
pub fn add_moderator_routes<T, B> (app: App<T>) -> App<T>
|
||||
@@ -110,7 +111,11 @@ pub fn add_moderator_routes<T, B> (app: App<T>) -> App<T>
|
||||
.route(web::post().to(moderator_user_session_impersonation_request_handler))
|
||||
.route(web::head().to(|| HttpResponse::Ok()))
|
||||
)
|
||||
.service(web::resource("/impersonation_requests/{user_token}")
|
||||
.service(web::resource("/impersonation_requests/list")
|
||||
.route(web::get().to(moderator_list_user_session_impersonation_requests_handler))
|
||||
.route(web::head().to(|| HttpResponse::Ok()))
|
||||
)
|
||||
.service(web::resource("/impersonation_requests/user/{user_token}")
|
||||
.route(web::get().to(moderator_list_user_session_impersonation_requests_for_user_handler))
|
||||
.route(web::head().to(|| HttpResponse::Ok()))
|
||||
)
|
||||
|
||||
Reference in new issue
Block a user