This is an automated email from the ASF dual-hosted git repository.
mssun pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-teaclave.git
The following commit(s) were added to refs/heads/master by this push:
new 22eb01b Fix privilege issue (#636)
22eb01b is described below
commit 22eb01b67b001deda5a112ee3da4c79b4633e06c
Author: Mingshen Sun <[email protected]>
AuthorDate: Fri Mar 18 09:55:08 2022 -0700
Fix privilege issue (#636)
* fix inconsistency of GetFunction and ListFunctions interfaces
* add GetKeysByPrefix interface to the storage service to help the fix
---
cmake/scripts/test.sh | 1 +
services/management/enclave/src/service.rs | 38 ++++++++++--
.../proto/src/proto/teaclave_storage_service.proto | 9 +++
services/proto/src/teaclave_storage_service.rs | 62 ++++++++++++++++++++
services/storage/enclave/src/lib.rs | 1 +
services/storage/enclave/src/service.rs | 67 ++++++++++++++++++++--
tests/functional/enclave/src/management_service.rs | 6 +-
7 files changed, 173 insertions(+), 11 deletions(-)
diff --git a/cmake/scripts/test.sh b/cmake/scripts/test.sh
index e311602..a8a5747 100755
--- a/cmake/scripts/test.sh
+++ b/cmake/scripts/test.sh
@@ -51,6 +51,7 @@ run_unit_tests() {
start_storage_server
echo_title "encalve unit tests"
+ rm -rf mock_db_unit_test
./teaclave_unit_tests
popd
diff --git a/services/management/enclave/src/service.rs
b/services/management/enclave/src/service.rs
index 1a640e9..c0d2d20 100644
--- a/services/management/enclave/src/service.rs
+++ b/services/management/enclave/src/service.rs
@@ -36,7 +36,8 @@ use teaclave_proto::teaclave_frontend_service::{
};
use teaclave_proto::teaclave_management_service::TeaclaveManagement;
use teaclave_proto::teaclave_storage_service::{
- DeleteRequest, EnqueueRequest, GetRequest, PutRequest,
TeaclaveStorageClient,
+ DeleteRequest, EnqueueRequest, GetKeysByPrefixRequest, GetRequest,
PutRequest,
+ TeaclaveStorageClient,
};
use teaclave_rpc::endpoint::Endpoint;
use teaclave_rpc::Request;
@@ -313,7 +314,7 @@ impl TeaclaveManagement for TeaclaveManagementService {
Ok(response)
}
- // access control: function.public || function.owner == user_id
+ // access control: function.public || function.owner == user_id ||
request.role == PlatformAdmin
fn get_function(
&self,
request: Request<GetFunctionRequest>,
@@ -323,8 +324,9 @@ impl TeaclaveManagement for TeaclaveManagementService {
let function: Function = self
.read_from_db(&request.message.function_id)
.map_err(|_| ManagementServiceError::InvalidFunctionId)?;
+ let role = get_request_role(&request)?;
- if function.public || function.owner == user_id {
+ if function.public || role == UserRole::PlatformAdmin ||
function.owner == user_id {
let response = GetFunctionResponse {
name: function.name,
description: function.description,
@@ -454,7 +456,7 @@ impl TeaclaveManagement for TeaclaveManagementService {
);
}
- if let UserRole::DataOwner(s) = role {
+ if let UserRole::DataOwner(s) = &role {
request_user_id = s.into();
}
@@ -465,10 +467,16 @@ impl TeaclaveManagement for TeaclaveManagementService {
let user = self.read_from_db::<User>(&external_id);
match user {
Ok(us) => {
- let response = ListFunctionsResponse {
+ let mut response = ListFunctionsResponse {
registered_functions: us.registered_functions,
allowed_functions: us.allowed_functions,
};
+ if role == UserRole::PlatformAdmin {
+ let allowed_functions =
+
self.get_keys_by_prefix_from_db(Function::key_prefix())?;
+ response.allowed_functions = allowed_functions;
+ }
+
Ok(response)
}
Err(_) => {
@@ -802,6 +810,26 @@ impl TeaclaveManagementService {
T::from_slice(response.value.as_slice()).map_err(ManagementServiceError::Service)
}
+ fn get_keys_by_prefix_from_db(
+ &self,
+ prefix: impl Into<Vec<u8>>,
+ ) -> Result<Vec<String>, ManagementServiceError> {
+ let request = GetKeysByPrefixRequest::new(prefix.into());
+ let response = self
+ .storage_client
+ .clone()
+ .lock()
+ .map_err(|_| anyhow!("cannot lock storage client"))?
+ .get_keys_by_prefix(request)
+ .map_err(|e| ManagementServiceError::Service(e.into()))?;
+ Ok(response
+ .keys
+ .into_iter()
+ .map(String::from_utf8)
+ .collect::<Result<Vec<_>, _>>()
+ .map_err(|_| anyhow!("cannot convert keys"))?)
+ }
+
fn delete_from_db(&self, key: &ExternalID) -> Result<(),
ManagementServiceError> {
let request = DeleteRequest::new(key.to_bytes());
self.storage_client
diff --git a/services/proto/src/proto/teaclave_storage_service.proto
b/services/proto/src/proto/teaclave_storage_service.proto
index 183fbd0..0e78952 100644
--- a/services/proto/src/proto/teaclave_storage_service.proto
+++ b/services/proto/src/proto/teaclave_storage_service.proto
@@ -57,10 +57,19 @@ message DequeueResponse {
bytes value = 1;
}
+message GetKeysByPrefixRequest {
+ bytes prefix = 1;
+}
+
+message GetKeysByPrefixResponse {
+ repeated bytes keys = 1;
+}
+
service TeaclaveStorage {
rpc Get(GetRequest) returns (GetResponse);
rpc Put(PutRequest) returns (PutResponse);
rpc Delete(DeleteRequest) returns (DeleteResponse);
rpc Enqueue(EnqueueRequest) returns (EnqueueResponse);
rpc Dequeue(DequeueRequest) returns (DequeueResponse);
+ rpc GetKeysByPrefix(GetKeysByPrefixRequest) returns
(GetKeysByPrefixResponse);
}
diff --git a/services/proto/src/teaclave_storage_service.rs
b/services/proto/src/teaclave_storage_service.rs
index c89ef85..9e988db 100644
--- a/services/proto/src/teaclave_storage_service.rs
+++ b/services/proto/src/teaclave_storage_service.rs
@@ -133,6 +133,32 @@ impl DequeueResponse {
}
}
+#[into_request(TeaclaveStorageRequest::GetKeysByPrefix)]
+#[derive(Debug)]
+pub struct GetKeysByPrefixRequest {
+ pub prefix: Vec<u8>,
+}
+
+impl GetKeysByPrefixRequest {
+ pub fn new(prefix: impl Into<Vec<u8>>) -> Self {
+ Self {
+ prefix: prefix.into(),
+ }
+ }
+}
+
+#[into_request(TeaclaveStorageResponse::GetKeysByPrefix)]
+#[derive(Default, Debug)]
+pub struct GetKeysByPrefixResponse {
+ pub keys: Vec<Vec<u8>>,
+}
+
+impl GetKeysByPrefixResponse {
+ pub fn new(keys: Vec<Vec<u8>>) -> Self {
+ Self { keys }
+ }
+}
+
impl std::convert::TryFrom<proto::GetRequest> for GetRequest {
type Error = Error;
@@ -300,3 +326,39 @@ impl From<DequeueResponse> for proto::DequeueResponse {
}
}
}
+
+impl std::convert::TryFrom<proto::GetKeysByPrefixRequest> for
GetKeysByPrefixRequest {
+ type Error = Error;
+
+ fn try_from(proto: proto::GetKeysByPrefixRequest) -> Result<Self> {
+ let ret = Self {
+ prefix: proto.prefix,
+ };
+
+ Ok(ret)
+ }
+}
+
+impl From<GetKeysByPrefixRequest> for proto::GetKeysByPrefixRequest {
+ fn from(request: GetKeysByPrefixRequest) -> Self {
+ Self {
+ prefix: request.prefix,
+ }
+ }
+}
+
+impl std::convert::TryFrom<proto::GetKeysByPrefixResponse> for
GetKeysByPrefixResponse {
+ type Error = Error;
+
+ fn try_from(proto: proto::GetKeysByPrefixResponse) -> Result<Self> {
+ Ok(Self { keys: proto.keys })
+ }
+}
+
+impl From<GetKeysByPrefixResponse> for proto::GetKeysByPrefixResponse {
+ fn from(response: GetKeysByPrefixResponse) -> Self {
+ Self {
+ keys: response.keys,
+ }
+ }
+}
diff --git a/services/storage/enclave/src/lib.rs
b/services/storage/enclave/src/lib.rs
index 5f61369..2e4b262 100644
--- a/services/storage/enclave/src/lib.rs
+++ b/services/storage/enclave/src/lib.rs
@@ -178,6 +178,7 @@ pub mod tests {
service::tests::test_delete_key,
service::tests::test_enqueue,
service::tests::test_dequeue,
+ service::tests::test_get_keys_by_prefix,
)
}
}
diff --git a/services/storage/enclave/src/service.rs
b/services/storage/enclave/src/service.rs
index e729ba3..57188c9 100644
--- a/services/storage/enclave/src/service.rs
+++ b/services/storage/enclave/src/service.rs
@@ -18,14 +18,12 @@
use crate::error::StorageServiceError;
use crate::proxy::ProxyRequest;
use anyhow::anyhow;
+use rusty_leveldb::LdbIterator;
use rusty_leveldb::DB;
use std::cell::RefCell;
use std::prelude::v1::*;
use std::sync::mpsc::Receiver;
-use teaclave_proto::teaclave_storage_service::{
- DeleteRequest, DeleteResponse, DequeueRequest, DequeueResponse,
EnqueueRequest,
- EnqueueResponse, GetRequest, GetResponse, PutRequest, PutResponse,
TeaclaveStorage,
-};
+use teaclave_proto::teaclave_storage_service::*;
use teaclave_rpc::Request;
use teaclave_service_enclave_utils::{bail, teaclave_service};
use teaclave_types::TeaclaveServiceResponseResult;
@@ -243,6 +241,41 @@ impl TeaclaveStorage for TeaclaveStorageService {
Err(e) => bail!(e),
}
}
+
+ fn get_keys_by_prefix(
+ &self,
+ request: Request<GetKeysByPrefixRequest>,
+ ) -> TeaclaveServiceResponseResult<GetKeysByPrefixResponse> {
+ let prefix = request.message.prefix;
+ let mut db = self.database.borrow_mut();
+ let mut it = db.new_iter().map_err(StorageServiceError::Database)?;
+
+ let mut first_prefix = prefix.clone();
+ first_prefix.push(b'-');
+ let mut last_prefix = prefix;
+ last_prefix.push(b'.');
+
+ it.seek(&first_prefix[..]);
+ if !it.valid() {
+ return Ok(GetKeysByPrefixResponse::default());
+ }
+ let mut key = Vec::new();
+ let mut value = Vec::new();
+ let mut keys = Vec::new();
+ if !it.current(&mut key, &mut value) {
+ return Ok(GetKeysByPrefixResponse::default());
+ }
+ keys.push(key);
+
+ while let Some((k, _)) = it.next() {
+ if k >= last_prefix {
+ break;
+ }
+ keys.push(k);
+ }
+
+ Ok(GetKeysByPrefixResponse { keys })
+ }
}
#[cfg(feature = "enclave_unit_test")]
@@ -312,4 +345,30 @@ pub mod tests {
let request = DequeueRequest::new("test_dequeue_key").into_request();
assert_eq!(service.dequeue(request).unwrap().value, b"2");
}
+
+ pub fn test_get_keys_by_prefix() {
+ let service = get_mock_service();
+ let request = PutRequest::new("function-1",
"test_put_value").into_request();
+ assert!(service.put(request).is_ok());
+ let request = PutRequest::new("function-22",
"test_put_value").into_request();
+ assert!(service.put(request).is_ok());
+ let request = PutRequest::new("function-333",
"test_put_value").into_request();
+ assert!(service.put(request).is_ok());
+ let request = PutRequest::new("task-444",
"test_put_value").into_request();
+ assert!(service.put(request).is_ok());
+ let request = PutRequest::new("function-5",
"test_put_value").into_request();
+ assert!(service.put(request).is_ok());
+ let request = GetKeysByPrefixRequest::new("function").into_request();
+ let response = service.get_keys_by_prefix(request);
+ assert!(response.is_ok());
+ assert_eq!(
+ response.unwrap().keys,
+ std::vec![
+ b"function-1".to_vec(),
+ b"function-22".to_vec(),
+ b"function-333".to_vec(),
+ b"function-5".to_vec()
+ ]
+ );
+ }
}
diff --git a/tests/functional/enclave/src/management_service.rs
b/tests/functional/enclave/src/management_service.rs
index ad016a0..7a975b1 100644
--- a/tests/functional/enclave/src/management_service.rs
+++ b/tests/functional/enclave/src/management_service.rs
@@ -287,7 +287,8 @@ fn test_get_function() {
let mut client = authorized_client("mock_unauthorized_user");
let request = GetFunctionRequest::new(function_id);
let response = client.get_function(request);
- assert!(response.is_err());
+ // mock_unauthorized_user is PlatformAdmin
+ assert!(response.is_ok());
let function_id =
ExternalID::try_from("function-00000000-0000-0000-0000-000000000001").unwrap();
@@ -312,7 +313,8 @@ fn test_get_function() {
let mut client = authorized_client("mock_unauthorized_user");
let request = GetFunctionRequest::new(function_id);
let response = client.get_function(request);
- assert!(response.is_err());
+ // mock_unauthorized_user is PlatformAdmin
+ assert!(response.is_ok());
}
fn create_valid_task_request() -> CreateTaskRequest {
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]