Compare commits
4 Commits
20251028
...
d27c542e1f
| Author | SHA1 | Date | |
|---|---|---|---|
| d27c542e1f | |||
| 412eaf2bff | |||
| eed9bcdf8b | |||
| 14bda544f7 |
693
Cargo.lock
generated
693
Cargo.lock
generated
File diff suppressed because it is too large
Load Diff
@@ -20,7 +20,7 @@ serde = { version = "1.0.159", features = ["derive"] }
|
|||||||
bcrypt = "0.14.0"
|
bcrypt = "0.14.0"
|
||||||
uuid = { version = "1.2.2", features = ["v4"] }
|
uuid = { version = "1.2.2", features = ["v4"] }
|
||||||
mime_guess = "2.0.4"
|
mime_guess = "2.0.4"
|
||||||
askama = "0.11.1"
|
askama = "0.12.0"
|
||||||
futures-util = "0.3.27"
|
futures-util = "0.3.27"
|
||||||
urlencoding = "2.1.2"
|
urlencoding = "2.1.2"
|
||||||
rand = "0.8.5"
|
rand = "0.8.5"
|
||||||
|
|||||||
@@ -16,6 +16,10 @@ You can configure a list of clients (Relying Parties) in a `clients.yaml` file w
|
|||||||
description: Git with a cup of tea
|
description: Git with a cup of tea
|
||||||
secret: TOP_SECRET
|
secret: TOP_SECRET
|
||||||
redirect_uri: https://mygit.mywebsite.com/
|
redirect_uri: https://mygit.mywebsite.com/
|
||||||
|
# If you want new accounts to be granted access to this client by default
|
||||||
|
default: true
|
||||||
|
# If you want the client to be granted to every users, regardless their account configuration
|
||||||
|
granted_to_all_users: true
|
||||||
```
|
```
|
||||||
|
|
||||||
On the first run, BasicOIDC will create a new administrator with credentials `admin` / `admin`. On first login you will have to change these default credentials.
|
On the first run, BasicOIDC will create a new administrator with credentials `admin` / `admin`. On first login you will have to change these default credentials.
|
||||||
|
|||||||
@@ -65,7 +65,7 @@ pub struct UpdateUserQuery {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub async fn users_route(
|
pub async fn users_route(
|
||||||
user: CurrentUser,
|
admin: CurrentUser,
|
||||||
users: web::Data<Addr<UsersActor>>,
|
users: web::Data<Addr<UsersActor>>,
|
||||||
update_query: Option<web::Form<UpdateUserQuery>>,
|
update_query: Option<web::Form<UpdateUserQuery>>,
|
||||||
logger: ActionLogger,
|
logger: ActionLogger,
|
||||||
@@ -225,7 +225,7 @@ pub async fn users_route(
|
|||||||
|
|
||||||
HttpResponse::Ok().body(
|
HttpResponse::Ok().body(
|
||||||
UsersListTemplate {
|
UsersListTemplate {
|
||||||
_p: BaseSettingsPage::get("Users list", &user, danger, success),
|
_p: BaseSettingsPage::get("Users list", &admin, danger, success),
|
||||||
users,
|
users,
|
||||||
}
|
}
|
||||||
.render()
|
.render()
|
||||||
@@ -233,11 +233,20 @@ pub async fn users_route(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn create_user(user: CurrentUser, clients: web::Data<ClientManager>) -> impl Responder {
|
pub async fn create_user(admin: CurrentUser, clients: web::Data<ClientManager>) -> impl Responder {
|
||||||
|
let mut user = User::default();
|
||||||
|
user.authorized_clients = Some(
|
||||||
|
clients
|
||||||
|
.get_default_clients()
|
||||||
|
.iter()
|
||||||
|
.map(|u| u.id.clone())
|
||||||
|
.collect(),
|
||||||
|
);
|
||||||
|
|
||||||
HttpResponse::Ok().body(
|
HttpResponse::Ok().body(
|
||||||
EditUserTemplate {
|
EditUserTemplate {
|
||||||
_p: BaseSettingsPage::get("Create a new user", user.deref(), None, None),
|
_p: BaseSettingsPage::get("Create a new user", admin.deref(), None, None),
|
||||||
u: Default::default(),
|
u: user,
|
||||||
clients: clients.cloned(),
|
clients: clients.cloned(),
|
||||||
}
|
}
|
||||||
.render()
|
.render()
|
||||||
@@ -251,7 +260,7 @@ pub struct EditUserQuery {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub async fn edit_user(
|
pub async fn edit_user(
|
||||||
user: CurrentUser,
|
admin: CurrentUser,
|
||||||
clients: web::Data<ClientManager>,
|
clients: web::Data<ClientManager>,
|
||||||
users: web::Data<Addr<UsersActor>>,
|
users: web::Data<Addr<UsersActor>>,
|
||||||
query: web::Query<EditUserQuery>,
|
query: web::Query<EditUserQuery>,
|
||||||
@@ -266,7 +275,7 @@ pub async fn edit_user(
|
|||||||
EditUserTemplate {
|
EditUserTemplate {
|
||||||
_p: BaseSettingsPage::get(
|
_p: BaseSettingsPage::get(
|
||||||
"Edit user account",
|
"Edit user account",
|
||||||
user.deref(),
|
admin.deref(),
|
||||||
match edited_account.is_none() {
|
match edited_account.is_none() {
|
||||||
true => Some("Could not find requested user!".to_string()),
|
true => Some("Could not find requested user!".to_string()),
|
||||||
false => None,
|
false => None,
|
||||||
|
|||||||
@@ -164,7 +164,7 @@ pub async fn authorize(
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Check if user is authorized to access the application
|
// Check if user is authorized to access the application
|
||||||
if !user.can_access_app(&client.id) {
|
if !user.can_access_app(&client) {
|
||||||
return error_redirect(
|
return error_redirect(
|
||||||
&query,
|
&query,
|
||||||
"invalid_request",
|
"invalid_request",
|
||||||
|
|||||||
@@ -6,11 +6,28 @@ pub struct ClientID(pub String);
|
|||||||
|
|
||||||
#[derive(Clone, Debug, serde::Serialize, serde::Deserialize)]
|
#[derive(Clone, Debug, serde::Serialize, serde::Deserialize)]
|
||||||
pub struct Client {
|
pub struct Client {
|
||||||
|
/// The ID of the client
|
||||||
pub id: ClientID,
|
pub id: ClientID,
|
||||||
|
|
||||||
|
/// The human-readable name of the client
|
||||||
pub name: String,
|
pub name: String,
|
||||||
|
|
||||||
|
/// A short description of the service provided by the client
|
||||||
pub description: String,
|
pub description: String,
|
||||||
|
|
||||||
|
/// The secret used by the client to retrieve authenticated users information
|
||||||
pub secret: String,
|
pub secret: String,
|
||||||
|
|
||||||
|
/// The URI where the users should be redirected once authenticated
|
||||||
pub redirect_uri: String,
|
pub redirect_uri: String,
|
||||||
|
|
||||||
|
/// Specify if the client must be allowed by default for new account
|
||||||
|
#[serde(default = "bool::default")]
|
||||||
|
pub default: bool,
|
||||||
|
|
||||||
|
/// Specify whether a client is granted to all users
|
||||||
|
#[serde(default = "bool::default")]
|
||||||
|
pub granted_to_all_users: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PartialEq for Client {
|
impl PartialEq for Client {
|
||||||
@@ -33,6 +50,13 @@ impl EntityManager<Client> {
|
|||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Get the list of default clients.
|
||||||
|
///
|
||||||
|
/// i.e. the clients that are granted to new accounts by default
|
||||||
|
pub fn get_default_clients(&self) -> Vec<&Client> {
|
||||||
|
self.iter().filter(|u| u.default).collect()
|
||||||
|
}
|
||||||
|
|
||||||
pub fn apply_environment_variables(&mut self) {
|
pub fn apply_environment_variables(&mut self) {
|
||||||
for c in self.iter_mut() {
|
for c in self.iter_mut() {
|
||||||
c.id = ClientID(apply_env_vars(&c.id.0));
|
c.id = ClientID(apply_env_vars(&c.id.0));
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ use std::collections::HashMap;
|
|||||||
use std::net::IpAddr;
|
use std::net::IpAddr;
|
||||||
|
|
||||||
use crate::constants::SECOND_FACTOR_EXEMPTION_AFTER_SUCCESSFUL_LOGIN;
|
use crate::constants::SECOND_FACTOR_EXEMPTION_AFTER_SUCCESSFUL_LOGIN;
|
||||||
use crate::data::client::ClientID;
|
use crate::data::client::{Client, ClientID};
|
||||||
use crate::data::login_redirect::LoginRedirect;
|
use crate::data::login_redirect::LoginRedirect;
|
||||||
use crate::data::totp_key::TotpKey;
|
use crate::data::totp_key::TotpKey;
|
||||||
use crate::data::webauthn_manager::WebauthnPubKey;
|
use crate::data::webauthn_manager::WebauthnPubKey;
|
||||||
@@ -170,10 +170,14 @@ impl User {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn can_access_app(&self, id: &ClientID) -> bool {
|
pub fn can_access_app(&self, client: &Client) -> bool {
|
||||||
|
if client.granted_to_all_users {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
match self.granted_clients() {
|
match self.granted_clients() {
|
||||||
GrantedClients::AllClients => true,
|
GrantedClients::AllClients => true,
|
||||||
GrantedClients::SomeClients(c) => c.contains(id),
|
GrantedClients::SomeClients(c) => c.contains(&client.id),
|
||||||
GrantedClients::NoClient => false,
|
GrantedClients::NoClient => false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -144,7 +144,7 @@
|
|||||||
<div class="form-check">
|
<div class="form-check">
|
||||||
<input id="client-{{ c.id.0 }}" class="form-check-input authorize_client_checkbox" type="checkbox"
|
<input id="client-{{ c.id.0 }}" class="form-check-input authorize_client_checkbox" type="checkbox"
|
||||||
data-id="{{ c.id.0 }}"
|
data-id="{{ c.id.0 }}"
|
||||||
{% if u.can_access_app(c.id) %} checked="" {% endif %}>
|
{% if u.can_access_app(c) %} checked="" {% endif %}>
|
||||||
<label class="form-check-label" for="client-{{ c.id.0 }}">
|
<label class="form-check-label" for="client-{{ c.id.0 }}">
|
||||||
{{ c.name }}
|
{{ c.name }}
|
||||||
</label>
|
</label>
|
||||||
|
|||||||
Reference in New Issue
Block a user