From 2a871c5deda9f1f9dac583230d52b83a23f0602a Mon Sep 17 00:00:00 2001 From: TommyLike Date: Sat, 18 Mar 2023 11:11:43 +0800 Subject: [PATCH] Remove unused files --- src/infra/sign/mod.rs | 4 - src/infra/sign/openpgp.rs | 211 ------------------ src/infra/sign/signers.rs | 45 ---- src/infra/sign/traits.rs | 36 --- src/infra/sign/x509.rs | 198 ---------------- src/server/control_server.rs | 175 --------------- src/server/data_server.rs | 146 ------------ src/server/mod.rs | 2 - .../control_service/datakey_service.rs | 101 --------- src/service/control_service/mod.rs | 3 - .../control_service/model/datakey/dto.rs | 126 ----------- .../control_service/model/datakey/mod.rs | 1 - src/service/control_service/model/mod.rs | 3 - .../control_service/model/token/dto.rs | 46 ---- .../control_service/model/token/mod.rs | 1 - src/service/control_service/model/user/dto.rs | 104 --------- src/service/control_service/model/user/mod.rs | 1 - src/service/control_service/user_service.rs | 130 ----------- src/service/data_service/grpc_service.rs | 89 -------- src/service/data_service/mod.rs | 1 - src/service/mod.rs | 2 - 21 files changed, 1425 deletions(-) delete mode 100644 src/infra/sign/mod.rs delete mode 100644 src/infra/sign/openpgp.rs delete mode 100644 src/infra/sign/signers.rs delete mode 100644 src/infra/sign/traits.rs delete mode 100644 src/infra/sign/x509.rs delete mode 100644 src/server/control_server.rs delete mode 100644 src/server/data_server.rs delete mode 100644 src/server/mod.rs delete mode 100644 src/service/control_service/datakey_service.rs delete mode 100644 src/service/control_service/mod.rs delete mode 100644 src/service/control_service/model/datakey/dto.rs delete mode 100644 src/service/control_service/model/datakey/mod.rs delete mode 100644 src/service/control_service/model/mod.rs delete mode 100644 src/service/control_service/model/token/dto.rs delete mode 100644 src/service/control_service/model/token/mod.rs delete mode 100644 src/service/control_service/model/user/dto.rs delete mode 100644 src/service/control_service/model/user/mod.rs delete mode 100644 src/service/control_service/user_service.rs delete mode 100644 src/service/data_service/grpc_service.rs delete mode 100644 src/service/data_service/mod.rs delete mode 100644 src/service/mod.rs diff --git a/src/infra/sign/mod.rs b/src/infra/sign/mod.rs deleted file mode 100644 index 5750f59..0000000 --- a/src/infra/sign/mod.rs +++ /dev/null @@ -1,4 +0,0 @@ -pub mod openpgp; -pub mod x509; -pub mod signers; -pub mod traits; diff --git a/src/infra/sign/openpgp.rs b/src/infra/sign/openpgp.rs deleted file mode 100644 index e64e684..0000000 --- a/src/infra/sign/openpgp.rs +++ /dev/null @@ -1,211 +0,0 @@ -/* - * // Copyright (c) 2023 Huawei Technologies Co.,Ltd. All rights reserved. - * // - * // signatrust is licensed under Mulan PSL v2. - * // You can use this software according to the terms and conditions of the Mulan - * // PSL v2. - * // You may obtain a copy of Mulan PSL v2 at: - * // http://license.coscl.org.cn/MulanPSL2 - * // THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY - * // KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO - * // NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. - * // See the Mulan PSL v2 for more details. - */ - -use super::traits::SignPlugins; -use crate::model::datakey::entity::DataKey; -use crate::model::datakey::traits::Identity; -use crate::util::error::{Error, Result}; -use chrono::{DateTime, Utc}; -use pgp::composed::signed_key::{SignedSecretKey, SignedPublicKey}; -use pgp::composed::{key::SecretKeyParamsBuilder, KeyType}; -use pgp::crypto::{hash::HashAlgorithm, sym::SymmetricKeyAlgorithm}; -use pgp::packet::SignatureConfig; -use pgp::packet::*; - -use pgp::types::KeyTrait; -use pgp::types::{CompressionAlgorithm, SecretKeyTrait}; -use pgp::Deserializable; -use serde::Deserialize; -use smallvec::*; - -use std::collections::HashMap; - -use std::io::{Cursor}; -use std::str::from_utf8; - - -use validator::{Validate, ValidationError}; -use pgp::composed::StandaloneSignature; - -const DETACHED_SIGNATURE: &str = "detached"; - -#[derive(Debug, Validate, Deserialize)] -pub struct PgpKeyGenerationParameter { - #[validate(length(min = 4, max = 20, message="invalid openpgp attribute 'name'"))] - name: String, - #[validate(email(message="openpgp attribute 'email'"))] - email: String, - #[validate(custom( function = "validate_key_type", message="invalid openpgp attribute 'key_type'"))] - key_type: String, - #[validate(custom(function = "validate_key_size", message="invalid openpgp attribute 'key_length'"))] - key_length: String, - #[validate(custom(function = "validate_utc_time", message="invalid openpgp attribute 'created_at'"))] - create_at: String, - #[validate(custom(function= "validate_utc_time", message="invalid openpgp attribute 'expire_at'"))] - expire_at: String, -} - -impl PgpKeyGenerationParameter { - pub fn get_key(&self) -> Result { - return match self.key_type.as_str() { - "rsa" => Ok(KeyType::Rsa(self.key_length.parse::()?)), - "ecdh" => Ok(KeyType::ECDH), - "eddsa" => Ok(KeyType::EdDSA), - _ => Err(Error::ParameterError( - "invalid key type for openpgp".to_string(), - )), - }; - } - - pub fn get_user_id(&self) -> String { - format!("{} <{}>", self.name, self.email) - } -} - -fn validate_key_type(key_type: &str) -> std::result::Result<(), ValidationError> { - if !vec!["rsa", "ecdh", "eddsa"].contains(&key_type) { - return Err(ValidationError::new("invalid key type")); - } - Ok(()) -} - -fn validate_key_size(key_size: &str) -> std::result::Result<(), ValidationError> { - if !vec!["2048", "3072", "4096"].contains(&key_size) { - return Err(ValidationError::new("invalid key size")); - } - Ok(()) -} - -fn validate_utc_time(expire: &str) -> std::result::Result<(), ValidationError> { - let now = Utc::now(); - match expire.parse::>() { - Ok(expire) => { - if expire <= now { - return Err(ValidationError::new("expire time less than current time")) - } - }, - Err(_e) => { - return Err(ValidationError::new("failed to parse time string to utc")); - } - } - Ok(()) -} - -pub struct OpenPGPPlugin { - secret_key: SignedSecretKey, - public_key: SignedPublicKey, - identity: String, -} - -impl OpenPGPPlugin { - pub fn attributes_validate(attr: &HashMap) -> Result { - let parameter: PgpKeyGenerationParameter = - serde_json::from_str(serde_json::to_string(&attr)?.as_str())?; - match parameter.validate() { - Ok(_) => Ok(parameter), - Err(e) => Err(Error::ParameterError(format!("{:?}", e))), - } - } -} - -impl SignPlugins for OpenPGPPlugin { - fn new(db: &DataKey) -> Result { - let private = from_utf8(&db.private_key.unsecure()).map_err(|e| Error::KeyParseError(e.to_string()))?; - let (secret_key, _) = - SignedSecretKey::from_string(private).map_err(|e| Error::KeyParseError(e.to_string()))?; - let public = from_utf8(&db.public_key.unsecure()).map_err(|e| Error::KeyParseError(e.to_string()))?; - let (public_key, _) = - SignedPublicKey::from_string(public).map_err(|e| Error::KeyParseError(e.to_string()))?; - Ok(Self { - secret_key, - public_key, - identity: db.get_identity(), - }) - } - - fn parse_attributes( - _private_key: Option>, - _public_key: Option>, - _certificate: Option>, - ) -> HashMap { - todo!() - } - - fn generate_keys( - value: &HashMap, - ) -> Result<(Vec, Vec, Vec)> { - let parameter = OpenPGPPlugin::attributes_validate(value)?; - let mut key_params = SecretKeyParamsBuilder::default(); - let create_at = parameter.create_at.parse()?; - let expire :DateTime = parameter.expire_at.parse()?; - let duration: core::time::Duration = (expire - Utc::now()).to_std()?; - key_params - .key_type(parameter.get_key()?) - .can_create_certificates(false) - .can_sign(true) - .primary_user_id(parameter.get_user_id()) - .preferred_symmetric_algorithms(smallvec![SymmetricKeyAlgorithm::AES256,]) - .preferred_hash_algorithms(smallvec![HashAlgorithm::SHA2_256,]) - .preferred_compression_algorithms(smallvec![CompressionAlgorithm::ZLIB,]) - .created_at(create_at) - .expiration(Some(duration)); - let secret_key_params = key_params.build()?; - let secret_key = secret_key_params.generate()?; - let passwd_fn = || String::new(); - let signed_secret_key = secret_key.sign(passwd_fn)?; - let public_key = signed_secret_key.public_key(); - let signed_public_key = public_key.sign(&signed_secret_key, passwd_fn)?; - Ok(( - signed_secret_key.to_armored_bytes(None)?, - signed_public_key.to_armored_bytes(None)?, - vec![], - )) - } - - fn sign(&self, content: Vec, options: HashMap) -> Result> { - let passwd_fn = String::new; - let now = Utc::now(); - let sig_cfg = SignatureConfig { - version: SignatureVersion::V4, - typ: SignatureType::Binary, - pub_alg: self.public_key.primary_key.algorithm(), - hash_alg: HashAlgorithm::SHA2_256, - issuer: Some(self.secret_key.key_id()), - created: Some(now), - unhashed_subpackets: vec![], - hashed_subpackets: vec![ - Subpacket::SignatureCreationTime(now), - Subpacket::Issuer(self.secret_key.key_id()), - ], - }; - let read_cursor = Cursor::new(content); - let signature_packet = sig_cfg - .sign(&self.secret_key, passwd_fn, read_cursor) - .map_err(|e| Error::SignError(self.identity.clone(), e.to_string()))?; - - - //detached signature - if let Some(detached) = options.get(DETACHED_SIGNATURE) { - if detached == "true" { - let standard_signature = StandaloneSignature::new(signature_packet); - return Ok(standard_signature.to_armored_bytes(None)?) - } - } - let mut signature_bytes = Vec::with_capacity(1024); - let mut cursor = Cursor::new(&mut signature_bytes); - write_packet(&mut cursor, &signature_packet) - .map_err(|e| Error::SignError(self.identity.clone(), e.to_string()))?; - Ok(signature_bytes) - } -} diff --git a/src/infra/sign/signers.rs b/src/infra/sign/signers.rs deleted file mode 100644 index ba1c348..0000000 --- a/src/infra/sign/signers.rs +++ /dev/null @@ -1,45 +0,0 @@ -/* - * // Copyright (c) 2023 Huawei Technologies Co.,Ltd. All rights reserved. - * // - * // signatrust is licensed under Mulan PSL v2. - * // You can use this software according to the terms and conditions of the Mulan - * // PSL v2. - * // You may obtain a copy of Mulan PSL v2 at: - * // http://license.coscl.org.cn/MulanPSL2 - * // THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY - * // KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO - * // NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. - * // See the Mulan PSL v2 for more details. - */ - -use crate::infra::sign::openpgp::OpenPGPPlugin; -use crate::infra::sign::x509::X509Plugin; -use crate::infra::sign::traits::SignPlugins; -use crate::model::datakey::entity::{DataKey, KeyType}; -use crate::util::error::Result; -use std::collections::HashMap; -use std::sync::Arc; - -pub struct Signers {} - -impl Signers { - - //get responding sign plugin for data signing - pub fn load_from_data_key(data_key: &DataKey) -> Result>> { - match data_key.key_type { - KeyType::OpenPGP => Ok(Arc::new(Box::new(OpenPGPPlugin::new(data_key)?))), - KeyType::X509 => Ok(Arc::new(Box::new(X509Plugin::new(data_key)?))), - } - } - - //generating new key, including private & public keys and the certificate, empty if not required. - pub fn generate_keys( - key_type: &KeyType, - value: &HashMap, - ) -> Result<(Vec, Vec, Vec)> { - match key_type { - KeyType::OpenPGP => OpenPGPPlugin::generate_keys(value), - KeyType::X509 => X509Plugin::generate_keys(value), - } - } -} diff --git a/src/infra/sign/traits.rs b/src/infra/sign/traits.rs deleted file mode 100644 index 767de0e..0000000 --- a/src/infra/sign/traits.rs +++ /dev/null @@ -1,36 +0,0 @@ -/* - * // Copyright (c) 2023 Huawei Technologies Co.,Ltd. All rights reserved. - * // - * // signatrust is licensed under Mulan PSL v2. - * // You can use this software according to the terms and conditions of the Mulan - * // PSL v2. - * // You may obtain a copy of Mulan PSL v2 at: - * // http://license.coscl.org.cn/MulanPSL2 - * // THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY - * // KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO - * // NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. - * // See the Mulan PSL v2 for more details. - */ - -use crate::model::datakey::entity::DataKey; -use crate::util::error::Result; -use std::collections::HashMap; - -pub trait SignPlugins: Send + Sync { - fn new(db: &DataKey) -> Result - where - Self: Sized; - fn parse_attributes( - private_key: Option>, - public_key: Option>, - certificate: Option>, - ) -> HashMap - where - Self: Sized; - fn generate_keys( - value: &HashMap, - ) -> Result<(Vec, Vec, Vec)> - where - Self: Sized; - fn sign(&self, content: Vec, options: HashMap) -> Result>; -} diff --git a/src/infra/sign/x509.rs b/src/infra/sign/x509.rs deleted file mode 100644 index f62feee..0000000 --- a/src/infra/sign/x509.rs +++ /dev/null @@ -1,198 +0,0 @@ -/* - * // Copyright (c) 2023 Huawei Technologies Co.,Ltd. All rights reserved. - * // - * // signatrust is licensed under Mulan PSL v2. - * // You can use this software according to the terms and conditions of the Mulan - * // PSL v2. - * // You may obtain a copy of Mulan PSL v2 at: - * // http://license.coscl.org.cn/MulanPSL2 - * // THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY - * // KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO - * // NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. - * // See the Mulan PSL v2 for more details. - */ - -use std::collections::HashMap; - - - - - - -use chrono::{DateTime, Utc}; -use openssl::asn1::Asn1Time; -use openssl::cms::{CmsContentInfo, CMSOptions}; -use openssl::dsa::Dsa; -use openssl::hash::MessageDigest; -use openssl::pkey::{PKey, Private}; -use openssl::rsa::Rsa; -use openssl::x509; -use secstr::SecVec; -use serde::Deserialize; - -use validator::{Validate, ValidationError}; - -use crate::model::datakey::entity::DataKey; -use crate::model::datakey::traits::Identity; -use crate::util::error::{Error, Result}; - -use super::traits::SignPlugins; - -#[derive(Debug, Validate, Deserialize)] -pub struct X509KeyGenerationParameter { - #[validate(length(min = 1, max = 30, message="invalid x509 subject 'CommonName'"))] - common_name: String, - #[validate(length(min = 1, max = 30, message="invalid x509 subject 'OrganizationalUnit'"))] - organizational_unit: String, - #[validate(length(min = 1, max = 30, message="invalid x509 subject 'Organization'"))] - organization: String, - #[validate(length(min = 1, max = 30, message="invalid x509 subject 'Locality'"))] - locality: String, - #[validate(length(min = 1, max = 30, message="invalid x509 subject 'StateOrProvinceName'"))] - province_name: String, - #[validate(length(min = 2, max = 2, message="invalid x509 subject 'CountryName'"))] - country_name: String, - #[validate(custom(function = "validate_x509_key_type", message="invalid x509 attribute 'key_type'"))] - key_type: String, - #[validate(custom(function = "validate_x509_key_size", message="invalid x509 attribute 'key_length'"))] - key_length: String, - #[validate(custom(function = "validate_utc_time", message="invalid x509 attribute 'created_at'"))] - create_at: String, - #[validate(custom(function= "validate_utc_time", message="invalid x509 attribute 'expire_at'"))] - expire_at: String, -} - -impl X509KeyGenerationParameter { - pub fn get_key(&self) -> Result> { - return match self.key_type.as_str() { - "rsa" => Ok(PKey::from_rsa(Rsa::generate(self.key_length.parse()?)?)?), - "dsa" => Ok(PKey::from_dsa(Dsa::generate(self.key_length.parse()?)?)?), - _ => Err(Error::ParameterError( - "invalid key type for x509".to_string(), - )), - }; - } - - pub fn get_subject_name(&self) -> Result { - let mut x509_name = x509::X509NameBuilder::new()?; - x509_name.append_entry_by_text("CN", &self.common_name)?; - x509_name.append_entry_by_text("OU", &self.organizational_unit)?; - x509_name.append_entry_by_text("O", &self.organization)?; - x509_name.append_entry_by_text("L", &self.locality)?; - x509_name.append_entry_by_text("ST", &self.province_name)?; - x509_name.append_entry_by_text("C", &self.country_name)?; - Ok(x509_name.build()) - } -} - -fn validate_x509_key_type(key_type: &str) -> std::result::Result<(), ValidationError> { - if !vec!["rsa", "dsa"].contains(&key_type) { - return Err(ValidationError::new("invalid key type")); - } - Ok(()) -} - -fn validate_x509_key_size(key_size: &str) -> std::result::Result<(), ValidationError> { - if !vec!["2048", "3072", "4096"].contains(&key_size) { - return Err(ValidationError::new("invalid key size")); - } - Ok(()) -} - -fn validate_utc_time(expire: &str) -> std::result::Result<(), ValidationError> { - let now = Utc::now(); - match expire.parse::>() { - Ok(expire) => { - if expire <= now { - return Err(ValidationError::new("expire time less than current time")) - } - }, - Err(_e) => { - return Err(ValidationError::new("failed to parse time string to utc")); - } - } - Ok(()) -} - -fn days_in_duration(time: &str) -> Result { - let start = Utc::now(); - let end = time.parse::>()?; - Ok((end - start).num_days()) -} - -pub struct X509Plugin { - private_key: SecVec, - public_key: SecVec, - certificate: SecVec, - identity: String, -} - -impl X509Plugin { - pub fn attributes_validate(attr: &HashMap) -> Result { - let parameter: X509KeyGenerationParameter = - serde_json::from_str(serde_json::to_string(&attr)?.as_str())?; - match parameter.validate() { - Ok(_) => Ok(parameter), - Err(e) => Err(Error::ParameterError(format!("{:?}", e))), - } - } -} - -impl SignPlugins for X509Plugin { - fn new(db: &DataKey) -> Result { - Ok(Self { - private_key: db.private_key.clone(), - public_key: db.public_key.clone(), - certificate: db.certificate.clone(), - identity: db.get_identity(), - }) - } - - fn parse_attributes( - _private_key: Option>, - _public_key: Option>, - _certificate: Option>, - ) -> HashMap { - todo!() - } - - fn generate_keys( - value: &HashMap, - ) -> Result<(Vec, Vec, Vec)> { - let parameter = X509Plugin::attributes_validate(value)?; - let keys = parameter.get_key()?; - let mut generator = x509::X509Builder::new()?; - let hash = MessageDigest::sha256(); - generator.set_subject_name(parameter.get_subject_name()?.as_ref())?; - generator.set_issuer_name(parameter.get_subject_name()?.as_ref())?; - generator.set_pubkey(keys.as_ref())?; - generator.set_version(2)?; - generator.set_not_before(Asn1Time::days_from_now(days_in_duration(¶meter.create_at)? as u32)?.as_ref())?; - generator.set_not_after(Asn1Time::days_from_now(days_in_duration(¶meter.expire_at)? as u32)?.as_ref())?; - generator.sign(keys.as_ref(), hash)?; - let cert = generator.build(); - Ok(( - keys.private_key_to_pem_pkcs8()?, - keys.public_key_to_pem()?, - cert.to_pem()? - )) - } - - fn sign(&self, content: Vec, _options: HashMap) -> Result> { - let private_key = PKey::private_key_from_pem(self.private_key.unsecure())?; - let certificate = x509::X509::from_pem(self.certificate.unsecure())?; - //cms option reference: https://man.openbsd.org/CMS_sign.3 - let cms_signature = CmsContentInfo::sign( - Some(&certificate), - Some(&private_key), - None, - Some(&content), - CMSOptions::DETACHED - | CMSOptions::CMS_NOCERTS - | CMSOptions::BINARY - | CMSOptions::NOSMIMECAP - | CMSOptions::NOATTR, - )?; - Ok(cms_signature.to_der()?) - } -} diff --git a/src/server/control_server.rs b/src/server/control_server.rs deleted file mode 100644 index 94f5c60..0000000 --- a/src/server/control_server.rs +++ /dev/null @@ -1,175 +0,0 @@ -/* - * // Copyright (c) 2023 Huawei Technologies Co.,Ltd. All rights reserved. - * // - * // signatrust is licensed under Mulan PSL v2. - * // You can use this software according to the terms and conditions of the Mulan - * // PSL v2. - * // You may obtain a copy of Mulan PSL v2 at: - * // http://license.coscl.org.cn/MulanPSL2 - * // THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY - * // KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO - * // NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. - * // See the Mulan PSL v2 for more details. - */ - -use std::net::SocketAddr; -use std::sync::{Arc, RwLock}; - - -use actix_web::{App, HttpServer, middleware, web, cookie::Key}; -use config::Config; -use openssl::ssl::{SslAcceptor, SslFiletype, SslMethod}; - - - - -use actix_identity::IdentityMiddleware; -use actix_session::{config::PersistentSession, storage::CookieSessionStore, SessionMiddleware}; -use time::Duration as timeDuration; - - -use crate::infra::cipher::engine::{EncryptionEngine, EncryptionEngineWithClusterKey}; -use crate::infra::database::model::clusterkey::repository; -use crate::infra::database::model::datakey::repository as datakeyRepository; -use crate::infra::database::pool::{create_pool, get_db_pool}; -use crate::infra::kms::factory; - - - - - -use crate::service::control_service::*; - -use crate::util::error::Result; -use openidconnect::core::{ - CoreClient, -}; -use openidconnect::{JsonWebKeySet, ClientId, AuthUrl, UserInfoUrl, TokenUrl, RedirectUrl, ClientSecret, IssuerUrl}; -use crate::infra::database::model::token::repository::TokenRepository; -use crate::infra::database::model::user::repository::UserRepository; - -pub struct ControlServer { - server_config: Arc>, - data_key_repository: web::Data, - user_repository: web::Data, - token_repository: web::Data, -} - -impl ControlServer { - pub async fn new(server_config: Arc>) -> Result { - //initialize database and kms backend - let kms_provider = factory::KMSProviderFactory::new_provider( - &server_config.read()?.get_table("kms-provider")?, - )?; - let database = server_config.read()?.get_table("database")?; - create_pool(&database).await?; - let repository = - repository::EncryptedClusterKeyRepository::new(get_db_pool()?, kms_provider.clone()); - //initialize signature plugins - let engine_config = server_config.read()?.get_table("encryption-engine")?; - let mut engine = EncryptionEngineWithClusterKey::new( - Arc::new(Box::new(repository.clone())), - &engine_config, - )?; - engine.initialize().await?; - let data_repository = datakeyRepository::EncryptedDataKeyRepository::new( - get_db_pool()?, - Arc::new(Box::new(engine)), - ); - //initialize user repo - let user_repo = UserRepository::new(get_db_pool()?); - //initialize user repo - let token_repo = TokenRepository::new(get_db_pool()?); - let server = ControlServer { - server_config, - data_key_repository: web::Data::new(data_repository), - user_repository: web::Data::new(user_repo), - token_repository: web::Data::new(token_repo), - }; - Ok(server) - } - - pub fn initialize_oidc_client(&self) -> Result { - Ok(CoreClient::new( - ClientId::new(self.server_config.read()?.get_string("oidc.client_id")?), - Some(ClientSecret::new(self.server_config.read()?.get_string("oidc.client_secret")?)), - IssuerUrl::new(self.server_config.read()?.get_string("oidc.auth_url")?)?, - AuthUrl::new(self.server_config.read()?.get_string("oidc.auth_url")?)?, - Some(TokenUrl::new(self.server_config.read()?.get_string("oidc.token_url")?)?), - Some(UserInfoUrl::new(self.server_config.read()?.get_string("oidc.userinfo_url")?)?), - JsonWebKeySet::default()).set_redirect_uri(RedirectUrl::new(self.server_config.read()?.get_string("oidc.redirect_url")?)?, - )) - } - - pub async fn run(&self) -> Result<()> { - //start actix web server - let addr: SocketAddr = format!( - "{}:{}", - self.server_config - .read()? - .get_string("control-server.server_ip")?, - self.server_config - .read()? - .get_string("control-server.server_port")? - ) - .parse()?; - - let key = self.server_config.read()?.get_string("control-server.cookie_key")?; - - //initialize oidc client - let client = web::Data::new(self.initialize_oidc_client()?); - //TODO: remove me when openid connect library is ready - let user_info_url = web::Data::new(self.server_config.read()?.get_string("oidc.userinfo_url")?); - - info!("control server starts"); - // Start http server - let data_key_repository = self.data_key_repository.clone(); - let user_repository = self.user_repository.clone(); - let token_repository = self.token_repository.clone(); - let http_server = HttpServer::new(move || { - App::new() - // enable logger - .app_data(data_key_repository.clone()) - .app_data(client.clone()) - .app_data(user_info_url.clone()) - .app_data(user_repository.clone()) - .app_data(token_repository.clone()) - .wrap(middleware::Logger::default()) - .wrap(IdentityMiddleware::default()) - .wrap( - SessionMiddleware::builder( - CookieSessionStore::default(), Key::from(key.as_bytes())) - .session_lifecycle(PersistentSession::default().session_ttl(timeDuration::hours(1))) - .cookie_name("signatrust".to_owned()) - .cookie_secure(false) - .cookie_domain(None) - .cookie_path("/".to_owned()) - .build(), - ) - .service(web::scope("/api/v1") - .service(user_service::get_scope()) - .service(datakey_service::get_scope())) - }); - if self.server_config - .read()? - .get_string("tls_cert")? - .is_empty() - || self - .server_config - .read()? - .get_string("tls_key")? - .is_empty() { - info!("tls key and cert not configured, control server tls will be disabled"); - http_server.bind(addr)?.run().await?; - } else { - let mut builder = SslAcceptor::mozilla_intermediate(SslMethod::tls()).unwrap(); - builder - .set_private_key_file( - self.server_config.read()?.get_string("tls_key")?, SslFiletype::PEM).unwrap(); - builder.set_certificate_chain_file( - self.server_config.read()?.get_string("tls_cert")?).unwrap(); - http_server.bind_openssl(addr, builder)?.run().await?; - } - Ok(()) - } -} diff --git a/src/server/data_server.rs b/src/server/data_server.rs deleted file mode 100644 index 1557676..0000000 --- a/src/server/data_server.rs +++ /dev/null @@ -1,146 +0,0 @@ -/* - * // Copyright (c) 2023 Huawei Technologies Co.,Ltd. All rights reserved. - * // - * // signatrust is licensed under Mulan PSL v2. - * // You can use this software according to the terms and conditions of the Mulan - * // PSL v2. - * // You may obtain a copy of Mulan PSL v2 at: - * // http://license.coscl.org.cn/MulanPSL2 - * // THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY - * // KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO - * // NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. - * // See the Mulan PSL v2 for more details. - */ - - -use std::net::SocketAddr; -use std::sync::{Arc, atomic::AtomicBool, RwLock}; -use std::sync::atomic::Ordering; - -use config::Config; - -use tokio::fs; -use tokio::time::{Duration, sleep}; -use tonic::{ - transport::{ - Certificate, - Identity, Server, ServerTlsConfig, - }, -}; - - -use crate::infra::cipher::engine::{EncryptionEngine, EncryptionEngineWithClusterKey}; -use crate::infra::database::model::clusterkey::repository; -use crate::infra::database::model::datakey::repository as datakeyRepository; -use crate::infra::database::pool::{create_pool, get_db_pool}; -use crate::infra::kms::factory; - - - - - -use crate::service::data_service::grpc_service::get_grpc_service; - -use crate::util::error::Result; - -pub struct DataServer { - server_config: Arc>, - signal: Arc, - server_identity: Option, - ca_cert: Option, - data_key_repository: Arc -} - -impl DataServer { - pub async fn new(server_config: Arc>, signal: Arc) -> Result { - //initialize database and kms backend - let kms_provider = factory::KMSProviderFactory::new_provider( - &server_config.read()?.get_table("kms-provider")?, - )?; - let database = server_config.read()?.get_table("database")?; - create_pool(&database).await?; - let repository = - repository::EncryptedClusterKeyRepository::new(get_db_pool()?, kms_provider.clone()); - //initialize signature plugins - let engine_config = server_config.read()?.get_table("encryption-engine")?; - let mut engine = EncryptionEngineWithClusterKey::new( - Arc::new(Box::new(repository.clone())), - &engine_config, - )?; - engine.initialize().await?; - let data_repository = datakeyRepository::EncryptedDataKeyRepository::new( - get_db_pool()?, - Arc::new(Box::new(engine)), - ); - let mut server = DataServer { - server_config, - signal, - server_identity: None, - ca_cert: None, - data_key_repository: Arc::new(data_repository) - }; - server.load().await?; - Ok(server) - } - - async fn load(&mut self) -> Result<()> { - if self - .server_config - .read()? - .get_string("tls_cert")? - .is_empty() - || self - .server_config - .read()? - .get_string("tls_key")? - .is_empty() - { - info!("tls key and cert not configured, data server tls will be disabled"); - return Ok(()); - } - self.ca_cert = Some( - Certificate::from_pem( - fs::read(self.server_config.read()?.get_string("ca_root")?).await?)); - self.server_identity = Some(Identity::from_pem( - fs::read(self.server_config.read()?.get_string("tls_cert")?).await?, - fs::read(self.server_config.read()?.get_string("tls_key")?).await?)); - Ok(()) - } - - async fn shutdown_signal(&self) { - while !self.signal.load(Ordering::Relaxed) { - sleep(Duration::from_secs(1)).await; - } - info!("quit signal received...") - } - - pub async fn run(&self) -> Result<()> { - //start grpc server - let addr: SocketAddr = format!( - "{}:{}", - self.server_config - .read()? - .get_string("data-server.server_ip")?, - self.server_config - .read()? - .get_string("data-server.server_port")? - ) - .parse()?; - - let mut server = Server::builder(); - info!("data server starts"); - if let Some(identity) = self.server_identity.clone() { - server - .tls_config(ServerTlsConfig::new().identity(identity).client_ca_root(self.ca_cert.clone().unwrap()))? - .add_service(get_grpc_service(self.data_key_repository.clone())) - .serve_with_shutdown(addr, self.shutdown_signal()) - .await? - } else { - server - .add_service(get_grpc_service(self.data_key_repository.clone())) - .serve_with_shutdown(addr, self.shutdown_signal()) - .await? - } - Ok(()) - } -} diff --git a/src/server/mod.rs b/src/server/mod.rs deleted file mode 100644 index a358ff2..0000000 --- a/src/server/mod.rs +++ /dev/null @@ -1,2 +0,0 @@ -pub mod control_server; -pub mod data_server; diff --git a/src/service/control_service/datakey_service.rs b/src/service/control_service/datakey_service.rs deleted file mode 100644 index 7607abb..0000000 --- a/src/service/control_service/datakey_service.rs +++ /dev/null @@ -1,101 +0,0 @@ -/* - * // Copyright (c) 2023 Huawei Technologies Co.,Ltd. All rights reserved. - * // - * // signatrust is licensed under Mulan PSL v2. - * // You can use this software according to the terms and conditions of the Mulan - * // PSL v2. - * // You may obtain a copy of Mulan PSL v2 at: - * // http://license.coscl.org.cn/MulanPSL2 - * // THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY - * // KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO - * // NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. - * // See the Mulan PSL v2 for more details. - */ - -use actix_web::{ - HttpResponse, Responder, Result, web, Scope -}; -use secstr::SecVec; - -use crate::infra::database::model::datakey::repository::EncryptedDataKeyRepository; -use crate::service::control_service::model::datakey::dto::{DataKeyDTO, ExportKey}; -use crate::util::error::Error; -use validator::Validate; -use crate::infra::sign::signers::Signers; -use crate::model::datakey::entity::{DataKey, KeyState}; -use crate::model::datakey::repository::Repository; -use super::model::user::dto::UserIdentity; - - -async fn create_data_key(_user: UserIdentity, repository: web::Data, datakey: web::Json,) -> Result { - datakey.validate()?; - let mut key = DataKey::try_from(datakey.0)?; - let (private_key, public_key, certificate) = - Signers::generate_keys(&key.key_type, &key.attributes)?; - key.private_key = SecVec::new(private_key); - key.public_key = SecVec::new(public_key); - key.certificate = SecVec::new(certificate); - Ok(HttpResponse::Created().json(DataKeyDTO::try_from(repository.into_inner().create(&key).await?)?)) -} - -async fn list_data_key(_user: UserIdentity, repository: web::Data) -> Result { - let keys = repository.into_inner().get_all().await?; - let mut results = vec![]; - for k in keys { - results.push(DataKeyDTO::try_from(k)?) - } - Ok(HttpResponse::Ok().json(results)) -} - -async fn show_data_key(_user: UserIdentity, repository: web::Data, id: web::Path) -> Result { - let key = repository.into_inner().get_by_id(id.parse::()?).await?; - Ok(HttpResponse::Ok().json(DataKeyDTO::try_from(key)?)) -} - -async fn delete_data_key(_user: UserIdentity, repository: web::Data, id: web::Path) -> Result { - let repo = repository.into_inner(); - let key = repo.get_by_id(id.parse::()?).await?; - repo.delete_by_id(key.id).await?; - Ok(HttpResponse::Ok()) -} - -async fn export_data_key(user: UserIdentity, repository: web::Data, id: web::Path) -> Result { - info!("user {0} export a key {1}", user.email, id); - let key = repository.into_inner().get_by_id(id.parse::()?).await?; - let exported = ExportKey::try_from(key)?; - Ok(HttpResponse::Ok().json(exported)) -} - -async fn enable_data_key(_user: UserIdentity, repository: web::Data, id: web::Path) -> Result { - let repo = repository.into_inner(); - let key = repo.get_by_id(id.parse::()?).await?; - repo.update_state(key.id, KeyState::Enabled).await?; - Ok(HttpResponse::Ok()) -} - -async fn disable_data_key(_user: UserIdentity, repository: web::Data, id: web::Path) -> Result { - let repo = repository.into_inner(); - let key = repo.get_by_id(id.parse::()?).await?; - repo.update_state(key.id, KeyState::Disabled).await?; - Ok(HttpResponse::Ok()) -} - -async fn import_data_key(_user: UserIdentity, _repository: web::Data) -> Result { - Ok(HttpResponse::Ok()) -} - - -pub fn get_scope() -> Scope { - web::scope("/keys") - .service( - web::resource("/") - .route(web::get().to(list_data_key)) - .route(web::post().to(create_data_key))) - .service( web::resource("/{id}") - .route(web::get().to(show_data_key)) - .route(web::delete().to(delete_data_key))) - .service( web::resource("/import").route(web::post().to(import_data_key))) - .service( web::resource("/{id}/export").route(web::post().to(export_data_key))) - .service( web::resource("/{id}/enable").route(web::post().to(enable_data_key))) - .service( web::resource("/{id}/disable").route(web::post().to(disable_data_key))) -} diff --git a/src/service/control_service/mod.rs b/src/service/control_service/mod.rs deleted file mode 100644 index ffa06e6..0000000 --- a/src/service/control_service/mod.rs +++ /dev/null @@ -1,3 +0,0 @@ -pub mod datakey_service; -pub mod user_service; -pub mod model; \ No newline at end of file diff --git a/src/service/control_service/model/datakey/dto.rs b/src/service/control_service/model/datakey/dto.rs deleted file mode 100644 index a87072e..0000000 --- a/src/service/control_service/model/datakey/dto.rs +++ /dev/null @@ -1,126 +0,0 @@ -/* - * // Copyright (c) 2023 Huawei Technologies Co.,Ltd. All rights reserved. - * // - * // signatrust is licensed under Mulan PSL v2. - * // You can use this software according to the terms and conditions of the Mulan - * // PSL v2. - * // You may obtain a copy of Mulan PSL v2 at: - * // http://license.coscl.org.cn/MulanPSL2 - * // THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY - * // KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO - * // NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. - * // See the Mulan PSL v2 for more details. - */ - -use crate::model::datakey::entity::{DataKey, KeyState}; -use crate::model::datakey::entity::KeyType; - -use crate::util::error::Result; - -use chrono::{DateTime, Utc}; - - - - - -use std::str::FromStr; - -use secstr::*; -use validator::{Validate, ValidationError}; -use std::collections::HashMap; -use crate::util::error::Error; -use serde::{Deserialize, Serialize}; - -#[derive(Deserialize, Serialize)] -pub struct ExportKey { - pub private_key: String, - pub public_key: String, - pub certificate: String, -} - -impl TryFrom for ExportKey { - type Error = Error; - - fn try_from(value: DataKey) -> std::result::Result { - Ok(ExportKey{ - private_key: String::from_utf8_lossy(value.private_key.unsecure()).to_string(), - public_key: String::from_utf8_lossy(value.public_key.unsecure()).to_string(), - certificate: String::from_utf8_lossy(value.certificate.unsecure()).to_string(), - }) - } -} - -#[derive(Debug, Validate, Deserialize, Serialize)] -pub struct DataKeyDTO { - #[serde(skip_deserializing)] - pub id: i32, - #[validate(length(min = 4, max = 20))] - pub name: String, - #[validate(email)] - pub email: String, - #[validate(length(min = 0, max = 100))] - pub description: String, - pub user: String, - pub attributes: HashMap, - pub key_type: String, - #[validate(custom = "validate_utc_time")] - pub create_at: String, - #[validate(custom = "validate_utc_time")] - pub expire_at: String, - #[serde(skip_deserializing)] - pub key_state: String, -} - -fn validate_utc_time(expire: &str) -> std::result::Result<(), ValidationError> { - if expire.parse::>().is_err() { - return Err(ValidationError::new("failed to parse time string to utc")); - } - Ok(()) -} - -impl TryFrom for DataKey { - type Error = Error; - - fn try_from(dto: DataKeyDTO) -> Result { - let mut combined_attributes = dto.attributes.clone(); - combined_attributes.insert("name".to_string(), dto.name.clone()); - combined_attributes.insert("email".to_string(), dto.email.clone()); - combined_attributes.insert("create_at".to_string(), dto.create_at.clone()); - combined_attributes.insert("expire_at".to_string(), dto.expire_at.clone()); - Ok(DataKey { - id: dto.id, - name: dto.name, - description: dto.description, - user: dto.user, - email: dto.email, - attributes: combined_attributes, - key_type: KeyType::from_str(dto.key_type.as_str())?, - private_key: SecVec::new(vec![]), - public_key: SecVec::new(vec![]), - certificate: SecVec::new(vec![]), - create_at: dto.create_at.parse()?, - expire_at: dto.expire_at.parse()?, - soft_delete: false, - key_state: KeyState::default() - }) - } -} - -impl TryFrom for DataKeyDTO { - type Error = Error; - - fn try_from(dto: DataKey) -> Result { - Ok(DataKeyDTO { - id: dto.id, - name: dto.name, - description: dto.description, - user: dto.user, - email: dto.email, - attributes: dto.attributes, - key_type: dto.key_type.to_string(), - create_at: dto.create_at.to_string(), - expire_at: dto.expire_at.to_string(), - key_state: dto.key_state.to_string(), - }) - } -} diff --git a/src/service/control_service/model/datakey/mod.rs b/src/service/control_service/model/datakey/mod.rs deleted file mode 100644 index 6c29114..0000000 --- a/src/service/control_service/model/datakey/mod.rs +++ /dev/null @@ -1 +0,0 @@ -pub mod dto; \ No newline at end of file diff --git a/src/service/control_service/model/mod.rs b/src/service/control_service/model/mod.rs deleted file mode 100644 index 151f572..0000000 --- a/src/service/control_service/model/mod.rs +++ /dev/null @@ -1,3 +0,0 @@ -pub mod datakey; -pub mod user; -pub mod token; \ No newline at end of file diff --git a/src/service/control_service/model/token/dto.rs b/src/service/control_service/model/token/dto.rs deleted file mode 100644 index c18f56d..0000000 --- a/src/service/control_service/model/token/dto.rs +++ /dev/null @@ -1,46 +0,0 @@ -/* - * // Copyright (c) 2023 Huawei Technologies Co.,Ltd. All rights reserved. - * // - * // signatrust is licensed under Mulan PSL v2. - * // You can use this software according to the terms and conditions of the Mulan - * // PSL v2. - * // You may obtain a copy of Mulan PSL v2 at: - * // http://license.coscl.org.cn/MulanPSL2 - * // THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY - * // KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO - * // NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. - * // See the Mulan PSL v2 for more details. - */ - -use serde::{Deserialize, Serialize}; -use std::convert::From; -use chrono::{DateTime, Utc}; -use crate::model::token::entity::Token; - - -#[derive(Debug, Deserialize, Serialize)] -pub struct TokenDTO { - pub token: String, - pub expire_at: DateTime -} - - -impl From for Token { - fn from(token: TokenDTO) -> Self { - Token { - id: 0, - user_id: 0, - token: token.token.clone(), - expire_at: token.expire_at, - } - } -} - -impl From for TokenDTO { - fn from(token: Token) -> Self { - TokenDTO { - token: token.token.clone(), - expire_at: token.expire_at, - } - } -} \ No newline at end of file diff --git a/src/service/control_service/model/token/mod.rs b/src/service/control_service/model/token/mod.rs deleted file mode 100644 index 6c29114..0000000 --- a/src/service/control_service/model/token/mod.rs +++ /dev/null @@ -1 +0,0 @@ -pub mod dto; \ No newline at end of file diff --git a/src/service/control_service/model/user/dto.rs b/src/service/control_service/model/user/dto.rs deleted file mode 100644 index 3523ef7..0000000 --- a/src/service/control_service/model/user/dto.rs +++ /dev/null @@ -1,104 +0,0 @@ -/* - * // Copyright (c) 2023 Huawei Technologies Co.,Ltd. All rights reserved. - * // - * // signatrust is licensed under Mulan PSL v2. - * // You can use this software according to the terms and conditions of the Mulan - * // PSL v2. - * // You may obtain a copy of Mulan PSL v2 at: - * // http://license.coscl.org.cn/MulanPSL2 - * // THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY - * // KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO - * // NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. - * // See the Mulan PSL v2 for more details. - */ - -use actix_web::{Result, HttpRequest, FromRequest, dev::Payload}; -use crate::util::error::{Error}; - -use actix_identity::Identity; -use actix_web::web; -use std::pin::Pin; -use futures::Future; -use serde::{Deserialize, Serialize}; -use std::convert::From; -use chrono::{Utc}; -use crate::infra::database::model::token::repository::TokenRepository; -use crate::infra::database::model::user::repository::UserRepository; -use crate::model::token::repository::Repository as tokenRepository; -use crate::model::user::entity::User; -use crate::model::user::repository::Repository as userRepository; - -#[derive(Debug, Deserialize, Serialize)] -pub struct UserIdentity { - pub email: String, - pub id: i32, -} - -impl FromRequest for UserIdentity { - type Error = Error; - type Future = Pin>>>; - - fn from_request(req: &HttpRequest, pl: &mut Payload) -> Self::Future { - let mut login: Option = None; - //fetch from session - if let Ok(identity) = Identity::from_request(&req.clone(), pl).into_inner() { - if let Ok(user_json) = identity.id() { - if let Ok(user) = serde_json::from_str(&user_json) { - login = Some(user) - } - } - } - let req = req.clone(); - Box::pin(async move { - match login { - //fetch valid token - None => { - if let Some(value) = req.clone().headers().get("Authorization") { - if let Some(tk_repo) = req.clone().app_data::>() { - if let Ok(token) = tk_repo.get_ref().get_token_by_value(value.to_str().unwrap()).await { - //token exists and valid - if token.expire_at.gt(&Utc::now()) { - if let Some(us_repo) = req.clone().app_data::>() { - if let Ok(user) = us_repo.get_ref().get_by_id(token.user_id).await { - return Ok(UserIdentity::from(user)); - } - } else { - warn!("unable to find token's user info"); - } - } else { - warn!("token expired"); - } - } else { - warn!("unable to find token record"); - } - } - } else { - warn!("authorization header provided, while empty value"); - } - Err(Error::UnauthorizedError) - } - Some(user) => { - Ok(user) - } - } - }) - } -} - -impl From for User { - fn from(id: UserIdentity) -> Self { - User { - id: id.id, - email: id.email - } - } -} - -impl From for UserIdentity { - fn from(id: User) -> Self { - UserIdentity { - id: id.id, - email: id.email, - } - } -} \ No newline at end of file diff --git a/src/service/control_service/model/user/mod.rs b/src/service/control_service/model/user/mod.rs deleted file mode 100644 index 6c29114..0000000 --- a/src/service/control_service/model/user/mod.rs +++ /dev/null @@ -1 +0,0 @@ -pub mod dto; \ No newline at end of file diff --git a/src/service/control_service/user_service.rs b/src/service/control_service/user_service.rs deleted file mode 100644 index 8143254..0000000 --- a/src/service/control_service/user_service.rs +++ /dev/null @@ -1,130 +0,0 @@ -/* - * // Copyright (c) 2023 Huawei Technologies Co.,Ltd. All rights reserved. - * // - * // signatrust is licensed under Mulan PSL v2. - * // You can use this software according to the terms and conditions of the Mulan - * // PSL v2. - * // You may obtain a copy of Mulan PSL v2 at: - * // http://license.coscl.org.cn/MulanPSL2 - * // THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY - * // KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO - * // NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. - * // See the Mulan PSL v2 for more details. - */ - -use actix_web::{HttpResponse, Responder, Result, web, Scope, HttpRequest, HttpMessage}; - -use serde::{Deserialize}; - -use crate::util::error::Error; -use super::model::user::dto::UserIdentity; -use actix_identity::Identity; - -use openidconnect::{ - AuthenticationFlow, AuthorizationCode, CsrfToken, Nonce, - OAuth2TokenResponse, core::CoreResponseType, core::CoreClient -}; - -use crate::model::user::repository::Repository as userRepository; -use reqwest::{header, Client}; -use openidconnect::Scope as OIDCScore; -use openidconnect::reqwest::async_http_client; -use crate::infra::database::model::token::repository::TokenRepository; -use crate::infra::database::model::user::repository::UserRepository; -use crate::model::token::entity::Token; -use crate::model::token::repository::Repository as tokenRepository; -use crate::model::user::entity::User; -use crate::service::control_service::model::token::dto::TokenDTO; - -#[derive(Deserialize)] -struct Code { - pub code: String, -} - -#[derive(Deserialize)] -pub struct UserEmail { - pub email: String, -} - -async fn login(client: web::Data) -> Result { - let (authorize_url, _, _) = client - .authorize_url(AuthenticationFlow::::AuthorizationCode, - CsrfToken::new_random, Nonce::new_random, ) - .add_scope(OIDCScore::new("email".to_string())) - .add_scope(OIDCScore::new("openid".to_string())) - .add_scope(OIDCScore::new("profile".to_string())) - .url(); - Ok(HttpResponse::Found().insert_header(("Location", authorize_url.as_str())).finish()) -} - -async fn info(user: UserIdentity) -> Result { - Ok(HttpResponse::Ok().json(user)) -} - -async fn logout(id: Identity) -> Result { - id.logout(); - Ok( HttpResponse::NoContent().finish()) -} - -async fn callback(req: HttpRequest, client: web::Data, user_repo: web::Data, userinfo_url: web::Data, code: web::Query) -> Result { - match client - .exchange_code(AuthorizationCode::new(code.code.clone())) - .request_async(async_http_client).await { - Ok(token_response) => { - let id: User = User::new(get_user_info(&userinfo_url, token_response.access_token().secret()).await?.email)?; - let user_entity:UserIdentity = UserIdentity::from(user_repo.into_inner().create(&id).await?); - match Identity::login(&req.extensions(), serde_json::to_string(&user_entity)?) { - Ok(_) => { - Ok(HttpResponse::Found().insert_header(("Location", "/")).finish()) - } - Err(err) => { - Err(Error::AuthError(format!("failed to get oidc token {}", err.to_string()))) - } - } - } - Err(err) => { - Err(Error::AuthError(format!("failed to get oidc token {}", err.to_string()))) - } - } -} - -async fn new_token(user: UserIdentity, token_repo: web::Data) -> Result { - let token = token_repo.into_inner().create(&Token::new(user.id)?).await?; - Ok(HttpResponse::Ok().json(TokenDTO::from(token))) -} - -async fn list_token(user: UserIdentity, token_repo: web::Data) -> Result { - let token = token_repo.into_inner().get_token_by_user_id(user.id).await?; - let mut results = vec![]; - for t in token.into_iter() { - results.push(TokenDTO::from(t)); - } - Ok(HttpResponse::Ok().json(results)) -} - -// NOTE: openidconnect can't handle the case when null is returned in the userinfo, we have to handle it this way. -// https://github.com/ramosbugs/openidconnect-rs/issues/100 -async fn get_user_info(userinfo_url: &str, access_token: &str) -> Result { - let mut auth_header = header::HeaderMap::new(); - auth_header.insert("Authorization", header::HeaderValue::from_str( access_token)?); - match Client::builder().default_headers(auth_header).build() { - Ok(client) => { - let resp: UserEmail = client.get(userinfo_url).send().await?.json().await?; - Ok(resp) - } - Err(err) => { - Err(Error::AuthError(err.to_string())) - } - } -} - - - -pub fn get_scope() -> Scope { - web::scope("/users") - .service(web::resource("/").route(web::get().to(info))) - .service(web::resource("/login").route(web::get().to(login))) - .service(web::resource("/logout").route(web::post().to(logout))) - .service(web::resource("/callback").route(web::get().to(callback))) - .service(web::resource("/api_keys").route(web::get().to(new_token)).route(web::post().to(list_token))) -} \ No newline at end of file diff --git a/src/service/data_service/grpc_service.rs b/src/service/data_service/grpc_service.rs deleted file mode 100644 index c63ee96..0000000 --- a/src/service/data_service/grpc_service.rs +++ /dev/null @@ -1,89 +0,0 @@ -/* - * // Copyright (c) 2023 Huawei Technologies Co.,Ltd. All rights reserved. - * // - * // signatrust is licensed under Mulan PSL v2. - * // You can use this software according to the terms and conditions of the Mulan - * // PSL v2. - * // You may obtain a copy of Mulan PSL v2 at: - * // http://license.coscl.org.cn/MulanPSL2 - * // THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY - * // KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO - * // NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. - * // See the Mulan PSL v2 for more details. - */ - -use std::collections::HashMap; - -use std::sync::Arc; -pub mod signatrust { - tonic::include_proto!("signatrust"); -} -use tokio_stream::StreamExt; - -use signatrust::{ - signatrust_server::Signatrust, signatrust_server::SignatrustServer, SignStreamRequest, - SignStreamResponse, -}; -use tonic::{Request, Response, Status, Streaming}; -use crate::infra::database::model::datakey::repository::EncryptedDataKeyRepository; - - -use crate::util::error::Result as InnerResult; -use crate::util::signer_container::DataKeyContainer; - -pub struct SignService { - data_key_repository: Arc, - container: DataKeyContainer -} - -impl SignService { - pub fn new(data_key_repository: Arc) -> SignService { - SignService { - data_key_repository: data_key_repository.clone(), - container: DataKeyContainer::new(data_key_repository), - } - } - async fn sign_stream_inner(&self, key_type: String, key_name: String, options: &HashMap, data: Vec) -> InnerResult> { - self.container.get_signer(key_type, key_name).await?.sign(data.clone(), options.clone()) - } -} - -#[tonic::async_trait] -impl Signatrust for SignService { - async fn sign_stream( - &self, - request: Request>, - ) -> Result, Status> { - let mut binaries = request.into_inner(); - let mut data: Vec = vec![]; - let mut key_name: String = "".to_string(); - let mut key_type: String = "".to_string(); - let mut options: HashMap = HashMap::new(); - while let Some(content) = binaries.next().await { - let mut inner_result = content.unwrap(); - data.append(&mut inner_result.data); - key_name = inner_result.key_id; - key_type = inner_result.key_type; - options = inner_result.options; - } - match self.sign_stream_inner(key_type, key_name, &options, data).await { - Ok(content) => { - Ok(Response::new(SignStreamResponse { - signature: content, - error: "".to_string() - })) - } - Err(err) => { - Ok(Response::new(SignStreamResponse { - signature: vec![], - error: err.to_string(), - })) - } - } - } -} - -pub fn get_grpc_service(data_key_repository: Arc) -> SignatrustServer { - let app = SignService::new(data_key_repository); - SignatrustServer::new(app) -} diff --git a/src/service/data_service/mod.rs b/src/service/data_service/mod.rs deleted file mode 100644 index 459f56f..0000000 --- a/src/service/data_service/mod.rs +++ /dev/null @@ -1 +0,0 @@ -pub mod grpc_service; \ No newline at end of file diff --git a/src/service/mod.rs b/src/service/mod.rs deleted file mode 100644 index e5cd3c7..0000000 --- a/src/service/mod.rs +++ /dev/null @@ -1,2 +0,0 @@ -pub mod control_service; -pub mod data_service; -- Gitee