ezidam: authorize: don't prompt login if already authenticated
This commit is contained in:
parent
8db0bbb874
commit
1dec56ed14
5 changed files with 76 additions and 34 deletions
|
|
@ -4,6 +4,7 @@ use jwt::JwtClaims;
|
||||||
use rocket::request::{FromRequest, Outcome};
|
use rocket::request::{FromRequest, Outcome};
|
||||||
use rocket::Request;
|
use rocket::Request;
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
pub struct JwtAdmin(pub JwtClaims);
|
pub struct JwtAdmin(pub JwtClaims);
|
||||||
|
|
||||||
#[rocket::async_trait]
|
#[rocket::async_trait]
|
||||||
|
|
|
||||||
|
|
@ -1,13 +1,15 @@
|
||||||
use super::use_access_token_or_refresh_token;
|
use super::use_access_token_or_refresh_token;
|
||||||
|
use super::Error;
|
||||||
use jwt::JwtClaims;
|
use jwt::JwtClaims;
|
||||||
use rocket::request::{FromRequest, Outcome};
|
use rocket::request::{FromRequest, Outcome};
|
||||||
use rocket::Request;
|
use rocket::Request;
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
pub struct JwtUser(pub JwtClaims);
|
pub struct JwtUser(pub JwtClaims);
|
||||||
|
|
||||||
#[rocket::async_trait]
|
#[rocket::async_trait]
|
||||||
impl<'r> FromRequest<'r> for JwtUser {
|
impl<'r> FromRequest<'r> for JwtUser {
|
||||||
type Error = super::Error;
|
type Error = Error;
|
||||||
|
|
||||||
async fn from_request(request: &'r Request<'_>) -> Outcome<Self, Self::Error> {
|
async fn from_request(request: &'r Request<'_>) -> Outcome<Self, Self::Error> {
|
||||||
let get_admin: Option<bool> = None;
|
let get_admin: Option<bool> = None;
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,7 @@ pub fn routes() -> Vec<Route> {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub mod content {
|
pub mod content {
|
||||||
|
use jwt::JwtClaims;
|
||||||
use rocket::serde::Serialize;
|
use rocket::serde::Serialize;
|
||||||
|
|
||||||
#[derive(Serialize)]
|
#[derive(Serialize)]
|
||||||
|
|
@ -23,6 +24,7 @@ pub mod content {
|
||||||
pub struct Authorize {
|
pub struct Authorize {
|
||||||
pub app_name: String,
|
pub app_name: String,
|
||||||
pub business_name: String,
|
pub business_name: String,
|
||||||
|
pub user: Option<JwtClaims>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize)]
|
#[derive(Serialize)]
|
||||||
|
|
|
||||||
|
|
@ -6,11 +6,10 @@ use rocket::{get, post};
|
||||||
use settings::Settings;
|
use settings::Settings;
|
||||||
use users::User;
|
use users::User;
|
||||||
|
|
||||||
// TODO: When already signed in, pass Result<GuardType> in existing routes directly
|
#[get("/oauth/authorize?<auth_request..>", rank = 1)]
|
||||||
|
|
||||||
#[get("/oauth/authorize?<auth_request..>", rank = 2)]
|
|
||||||
pub async fn authorize_page(
|
pub async fn authorize_page(
|
||||||
mut db: Connection<Database>,
|
mut db: Connection<Database>,
|
||||||
|
user: Option<JwtUser>,
|
||||||
flash: Option<FlashMessage<'_>>,
|
flash: Option<FlashMessage<'_>>,
|
||||||
auth_request: AuthenticationRequest<'_>,
|
auth_request: AuthenticationRequest<'_>,
|
||||||
) -> Result<Template> {
|
) -> Result<Template> {
|
||||||
|
|
@ -34,6 +33,7 @@ pub async fn authorize_page(
|
||||||
let content = super::content::Authorize {
|
let content = super::content::Authorize {
|
||||||
app_name: app.label().into(),
|
app_name: app.label().into(),
|
||||||
business_name: settings.business_name().into(),
|
business_name: settings.business_name().into(),
|
||||||
|
user: user.map(|user| user.0),
|
||||||
};
|
};
|
||||||
|
|
||||||
Ok(flash
|
Ok(flash
|
||||||
|
|
@ -41,7 +41,7 @@ pub async fn authorize_page(
|
||||||
.unwrap_or_else(|| Page::Authorize(content).into()))
|
.unwrap_or_else(|| Page::Authorize(content).into()))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[get("/oauth/authorize", rank = 3)]
|
#[get("/oauth/authorize", rank = 2)]
|
||||||
pub async fn authorize_ezidam(mut db: Connection<Database>) -> Result<Redirect> {
|
pub async fn authorize_ezidam(mut db: Connection<Database>) -> Result<Redirect> {
|
||||||
let mut transaction = db.begin().await?;
|
let mut transaction = db.begin().await?;
|
||||||
|
|
||||||
|
|
@ -92,7 +92,8 @@ fn user_archived(login: &str, request: AuthenticationRequest) -> Flash<Redirect>
|
||||||
|
|
||||||
#[post("/oauth/authorize?<auth_request..>", data = "<form>")]
|
#[post("/oauth/authorize?<auth_request..>", data = "<form>")]
|
||||||
pub async fn authorize_form(
|
pub async fn authorize_form(
|
||||||
form: Form<Authorize<'_>>,
|
form: Option<Form<Authorize<'_>>>,
|
||||||
|
user: Option<JwtUser>,
|
||||||
mut db: Connection<Database>,
|
mut db: Connection<Database>,
|
||||||
auth_request: AuthenticationRequest<'_>,
|
auth_request: AuthenticationRequest<'_>,
|
||||||
) -> Result<Either<Redirect, Flash<Redirect>>> {
|
) -> Result<Either<Redirect, Flash<Redirect>>> {
|
||||||
|
|
@ -108,10 +109,24 @@ pub async fn authorize_form(
|
||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
|
let user_id = match user {
|
||||||
|
Some(user) => {
|
||||||
|
transaction.commit().await?;
|
||||||
|
|
||||||
|
UserID(user.0.subject)
|
||||||
|
}
|
||||||
|
None => {
|
||||||
|
let form = match form {
|
||||||
|
Some(form) => {
|
||||||
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();
|
form.into_inner()
|
||||||
|
}
|
||||||
|
None => {
|
||||||
|
return Ok(Either::Right(invalid_form(auth_request)));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
// 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 {
|
||||||
|
|
@ -137,12 +152,16 @@ pub async fn authorize_form(
|
||||||
return Ok(Either::Right(invalid_credentials(form.login, auth_request)));
|
return Ok(Either::Right(invalid_credentials(form.login, auth_request)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
user.id().to_owned()
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
// Generate authorization code
|
// Generate authorization code
|
||||||
let code = task::spawn_blocking(|| SecretString::new(35)).await?;
|
let code = task::spawn_blocking(|| SecretString::new(35)).await?;
|
||||||
|
|
||||||
// Save authorization code
|
// Save authorization code
|
||||||
let mut transaction = db.begin().await?;
|
let mut transaction = db.begin().await?;
|
||||||
AuthorizationCode::insert(&mut transaction, code.as_ref(), app.id(), user.id()).await?;
|
AuthorizationCode::insert(&mut transaction, code.as_ref(), app.id(), &user_id).await?;
|
||||||
transaction.commit().await?;
|
transaction.commit().await?;
|
||||||
|
|
||||||
// Construct uri to redirect to
|
// Construct uri to redirect to
|
||||||
|
|
|
||||||
|
|
@ -24,6 +24,19 @@
|
||||||
<p class="text-muted">With your {{ business_name }} account</p>
|
<p class="text-muted">With your {{ business_name }} account</p>
|
||||||
</div>
|
</div>
|
||||||
<form action="" method="post" autocomplete="off" novalidate class="mt-4">
|
<form action="" method="post" autocomplete="off" novalidate class="mt-4">
|
||||||
|
{% if user %}
|
||||||
|
<div class="mb-4 text-center">
|
||||||
|
<span class="avatar avatar-xl mb-3"
|
||||||
|
style="background-image: url(/avatar/{{ user.sub }}?size=250)"></span>
|
||||||
|
<h3>
|
||||||
|
{% if user.name %}
|
||||||
|
{{ user.name }}
|
||||||
|
{% else %}
|
||||||
|
{{ user.username }}
|
||||||
|
{% endif %}
|
||||||
|
</h3>
|
||||||
|
</div>
|
||||||
|
{% else %}
|
||||||
<div class="mb-3">
|
<div class="mb-3">
|
||||||
<label class="form-label">Login</label>
|
<label class="form-label">Login</label>
|
||||||
<input name="login" type="text" class="form-control" placeholder="Email or username"
|
<input name="login" type="text" class="form-control" placeholder="Email or username"
|
||||||
|
|
@ -36,15 +49,20 @@
|
||||||
autocomplete="off">
|
autocomplete="off">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
<div class="form-footer">
|
<div class="form-footer">
|
||||||
<button type="submit" class="btn btn-primary w-100">Sign in</button>
|
<button type="submit" class="btn btn-primary w-100">Authorize</button>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
{% if user %}
|
||||||
|
{% else %}
|
||||||
<div class="text-center text-muted mt-3">
|
<div class="text-center text-muted mt-3">
|
||||||
<a href="./sign-up.html" tabindex="-1">Reset password</a>
|
<a href="./sign-up.html" tabindex="-1">Reset password</a>
|
||||||
</div>
|
</div>
|
||||||
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
{% include "shell/footer" %}
|
{% include "shell/footer" %}
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue