140 lines
3.9 KiB
Rust
140 lines
3.9 KiB
Rust
use iam_service::models::{CreateUserRequest, LoginRequest};
|
|
use iam_service::services::{AuthService, TenantService, UserService};
|
|
use sqlx::PgPool;
|
|
use uuid::Uuid;
|
|
|
|
#[tokio::test]
|
|
async fn password_reset_self_and_admin_flow()
|
|
-> Result<(), Box<dyn std::error::Error>> {
|
|
let database_url = match std::env::var("DATABASE_URL") {
|
|
Ok(v) if !v.trim().is_empty() => v,
|
|
_ => return Ok(()),
|
|
};
|
|
|
|
let pool = PgPool::connect(&database_url).await?;
|
|
|
|
let has_users: Option<String> = sqlx::query_scalar("SELECT to_regclass('public.users')::text")
|
|
.fetch_one(&pool)
|
|
.await?;
|
|
let has_refresh_tokens: Option<String> =
|
|
sqlx::query_scalar("SELECT to_regclass('public.refresh_tokens')::text")
|
|
.fetch_one(&pool)
|
|
.await?;
|
|
if has_users.is_none() || has_refresh_tokens.is_none() {
|
|
return Ok(());
|
|
}
|
|
|
|
let tenant_service = TenantService::new(pool.clone());
|
|
let user_service = UserService::new(pool.clone());
|
|
let auth_service = AuthService::new(pool.clone(), "unused".to_string());
|
|
|
|
let tenant = tenant_service
|
|
.create_tenant(iam_service::models::CreateTenantRequest {
|
|
name: format!("pwreset-{}", Uuid::new_v4()),
|
|
config: None,
|
|
})
|
|
.await?;
|
|
|
|
let admin = auth_service
|
|
.register(
|
|
tenant.id,
|
|
CreateUserRequest {
|
|
email: format!("admin-{}@example.com", Uuid::new_v4()),
|
|
password: "AdminOldPassword123".to_string(),
|
|
},
|
|
)
|
|
.await?;
|
|
let user = auth_service
|
|
.register(
|
|
tenant.id,
|
|
CreateUserRequest {
|
|
email: format!("user-{}@example.com", Uuid::new_v4()),
|
|
password: "UserOldPassword123".to_string(),
|
|
},
|
|
)
|
|
.await?;
|
|
|
|
let login1 = auth_service
|
|
.login(
|
|
tenant.id,
|
|
LoginRequest {
|
|
email: user.email.clone(),
|
|
password: "UserOldPassword123".to_string(),
|
|
},
|
|
)
|
|
.await?;
|
|
let active_tokens: i64 =
|
|
sqlx::query_scalar("SELECT COUNT(1) FROM refresh_tokens WHERE user_id = $1 AND is_revoked = FALSE")
|
|
.bind(user.id)
|
|
.fetch_one(&pool)
|
|
.await?;
|
|
assert!(active_tokens >= 1);
|
|
|
|
user_service
|
|
.reset_my_password(
|
|
tenant.id,
|
|
user.id,
|
|
"UserOldPassword123".to_string(),
|
|
"UserNewPassword456".to_string(),
|
|
)
|
|
.await?;
|
|
|
|
let revoked_tokens: i64 =
|
|
sqlx::query_scalar("SELECT COUNT(1) FROM refresh_tokens WHERE user_id = $1 AND is_revoked = TRUE")
|
|
.bind(user.id)
|
|
.fetch_one(&pool)
|
|
.await?;
|
|
assert!(revoked_tokens >= 1);
|
|
|
|
let old_login = auth_service
|
|
.login(
|
|
tenant.id,
|
|
LoginRequest {
|
|
email: user.email.clone(),
|
|
password: "UserOldPassword123".to_string(),
|
|
},
|
|
)
|
|
.await;
|
|
assert!(old_login.is_err());
|
|
|
|
let _new_login = auth_service
|
|
.login(
|
|
tenant.id,
|
|
LoginRequest {
|
|
email: user.email.clone(),
|
|
password: "UserNewPassword456".to_string(),
|
|
},
|
|
)
|
|
.await?;
|
|
|
|
let temp = user_service
|
|
.reset_user_password_as_admin(tenant.id, admin.id, user.id, Some(24))
|
|
.await?;
|
|
assert!(temp.len() >= 16 && temp.len() <= 64);
|
|
|
|
let old2 = auth_service
|
|
.login(
|
|
tenant.id,
|
|
LoginRequest {
|
|
email: user.email.clone(),
|
|
password: "UserNewPassword456".to_string(),
|
|
},
|
|
)
|
|
.await;
|
|
assert!(old2.is_err());
|
|
|
|
let _temp_login = auth_service
|
|
.login(
|
|
tenant.id,
|
|
LoginRequest {
|
|
email: user.email.clone(),
|
|
password: temp.clone(),
|
|
},
|
|
)
|
|
.await?;
|
|
|
|
let _ = login1;
|
|
Ok(())
|
|
}
|
|
|