Skip to content

Commit 2b29548

Browse files
authored
Initialize root path and parameter when initializing workspace (#191)
* initialize root path and parameter when initializing workspace * merge workspaces router instead of nesting * bump up nebula version into 0.0.2 * add me to authors
1 parent 44b566a commit 2b29548

File tree

7 files changed

+150
-55
lines changed

7 files changed

+150
-55
lines changed

Cargo.lock

Lines changed: 13 additions & 13 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,9 @@ resolver = "2"
33
members = ["crates/*"]
44

55
[workspace.package]
6-
version = "0.0.1"
6+
version = "0.0.2"
77
edition = "2021"
8-
authors = ["John Choi <john@cremit.io>"]
8+
authors = ["John Choi <john@cremit.io>", "Boris Im <boris@cremit.io>"]
99
repository = "https://github.com/cremithq/nebula"
1010
keywords = ["secret", "vault"]
1111
categories = ["security"]

crates/nebula-backbone/src/application/mod.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,12 @@ pub(crate) struct Application {
4646

4747
impl Application {
4848
pub fn workspace(&self) -> impl WorkspaceUseCase {
49-
WorkspaceUseCaseImpl::new(self.database_connection.clone(), self.workspace_service.clone())
49+
WorkspaceUseCaseImpl::new(
50+
self.database_connection.clone(),
51+
self.workspace_service.clone(),
52+
self.secret_service.clone(),
53+
self.parameter_service.clone(),
54+
)
5055
}
5156

5257
pub fn with_workspace(&self, workspace_name: &str) -> ApplicationWithWorkspace {

crates/nebula-backbone/src/application/workspace/mod.rs

Lines changed: 108 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,17 @@ use sea_orm::{DatabaseConnection, TransactionTrait};
55

66
use crate::{
77
database::Persistable,
8-
domain::workspace::{Error as WorkspaceServiceError, Workspace, WorkspaceService},
8+
domain::{
9+
parameter::Error as ParameterError,
10+
secret::Error as SecretError,
11+
workspace::{Error as WorkspaceServiceError, Workspace, WorkspaceService},
12+
},
913
};
1014

1115
use self::{command::CreatingWorkspaceCommand, data::WorkspaceData};
1216

17+
use super::{ParameterService, SecretService};
18+
1319
pub mod command;
1420
pub mod data;
1521

@@ -20,20 +26,26 @@ pub(crate) trait WorkspaceUseCase {
2026
async fn delete_by_name(&self, name: &str) -> Result<()>;
2127
}
2228

23-
#[derive(Default)]
24-
pub(crate) struct WorkspaceUseCaseImpl<W: WorkspaceService + Sync + Send> {
29+
pub(crate) struct WorkspaceUseCaseImpl {
2530
database_connection: Arc<DatabaseConnection>,
26-
workspace_service: Arc<W>,
31+
workspace_service: Arc<dyn WorkspaceService + Sync + Send>,
32+
secret_service: Arc<dyn SecretService + Sync + Send>,
33+
parameter_service: Arc<dyn ParameterService + Sync + Send>,
2734
}
2835

29-
impl<W: WorkspaceService + Sync + Send> WorkspaceUseCaseImpl<W> {
30-
pub fn new(database_connection: Arc<DatabaseConnection>, workspace_service: Arc<W>) -> Self {
31-
Self { database_connection, workspace_service }
36+
impl WorkspaceUseCaseImpl {
37+
pub fn new(
38+
database_connection: Arc<DatabaseConnection>,
39+
workspace_service: Arc<dyn WorkspaceService + Sync + Send>,
40+
secret_service: Arc<dyn SecretService + Sync + Send>,
41+
parameter_service: Arc<dyn ParameterService + Sync + Send>,
42+
) -> Self {
43+
Self { database_connection, workspace_service, secret_service, parameter_service }
3244
}
3345
}
3446

3547
#[async_trait]
36-
impl<W: WorkspaceService + Sync + Send> WorkspaceUseCase for WorkspaceUseCaseImpl<W> {
48+
impl WorkspaceUseCase for WorkspaceUseCaseImpl {
3749
async fn get_all(&self) -> Result<Vec<WorkspaceData>> {
3850
let transaction = self.database_connection.begin().await.map_err(anyhow::Error::from)?;
3951

@@ -49,6 +61,8 @@ impl<W: WorkspaceService + Sync + Send> WorkspaceUseCase for WorkspaceUseCaseImp
4961
let transaction = self.database_connection.begin().await.map_err(anyhow::Error::from)?;
5062

5163
self.workspace_service.create(&transaction, &cmd.name).await?;
64+
self.secret_service.initialize_root_path(&transaction).await?;
65+
self.parameter_service.create(&transaction).await?;
5266

5367
transaction.commit().await.map_err(anyhow::Error::from)?;
5468

@@ -87,6 +101,24 @@ pub enum Error {
87101
Anyhow(#[from] anyhow::Error),
88102
}
89103

104+
impl From<SecretError> for Error {
105+
fn from(value: SecretError) -> Self {
106+
match value {
107+
SecretError::Anyhow(e) => Self::Anyhow(e),
108+
_ => Self::Anyhow(value.into()),
109+
}
110+
}
111+
}
112+
113+
impl From<ParameterError> for Error {
114+
fn from(value: ParameterError) -> Self {
115+
match value {
116+
ParameterError::Anyhow(e) => Self::Anyhow(e),
117+
_ => Self::Anyhow(value.into()),
118+
}
119+
}
120+
}
121+
90122
impl From<WorkspaceServiceError> for Error {
91123
fn from(value: WorkspaceServiceError) -> Self {
92124
match value {
@@ -104,12 +136,20 @@ mod test {
104136
use std::sync::Arc;
105137

106138
use anyhow::anyhow;
139+
use nebula_abe::{
140+
curves::{bn462::Bn462Curve, PairingCurve},
141+
schemes::isabella24::GlobalParams,
142+
};
107143
use sea_orm::{DatabaseBackend, MockDatabase, MockExecResult};
108144
use ulid::Ulid;
109145

110146
use super::{command::CreatingWorkspaceCommand, Error, WorkspaceUseCase, WorkspaceUseCaseImpl};
111147

112-
use crate::domain::workspace::{Error as WorkspaceServiceError, MockWorkspaceService, Workspace};
148+
use crate::domain::{
149+
parameter::{MockParameterService, Parameter},
150+
secret::MockSecretService,
151+
workspace::{Error as WorkspaceServiceError, MockWorkspaceService, Workspace},
152+
};
113153

114154
#[tokio::test]
115155
async fn when_creating_workspace_use_case_should_delegate_to_service() {
@@ -123,31 +163,28 @@ mod test {
123163
.times(1)
124164
.returning(|_, _| Ok(()));
125165

126-
let workspace_use_case = WorkspaceUseCaseImpl::new(mock_database, Arc::new(workspace_service_mock));
166+
let mut secret_service_mock = MockSecretService::new();
167+
secret_service_mock.expect_initialize_root_path().times(1).returning(|_| Ok(()));
168+
169+
let mut rng = <Bn462Curve as PairingCurve>::Rng::new();
170+
let mut parameter_service_mock = MockParameterService::new();
171+
parameter_service_mock
172+
.expect_create()
173+
.times(1)
174+
.returning(move |_| Ok(Parameter { version: 1, value: GlobalParams::<Bn462Curve>::new(&mut rng) }));
175+
176+
let workspace_use_case = WorkspaceUseCaseImpl::new(
177+
mock_database,
178+
Arc::new(workspace_service_mock),
179+
Arc::new(secret_service_mock),
180+
Arc::new(parameter_service_mock),
181+
);
127182
workspace_use_case
128183
.create(CreatingWorkspaceCommand { name: WORKSPACE_NAME.to_owned() })
129184
.await
130185
.expect("creating workspace should be successful");
131186
}
132187

133-
#[tokio::test]
134-
async fn when_creating_workspace_succeed_use_case_should_returns_empty_ok() {
135-
const WORKSPACE_NAME: &str = "testworkspace";
136-
let mock_database = Arc::new(MockDatabase::new(DatabaseBackend::Postgres).into_connection());
137-
let mut workspace_service_mock = MockWorkspaceService::new();
138-
139-
workspace_service_mock
140-
.expect_create()
141-
.withf(|_, name| name == WORKSPACE_NAME)
142-
.times(1)
143-
.returning(|_, _| Ok(()));
144-
145-
let workspace_use_case = WorkspaceUseCaseImpl::new(mock_database, Arc::new(workspace_service_mock));
146-
let result = workspace_use_case.create(CreatingWorkspaceCommand { name: WORKSPACE_NAME.to_owned() }).await;
147-
148-
assert!(matches!(result, Ok(())));
149-
}
150-
151188
#[tokio::test]
152189
async fn when_creating_workspace_failed_with_anyhow_use_case_should_returns_anyhow() {
153190
const WORKSPACE_NAME: &str = "testworkspace";
@@ -159,8 +196,15 @@ mod test {
159196
.withf(|_, name| name == WORKSPACE_NAME)
160197
.times(1)
161198
.returning(|_, _| Err(WorkspaceServiceError::Anyhow(anyhow!("some error"))));
162-
163-
let workspace_use_case = WorkspaceUseCaseImpl::new(mock_database, Arc::new(workspace_service_mock));
199+
let secret_service_mock = MockSecretService::new();
200+
let parameter_service_mock = MockParameterService::new();
201+
202+
let workspace_use_case = WorkspaceUseCaseImpl::new(
203+
mock_database,
204+
Arc::new(workspace_service_mock),
205+
Arc::new(secret_service_mock),
206+
Arc::new(parameter_service_mock),
207+
);
164208
let result = workspace_use_case.create(CreatingWorkspaceCommand { name: WORKSPACE_NAME.to_owned() }).await;
165209

166210
assert!(matches!(result, Err(Error::Anyhow(_))));
@@ -179,8 +223,15 @@ mod test {
179223
.withf(|_, name| name == WORKSPACE_NAME)
180224
.times(1)
181225
.returning(|_, _| Err(WorkspaceServiceError::WorkspaceNameConflicted));
182-
183-
let workspace_use_case = WorkspaceUseCaseImpl::new(mock_database, Arc::new(workspace_service_mock));
226+
let secret_service_mock = MockSecretService::new();
227+
let parameter_service_mock = MockParameterService::new();
228+
229+
let workspace_use_case = WorkspaceUseCaseImpl::new(
230+
mock_database,
231+
Arc::new(workspace_service_mock),
232+
Arc::new(secret_service_mock),
233+
Arc::new(parameter_service_mock),
234+
);
184235
let result = workspace_use_case.create(CreatingWorkspaceCommand { name: WORKSPACE_NAME.to_owned() }).await;
185236

186237
assert!(matches!(result, Err(Error::WorkspaceNameConflicted)));
@@ -195,8 +246,15 @@ mod test {
195246
.expect_get_all()
196247
.times(1)
197248
.returning(|_| Ok(vec![Workspace::new(Ulid::new(), "testworkspace".to_owned())]));
198-
199-
let workspace_use_case = WorkspaceUseCaseImpl::new(mock_database, Arc::new(workspace_service_mock));
249+
let secret_service_mock = MockSecretService::new();
250+
let parameter_service_mock = MockParameterService::new();
251+
252+
let workspace_use_case = WorkspaceUseCaseImpl::new(
253+
mock_database,
254+
Arc::new(workspace_service_mock),
255+
Arc::new(secret_service_mock),
256+
Arc::new(parameter_service_mock),
257+
);
200258
let result = workspace_use_case.get_all().await;
201259

202260
assert_eq!(result.expect("getting workspaces should be successful")[0].name, "testworkspace");
@@ -210,14 +268,21 @@ mod test {
210268

211269
let mock_database = Arc::new(mock_database.into_connection());
212270
let mut workspace_service_mock = MockWorkspaceService::new();
271+
let secret_service_mock = MockSecretService::new();
272+
let parameter_service_mock = MockParameterService::new();
213273

214274
workspace_service_mock
215275
.expect_get_by_name()
216276
.withf(|_, name| name == WORKSPACE_NAME)
217277
.times(1)
218278
.returning(|_, _| Ok(Some(Workspace::new(Ulid::new(), "testworkspace".to_owned()))));
219279

220-
let workspace_use_case = WorkspaceUseCaseImpl::new(mock_database, Arc::new(workspace_service_mock));
280+
let workspace_use_case = WorkspaceUseCaseImpl::new(
281+
mock_database,
282+
Arc::new(workspace_service_mock),
283+
Arc::new(secret_service_mock),
284+
Arc::new(parameter_service_mock),
285+
);
221286
let result = workspace_use_case.delete_by_name(WORKSPACE_NAME).await;
222287

223288
assert!(matches!(result, Ok(())));
@@ -229,13 +294,20 @@ mod test {
229294
let mock_database = Arc::new(MockDatabase::new(DatabaseBackend::Postgres).into_connection());
230295
let mut workspace_service_mock = MockWorkspaceService::new();
231296

297+
let secret_service_mock = MockSecretService::new();
298+
let parameter_service_mock = MockParameterService::new();
232299
workspace_service_mock
233300
.expect_get_by_name()
234301
.withf(|_, name| name == WORKSPACE_NAME)
235302
.times(1)
236303
.returning(|_, _| Ok(None));
237304

238-
let workspace_use_case = WorkspaceUseCaseImpl::new(mock_database, Arc::new(workspace_service_mock));
305+
let workspace_use_case = WorkspaceUseCaseImpl::new(
306+
mock_database,
307+
Arc::new(workspace_service_mock),
308+
Arc::new(secret_service_mock),
309+
Arc::new(parameter_service_mock),
310+
);
239311
let result = workspace_use_case.delete_by_name(WORKSPACE_NAME).await;
240312

241313
assert!(matches!(result, Err(Error::WorkspaceNotExists)));

0 commit comments

Comments
 (0)