ezidam, openid: refactor check app in method, verifying and send POST as well
This commit is contained in:
parent
8ae0c59a25
commit
eb93cbd7ec
7 changed files with 76 additions and 22 deletions
1
Cargo.lock
generated
1
Cargo.lock
generated
|
|
@ -86,6 +86,7 @@ dependencies = [
|
||||||
"database",
|
"database",
|
||||||
"hash",
|
"hash",
|
||||||
"id",
|
"id",
|
||||||
|
"openid",
|
||||||
"thiserror",
|
"thiserror",
|
||||||
"url",
|
"url",
|
||||||
]
|
]
|
||||||
|
|
|
||||||
|
|
@ -12,3 +12,4 @@ url = { workspace = true }
|
||||||
id = { path = "../id" }
|
id = { path = "../id" }
|
||||||
database = { path = "../database" }
|
database = { path = "../database" }
|
||||||
hash = { path = "../hash" }
|
hash = { path = "../hash" }
|
||||||
|
openid = { path = "../openid" }
|
||||||
|
|
@ -42,11 +42,11 @@ impl App {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// App needs to be not archived
|
/// App needs to be not archived
|
||||||
pub async fn get_one(
|
pub(crate) async fn get_one(
|
||||||
conn: impl SqliteExecutor<'_>,
|
conn: impl SqliteExecutor<'_>,
|
||||||
id: &str,
|
id: &str,
|
||||||
redirect: &str,
|
redirect: &str,
|
||||||
) -> Result<Option<Self>, Error> {
|
) -> Result<Option<Self>, database::Error> {
|
||||||
Ok(DatabaseApps::get_one(conn, id, redirect)
|
Ok(DatabaseApps::get_one(conn, id, redirect)
|
||||||
.await?
|
.await?
|
||||||
.map(Self::from))
|
.map(Self::from))
|
||||||
|
|
|
||||||
42
crates/apps/src/get_valid.rs
Normal file
42
crates/apps/src/get_valid.rs
Normal file
|
|
@ -0,0 +1,42 @@
|
||||||
|
// error
|
||||||
|
#[derive(thiserror::Error)]
|
||||||
|
// the rest
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub enum Error {
|
||||||
|
#[error("Database: {0}")]
|
||||||
|
Database(#[from] database::Error),
|
||||||
|
|
||||||
|
#[error("Bad response types")]
|
||||||
|
ResponseTypes,
|
||||||
|
|
||||||
|
#[error("Invalid scopes")]
|
||||||
|
Scopes,
|
||||||
|
|
||||||
|
#[error("Invalid application")]
|
||||||
|
Application,
|
||||||
|
}
|
||||||
|
|
||||||
|
use super::App;
|
||||||
|
use database::sqlx::SqliteExecutor;
|
||||||
|
|
||||||
|
impl App {
|
||||||
|
pub async fn get_valid_app(
|
||||||
|
conn: impl SqliteExecutor<'_>,
|
||||||
|
response_type: &str,
|
||||||
|
scope: &str,
|
||||||
|
client_id: &str,
|
||||||
|
redirect_uri: &str,
|
||||||
|
) -> Result<App, Error> {
|
||||||
|
// Check for valid response types
|
||||||
|
openid::parse_response_types(response_type).ok_or_else(|| Error::ResponseTypes)?;
|
||||||
|
|
||||||
|
// Check for supported scopes
|
||||||
|
if !openid::SupportedScopes::check_supported_scopes(scope) {
|
||||||
|
return Err(Error::Scopes);
|
||||||
|
}
|
||||||
|
|
||||||
|
Self::get_one(conn, client_id, redirect_uri)
|
||||||
|
.await?
|
||||||
|
.ok_or_else(|| Error::Application)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,10 +1,12 @@
|
||||||
mod database;
|
mod database;
|
||||||
mod error;
|
mod error;
|
||||||
|
mod get_valid;
|
||||||
|
|
||||||
use chrono::{DateTime, Utc};
|
use chrono::{DateTime, Utc};
|
||||||
use id::AppID;
|
use id::AppID;
|
||||||
|
|
||||||
pub use crate::error::Error;
|
pub use crate::error::Error;
|
||||||
|
pub use get_valid::Error as GetValidError;
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct App {
|
pub struct App {
|
||||||
|
|
|
||||||
|
|
@ -57,3 +57,14 @@ impl From<apps::Error> for Error {
|
||||||
Error::internal_server_error(e)
|
Error::internal_server_error(e)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl From<apps::GetValidError> for Error {
|
||||||
|
fn from(e: apps::GetValidError) -> Self {
|
||||||
|
match e {
|
||||||
|
apps::GetValidError::Database(e) => Error::internal_server_error(e),
|
||||||
|
apps::GetValidError::ResponseTypes
|
||||||
|
| apps::GetValidError::Scopes
|
||||||
|
| apps::GetValidError::Application => Error::bad_request(e),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -28,25 +28,17 @@ async fn authorize_page(
|
||||||
flash: Option<FlashMessage<'_>>,
|
flash: Option<FlashMessage<'_>>,
|
||||||
auth_request: AuthenticationRequest<'_>,
|
auth_request: AuthenticationRequest<'_>,
|
||||||
) -> Result<Template> {
|
) -> Result<Template> {
|
||||||
// Check for valid response types
|
|
||||||
openid::parse_response_types(auth_request.response_type)
|
|
||||||
.ok_or_else(|| Error::bad_request("Bad response types"))?;
|
|
||||||
|
|
||||||
// Check for supported scopes
|
|
||||||
if !openid::SupportedScopes::check_supported_scopes(auth_request.scope) {
|
|
||||||
return Err(Error::bad_request("Invalid scopes"));
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut transaction = db.begin().await?;
|
let mut transaction = db.begin().await?;
|
||||||
// TODO: wrap checking in function?
|
|
||||||
|
|
||||||
let app = App::get_one(
|
// Get app info
|
||||||
|
let app = App::get_valid_app(
|
||||||
&mut transaction,
|
&mut transaction,
|
||||||
|
auth_request.response_type,
|
||||||
|
auth_request.scope,
|
||||||
auth_request.client_id,
|
auth_request.client_id,
|
||||||
auth_request.redirect_uri,
|
auth_request.redirect_uri,
|
||||||
)
|
)
|
||||||
.await?
|
.await?;
|
||||||
.ok_or_else(|| Error::bad_request("Invalid application"))?;
|
|
||||||
|
|
||||||
let settings = Settings::get(&mut transaction).await?;
|
let settings = Settings::get(&mut transaction).await?;
|
||||||
|
|
||||||
|
|
@ -118,16 +110,23 @@ async fn authorize(
|
||||||
mut db: Connection<Database>,
|
mut db: Connection<Database>,
|
||||||
auth_request: AuthenticationRequest<'_>,
|
auth_request: AuthenticationRequest<'_>,
|
||||||
) -> Result<Either<Redirect, Flash<Redirect>>> {
|
) -> Result<Either<Redirect, Flash<Redirect>>> {
|
||||||
// TODO: check app and stuff before doing anything AGAIN, this is important
|
let mut transaction = db.begin().await?;
|
||||||
// TODO: check if request uri matches
|
|
||||||
|
// Get app info
|
||||||
|
let app = App::get_valid_app(
|
||||||
|
&mut transaction,
|
||||||
|
auth_request.response_type,
|
||||||
|
auth_request.scope,
|
||||||
|
auth_request.client_id,
|
||||||
|
auth_request.redirect_uri,
|
||||||
|
)
|
||||||
|
.await?;
|
||||||
|
|
||||||
if form.login.is_empty() {
|
if form.login.is_empty() {
|
||||||
return Ok(Either::Right(invalid_form(auth_request)));
|
return Ok(Either::Right(invalid_form(auth_request)));
|
||||||
}
|
}
|
||||||
let form = form.into_inner();
|
let form = form.into_inner();
|
||||||
|
|
||||||
let mut transaction = db.begin().await?;
|
|
||||||
|
|
||||||
// Get user
|
// Get user
|
||||||
let Some(user) = User::get_by_login(&mut transaction, form.login).await? else {
|
let Some(user) = User::get_by_login(&mut transaction, form.login).await? else {
|
||||||
return Ok(Either::Right(invalid_credentials(form.login, auth_request)));
|
return Ok(Either::Right(invalid_credentials(form.login, auth_request)));
|
||||||
|
|
@ -154,9 +153,7 @@ async fn authorize(
|
||||||
// TODO: refresh token + jwt
|
// TODO: refresh token + jwt
|
||||||
|
|
||||||
// TODO: put more data
|
// TODO: put more data
|
||||||
Ok(Either::Left(Redirect::to(
|
Ok(Either::Left(Redirect::to(app.redirect_uri().to_string())))
|
||||||
auth_request.redirect_uri.to_string(),
|
|
||||||
)))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: oauth redirect route for ezidam
|
// TODO: oauth redirect route for ezidam
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue