You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@teaclave.apache.org by ms...@apache.org on 2020/06/03 04:18:23 UTC

[incubator-teaclave] branch master updated: [services] Add update input/output file interface (#330)

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 b37f274  [services] Add update input/output file interface (#330)
b37f274 is described below

commit b37f2749eb9e7575279a68a590db93a7d96a4502
Author: renxingliang <53...@users.noreply.github.com>
AuthorDate: Wed Jun 3 00:18:13 2020 -0400

    [services] Add update input/output file interface (#330)
---
 sdk/python/teaclave.py                             |  14 +++
 services/frontend/enclave/src/service.rs           |  17 ++-
 services/management/enclave/src/service.rs         |  68 ++++++++++-
 .../src/proto/teaclave_frontend_service.proto      |  20 ++++
 .../src/proto/teaclave_management_service.proto    |   2 +
 services/proto/src/teaclave_frontend_service.rs    | 130 +++++++++++++++++++++
 services/proto/src/teaclave_management_service.rs  |   4 +
 tests/functional/enclave/src/frontend_service.rs   |  35 ++++++
 8 files changed, 288 insertions(+), 2 deletions(-)

diff --git a/sdk/python/teaclave.py b/sdk/python/teaclave.py
index f9cd8e3..31d0858 100644
--- a/sdk/python/teaclave.py
+++ b/sdk/python/teaclave.py
@@ -121,6 +121,20 @@ class RegisterOutputFileRequest:
         self.url = url
         self.crypto_info = crypto_info
 
+class UpdateInputFileRequest:
+    def __init__(self, metadata, data_id, url):
+        self.request = "update_input_file"
+        self.metadata = metadata
+        self.data_id =data_id
+        self.url = url
+
+
+class UpdateOutputFileRequest:
+    def __init__(self, metadata, data_id, url):
+        self.request = "update_output_file"
+        self.metadata = metadata
+        self.data_id =data_id
+        self.url = url
 
 class CreateTaskRequest:
     def __init__(self, metadata, function_id, function_arguments, executor,
diff --git a/services/frontend/enclave/src/service.rs b/services/frontend/enclave/src/service.rs
index ce62bba..c0f60d5 100644
--- a/services/frontend/enclave/src/service.rs
+++ b/services/frontend/enclave/src/service.rs
@@ -32,7 +32,8 @@ use teaclave_proto::teaclave_frontend_service::{
     RegisterFunctionRequest, RegisterFunctionResponse, RegisterFusionOutputRequest,
     RegisterFusionOutputResponse, RegisterInputFileRequest, RegisterInputFileResponse,
     RegisterInputFromOutputRequest, RegisterInputFromOutputResponse, RegisterOutputFileRequest,
-    RegisterOutputFileResponse, TeaclaveFrontend,
+    RegisterOutputFileResponse, TeaclaveFrontend, UpdateInputFileRequest, UpdateInputFileResponse,
+    UpdateOutputFileRequest, UpdateOutputFileResponse,
 };
 use teaclave_proto::teaclave_management_service::TeaclaveManagementClient;
 use teaclave_rpc::endpoint::Endpoint;
@@ -135,6 +136,13 @@ impl TeaclaveFrontend for TeaclaveFrontendService {
         authentication_and_forward_to_management!(self, request, register_input_file)
     }
 
+    fn update_input_file(
+        &self,
+        request: Request<UpdateInputFileRequest>,
+    ) -> TeaclaveServiceResponseResult<UpdateInputFileResponse> {
+        authentication_and_forward_to_management!(self, request, update_input_file)
+    }
+
     fn register_output_file(
         &self,
         request: Request<RegisterOutputFileRequest>,
@@ -142,6 +150,13 @@ impl TeaclaveFrontend for TeaclaveFrontendService {
         authentication_and_forward_to_management!(self, request, register_output_file)
     }
 
+    fn update_output_file(
+        &self,
+        request: Request<UpdateOutputFileRequest>,
+    ) -> TeaclaveServiceResponseResult<UpdateOutputFileResponse> {
+        authentication_and_forward_to_management!(self, request, update_output_file)
+    }
+
     fn register_fusion_output(
         &self,
         request: Request<RegisterFusionOutputRequest>,
diff --git a/services/management/enclave/src/service.rs b/services/management/enclave/src/service.rs
index 49f436f..a46a197 100644
--- a/services/management/enclave/src/service.rs
+++ b/services/management/enclave/src/service.rs
@@ -28,7 +28,8 @@ use teaclave_proto::teaclave_frontend_service::{
     RegisterFunctionRequest, RegisterFunctionResponse, RegisterFusionOutputRequest,
     RegisterFusionOutputResponse, RegisterInputFileRequest, RegisterInputFileResponse,
     RegisterInputFromOutputRequest, RegisterInputFromOutputResponse, RegisterOutputFileRequest,
-    RegisterOutputFileResponse,
+    RegisterOutputFileResponse, UpdateInputFileRequest, UpdateInputFileResponse,
+    UpdateOutputFileRequest, UpdateOutputFileResponse,
 };
 use teaclave_proto::teaclave_management_service::TeaclaveManagement;
 use teaclave_proto::teaclave_storage_service::{
@@ -90,6 +91,39 @@ impl TeaclaveManagement for TeaclaveManagementService {
         Ok(response)
     }
 
+    // access control:
+    // 1) exisiting_file.owner_list.len() == 1
+    // 2) user_id in existing_file.owner_list
+    fn update_input_file(
+        &self,
+        request: Request<UpdateInputFileRequest>,
+    ) -> TeaclaveServiceResponseResult<UpdateInputFileResponse> {
+        let user_id = self.get_request_user_id(request.metadata())?;
+        let request = request.message;
+
+        let old_input_file: TeaclaveInputFile = self
+            .read_from_db(&request.data_id)
+            .map_err(|_| ServiceError::PermissionDenied)?;
+
+        ensure!(
+            old_input_file.owner == OwnerList::from(vec![user_id]),
+            ServiceError::PermissionDenied
+        );
+
+        let input_file = TeaclaveInputFile::new(
+            request.url,
+            old_input_file.cmac,
+            old_input_file.crypto_info,
+            old_input_file.owner,
+        );
+
+        self.write_to_db(&input_file)
+            .map_err(|_| ServiceError::StorageError)?;
+
+        let response = UpdateInputFileResponse::new(input_file.external_id());
+        Ok(response)
+    }
+
     // access control: none
     fn register_output_file(
         &self,
@@ -106,6 +140,38 @@ impl TeaclaveManagement for TeaclaveManagementService {
         Ok(response)
     }
 
+    // access control:
+    // 1) exisiting_file.owner_list.len() == 1
+    // 2) user_id in existing_file.owner_list
+    fn update_output_file(
+        &self,
+        request: Request<UpdateOutputFileRequest>,
+    ) -> TeaclaveServiceResponseResult<UpdateOutputFileResponse> {
+        let user_id = self.get_request_user_id(request.metadata())?;
+        let request = request.message;
+
+        let old_output_file: TeaclaveOutputFile = self
+            .read_from_db(&request.data_id)
+            .map_err(|_| ServiceError::PermissionDenied)?;
+
+        ensure!(
+            old_output_file.owner == OwnerList::from(vec![user_id]),
+            ServiceError::PermissionDenied
+        );
+
+        let output_file = TeaclaveOutputFile::new(
+            request.url,
+            old_output_file.crypto_info,
+            old_output_file.owner,
+        );
+
+        self.write_to_db(&output_file)
+            .map_err(|_| ServiceError::StorageError)?;
+
+        let response = UpdateOutputFileResponse::new(output_file.external_id());
+        Ok(response)
+    }
+
     // access control: user_id in owner_list
     fn register_fusion_output(
         &self,
diff --git a/services/proto/src/proto/teaclave_frontend_service.proto b/services/proto/src/proto/teaclave_frontend_service.proto
index cb2ce90..0f7e313 100644
--- a/services/proto/src/proto/teaclave_frontend_service.proto
+++ b/services/proto/src/proto/teaclave_frontend_service.proto
@@ -14,6 +14,15 @@ message RegisterInputFileResponse {
   string data_id = 1;
 }
 
+message UpdateInputFileRequest {
+  string data_id = 1;
+  string url = 2;
+}
+
+message UpdateInputFileResponse {
+  string data_id = 1;
+}
+
 message RegisterOutputFileRequest {
   string url = 1;
   teaclave_common_proto.FileCryptoInfo crypto_info = 2;
@@ -23,6 +32,15 @@ message RegisterOutputFileResponse {
   string data_id = 1;
 }
 
+message UpdateOutputFileRequest {
+  string data_id = 1;
+  string url = 2;
+}
+
+message UpdateOutputFileResponse {
+  string data_id = 1;
+}
+
 message RegisterFusionOutputRequest {
   repeated string owner_list = 1;
 }
@@ -163,6 +181,8 @@ message InvokeTaskResponse { }
 service TeaclaveFrontend {
   rpc RegisterInputFile (RegisterInputFileRequest) returns (RegisterInputFileResponse);
   rpc RegisterOutputFile (RegisterOutputFileRequest) returns (RegisterOutputFileResponse);
+  rpc UpdateInputFile (UpdateInputFileRequest) returns (UpdateInputFileResponse);
+  rpc UpdateOutputFile (UpdateOutputFileRequest) returns (UpdateOutputFileResponse);
   rpc RegisterFusionOutput (RegisterFusionOutputRequest) returns (RegisterFusionOutputResponse);
   rpc RegisterInputFromOutput (RegisterInputFromOutputRequest) returns (RegisterInputFromOutputResponse);
   rpc GetOutputFile (GetOutputFileRequest) returns (GetOutputFileResponse);
diff --git a/services/proto/src/proto/teaclave_management_service.proto b/services/proto/src/proto/teaclave_management_service.proto
index b026b6f..8957c49 100644
--- a/services/proto/src/proto/teaclave_management_service.proto
+++ b/services/proto/src/proto/teaclave_management_service.proto
@@ -7,6 +7,8 @@ import "teaclave_frontend_service.proto";
 service TeaclaveManagement {
   rpc RegisterInputFile (teaclave_frontend_service_proto.RegisterInputFileRequest) returns (teaclave_frontend_service_proto.RegisterInputFileResponse);
   rpc RegisterOutputFile (teaclave_frontend_service_proto.RegisterOutputFileRequest) returns (teaclave_frontend_service_proto.RegisterOutputFileResponse);
+  rpc UpdateInputFile (teaclave_frontend_service_proto.UpdateInputFileRequest) returns (teaclave_frontend_service_proto.UpdateInputFileResponse);
+  rpc UpdateOutputFile (teaclave_frontend_service_proto.UpdateOutputFileRequest) returns (teaclave_frontend_service_proto.UpdateOutputFileResponse);
   rpc RegisterFusionOutput (teaclave_frontend_service_proto.RegisterFusionOutputRequest) returns (teaclave_frontend_service_proto.RegisterFusionOutputResponse);
   rpc RegisterInputFromOutput (teaclave_frontend_service_proto.RegisterInputFromOutputRequest) returns (teaclave_frontend_service_proto.RegisterInputFromOutputResponse);
   rpc GetOutputFile (teaclave_frontend_service_proto.GetOutputFileRequest) returns (teaclave_frontend_service_proto.GetOutputFileResponse);
diff --git a/services/proto/src/teaclave_frontend_service.rs b/services/proto/src/teaclave_frontend_service.rs
index 0b8db6e..abc30e5 100644
--- a/services/proto/src/teaclave_frontend_service.rs
+++ b/services/proto/src/teaclave_frontend_service.rs
@@ -57,6 +57,20 @@ impl RegisterInputFileRequest {
     }
 }
 
+#[into_request(TeaclaveFrontendRequest::UpdateInputFile)]
+#[into_request(TeaclaveManagementRequest::UpdateInputFile)]
+#[derive(Debug, PartialEq)]
+pub struct UpdateInputFileRequest {
+    pub data_id: ExternalID,
+    pub url: Url,
+}
+
+impl UpdateInputFileRequest {
+    pub fn new(data_id: ExternalID, url: Url) -> Self {
+        Self { data_id, url }
+    }
+}
+
 #[into_request(TeaclaveFrontendResponse::RegisterInputFile)]
 #[into_request(TeaclaveManagementResponse::RegisterInputFile)]
 #[derive(Debug, PartialEq)]
@@ -70,6 +84,19 @@ impl RegisterInputFileResponse {
     }
 }
 
+#[into_request(TeaclaveFrontendResponse::UpdateInputFile)]
+#[into_request(TeaclaveManagementResponse::UpdateInputFile)]
+#[derive(Debug, PartialEq)]
+pub struct UpdateInputFileResponse {
+    pub data_id: ExternalID,
+}
+
+impl UpdateInputFileResponse {
+    pub fn new(data_id: ExternalID) -> Self {
+        Self { data_id }
+    }
+}
+
 #[into_request(TeaclaveFrontendRequest::RegisterOutputFile)]
 #[into_request(TeaclaveManagementRequest::RegisterOutputFile)]
 #[derive(Debug)]
@@ -87,6 +114,20 @@ impl RegisterOutputFileRequest {
     }
 }
 
+#[into_request(TeaclaveFrontendRequest::UpdateOutputFile)]
+#[into_request(TeaclaveManagementRequest::UpdateOutputFile)]
+#[derive(Debug)]
+pub struct UpdateOutputFileRequest {
+    pub data_id: ExternalID,
+    pub url: Url,
+}
+
+impl UpdateOutputFileRequest {
+    pub fn new(data_id: ExternalID, url: Url) -> Self {
+        Self { data_id, url }
+    }
+}
+
 #[into_request(TeaclaveFrontendResponse::RegisterOutputFile)]
 #[into_request(TeaclaveManagementResponse::RegisterOutputFile)]
 #[derive(Debug)]
@@ -100,6 +141,19 @@ impl RegisterOutputFileResponse {
     }
 }
 
+#[into_request(TeaclaveFrontendResponse::UpdateOutputFile)]
+#[into_request(TeaclaveManagementResponse::UpdateOutputFile)]
+#[derive(Debug)]
+pub struct UpdateOutputFileResponse {
+    pub data_id: ExternalID,
+}
+
+impl UpdateOutputFileResponse {
+    pub fn new(data_id: ExternalID) -> Self {
+        Self { data_id }
+    }
+}
+
 #[into_request(TeaclaveFrontendRequest::RegisterFusionOutput)]
 #[into_request(TeaclaveManagementRequest::RegisterFusionOutput)]
 #[derive(Debug)]
@@ -518,6 +572,26 @@ impl From<RegisterInputFileRequest> for proto::RegisterInputFileRequest {
     }
 }
 
+impl std::convert::TryFrom<proto::UpdateInputFileRequest> for UpdateInputFileRequest {
+    type Error = Error;
+
+    fn try_from(proto: proto::UpdateInputFileRequest) -> Result<Self> {
+        let data_id = proto.data_id.try_into()?;
+        let url = Url::parse(&proto.url)?;
+
+        Ok(UpdateInputFileRequest { data_id, url })
+    }
+}
+
+impl From<UpdateInputFileRequest> for proto::UpdateInputFileRequest {
+    fn from(request: UpdateInputFileRequest) -> Self {
+        Self {
+            data_id: request.data_id.to_string(),
+            url: request.url.into_string(),
+        }
+    }
+}
+
 impl std::convert::TryFrom<proto::RegisterInputFileResponse> for RegisterInputFileResponse {
     type Error = Error;
 
@@ -535,6 +609,23 @@ impl From<RegisterInputFileResponse> for proto::RegisterInputFileResponse {
     }
 }
 
+impl std::convert::TryFrom<proto::UpdateInputFileResponse> for UpdateInputFileResponse {
+    type Error = Error;
+
+    fn try_from(proto: proto::UpdateInputFileResponse) -> Result<Self> {
+        let data_id = proto.data_id.try_into()?;
+        Ok(Self { data_id })
+    }
+}
+
+impl From<UpdateInputFileResponse> for proto::UpdateInputFileResponse {
+    fn from(request: UpdateInputFileResponse) -> Self {
+        Self {
+            data_id: request.data_id.to_string(),
+        }
+    }
+}
+
 impl std::convert::TryFrom<proto::RegisterOutputFileRequest> for RegisterOutputFileRequest {
     type Error = Error;
 
@@ -560,6 +651,28 @@ impl From<RegisterOutputFileRequest> for proto::RegisterOutputFileRequest {
     }
 }
 
+impl std::convert::TryFrom<proto::UpdateOutputFileRequest> for UpdateOutputFileRequest {
+    type Error = Error;
+
+    fn try_from(proto: proto::UpdateOutputFileRequest) -> Result<Self> {
+        let ret = Self {
+            data_id: proto.data_id.try_into()?,
+            url: Url::parse(&proto.url)?,
+        };
+
+        Ok(ret)
+    }
+}
+
+impl From<UpdateOutputFileRequest> for proto::UpdateOutputFileRequest {
+    fn from(request: UpdateOutputFileRequest) -> Self {
+        Self {
+            data_id: request.data_id.to_string(),
+            url: request.url.into_string(),
+        }
+    }
+}
+
 impl std::convert::TryFrom<proto::RegisterOutputFileResponse> for RegisterOutputFileResponse {
     type Error = Error;
 
@@ -577,6 +690,23 @@ impl From<RegisterOutputFileResponse> for proto::RegisterOutputFileResponse {
     }
 }
 
+impl std::convert::TryFrom<proto::UpdateOutputFileResponse> for UpdateOutputFileResponse {
+    type Error = Error;
+
+    fn try_from(proto: proto::UpdateOutputFileResponse) -> Result<Self> {
+        let data_id = proto.data_id.try_into()?;
+        Ok(Self { data_id })
+    }
+}
+
+impl From<UpdateOutputFileResponse> for proto::UpdateOutputFileResponse {
+    fn from(request: UpdateOutputFileResponse) -> Self {
+        Self {
+            data_id: request.data_id.to_string(),
+        }
+    }
+}
+
 impl std::convert::TryFrom<proto::RegisterFusionOutputRequest> for RegisterFusionOutputRequest {
     type Error = Error;
 
diff --git a/services/proto/src/teaclave_management_service.rs b/services/proto/src/teaclave_management_service.rs
index 67908ed..73787b4 100644
--- a/services/proto/src/teaclave_management_service.rs
+++ b/services/proto/src/teaclave_management_service.rs
@@ -23,9 +23,13 @@ pub use proto::TeaclaveManagementRequest;
 pub use proto::TeaclaveManagementResponse;
 
 pub type RegisterInputFileRequest = crate::teaclave_frontend_service::RegisterInputFileRequest;
+pub type UpdateInputFileRequest = crate::teaclave_frontend_service::UpdateInputFileRequest;
 pub type RegisterInputFileResponse = crate::teaclave_frontend_service::RegisterInputFileResponse;
+pub type UpdateInputFileResponse = crate::teaclave_frontend_service::UpdateInputFileResponse;
 pub type RegisterOutputFileRequest = crate::teaclave_frontend_service::RegisterOutputFileRequest;
+pub type UpdateOutputFileRequest = crate::teaclave_frontend_service::UpdateOutputFileRequest;
 pub type RegisterOutputFileResponse = crate::teaclave_frontend_service::RegisterOutputFileResponse;
+pub type UpdateOutputFileResponse = crate::teaclave_frontend_service::UpdateOutputFileResponse;
 pub type RegisterFusionOutputRequest =
     crate::teaclave_frontend_service::RegisterFusionOutputRequest;
 pub type RegisterFusionOutputResponse =
diff --git a/tests/functional/enclave/src/frontend_service.rs b/tests/functional/enclave/src/frontend_service.rs
index 9ec42bf..1ad2352 100644
--- a/tests/functional/enclave/src/frontend_service.rs
+++ b/tests/functional/enclave/src/frontend_service.rs
@@ -53,6 +53,24 @@ fn test_register_input_file() {
 }
 
 #[test_case]
+fn test_update_input_file() {
+    let url = Url::parse("https://external-storage.com/filepath?presigned_token").unwrap();
+    let cmac = FileAuthTag::mock();
+    let crypto_info = FileCrypto::default();
+
+    let request = RegisterInputFileRequest::new(url.clone(), cmac, crypto_info);
+    let response = authorized_client().register_input_file(request);
+    assert!(response.is_ok());
+
+    let old_data_id = response.unwrap().data_id;
+    let new_url = Url::parse("https://external-storage.com/filepath-new?presigned_token").unwrap();
+    let update_request = UpdateInputFileRequest::new(old_data_id.clone(), new_url.clone());
+    let update_response = authorized_client().update_input_file(update_request);
+    assert!(update_response.is_ok());
+    assert!(old_data_id != update_response.unwrap().data_id);
+}
+
+#[test_case]
 fn test_register_output_file() {
     let url = Url::parse("https://external-storage.com/filepath?presigned_token").unwrap();
     let crypto_info = FileCrypto::default();
@@ -67,6 +85,23 @@ fn test_register_output_file() {
 }
 
 #[test_case]
+fn test_update_output_file() {
+    let url = Url::parse("https://external-storage.com/filepath?presigned_token").unwrap();
+    let crypto_info = FileCrypto::default();
+
+    let request = RegisterOutputFileRequest::new(url.clone(), crypto_info);
+    let response = authorized_client().register_output_file(request);
+    assert!(response.is_ok());
+
+    let old_data_id = response.unwrap().data_id;
+    let new_url = Url::parse("https://external-storage.com/filepath-new?presigned_token").unwrap();
+    let update_request = UpdateOutputFileRequest::new(old_data_id.clone(), new_url.clone());
+    let update_response = authorized_client().update_output_file(update_request);
+    assert!(update_response.is_ok());
+    assert!(old_data_id != update_response.unwrap().data_id);
+}
+
+#[test_case]
 fn test_register_fusion_output() {
     let request = RegisterFusionOutputRequest::new(vec!["frontend_user", "mock_user"]);
     let response = authorized_client().register_fusion_output(request);


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@teaclave.apache.org
For additional commands, e-mail: commits-help@teaclave.apache.org