mirror of
https://gitlab.com/fabinfra/fabaccess/bffh.git
synced 2024-11-11 01:53:23 +01:00
Actually set the API user as well
This commit is contained in:
parent
38eb26b684
commit
d5b635025d
@ -39,7 +39,7 @@ impl connection_capnp::bootstrap::Server for Bootstrap {
|
|||||||
// TODO: When should we allow multiple auth and how do me make sure that does not leak
|
// TODO: When should we allow multiple auth and how do me make sure that does not leak
|
||||||
// priviledges (e.g. due to previously issues caps)?
|
// priviledges (e.g. due to previously issues caps)?
|
||||||
|
|
||||||
res.get().set_auth(capnp_rpc::new_client(auth::Auth::new(self.db.passdb.clone(), self.session.clone())));
|
res.get().set_auth(capnp_rpc::new_client(auth::Auth::new(self.db.clone(), self.session.clone())));
|
||||||
|
|
||||||
Promise::ok(())
|
Promise::ok(())
|
||||||
}
|
}
|
||||||
|
@ -22,19 +22,28 @@ use capnp::capability::{Params, Results, Promise};
|
|||||||
use crate::api::Session;
|
use crate::api::Session;
|
||||||
|
|
||||||
pub use crate::schema::auth_capnp;
|
pub use crate::schema::auth_capnp;
|
||||||
|
use crate::db::Databases;
|
||||||
use crate::db::pass::PassDB;
|
use crate::db::pass::PassDB;
|
||||||
|
use crate::db::user::{Internal as UserDB};
|
||||||
|
|
||||||
pub struct AppData {
|
pub struct AppData {
|
||||||
passdb: Arc<PassDB>,
|
passdb: Arc<PassDB>,
|
||||||
|
userdb: Arc<UserDB>,
|
||||||
|
}
|
||||||
|
pub struct SessionData {
|
||||||
|
session: Arc<Session>,
|
||||||
}
|
}
|
||||||
pub struct SessionData;
|
|
||||||
|
|
||||||
|
|
||||||
struct CB;
|
struct CB;
|
||||||
impl Callback<AppData, SessionData> for CB {
|
impl Callback<AppData, SessionData> for CB {
|
||||||
fn callback(mut sasl: SaslCtx<AppData, SessionData>, session: SaslSession<SessionData>, prop: Property) -> libc::c_int {
|
fn callback(mut sasl: SaslCtx<AppData, SessionData>, mut session: SaslSession<SessionData>, prop: Property) -> libc::c_int {
|
||||||
let ret = match prop {
|
let ret = match prop {
|
||||||
Property::GSASL_VALIDATE_SIMPLE => {
|
Property::GSASL_VALIDATE_SIMPLE => {
|
||||||
|
// FIXME: get_property and retrive_mut can't be used interleaved but that's
|
||||||
|
// technically safe.
|
||||||
|
let cap_session = session.retrieve_mut().map(|sd| sd.session.clone());
|
||||||
|
|
||||||
let authid = match session.get_property(Property::GSASL_AUTHID) {
|
let authid = match session.get_property(Property::GSASL_AUTHID) {
|
||||||
None => return ReturnCode::GSASL_NO_AUTHID as libc::c_int,
|
None => return ReturnCode::GSASL_NO_AUTHID as libc::c_int,
|
||||||
Some(a) => {
|
Some(a) => {
|
||||||
@ -52,9 +61,15 @@ impl Callback<AppData, SessionData> for CB {
|
|||||||
let pass = pass.unwrap();
|
let pass = pass.unwrap();
|
||||||
|
|
||||||
|
|
||||||
if let Some(sessiondata) = sasl.retrieve_mut() {
|
if let Some(appdata) = sasl.retrieve_mut() {
|
||||||
if let Ok(Some(b)) = sessiondata.passdb.check(authid, pass.to_bytes()) {
|
if let Ok(Some(b)) = appdata.passdb.check(authid, pass.to_bytes()) {
|
||||||
if b {
|
if b {
|
||||||
|
if let Some(s) = cap_session {
|
||||||
|
if let Ok(Some(user)) = appdata.userdb.get_user(authid) {
|
||||||
|
s.user.try_lock().unwrap().replace(user);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ReturnCode::GSASL_OK
|
ReturnCode::GSASL_OK
|
||||||
} else {
|
} else {
|
||||||
ReturnCode::GSASL_AUTHENTICATION_ERROR
|
ReturnCode::GSASL_AUTHENTICATION_ERROR
|
||||||
@ -81,10 +96,10 @@ pub struct Auth {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Auth {
|
impl Auth {
|
||||||
pub fn new(passdb: Arc<PassDB>, session: Arc<Session>) -> Self {
|
pub fn new(dbs: Databases, session: Arc<Session>) -> Self {
|
||||||
let mut ctx = SASL::new().unwrap();
|
let mut ctx = SASL::new().unwrap();
|
||||||
|
|
||||||
let appdata = Box::new(AppData { passdb });
|
let appdata = Box::new(AppData { passdb: dbs.passdb.clone(), userdb: dbs.userdb.clone() });
|
||||||
|
|
||||||
ctx.store(appdata);
|
ctx.store(appdata);
|
||||||
|
|
||||||
@ -141,6 +156,8 @@ impl auth_capnp::authentication::Server for Auth {
|
|||||||
}),
|
}),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
session.store(Box::new(SessionData { session: self.session.clone() }));
|
||||||
|
|
||||||
// If the client has provided initial data go use that
|
// If the client has provided initial data go use that
|
||||||
use auth_capnp::request::initial_response::Which;
|
use auth_capnp::request::initial_response::Which;
|
||||||
let step_res = match req.get_initial_response().which() {
|
let step_res = match req.get_initial_response().which() {
|
||||||
|
@ -100,10 +100,10 @@ impl write::Server for Write {
|
|||||||
_results: write::UseResults)
|
_results: write::UseResults)
|
||||||
-> Promise<(), Error>
|
-> Promise<(), Error>
|
||||||
{
|
{
|
||||||
let uid = self.0.session.user.as_ref().map(|u| u.id.clone());
|
let uid = self.0.session.user.try_lock().unwrap().as_ref().map(|u| u.id.clone());
|
||||||
let new_state = MachineState::used(uid.clone());
|
let new_state = MachineState::used(uid.clone());
|
||||||
let this = self.0.clone();
|
let this = self.0.clone();
|
||||||
let f = this.machine.request_state_change(this.session.user.as_ref(), new_state)
|
let f = this.machine.request_state_change(this.session.user.try_lock().unwrap().as_ref(), new_state)
|
||||||
.map(|res_token| match res_token {
|
.map(|res_token| match res_token {
|
||||||
// TODO: Do something with the token we get returned
|
// TODO: Do something with the token we get returned
|
||||||
Ok(_tok) => {
|
Ok(_tok) => {
|
||||||
|
@ -4,6 +4,7 @@ use futures::FutureExt;
|
|||||||
|
|
||||||
use slog::Logger;
|
use slog::Logger;
|
||||||
|
|
||||||
|
use smol::lock::Mutex;
|
||||||
use smol::net::TcpStream;
|
use smol::net::TcpStream;
|
||||||
|
|
||||||
use crate::error::Result;
|
use crate::error::Result;
|
||||||
@ -18,26 +19,26 @@ use crate::db::access::{AccessControl, Permission};
|
|||||||
use crate::db::user::User;
|
use crate::db::user::User;
|
||||||
use crate::network::Network;
|
use crate::network::Network;
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug)]
|
||||||
/// Connection context
|
/// Connection context
|
||||||
// TODO this should track over several connections
|
// TODO this should track over several connections
|
||||||
pub struct Session {
|
pub struct Session {
|
||||||
// Session-spezific log
|
// Session-spezific log
|
||||||
pub log: Logger,
|
pub log: Logger,
|
||||||
pub user: Option<User>,
|
pub user: Mutex<Option<User>>,
|
||||||
pub accessdb: Arc<AccessControl>,
|
pub accessdb: Arc<AccessControl>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Session {
|
impl Session {
|
||||||
pub fn new(log: Logger, accessdb: Arc<AccessControl>) -> Self {
|
pub fn new(log: Logger, accessdb: Arc<AccessControl>) -> Self {
|
||||||
let user = None;
|
let user = Mutex::new(None);
|
||||||
|
|
||||||
Session { log, user, accessdb }
|
Session { log, user, accessdb }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Check if the current session has a certain permission
|
/// Check if the current session has a certain permission
|
||||||
pub async fn check_permission<P: AsRef<Permission>>(&self, perm: &P) -> Result<bool> {
|
pub async fn check_permission<P: AsRef<Permission>>(&self, perm: &P) -> Result<bool> {
|
||||||
if let Some(user) = self.user.as_ref() {
|
if let Some(user) = self.user.lock().await.as_ref() {
|
||||||
self.accessdb.check(&user.data, perm).await
|
self.accessdb.check(&user.data, perm).await
|
||||||
} else {
|
} else {
|
||||||
Ok(false)
|
Ok(false)
|
||||||
|
Loading…
Reference in New Issue
Block a user