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]

Reply via email to