feat: with noop
Some checks are pending
ci/woodpecker/pr/test Pipeline is pending

Signed-off-by: kjuulh <contact@kjuulh.io>
This commit is contained in:
2023-11-12 22:42:55 +01:00
parent 835cd32fb1
commit d4a162876a
7 changed files with 193 additions and 19 deletions

View File

@@ -26,12 +26,17 @@ pub struct AuthService(Arc<dyn Auth + Send + Sync + 'static>);
impl AuthService {
pub async fn new(config: &AuthClap) -> anyhow::Result<Self> {
match config.engine {
AuthEngine::Noop => Ok(Self::new_noop()),
AuthEngine::Noop => {
let session = SessionService::new(config).await?;
Ok(Self::new_noop(session, &config.config))
}
AuthEngine::Zitadel => {
let session = SessionService::new(config).await?;
let oauth: OAuth = ZitadelConfig::try_from(config.zitadel.clone())?.into();
let introspection: IntrospectionService =
IntrospectionService::new_zitadel(config).await?;
Ok(Self::new_zitadel(
oauth,
introspection,
@@ -56,8 +61,11 @@ impl AuthService {
}))
}
pub fn new_noop() -> Self {
Self(Arc::new(NoopAuthService {}))
pub fn new_noop(session: SessionService, config: &ConfigClap) -> Self {
Self(Arc::new(NoopAuthService {
session,
config: config.clone(),
}))
}
}
@@ -111,26 +119,62 @@ impl Auth for ZitadelAuthService {
}
}
pub struct NoopAuthService {}
pub struct NoopAuthService {
session: SessionService,
config: ConfigClap,
}
#[async_trait]
impl Auth for NoopAuthService {
async fn login(&self) -> anyhow::Result<Url> {
todo!()
let url = Url::parse(&format!(
"{}/auth/authorized?code=noop&state=noop",
self.config
.return_url
.rsplit_once('/')
.map(|(a, b)| a)
.unwrap()
))
.unwrap();
Ok(url)
}
async fn login_authorized(
&self,
_code: &str,
_state: &str,
) -> anyhow::Result<(HeaderMap, Url)> {
todo!()
let cookie_value = self
.session
.insert_user(
"user",
IdToken {
sub: uuid::Uuid::new_v4().to_string(),
email: format!("{}@kjuulh.io", uuid::Uuid::new_v4()),
name: uuid::Uuid::new_v4().to_string(),
},
)
.await?;
let cookie = format!("{}={}; SameSite=Lax; Path=/", COOKIE_NAME, cookie_value);
let mut headers = HeaderMap::new();
headers.insert(SET_COOKIE, cookie.parse().unwrap());
Ok((
headers,
Url::parse(&self.config.return_url)
.context("failed to parse login_authorized zitadel return url")?,
))
}
async fn login_token(&self, _user: &str, _password: &str) -> anyhow::Result<IdToken> {
todo!()
}
async fn get_user_from_session(&self, _cookie: &str) -> anyhow::Result<User> {
todo!()
async fn get_user_from_session(&self, cookie: &str) -> anyhow::Result<User> {
match self.session.get_user(cookie).await? {
Some(u) => Ok(u),
None => Err(anyhow::anyhow!("failed to find user")),
}
}
}

View File

@@ -15,7 +15,7 @@ pub struct AuthConfigFile {
zitadel: Option<ZitadelClap>,
}
#[derive(clap::Args, Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
#[derive(clap::Args, Clone, Debug, PartialEq, Eq, Serialize, Deserialize, Default)]
#[group(requires_all = ["client_id", "client_secret", "redirect_url", "authority_url"])]
pub struct ZitadelClap {
#[arg(env = "ZITADEL_CLIENT_ID", long = "zitadel-client-id")]

View File

@@ -19,7 +19,7 @@ pub struct SessionClap {
pub postgresql: PostgresqlSessionClap,
}
#[derive(clap::Args, Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
#[derive(clap::Args, Clone, Debug, PartialEq, Eq, Serialize, Deserialize, Default)]
pub struct PostgresqlSessionClap {
#[arg(env = "SESSION_POSTGRES_CONN", long = "session-postgres-conn")]
pub conn: Option<String>,
@@ -36,7 +36,7 @@ pub struct SessionService(Arc<dyn Session + Send + Sync + 'static>);
impl SessionService {
pub async fn new(config: &AuthClap) -> anyhow::Result<Self> {
match config.session_backend {
SessionBackend::InMemory => Ok(Self(Arc::new(InMemorySessionService {}))),
SessionBackend::InMemory => Ok(Self(Arc::new(InMemorySessionService::default()))),
SessionBackend::Postgresql => {
let postgres_session = PostgresSessionStore::new(
config
@@ -119,15 +119,30 @@ impl Session for PostgresSessionService {
}
}
pub struct InMemorySessionService {}
#[derive(Default)]
pub struct InMemorySessionService {
store: std::sync::Mutex<std::collections::BTreeMap<String, User>>,
}
#[async_trait]
impl Session for InMemorySessionService {
async fn insert_user(&self, _id: &str, _id_token: IdToken) -> anyhow::Result<String> {
todo!()
async fn insert_user(&self, _id: &str, id_token: IdToken) -> anyhow::Result<String> {
let user = User {
id: id_token.sub,
email: id_token.email,
name: id_token.name,
};
let id = uuid::Uuid::new_v4();
self.store.lock().unwrap().insert(id.to_string(), user);
Ok(id.to_string())
}
async fn get_user(&self, _cookie: &str) -> anyhow::Result<Option<User>> {
todo!()
async fn get_user(&self, cookie: &str) -> anyhow::Result<Option<User>> {
let user = self.store.lock().unwrap().get(cookie).cloned();
Ok(user)
}
}