From 1dca24a66049a50759466f2cf309d9e1e63675f8 Mon Sep 17 00:00:00 2001 From: Dominik George <dominik.george@teckids.org> Date: Wed, 19 May 2021 13:51:18 +0200 Subject: [PATCH] Refactor access toke nretrieval of existing tokens into oauth module --- src/nss.rs | 47 ++++++++++------------------------------------- src/oauth.rs | 33 +++++++++++++++++++++++++++++++++ src/pam.rs | 13 +++++++------ 3 files changed, 50 insertions(+), 43 deletions(-) diff --git a/src/nss.rs b/src/nss.rs index 118285c..e35a37e 100644 --- a/src/nss.rs +++ b/src/nss.rs @@ -24,7 +24,7 @@ use crate::cache::get_context_user; use crate::logging::setup_log; -use crate::oauth::{get_access_token_client, get_data_jq}; +use crate::oauth::{get_data_jq, get_usable_token}; use serde::{Serialize, Deserialize}; use libnss::interop::Response; @@ -69,20 +69,11 @@ impl PasswdHooks for OidcPasswd { let conf = nss_hook_prepare(); info!("[NSS] passwd.get_all_entries called"); - let user_token_res = get_context_user().get_access_token(); - // FIXME Implement caching of system token - let system_token_res = get_access_token_client(&conf, "nss", "", ""); - let token = match user_token_res { + let token = match get_usable_token(&conf, "nss", &mut get_context_user()) { Some(t) => t, None => { - debug!("Could not find a user token to request NSS data; trying client credentials"); - match system_token_res { - Ok(ct) => ct, - Err(e) => { - error!("Failed to get access token with client credentials: {}", e); - return Response::Unavail; - } - } + error!("Failed to get usable access token"); + return Response::Unavail; } }; @@ -100,20 +91,11 @@ impl PasswdHooks for OidcPasswd { let conf = nss_hook_prepare(); info!("[NSS] passwd.get_entry_by_uid called for {}", uid); - let user_token_res = get_context_user().get_access_token(); - // FIXME Implement caching of system token - let system_token_res = get_access_token_client(&conf, "nss", "", ""); - let token = match user_token_res { + let token = match get_usable_token(&conf, "nss", &mut get_context_user()) { Some(t) => t, None => { - debug!("Could not find a user token to request NSS data; trying client credentials"); - match system_token_res { - Ok(ct) => ct, - Err(e) => { - error!("Failed to get access token with client credentials: {}", e); - return Response::Unavail; - } - } + error!("Failed to get usable access token"); + return Response::Unavail; } }; @@ -131,20 +113,11 @@ impl PasswdHooks for OidcPasswd { let conf = nss_hook_prepare(); info!("[NSS] passwd.get_entry_by_name called for {}", name); - let user_token_res = get_context_user().get_access_token(); - // FIXME Implement caching of system token - let system_token_res = get_access_token_client(&conf, "nss", "", ""); - let token = match user_token_res { + let token = match get_usable_token(&conf, "nss", &mut get_context_user()) { Some(t) => t, None => { - debug!("Could not find a user token to request NSS data; trying client credentials"); - match system_token_res { - Ok(ct) => ct, - Err(e) => { - error!("Failed to get access token with client credentials: {}", e); - return Response::Unavail; - } - } + error!("Failed to get usable access token"); + return Response::Unavail; } }; diff --git a/src/oauth.rs b/src/oauth.rs index 8d7d26c..6e17ed1 100644 --- a/src/oauth.rs +++ b/src/oauth.rs @@ -24,6 +24,8 @@ use crate::config::{ use config::Config; +use crate::cache::UserInfo; + use oauth2::{ AuthUrl, ClientId, @@ -240,6 +242,37 @@ fn get_jq_prog(conf: &Config, prefix: &str, endpoint: &str, multi: bool, rev: bo jq_rs::compile(&jq_code) } +/// Get a usable access token for the passed user and prefix +/// +/// Will return the user's personal token, or a system token, or None, +/// in that order. +/// +/// Arguments +/// --------- +/// +/// `conf` - reference to the config object +/// `user` - reference to a user info object to get a token for +/// `prefix` - current prefix (probably `nss` or `pam`) +pub fn get_usable_token(conf: &Config, prefix: &str, user: &mut UserInfo) -> Option<BasicTokenResponse> { + let user_token_res = user.get_access_token(); + // FIXME Implement caching of system token + let system_token_res = get_access_token_client(&conf, prefix, "", ""); + + match user_token_res { + Some(t) => Some(t), + None => { + debug!("Could not find a user token; trying client credentials"); + match system_token_res { + Ok(ct) => Some(ct), + Err(e) => { + error!("Failed to get access token with client credentials: {}", e); + None + } + } + } + } +} + /// Retrieve JSON data from a configured endpoint, transforming using configured jq programs /// /// This function takes a prefix (probably `nss` or `pam`, and an endpoint name to lookup diff --git a/src/pam.rs b/src/pam.rs index 364c98d..9088c60 100644 --- a/src/pam.rs +++ b/src/pam.rs @@ -22,7 +22,7 @@ use crate::config::{ }; use config::Config; -use crate::oauth::{get_access_token_password, get_data_jq}; +use crate::oauth::{get_access_token_password, get_data_jq, get_usable_token}; use crate::logging::setup_log; @@ -143,13 +143,14 @@ impl PamServiceModule for PamOidc { // Retrieve access token (as acquired in the auth stage, probably) set_is_getpwnam_safe(false); - // FIXME implement fallback to system token - let res = get_context_user().get_access_token(); - set_is_getpwnam_safe(true); - let token = match res { + let token = match get_usable_token(&conf, "pam", &mut get_context_user()) { Some(t) => t, - None => return PamError::CRED_UNAVAIL + None => { + error!("Failed to get usable access token"); + return PamError::CRED_UNAVAIL; + } }; + set_is_getpwnam_safe(true); // Get and transform data from API let data: bool = match get_data_jq(&conf, "pam", "authz", "".to_string(), &token, true) { -- GitLab