Skip to content

Commit

Permalink
Implement role checking in delete_access
Browse files Browse the repository at this point in the history
  • Loading branch information
sabotack committed Dec 5, 2023
1 parent f87e1c0 commit b79a3d0
Show file tree
Hide file tree
Showing 2 changed files with 133 additions and 5 deletions.
40 changes: 40 additions & 0 deletions src/api/ecdar_api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -605,6 +605,46 @@ impl EcdarApi for ConcreteEcdarApi {
) -> Result<Response<()>, Status> {
let message = request.get_ref().clone();

let uid = request
.uid()
.ok_or(Status::internal("Could not get uid from request metadata"))?;

let user_access = self
.contexts
.access_context
.get_by_id(message.id)
.await
.map_err(|err| Status::new(Code::Internal, err.to_string()))?
.ok_or_else(|| {
Status::new(
Code::NotFound,
"No access entity found for user".to_string(),
)
})?;

check_editor_role_helper(
Arc::clone(&self.contexts.access_context),
uid,
user_access.model_id,
)
.await?;

let model = self
.contexts
.model_context
.get_by_id(user_access.model_id)
.await
.map_err(|err| Status::new(Code::Internal, err.to_string()))?
.ok_or_else(|| Status::new(Code::NotFound, "No model found for access".to_string()))?;

// Check that the requester is not trying to delete the owner's access
if model.owner_id == message.id {
return Err(Status::new(
Code::PermissionDenied,
"You cannot delete the access entity for this user",
));
}

match self.contexts.access_context.delete(message.id).await {
Ok(_) => Ok(Response::new(())),
Err(error) => match error {
Expand Down
98 changes: 93 additions & 5 deletions src/tests/api/access_logic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -351,10 +351,54 @@ async fn delete_invalid_access_returns_err() {
mock_services
.access_context_mock
.expect_delete()
.with(predicate::eq(1))
.with(predicate::eq(2))
.returning(move |_| Err(DbErr::RecordNotFound("".to_string())));

let request = Request::new(DeleteAccessRequest { id: 1 });
mock_services
.access_context_mock
.expect_get_by_id()
.with(predicate::eq(2))
.returning(move |_| {
Ok(Some(access::Model {
id: 1,
role: "Editor".to_string(),
model_id: 1,
user_id: 2,
}))
});

mock_services
.access_context_mock
.expect_get_access_by_uid_and_model_id()
.with(predicate::eq(1), predicate::eq(1))
.returning(move |_, _| {
Ok(Some(access::Model {
id: 1,
role: "Editor".to_string(),
model_id: 1,
user_id: 1,
}))
});

mock_services
.model_context_mock
.expect_get_by_id()
.with(predicate::eq(1))
.returning(move |_| {
Ok(Some(model::Model {
id: 1,
name: "test".to_string(),
owner_id: 1,
components_info: Default::default(),
}))
});

let mut request = Request::new(DeleteAccessRequest { id: 2 });

request.metadata_mut().insert(
"uid",
tonic::metadata::MetadataValue::from_str("1").unwrap(),
);

let api = get_mock_concrete_ecdar_api(mock_services);

Expand All @@ -368,7 +412,7 @@ async fn delete_access_returns_ok() {
let mut mock_services = get_mock_services();

let access = access::Model {
id: 1,
id: 2,
role: "Editor".to_string(),
model_id: Default::default(),
user_id: Default::default(),
Expand All @@ -377,10 +421,54 @@ async fn delete_access_returns_ok() {
mock_services
.access_context_mock
.expect_delete()
.with(predicate::eq(1))
.with(predicate::eq(2))
.returning(move |_| Ok(access.clone()));

let request = Request::new(DeleteAccessRequest { id: 1 });
mock_services
.access_context_mock
.expect_get_by_id()
.with(predicate::eq(2))
.returning(move |_| {
Ok(Some(access::Model {
id: 1,
role: "Editor".to_string(),
model_id: 1,
user_id: 2,
}))
});

mock_services
.access_context_mock
.expect_get_access_by_uid_and_model_id()
.with(predicate::eq(1), predicate::eq(1))
.returning(move |_, _| {
Ok(Some(access::Model {
id: 1,
role: "Editor".to_string(),
model_id: 1,
user_id: 1,
}))
});

mock_services
.model_context_mock
.expect_get_by_id()
.with(predicate::eq(1))
.returning(move |_| {
Ok(Some(model::Model {
id: 1,
name: "test".to_string(),
owner_id: 1,
components_info: Default::default(),
}))
});

let mut request = Request::new(DeleteAccessRequest { id: 2 });

request.metadata_mut().insert(
"uid",
tonic::metadata::MetadataValue::from_str("1").unwrap(),
);

let api = get_mock_concrete_ecdar_api(mock_services);

Expand Down

0 comments on commit b79a3d0

Please sign in to comment.