Compare commits

..

No commits in common. "d70d622e041810c909d9a023e11ea110b403c925" and "fa31485e44680de0213553a2fc417eb57b290990" have entirely different histories.

6 changed files with 6 additions and 74 deletions

View file

@ -28,13 +28,8 @@
- [ ] Support error responses by https://datatracker.ietf.org/doc/html/rfc6749#section-4.1.2.1 - [ ] Support error responses by https://datatracker.ietf.org/doc/html/rfc6749#section-4.1.2.1
- [ ] UserWebGUI: Redirect to login when JWT expire - [ ] Redirect to login when JWT expire
- [ ] UserWebGUI: Show user authorizations.
- [ ] UserWebGUI: Show available apps
- [ ] UserWebGUI: Direct user grant flow, User can login to the target app/client, event if it did
not started here.
- [ ] Add admin panel via API - [ ] Add admin panel via API
- [ ] AdminWebGUI: Ability to create invitation links
- [ ] Add admin CLI - [ ] Add admin CLI
- [ ] add TOTP - [ ] add TOTP

View file

@ -1,28 +0,0 @@
[instance]
base_uri = "http://localhost:8085"
name = "Example org"
logo_uri = "https://example.org/logo.png"
[[applications]]
slug = "demo_app"
name = "Demo app"
description = "A super application where you can do everything you want."
client_id = "a1785786-8be1-443c-9a6f-35feed703609"
client_secret = "49c6c16a-0a8a-4981-a60d-5cb96582cc1a"
allowed_redirect_uris = [
"http://localhost:9090/authorize",
"http://localhost:9876/callback"
]
authorize_flow = "implicit"
[[roles]]
slug = "basic"
name = "Basic"
description = "Basic user"
default = true
[[roles]]
slug = "admin"
name = "Administrator"
description = "Full power on organization instance"

View file

@ -13,7 +13,6 @@ allowed_redirect_uris = [
"http://localhost:9090/authorize", "http://localhost:9090/authorize",
"http://localhost:9876/callback" "http://localhost:9876/callback"
] ]
authorize_flow = "Implicit"
[[roles]] [[roles]]
slug = "basic" slug = "basic"

View file

@ -8,7 +8,7 @@ use url::Url;
use uuid::Uuid; use uuid::Uuid;
use crate::{ use crate::{
models::{authorization::Authorization, config::AppAuthorizeFlow, token_claims::UserTokenClaims}, models::{authorization::Authorization, token_claims::UserTokenClaims},
renderer::TemplateRenderer, server::AppState, renderer::TemplateRenderer, server::AppState,
services::oauth2::{parse_scope, verify_redirect_uri}, services::oauth2::{parse_scope, verify_redirect_uri},
utils::get_random_alphanumerical utils::get_random_alphanumerical
@ -97,7 +97,6 @@ pub async fn authorize_form(
).into_response(); ).into_response();
} }
}; };
// 2. Check if the app is already authorized // 2. Check if the app is already authorized
let authorizations_res = sqlx::query_as::<_, Authorization>( let authorizations_res = sqlx::query_as::<_, Authorization>(
"SELECT * FROM authorizations WHERE user_id = $1 AND client_id = $2 AND scopes = $3" "SELECT * FROM authorizations WHERE user_id = $1 AND client_id = $2 AND scopes = $3"
@ -140,19 +139,7 @@ pub async fn authorize_form(
} }
} }
// 3. Check for implicit/explicit flow
if app.authorize_flow == AppAuthorizeFlow::Implicit {
debug!("Performing Implicit authorization flow.");
// Authorization already given, just redirect to the app
return perform_authorize(
State(app_state),
Extension(token_claims),
Form(authorization_params)
).await.into_response()
}
// 4. Show form that POST to authorize // 4. Show form that POST to authorize
debug!("Performing explicit authorization flow.");
renderer renderer
.render( .render(
"pages/authorize", "pages/authorize",

View file

@ -1,10 +1,5 @@
use axum::{
extract::{OriginalUri, Request, State}, use axum::{extract::{OriginalUri, Request, State}, http::StatusCode, middleware::Next, response::{Html, IntoResponse, Redirect, Response}, Extension};
http::{HeaderMap, HeaderValue, StatusCode},
middleware::Next,
response::{Html, IntoResponse, Redirect, Response},
Extension
};
use axum_extra::extract::CookieJar; use axum_extra::extract::CookieJar;
use crate::{ use crate::{
@ -17,7 +12,6 @@ use crate::{
/// add optional auth to the extension data /// add optional auth to the extension data
pub async fn auth_middleware( pub async fn auth_middleware(
State(app_state): State<AppState>, State(app_state): State<AppState>,
OriginalUri(original_uri): OriginalUri,
cookies: CookieJar, cookies: CookieJar,
mut req: Request, mut req: Request,
next: Next, next: Next,
@ -32,13 +26,8 @@ pub async fn auth_middleware(
let token_claims: UserTokenClaims = match verify_token(&app_state.secrets, jwt) { let token_claims: UserTokenClaims = match verify_token(&app_state.secrets, jwt) {
Ok(val) => val, Ok(val) => val,
Err(_e) => { Err(_e) => {
// UserWebGUI: delete invalid JWT cookie
let mut headers = HeaderMap::new();
let jwt_cookie = "minauth_jwt=deleted; SameSite=Lax; Max-Age=0".to_string();
headers.insert("Set-Cookie", HeaderValue::from_str(&jwt_cookie).unwrap());
headers.insert("Location", HeaderValue::from_str(&original_uri.to_string()).unwrap());
return Err( return Err(
(StatusCode::SEE_OTHER, headers, Html("Unauthorized: Invalid JWT cookie.")) (StatusCode::UNAUTHORIZED, Html("Unauthorized: The provided JWT is invalid."))
); );
} }
}; };

View file

@ -12,15 +12,6 @@ struct InstanceConfig {
logo_uri: Option<String> logo_uri: Option<String>
} }
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
#[fully_pub]
enum AppAuthorizeFlow {
/// user must grant the app
Explicit,
/// authorized by default for all scopes
Implicit
}
#[derive(Debug, Clone, Serialize, Deserialize)] #[derive(Debug, Clone, Serialize, Deserialize)]
#[fully_pub] #[fully_pub]
struct Application { struct Application {
@ -29,8 +20,7 @@ struct Application {
description: String, description: String,
client_id: String, client_id: String,
client_secret: String, client_secret: String,
allowed_redirect_uris: Vec<String>, allowed_redirect_uris: Vec<String>
authorize_flow: AppAuthorizeFlow
} }
#[derive(Debug, Clone, Serialize, Deserialize)] #[derive(Debug, Clone, Serialize, Deserialize)]