Skip to content

Commit 91021c9

Browse files
committed
editoast: provide PgAuthDriver a connection instead of the pool
Signed-off-by: Leo Valais <[email protected]>
1 parent ba375b7 commit 91021c9

File tree

4 files changed

+38
-28
lines changed

4 files changed

+38
-28
lines changed

editoast/editoast_models/src/db_connection_pool.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ impl DbConnection {
5555
//
5656
// :WARNING: If you ever need to modify this function, please take a look at the
5757
// original `diesel` function, they probably do it right more than us.
58-
pub async fn transaction<'a, R, E, F>(self, callback: F) -> std::result::Result<R, E>
58+
pub async fn transaction<'a, R, E, F>(&self, callback: F) -> std::result::Result<R, E>
5959
where
6060
F: FnOnce(Self) -> ScopedBoxFuture<'a, 'a, std::result::Result<R, E>> + Send + 'a,
6161
E: From<diesel::result::Error> + Send + 'a,

editoast/openapi.yaml

+20
Original file line numberDiff line numberDiff line change
@@ -3454,6 +3454,25 @@ components:
34543454
type: string
34553455
enum:
34563456
- editoast:authz:AuthError
3457+
EditoastAuthorizationErrorDbError:
3458+
type: object
3459+
required:
3460+
- type
3461+
- status
3462+
- message
3463+
properties:
3464+
context:
3465+
type: object
3466+
message:
3467+
type: string
3468+
status:
3469+
type: integer
3470+
enum:
3471+
- 500
3472+
type:
3473+
type: string
3474+
enum:
3475+
- editoast:authz:DbError
34573476
EditoastAuthorizationErrorUnauthenticated:
34583477
type: object
34593478
required:
@@ -3984,6 +4003,7 @@ components:
39844003
- $ref: '#/components/schemas/EditoastAppHealthErrorTimeout'
39854004
- $ref: '#/components/schemas/EditoastAttachedErrorTrackNotFound'
39864005
- $ref: '#/components/schemas/EditoastAuthorizationErrorAuthError'
4006+
- $ref: '#/components/schemas/EditoastAuthorizationErrorDbError'
39874007
- $ref: '#/components/schemas/EditoastAuthorizationErrorUnauthenticated'
39884008
- $ref: '#/components/schemas/EditoastAuthorizationErrorUnauthorized'
39894009
- $ref: '#/components/schemas/EditoastAuthzErrorAuthz'

editoast/src/models/auth.rs

+12-25
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,28 @@
11
use std::collections::HashSet;
22
use std::ops::DerefMut;
3-
use std::sync::Arc;
43

54
use diesel::{dsl, prelude::*};
6-
use diesel_async::{scoped_futures::ScopedFutureExt, RunQueryDsl};
5+
use diesel_async::{scoped_futures::ScopedFutureExt as _, RunQueryDsl};
76
use editoast_authz::{
87
authorizer::{StorageDriver, UserInfo},
98
roles::{BuiltinRoleSet, RoleConfig},
109
};
11-
use editoast_models::DbConnectionPoolV2;
10+
use editoast_models::DbConnection;
1211

1312
use editoast_models::tables::*;
1413
use itertools::Itertools as _;
1514
use tracing::Level;
1615

1716
#[derive(Clone)]
1817
pub struct PgAuthDriver<B: BuiltinRoleSet + Send + Sync> {
19-
pool: Arc<DbConnectionPoolV2>,
18+
conn: DbConnection,
2019
_role_set: std::marker::PhantomData<B>,
2120
}
2221

2322
impl<B: BuiltinRoleSet + Send + Sync> PgAuthDriver<B> {
24-
pub fn new(pool: Arc<DbConnectionPoolV2>) -> Self {
23+
pub fn new(conn: DbConnection) -> Self {
2524
Self {
26-
pool,
25+
conn,
2726
_role_set: Default::default(),
2827
}
2928
}
@@ -33,8 +32,6 @@ impl<B: BuiltinRoleSet + Send + Sync> PgAuthDriver<B> {
3332
pub enum AuthDriverError {
3433
#[error(transparent)]
3534
DieselError(#[from] diesel::result::Error),
36-
#[error(transparent)]
37-
PoolError(#[from] editoast_models::db_connection_pool::DatabasePoolError),
3835
}
3936

4037
impl<B: BuiltinRoleSet + Send + Sync> StorageDriver for PgAuthDriver<B> {
@@ -43,23 +40,21 @@ impl<B: BuiltinRoleSet + Send + Sync> StorageDriver for PgAuthDriver<B> {
4340

4441
#[tracing::instrument(skip_all, fields(%user_info), ret(level = Level::DEBUG), err)]
4542
async fn get_user_id(&self, user_info: &UserInfo) -> Result<Option<i64>, Self::Error> {
46-
let conn = self.pool.get().await?;
4743
let id = authn_user::table
4844
.select(authn_user::id)
4945
.filter(authn_user::identity_id.eq(&user_info.identity))
50-
.first::<i64>(conn.write().await.deref_mut())
46+
.first::<i64>(self.conn.write().await.deref_mut())
5147
.await
5248
.optional()?;
5349
Ok(id)
5450
}
5551

5652
#[tracing::instrument(skip_all, fields(%user_id), ret(level = Level::DEBUG), err)]
5753
async fn get_user_info(&self, user_id: i64) -> Result<Option<UserInfo>, Self::Error> {
58-
let conn = self.pool.get().await?;
5954
let info = authn_user::table
6055
.select((authn_user::identity_id, authn_user::name))
6156
.filter(authn_user::id.eq(user_id))
62-
.first::<(String, Option<String>)>(conn.write().await.deref_mut())
57+
.first::<(String, Option<String>)>(self.conn.write().await.deref_mut())
6358
.await
6459
.optional()
6560
.map(|res| {
@@ -73,9 +68,7 @@ impl<B: BuiltinRoleSet + Send + Sync> StorageDriver for PgAuthDriver<B> {
7368

7469
#[tracing::instrument(skip_all, fields(%user), ret(level = Level::DEBUG), err)]
7570
async fn ensure_user(&self, user: &UserInfo) -> Result<i64, Self::Error> {
76-
self.pool
77-
.get()
78-
.await?
71+
self.conn
7972
.transaction(|conn| {
8073
async move {
8174
let user_id = self.get_user_id(user).await?;
@@ -118,16 +111,14 @@ impl<B: BuiltinRoleSet + Send + Sync> StorageDriver for PgAuthDriver<B> {
118111
subject_id: i64,
119112
roles_config: &RoleConfig<Self::BuiltinRole>,
120113
) -> Result<HashSet<Self::BuiltinRole>, Self::Error> {
121-
let conn = self.pool.get().await?;
122-
123114
let roles = authz_role::table
124115
.select(authz_role::role)
125116
.left_join(
126117
authn_group_membership::table.on(authn_group_membership::user.eq(subject_id)),
127118
)
128119
.filter(authz_role::subject.eq(subject_id))
129120
.or_filter(authz_role::subject.eq(authn_group_membership::group))
130-
.load::<String>(conn.write().await.deref_mut())
121+
.load::<String>(self.conn.write().await.deref_mut())
131122
.await?
132123
.into_iter()
133124
.map(|role| {
@@ -147,8 +138,6 @@ impl<B: BuiltinRoleSet + Send + Sync> StorageDriver for PgAuthDriver<B> {
147138
roles_config: &RoleConfig<Self::BuiltinRole>,
148139
roles: HashSet<Self::BuiltinRole>,
149140
) -> Result<(), Self::Error> {
150-
let conn = self.pool.get().await?;
151-
152141
dsl::insert_into(authz_role::table)
153142
.values(
154143
roles
@@ -163,7 +152,7 @@ impl<B: BuiltinRoleSet + Send + Sync> StorageDriver for PgAuthDriver<B> {
163152
)
164153
.on_conflict((authz_role::subject, authz_role::role))
165154
.do_nothing()
166-
.execute(conn.write().await.deref_mut())
155+
.execute(self.conn.write().await.deref_mut())
167156
.await?;
168157

169158
Ok(())
@@ -176,8 +165,6 @@ impl<B: BuiltinRoleSet + Send + Sync> StorageDriver for PgAuthDriver<B> {
176165
roles_config: &RoleConfig<Self::BuiltinRole>,
177166
roles: HashSet<Self::BuiltinRole>,
178167
) -> Result<HashSet<Self::BuiltinRole>, Self::Error> {
179-
let conn = self.pool.get().await?;
180-
181168
let deleted_roles = dsl::delete(
182169
authz_role::table
183170
.filter(authz_role::subject.eq(subject_id))
@@ -186,7 +173,7 @@ impl<B: BuiltinRoleSet + Send + Sync> StorageDriver for PgAuthDriver<B> {
186173
),
187174
)
188175
.returning(authz_role::role)
189-
.load::<String>(conn.write().await.deref_mut())
176+
.load::<String>(self.conn.write().await.deref_mut())
190177
.await?
191178
.into_iter()
192179
.map(|role| {
@@ -227,7 +214,7 @@ mod tests {
227214
#[rstest::rstest]
228215
async fn test_auth_driver() {
229216
let pool = DbConnectionPoolV2::for_tests();
230-
let mut driver = PgAuthDriver::<TestBuiltinRole>::new(pool.into());
217+
let mut driver = PgAuthDriver::<TestBuiltinRole>::new(pool.get_ok());
231218
let config = default_test_config();
232219

233220
let uid = driver

editoast/src/views/mod.rs

+5-2
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,7 @@ async fn make_authorizer(
124124
if roles.is_superuser() {
125125
return Ok(Authorizer::new_superuser(
126126
roles,
127-
PgAuthDriver::<BuiltinRole>::new(db_pool.clone()),
127+
PgAuthDriver::<BuiltinRole>::new(db_pool.get().await?),
128128
));
129129
}
130130
let Some(header) = headers.get("x-remote-user") else {
@@ -141,7 +141,7 @@ async fn make_authorizer(
141141
name: name.to_owned(),
142142
},
143143
roles,
144-
PgAuthDriver::<BuiltinRole>::new(db_pool.clone()),
144+
PgAuthDriver::<BuiltinRole>::new(db_pool.get().await?),
145145
)
146146
.await?;
147147
Ok(authorizer)
@@ -176,6 +176,9 @@ pub enum AuthorizationError {
176176
AuthError(
177177
#[from] <PgAuthDriver<BuiltinRole> as editoast_authz::authorizer::StorageDriver>::Error,
178178
),
179+
#[error(transparent)]
180+
#[editoast_error(status = 500)]
181+
DbError(#[from] editoast_models::db_connection_pool::DatabasePoolError),
179182
}
180183

181184
#[derive(Debug, Error, EditoastError)]

0 commit comments

Comments
 (0)