mirror of
https://github.com/warp-tech/warpgate.git
synced 2024-09-20 06:46:17 +08:00
don't suggest public key auth in the web auth API
This commit is contained in:
parent
e3b26b2699
commit
b346ca3d0b
|
@ -5,7 +5,7 @@ use std::time::{Duration, Instant};
|
|||
use once_cell::sync::Lazy;
|
||||
use tokio::sync::{broadcast, Mutex};
|
||||
use uuid::Uuid;
|
||||
use warpgate_common::auth::{AuthResult, AuthState};
|
||||
use warpgate_common::auth::{AuthResult, AuthState, CredentialKind};
|
||||
use warpgate_common::{SessionId, WarpgateError};
|
||||
|
||||
use crate::ConfigProvider;
|
||||
|
@ -52,13 +52,14 @@ impl AuthStateStore {
|
|||
session_id: Option<&SessionId>,
|
||||
username: &str,
|
||||
protocol: &str,
|
||||
supported_credential_types: &[CredentialKind],
|
||||
) -> Result<(Uuid, Arc<Mutex<AuthState>>), WarpgateError> {
|
||||
let id = Uuid::new_v4();
|
||||
let policy = self
|
||||
.config_provider
|
||||
.lock()
|
||||
.await
|
||||
.get_credential_policy(username)
|
||||
.get_credential_policy(username, supported_credential_types)
|
||||
.await?;
|
||||
let Some(policy) = policy else {
|
||||
return Err(WarpgateError::UserNotFound)
|
||||
|
|
|
@ -63,6 +63,7 @@ impl ConfigProvider for DatabaseConfigProvider {
|
|||
async fn get_credential_policy(
|
||||
&mut self,
|
||||
username: &str,
|
||||
supported_credential_types: &[CredentialKind],
|
||||
) -> Result<Option<Box<dyn CredentialPolicy + Sync + Send>>, WarpgateError> {
|
||||
let db = self.db.lock().await;
|
||||
|
||||
|
@ -78,8 +79,12 @@ impl ConfigProvider for DatabaseConfigProvider {
|
|||
|
||||
let user: UserConfig = user_model.try_into()?;
|
||||
|
||||
let supported_credential_types: HashSet<CredentialKind> =
|
||||
user.credentials.iter().map(|x| x.kind()).collect();
|
||||
let supported_credential_types: HashSet<CredentialKind> = user
|
||||
.credentials
|
||||
.iter()
|
||||
.map(|x| x.kind())
|
||||
.filter(|x| supported_credential_types.contains(x))
|
||||
.collect();
|
||||
let default_policy = Box::new(AnySingleCredentialPolicy {
|
||||
supported_credential_types: supported_credential_types.clone(),
|
||||
}) as Box<dyn CredentialPolicy + Sync + Send>;
|
||||
|
|
|
@ -59,6 +59,7 @@ impl ConfigProvider for FileConfigProvider {
|
|||
async fn get_credential_policy(
|
||||
&mut self,
|
||||
username: &str,
|
||||
supported_credential_types: &[CredentialKind],
|
||||
) -> Result<Option<Box<dyn CredentialPolicy + Sync + Send>>, WarpgateError> {
|
||||
let user = {
|
||||
self.config
|
||||
|
@ -75,8 +76,12 @@ impl ConfigProvider for FileConfigProvider {
|
|||
return Ok(None);
|
||||
};
|
||||
|
||||
let supported_credential_types: HashSet<CredentialKind> =
|
||||
user.credentials.iter().map(|x| x.kind()).collect();
|
||||
let supported_credential_types: HashSet<CredentialKind> = user
|
||||
.credentials
|
||||
.iter()
|
||||
.map(|x| x.kind())
|
||||
.filter(|x| supported_credential_types.contains(x))
|
||||
.collect();
|
||||
let default_policy = Box::new(AnySingleCredentialPolicy {
|
||||
supported_credential_types: supported_credential_types.clone(),
|
||||
}) as Box<dyn CredentialPolicy + Sync + Send>;
|
||||
|
|
|
@ -10,7 +10,7 @@ use sea_orm::{ActiveModelTrait, ColumnTrait, DatabaseConnection, EntityTrait, Qu
|
|||
use tokio::sync::Mutex;
|
||||
use tracing::*;
|
||||
use uuid::Uuid;
|
||||
use warpgate_common::auth::{AuthCredential, CredentialPolicy};
|
||||
use warpgate_common::auth::{AuthCredential, CredentialPolicy, CredentialKind};
|
||||
use warpgate_common::{Secret, Target, User, WarpgateError};
|
||||
use warpgate_db_entities::Ticket;
|
||||
|
||||
|
@ -34,6 +34,7 @@ pub trait ConfigProvider {
|
|||
async fn get_credential_policy(
|
||||
&mut self,
|
||||
username: &str,
|
||||
supported_credential_types: &[CredentialKind],
|
||||
) -> Result<Option<Box<dyn CredentialPolicy + Sync + Send>>, WarpgateError>;
|
||||
|
||||
async fn authorize_target(
|
||||
|
|
|
@ -81,18 +81,32 @@ enum AuthStateResponse {
|
|||
NotFound,
|
||||
}
|
||||
|
||||
const PREFERRED_NEED_CRED_ORDER: &[CredentialKind] = &[
|
||||
CredentialKind::PublicKey,
|
||||
CredentialKind::Password,
|
||||
CredentialKind::Totp,
|
||||
CredentialKind::Sso,
|
||||
CredentialKind::WebUserApproval,
|
||||
];
|
||||
|
||||
impl From<AuthResult> for ApiAuthState {
|
||||
fn from(state: AuthResult) -> Self {
|
||||
match state {
|
||||
AuthResult::Rejected => ApiAuthState::Failed,
|
||||
AuthResult::Need(kinds) => match kinds.iter().next() {
|
||||
Some(CredentialKind::Password) => ApiAuthState::PasswordNeeded,
|
||||
Some(CredentialKind::Totp) => ApiAuthState::OtpNeeded,
|
||||
Some(CredentialKind::Sso) => ApiAuthState::SsoNeeded,
|
||||
Some(CredentialKind::WebUserApproval) => ApiAuthState::WebUserApprovalNeeded,
|
||||
Some(CredentialKind::PublicKey) => ApiAuthState::PublicKeyNeeded,
|
||||
None => ApiAuthState::Failed,
|
||||
},
|
||||
AuthResult::Need(kinds) => {
|
||||
let kind = PREFERRED_NEED_CRED_ORDER
|
||||
.iter()
|
||||
.find(|x| kinds.contains(x))
|
||||
.or(kinds.iter().next());
|
||||
match kind {
|
||||
Some(CredentialKind::Password) => ApiAuthState::PasswordNeeded,
|
||||
Some(CredentialKind::Totp) => ApiAuthState::OtpNeeded,
|
||||
Some(CredentialKind::Sso) => ApiAuthState::SsoNeeded,
|
||||
Some(CredentialKind::WebUserApproval) => ApiAuthState::WebUserApprovalNeeded,
|
||||
Some(CredentialKind::PublicKey) => ApiAuthState::PublicKeyNeeded,
|
||||
None => ApiAuthState::Failed,
|
||||
}
|
||||
}
|
||||
AuthResult::Accepted { .. } => ApiAuthState::Success,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,7 +9,7 @@ use poem::{Endpoint, EndpointExt, FromRequest, IntoResponse, Request, Response};
|
|||
use serde::{Deserialize, Serialize};
|
||||
use tokio::sync::Mutex;
|
||||
use uuid::Uuid;
|
||||
use warpgate_common::auth::AuthState;
|
||||
use warpgate_common::auth::{AuthState, CredentialKind};
|
||||
use warpgate_common::{ProtocolName, TargetOptions, WarpgateError};
|
||||
use warpgate_core::{AuthStateStore, Services};
|
||||
|
||||
|
@ -204,7 +204,16 @@ pub async fn get_auth_state_for_request(
|
|||
}
|
||||
|
||||
let (id, state) = store
|
||||
.create(None, username, crate::common::PROTOCOL_NAME)
|
||||
.create(
|
||||
None,
|
||||
username,
|
||||
crate::common::PROTOCOL_NAME,
|
||||
&[
|
||||
CredentialKind::Password,
|
||||
CredentialKind::Sso,
|
||||
CredentialKind::Totp,
|
||||
],
|
||||
)
|
||||
.await?;
|
||||
session.set(AUTH_STATE_ID_SESSION_KEY, AuthStateId(id));
|
||||
Ok(state)
|
||||
|
|
|
@ -8,7 +8,7 @@ use tokio::net::TcpStream;
|
|||
use tokio::sync::Mutex;
|
||||
use tracing::*;
|
||||
use uuid::Uuid;
|
||||
use warpgate_common::auth::{AuthCredential, AuthResult, AuthSelector};
|
||||
use warpgate_common::auth::{AuthCredential, AuthResult, AuthSelector, CredentialKind};
|
||||
use warpgate_common::helpers::rng::get_crypto_rng;
|
||||
use warpgate_common::{Secret, TargetMySqlOptions, TargetOptions};
|
||||
use warpgate_core::{authorize_ticket, consume_ticket, Services, WarpgateServerHandle};
|
||||
|
@ -194,6 +194,7 @@ impl MySqlSession {
|
|||
Some(&self.server_handle.lock().await.id()),
|
||||
&username,
|
||||
crate::common::PROTOCOL_NAME,
|
||||
&[CredentialKind::Password],
|
||||
)
|
||||
.await?
|
||||
.1;
|
||||
|
|
|
@ -228,7 +228,17 @@ impl ServerSession {
|
|||
.auth_state_store
|
||||
.lock()
|
||||
.await
|
||||
.create(Some(&self.id), username, crate::PROTOCOL_NAME)
|
||||
.create(
|
||||
Some(&self.id),
|
||||
username,
|
||||
crate::PROTOCOL_NAME,
|
||||
&[
|
||||
CredentialKind::Password,
|
||||
CredentialKind::PublicKey,
|
||||
CredentialKind::Totp,
|
||||
CredentialKind::WebUserApproval,
|
||||
],
|
||||
)
|
||||
.await?
|
||||
.1;
|
||||
self.auth_state = Some(state);
|
||||
|
|
|
@ -120,6 +120,7 @@ async function cancel () {
|
|||
function onInputKey (event: KeyboardEvent) {
|
||||
if (event.key === 'Enter') {
|
||||
login()
|
||||
event.preventDefault()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue