blob: 41ee8b6193a10304c73f14cec676a8befa74e630 [file] [log] [blame]
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
use anyhow::Result;
use lazy_static::lazy_static;
use teaclave_attestation::verifier;
use teaclave_config::build::AS_ROOT_CA_CERT;
use teaclave_config::RuntimeConfig;
use teaclave_proto::teaclave_access_control_service::*;
use teaclave_proto::teaclave_authentication_service::*;
use teaclave_proto::teaclave_common::*;
use teaclave_proto::teaclave_frontend_service::*;
use teaclave_proto::teaclave_management_service::*;
use teaclave_proto::teaclave_scheduler_service::*;
use teaclave_proto::teaclave_storage_service::*;
use teaclave_rpc::transport::{Channel, ClientTlsConfig, Uri};
use teaclave_rpc::CredentialService;
use teaclave_types::*;
macro_rules! impl_get_internal_service_client_fn {
($service_name:ident, $fn_name:ident, $return:ty) => {
pub(crate) async fn $fn_name(username: &str) -> $return {
let runtime_config = RuntimeConfig::from_toml("runtime.config.toml").expect("runtime");
let address = runtime_config
.internal_endpoints
.$service_name
.advertised_address;
let dst = address.parse::<Uri>().unwrap();
let dst = if dst.scheme().is_none() {
format!("https://{}", address).parse().unwrap()
} else {
dst
};
let endpoint = Channel::builder(dst);
let tls_config = teaclave_rpc::config::SgxTrustedTlsClientConfig::new().into();
let channel = endpoint
.tls_config(tls_config)
.unwrap()
.connect()
.await
.unwrap();
let cred =
teaclave_rpc::UserCredential::with_role(username, "", UserRole::PlatformAdmin);
<$return>::new(teaclave_rpc::InterceptedService::new(channel, cred))
}
};
}
impl_get_internal_service_client_fn!(
management,
get_management_client,
TeaclaveManagementClient<CredentialService>
);
impl_get_internal_service_client_fn!(
scheduler,
get_scheduler_client_internal,
TeaclaveSchedulerClient<CredentialService>
);
impl_get_internal_service_client_fn!(
storage,
get_storage_client_internal,
TeaclaveStorageClient<CredentialService>
);
impl_get_internal_service_client_fn!(
access_control,
get_access_control_client_internal,
TeaclaveAccessControlClient<CredentialService>
);
pub async fn get_scheduler_client() -> TeaclaveSchedulerClient<CredentialService> {
get_scheduler_client_internal("mock_user").await
}
pub async fn get_storage_client() -> TeaclaveStorageClient<CredentialService> {
get_storage_client_internal("mock_user").await
}
pub async fn get_access_control_client() -> TeaclaveAccessControlClient<CredentialService> {
get_access_control_client_internal("mock_user").await
}
pub const CONFIG_FILE: &str = "runtime.config.toml";
pub const AUTH_SERVICE_ADDR: &str = "https://localhost:7776";
pub const FRONTEND_SERVICE_ADDR: &str = "https://localhost:7777";
lazy_static! {
static ref ENCLAVE_INFO: EnclaveInfo = {
let runtime_config = RuntimeConfig::from_toml(CONFIG_FILE).expect("runtime config");
EnclaveInfo::from_bytes(&runtime_config.audit.enclave_info_bytes)
};
}
pub async fn get_api_client_with_admin_credential(
) -> TeaclaveAuthenticationApiClient<CredentialService> {
create_authentication_api_client_with_credential(
shared_enclave_info(),
AUTH_SERVICE_ADDR,
"admin",
"teaclave",
)
.await
.unwrap()
}
pub fn shared_enclave_info() -> &'static EnclaveInfo {
&ENCLAVE_INFO
}
pub fn create_client_config(
enclave_info: &EnclaveInfo,
service_name: &str,
) -> Result<ClientTlsConfig> {
let enclave_attr = enclave_info
.get_enclave_attr(service_name)
.expect("enclave attr");
let config = teaclave_rpc::config::SgxTrustedTlsClientConfig::new()
.attestation_report_verifier(
vec![enclave_attr],
AS_ROOT_CA_CERT,
verifier::universal_quote_verifier,
)
.into();
Ok(config)
}
pub async fn create_frontend_client(
enclave_info: &EnclaveInfo,
service_addr: &str,
cred: UserCredential,
) -> Result<TeaclaveFrontendClient<CredentialService>> {
let tls_config = create_client_config(enclave_info, "teaclave_frontend_service")?;
let endpoint = Channel::builder(service_addr.parse::<Uri>()?);
let channel = endpoint
.tls_config(tls_config)
.unwrap()
.connect()
.await
.unwrap();
let cred = teaclave_rpc::UserCredential::new(cred.id, cred.token);
let client = TeaclaveFrontendClient::with_interceptor(channel, cred);
Ok(client)
}
pub async fn create_authentication_api_client(
enclave_info: &EnclaveInfo,
service_addr: &str,
) -> Result<TeaclaveAuthenticationApiClient<CredentialService>> {
let tls_config = create_client_config(enclave_info, "teaclave_authentication_service")?;
let endpoint = Channel::builder(service_addr.parse::<Uri>()?);
let channel = endpoint.tls_config(tls_config).unwrap().connect_lazy();
let client = TeaclaveAuthenticationApiClient::with_interceptor(
channel,
teaclave_rpc::UserCredential::default(),
);
Ok(client)
}
pub async fn create_authentication_api_client_with_credential(
enclave_info: &EnclaveInfo,
service_addr: &str,
username: &str,
password: &str,
) -> Result<TeaclaveAuthenticationApiClient<CredentialService>> {
let tls_config = create_client_config(enclave_info, "teaclave_authentication_service")?;
let endpoint = Channel::builder(service_addr.parse::<Uri>()?);
let channel = endpoint
.tls_config(tls_config)
.unwrap()
.connect()
.await
.unwrap();
let mut client = TeaclaveAuthenticationApiClient::new(channel.clone());
let request = UserLoginRequest::new(username, password);
let token = client.user_login(request).await?.into_inner().token;
let cred = teaclave_rpc::UserCredential::new(username, token);
let client = TeaclaveAuthenticationApiClient::with_interceptor(channel, cred);
Ok(client)
}
pub async fn register_new_account(
api_client: &mut TeaclaveAuthenticationApiClient<CredentialService>,
username: &str,
password: &str,
role: &str,
attribute: &str,
) -> Result<()> {
let request = UserRegisterRequest::new(username, password, role, attribute);
let response = api_client.user_register(request).await;
log::debug!("User register: {:?}", response);
Ok(())
}
pub async fn login(
api_client: &mut TeaclaveAuthenticationApiClient<CredentialService>,
username: &str,
password: &str,
) -> Result<UserCredential> {
let request = UserLoginRequest::new(username, password);
let response = api_client.user_login(request).await?.into_inner();
log::debug!("User login: {:?}", response);
Ok(UserCredential::new(username, response.token))
}
pub const USERNAME: &str = "frontend_user";
pub const USERNAME1: &str = "frontend_user1";
pub const USERNAME2: &str = "frontend_user2";
pub const USERNAME3: &str = "frontend_user3";
pub const TEST_PASSWORD: &str = "test_password";
pub async fn setup() {
// Register user for the first time
let mut api_client = get_api_client_with_admin_credential().await;
// Ignore error if register failed.
for uname in vec![USERNAME, USERNAME1, USERNAME2, USERNAME3].iter() {
let _ =
register_new_account(&mut api_client, uname, TEST_PASSWORD, "PlatformAdmin", "").await;
}
}