Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion src/api/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,8 @@ pub enum KeystoneApiError {

impl IntoResponse for KeystoneApiError {
fn into_response(self) -> Response {
error!("Error happened during request processing: {:?}", self);
error!("Error happened during request processing: {:#?}", self);
//tracing::debug!("stacktrace: {}", self.backtrace());
match self {
KeystoneApiError::Conflict(_) => (
StatusCode::CONFLICT,
Expand Down
57 changes: 16 additions & 41 deletions src/api/v3/auth/token/common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,6 @@ use crate::api::common;
use crate::api::error::{KeystoneApiError, TokenError};
use crate::api::v3::auth::token::types::{ProjectBuilder, Token, TokenBuilder, UserBuilder};
use crate::api::v3::role::types::Role;
use crate::assignment::AssignmentApi;
use crate::assignment::types::RoleAssignmentListParametersBuilder;
use crate::identity::{IdentityApi, types::UserResponse};
use crate::keystone::ServiceState;
use crate::resource::{
Expand Down Expand Up @@ -55,12 +53,12 @@ impl Token {
}
ProviderToken::DomainScope(_token) => {
response.domain(domain.ok_or(KeystoneApiError::InternalError(
"domain scope missing".to_string(),
"domain scope information missing".to_string(),
))?);
}
ProviderToken::ProjectScope(token) => {
let project = project.ok_or(KeystoneApiError::InternalError(
"domain scope missing".to_string(),
"project scope information missing".to_string(),
))?;

let mut project_response = ProjectBuilder::default();
Expand All @@ -75,26 +73,12 @@ impl Token {
}
response.project(project_response.build().map_err(TokenError::from)?);

let token_roles = state
.provider
.get_assignment_provider()
.list_role_assignments(
&state.db,
&state.provider,
&RoleAssignmentListParametersBuilder::default()
.user_id(user.id.clone())
.project_id(&token.project_id)
.build()?,
)
.await?;
response.roles(
token_roles
token
.roles
.clone()
.into_iter()
.map(|x| Role {
id: x.role_id.clone(),
name: x.role_name.clone().unwrap_or_default(),
..Default::default()
})
.map(Into::into)
.collect::<Vec<Role>>(),
);
}
Expand Down Expand Up @@ -171,26 +155,12 @@ impl Token {
}
response.project(project_response.build().map_err(TokenError::from)?);

let token_roles = state
.provider
.get_assignment_provider()
.list_role_assignments(
&state.db,
&state.provider,
&RoleAssignmentListParametersBuilder::default()
.user_id(user.id)
.project_id(&token.project_id)
.build()?,
)
.await?;
response.roles(
token_roles
token
.roles
.clone()
.into_iter()
.map(|x| Role {
id: x.role_id.clone(),
name: x.role_name.clone().unwrap_or_default(),
..Default::default()
})
.map(Into::into)
.collect::<Vec<Role>>(),
);
}
Expand All @@ -211,7 +181,7 @@ mod tests {
use crate::api::v3::role::types::Role;
use crate::assignment::{
MockAssignmentProvider,
types::{Assignment, AssignmentType, RoleAssignmentListParameters},
types::{Assignment, AssignmentType, Role as ProviderRole, RoleAssignmentListParameters},
};
use crate::config::Config;
use crate::identity::{MockIdentityProvider, types::UserResponse};
Expand Down Expand Up @@ -402,6 +372,11 @@ mod tests {
&ProviderToken::ProjectScope(ProjectScopeToken {
user_id: "bar".into(),
project_id: "project_id".into(),
roles: vec![ProviderRole {
id: "rid".into(),
name: "role_name".into(),
..Default::default()
}],
..Default::default()
}),
)
Expand Down
59 changes: 56 additions & 3 deletions src/api/v3/auth/token/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ async fn post(
}

if let Some(authed_user) = &user {
let token = state.provider.get_token_provider().issue_token(
let mut token = state.provider.get_token_provider().issue_token(
authed_user.id.clone(),
methods,
Vec::<String>::from([URL_SAFE
Expand All @@ -142,6 +142,24 @@ async fn post(
domain.as_ref(),
)?;

state
.provider
.get_token_provider()
.populate_role_assignments(&mut token, &state.db, &state.provider)
.await?;

state
.provider
.get_token_provider()
.expand_project_information(&mut token, &state.db, &state.provider)
.await?;

state
.provider
.get_token_provider()
.expand_domain_information(&mut token, &state.db, &state.provider)
.await?;

let api_token = TokenResponse {
token: ApiResponseToken::from_user_auth(
&state,
Expand Down Expand Up @@ -194,13 +212,31 @@ async fn show(
.map_err(|_| KeystoneApiError::InvalidHeader)?
.to_string();

let token = state
let mut token = state
.provider
.get_token_provider()
.validate_token(&subject_token, None)
.await
.map_err(|_| KeystoneApiError::InvalidToken)?;

state
.provider
.get_token_provider()
.populate_role_assignments(&mut token, &state.db, &state.provider)
.await?;

state
.provider
.get_token_provider()
.expand_project_information(&mut token, &state.db, &state.provider)
.await?;

state
.provider
.get_token_provider()
.expand_domain_information(&mut token, &state.db, &state.provider)
.await?;

let response_token = ApiResponseToken::from_provider_token(&state, &token).await?;

Ok(TokenResponse {
Expand Down Expand Up @@ -266,6 +302,15 @@ mod tests {
..Default::default()
}))
});
token_mock
.expect_populate_role_assignments()
.returning(|_, _, _| Ok(()));
token_mock
.expect_expand_project_information()
.returning(|_, _, _| Ok(()));
token_mock
.expect_expand_domain_information()
.returning(|_, _, _| Ok(()));

let provider = ProviderBuilder::default()
.config(config.clone())
Expand Down Expand Up @@ -392,7 +437,15 @@ mod tests {
..Default::default()
}))
});

token_mock
.expect_populate_role_assignments()
.returning(|_, _, _| Ok(()));
token_mock
.expect_expand_project_information()
.returning(|_, _, _| Ok(()));
token_mock
.expect_expand_domain_information()
.returning(|_, _, _| Ok(()));
token_mock
.expect_encode_token()
.returning(|_| Ok("token".to_string()));
Expand Down
6 changes: 6 additions & 0 deletions src/assignment/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,12 @@ pub enum AssignmentProviderError {
source: RoleAssignmentListForMultipleActorTargetParametersBuilderError,
},

#[error("building role assignment query: {}", source)]
RoleAssignmentListParametersBuilder {
#[from]
source: RoleAssignmentListParametersBuilderError,
},

#[error("building role data: {}", source)]
RoleBuilderError {
#[from]
Expand Down
9 changes: 9 additions & 0 deletions src/token/application_credential.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ use rmp::{decode::read_pfix, encode::write_pfix};
use std::collections::BTreeMap;
use std::io::Write;

use crate::assignment::types::Role;
use crate::resource::types::Project;
use crate::token::{
error::TokenProviderError,
fernet::{self, MsgPackToken},
Expand All @@ -35,6 +37,11 @@ pub struct ApplicationCredentialToken {
pub expires_at: DateTime<Utc>,
pub project_id: String,
pub application_credential_id: String,

#[builder(default)]
pub roles: Vec<Role>,
#[builder(default)]
pub project: Option<Project>,
}

impl ApplicationCredentialTokenBuilder {
Expand Down Expand Up @@ -110,6 +117,7 @@ impl MsgPackToken for ApplicationCredentialToken {
audit_ids,
project_id,
application_credential_id,
..Default::default()
})
}
}
Expand All @@ -130,6 +138,7 @@ mod tests {
application_credential_id: Uuid::new_v4().simple().to_string(),
audit_ids: vec!["Zm9vCg".into()],
expires_at: Local::now().trunc_subsecs(0).into(),
..Default::default()
};
let auth_map = BTreeMap::from([(1, "password".into())]);
let mut buf = vec![];
Expand Down
9 changes: 9 additions & 0 deletions src/token/domain_scoped.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ use rmp::{decode::read_pfix, encode::write_pfix};
use std::collections::BTreeMap;
use std::io::Write;

use crate::assignment::types::Role;
use crate::resource::types::Domain;
use crate::token::{
error::TokenProviderError,
fernet::{self, MsgPackToken},
Expand All @@ -35,6 +37,11 @@ pub struct DomainScopeToken {
pub audit_ids: Vec<String>,
pub expires_at: DateTime<Utc>,
pub domain_id: String,

#[builder(default)]
pub roles: Vec<Role>,
#[builder(default)]
pub domain: Option<Domain>,
}

impl DomainScopeTokenBuilder {
Expand Down Expand Up @@ -106,6 +113,7 @@ impl MsgPackToken for DomainScopeToken {
expires_at,
audit_ids,
domain_id,
..Default::default()
})
}
}
Expand All @@ -125,6 +133,7 @@ mod tests {
domain_id: Uuid::new_v4().simple().to_string(),
audit_ids: vec!["Zm9vCg".into()],
expires_at: Local::now().trunc_subsecs(0).into(),
..Default::default()
};
let auth_map = BTreeMap::from([(1, "password".into())]);
let mut buf = vec![];
Expand Down
14 changes: 14 additions & 0 deletions src/token/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -115,4 +115,18 @@ pub enum TokenProviderError {
#[from]
source: crate::token::domain_scoped::DomainScopeTokenBuilderError,
},

#[error(transparent)]
AssignmentProvider {
/// The source of the error.
#[from]
source: crate::assignment::error::AssignmentProviderError,
},

#[error(transparent)]
ResourceProvider {
/// The source of the error.
#[from]
source: crate::resource::error::ResourceProviderError,
},
}
3 changes: 3 additions & 0 deletions src/token/fernet.rs
Original file line number Diff line number Diff line change
Expand Up @@ -336,6 +336,7 @@ pub(super) mod tests {
domain_id: Uuid::new_v4().simple().to_string(),
audit_ids: vec!["Zm9vCg".into()],
expires_at: Local::now().trunc_subsecs(0).into(),
..Default::default()
});

let mut backend = FernetTokenProvider::default();
Expand Down Expand Up @@ -379,6 +380,7 @@ pub(super) mod tests {
project_id: Uuid::new_v4().simple().to_string(),
audit_ids: vec!["Zm9vCg".into()],
expires_at: Local::now().trunc_subsecs(0).into(),
..Default::default()
});

let mut backend = FernetTokenProvider::default();
Expand Down Expand Up @@ -427,6 +429,7 @@ pub(super) mod tests {
application_credential_id: Uuid::new_v4().simple().to_string(),
audit_ids: vec!["Zm9vCg".into()],
expires_at: Local::now().trunc_subsecs(0).into(),
..Default::default()
});

let mut backend = FernetTokenProvider::default();
Expand Down
Loading