This is an automated email from the ASF dual-hosted git repository.

mssun pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/incubator-teaclave.git


The following commit(s) were added to refs/heads/develop by this push:
     new 0634007  [authentication] Split authentication service into api and 
internal services (#213)
0634007 is described below

commit 06340078c08a6a41a61283976a43251329c6bf1c
Author: TX <[email protected]>
AuthorDate: Thu Jan 30 14:18:55 2020 -0800

    [authentication] Split authentication service into api and internal 
services (#213)
---
 services/authentication/enclave/src/api_service.rs | 150 +++++++++++
 .../authentication/enclave/src/internal_service.rs | 203 +++++++++++++++
 services/authentication/enclave/src/lib.rs         |  69 ++++-
 services/authentication/enclave/src/service.rs     | 282 ---------------------
 services/authentication/enclave/src/user_db.rs     |   4 +-
 services/frontend/enclave/src/service.rs           |   6 +-
 services/proto/proto_gen/templates/proto.j2        |  18 +-
 .../proto/teaclave_authentication_service.proto    |   7 +-
 .../proto/src/teaclave_authentication_service.rs   |  12 +-
 .../enclave/src/teaclave_authentication_service.rs |  69 +++--
 10 files changed, 482 insertions(+), 338 deletions(-)

diff --git a/services/authentication/enclave/src/api_service.rs 
b/services/authentication/enclave/src/api_service.rs
new file mode 100644
index 0000000..da5eb66
--- /dev/null
+++ b/services/authentication/enclave/src/api_service.rs
@@ -0,0 +1,150 @@
+use crate::user_db::{DbClient, DbError};
+use crate::user_info::UserInfo;
+use std::prelude::v1::*;
+use std::time::{Duration, SystemTime, UNIX_EPOCH};
+use std::untrusted::time::SystemTimeEx;
+use teaclave_proto::teaclave_authentication_service::{
+    TeaclaveAuthenticationApi, UserLoginRequest, UserLoginResponse, 
UserRegisterRequest,
+    UserRegisterResponse,
+};
+use teaclave_rpc::Request;
+use teaclave_service_enclave_utils::teaclave_service;
+use teaclave_types::{TeaclaveServiceResponseError, 
TeaclaveServiceResponseResult};
+use thiserror::Error;
+
+#[derive(Error, Debug)]
+enum TeaclaveAuthenticationApiError {
+    #[error("permission denied")]
+    PermissionDenied,
+    #[error("invalid userid")]
+    InvalidUserId,
+    #[error("invalid password")]
+    InvalidPassword,
+    #[error("service unavailable")]
+    ServiceUnavailable,
+}
+
+impl From<TeaclaveAuthenticationApiError> for TeaclaveServiceResponseError {
+    fn from(error: TeaclaveAuthenticationApiError) -> Self {
+        TeaclaveServiceResponseError::RequestError(error.to_string())
+    }
+}
+
+#[teaclave_service(
+    teaclave_authentication_service,
+    TeaclaveAuthenticationApi,
+    TeaclaveAuthenticationError
+)]
+#[derive(Clone)]
+pub(crate) struct TeaclaveAuthenticationApiService {
+    pub(crate) db_client: DbClient,
+    pub(crate) jwt_secret: Vec<u8>,
+}
+
+impl TeaclaveAuthenticationApi for TeaclaveAuthenticationApiService {
+    fn user_register(
+        &self,
+        request: Request<UserRegisterRequest>,
+    ) -> TeaclaveServiceResponseResult<UserRegisterResponse> {
+        let request = request.message;
+        if request.id.is_empty() {
+            return Err(TeaclaveAuthenticationApiError::InvalidUserId.into());
+        }
+        if self.db_client.get_user(&request.id).is_ok() {
+            return Err(TeaclaveAuthenticationApiError::InvalidUserId.into());
+        }
+        let new_user = UserInfo::new(&request.id, &request.password);
+        match self.db_client.create_user(&new_user) {
+            Ok(_) => Ok(UserRegisterResponse {}),
+            Err(DbError::UserExist) => 
Err(TeaclaveAuthenticationApiError::InvalidUserId.into()),
+            Err(_) => 
Err(TeaclaveAuthenticationApiError::ServiceUnavailable.into()),
+        }
+    }
+
+    fn user_login(
+        &self,
+        request: Request<UserLoginRequest>,
+    ) -> TeaclaveServiceResponseResult<UserLoginResponse> {
+        let request = request.message;
+        if request.id.is_empty() {
+            return Err(TeaclaveAuthenticationApiError::InvalidUserId.into());
+        }
+        if request.password.is_empty() {
+            return Err(TeaclaveAuthenticationApiError::InvalidPassword.into());
+        }
+        let user = self
+            .db_client
+            .get_user(&request.id)
+            .map_err(|_| TeaclaveAuthenticationApiError::PermissionDenied)?;
+        if !user.verify_password(&request.password) {
+            Err(TeaclaveAuthenticationApiError::PermissionDenied.into())
+        } else {
+            let now = SystemTime::now()
+                .duration_since(UNIX_EPOCH)
+                .map_err(|_| 
TeaclaveAuthenticationApiError::ServiceUnavailable)?;
+            let exp = (now + Duration::from_secs(24 * 60)).as_secs();
+            match user.get_token(exp, &self.jwt_secret) {
+                Ok(token) => Ok(UserLoginResponse { token }),
+                Err(_) => 
Err(TeaclaveAuthenticationApiError::ServiceUnavailable.into()),
+            }
+        }
+    }
+}
+
+#[cfg(feature = "enclave_unit_test")]
+pub mod tests {
+    use super::*;
+    use crate::user_db::*;
+    use crate::user_info::*;
+    use rand::RngCore;
+    use std::vec;
+
+    fn get_mock_service() -> TeaclaveAuthenticationApiService {
+        let database = Database::open().unwrap();
+        let mut jwt_secret = vec![0; JWT_SECRET_LEN];
+        let mut rng = rand::thread_rng();
+        rng.fill_bytes(&mut jwt_secret);
+        TeaclaveAuthenticationApiService {
+            db_client: database.get_client(),
+            jwt_secret,
+        }
+    }
+
+    pub fn test_user_register() {
+        let request = UserRegisterRequest {
+            id: "test_register_id".to_string(),
+            password: "test_password".to_string(),
+        };
+        let request = Request::new(request);
+        let service = get_mock_service();
+        assert!(service.user_register(request).is_ok());
+    }
+
+    pub fn test_user_login() {
+        let service = get_mock_service();
+        let request = UserRegisterRequest {
+            id: "test_login_id".to_string(),
+            password: "test_password".to_string(),
+        };
+        let request = Request::new(request);
+        assert!(service.user_register(request).is_ok());
+        let request = UserLoginRequest {
+            id: "test_login_id".to_string(),
+            password: "test_password".to_string(),
+        };
+        let request = Request::new(request);
+        let response = service.user_login(request);
+        assert!(response.is_ok());
+        let token = response.unwrap().token;
+        let user = service.db_client.get_user("test_login_id").unwrap();
+        assert!(user.validate_token(&service.jwt_secret, &token));
+
+        info!("saved user_info: {:?}", user);
+        let request = UserLoginRequest {
+            id: "test_login_id".to_string(),
+            password: "test_password1".to_string(),
+        };
+        let request = Request::new(request);
+        assert!(service.user_login(request).is_err());
+    }
+}
diff --git a/services/authentication/enclave/src/internal_service.rs 
b/services/authentication/enclave/src/internal_service.rs
new file mode 100644
index 0000000..72360a3
--- /dev/null
+++ b/services/authentication/enclave/src/internal_service.rs
@@ -0,0 +1,203 @@
+use crate::user_db::DbClient;
+use crate::user_info::UserInfo;
+use std::prelude::v1::*;
+use teaclave_proto::teaclave_authentication_service::{
+    TeaclaveAuthenticationInternal, UserAuthenticateRequest, 
UserAuthenticateResponse,
+};
+use teaclave_rpc::Request;
+use teaclave_service_enclave_utils::teaclave_service;
+use teaclave_types::TeaclaveServiceResponseResult;
+
+#[teaclave_service(teaclave_authentication_service, 
TeaclaveAuthenticationInternal)]
+#[derive(Clone)]
+pub(crate) struct TeaclaveAuthenticationInternalService {
+    pub(crate) db_client: DbClient,
+    pub(crate) jwt_secret: Vec<u8>,
+}
+
+impl TeaclaveAuthenticationInternal for TeaclaveAuthenticationInternalService {
+    fn user_authenticate(
+        &self,
+        request: Request<UserAuthenticateRequest>,
+    ) -> TeaclaveServiceResponseResult<UserAuthenticateResponse> {
+        let request = request.message;
+        if request.credential.id.is_empty() || 
request.credential.token.is_empty() {
+            return Ok(UserAuthenticateResponse { accept: false });
+        }
+        let user: UserInfo = match 
self.db_client.get_user(&request.credential.id) {
+            Ok(value) => value,
+            Err(_) => return Ok(UserAuthenticateResponse { accept: false }),
+        };
+        Ok(UserAuthenticateResponse {
+            accept: user.validate_token(&self.jwt_secret, 
&request.credential.token),
+        })
+    }
+}
+
+#[cfg(feature = "enclave_unit_test")]
+pub mod tests {
+    use super::*;
+    use crate::user_db::*;
+    use crate::user_info::*;
+    use rand::RngCore;
+    use std::time::{Duration, SystemTime, UNIX_EPOCH};
+    use std::untrusted::time::SystemTimeEx;
+    use std::vec;
+    use teaclave_proto::teaclave_common::UserCredential;
+
+    fn get_mock_service() -> TeaclaveAuthenticationInternalService {
+        let database = Database::open().unwrap();
+        let mut jwt_secret = vec![0; JWT_SECRET_LEN];
+        let mut rng = rand::thread_rng();
+        rng.fill_bytes(&mut jwt_secret);
+        let user = UserInfo::new("test_authenticate_id", 
"test_authenticate_id");
+        database.get_client().create_user(&user).unwrap();
+        TeaclaveAuthenticationInternalService {
+            db_client: database.get_client(),
+            jwt_secret,
+        }
+    }
+
+    pub fn test_user_authenticate() {
+        let id = "test_authenticate_id";
+        let service = get_mock_service();
+        let user = service.db_client.get_user(id).unwrap();
+
+        let now = SystemTime::now().duration_since(UNIX_EPOCH).unwrap();
+        let exp = (now + Duration::from_secs(24 * 60)).as_secs();
+        let token = user.get_token(exp, &service.jwt_secret).unwrap();
+
+        let response = get_authenticate_response(id, &token, &service);
+        assert!(response.accept);
+        let token = validate_token(id, &service.jwt_secret, &token);
+        info!("valid token: {:?}", token.unwrap());
+    }
+
+    pub fn test_invalid_algorithm() {
+        let id = "test_authenticate_id";
+        let service = get_mock_service();
+        let my_claims = get_correct_claim(id);
+        let token = gen_token(
+            my_claims,
+            Some(jsonwebtoken::Algorithm::HS256),
+            &service.jwt_secret,
+        );
+        let response = get_authenticate_response(id, &token, &service);
+        assert!(!response.accept);
+        let error = validate_token(id, &service.jwt_secret, &token);
+        assert!(error.is_err());
+        match *error.unwrap_err().kind() {
+            jsonwebtoken::errors::ErrorKind::InvalidAlgorithm => (),
+            _ => panic!("wrong error type"),
+        }
+    }
+
+    pub fn test_invalid_issuer() {
+        let id = "test_authenticate_id";
+        let service = get_mock_service();
+        let mut my_claims = get_correct_claim(id);
+        my_claims.iss = "wrong issuer".to_string();
+        let token = gen_token(my_claims, None, &service.jwt_secret);
+        let response = get_authenticate_response(id, &token, &service);
+        assert!(!response.accept);
+        let error = validate_token(id, &service.jwt_secret, &token);
+        assert!(error.is_err());
+        match *error.unwrap_err().kind() {
+            jsonwebtoken::errors::ErrorKind::InvalidIssuer => (),
+            _ => panic!("wrong error type"),
+        }
+    }
+
+    pub fn test_expired_token() {
+        let id = "test_authenticate_id";
+        let service = get_mock_service();
+        let mut my_claims = get_correct_claim(id);
+        my_claims.exp -= 24 * 60 + 1;
+        let token = gen_token(my_claims, None, &service.jwt_secret);
+        let response = get_authenticate_response(id, &token, &service);
+        assert!(!response.accept);
+        let error = validate_token(id, &service.jwt_secret, &token);
+        assert!(error.is_err());
+        match *error.unwrap_err().kind() {
+            jsonwebtoken::errors::ErrorKind::ExpiredSignature => (),
+            _ => panic!("wrong error type"),
+        }
+    }
+
+    pub fn test_invalid_user() {
+        let id = "test_authenticate_id";
+        let service = get_mock_service();
+        let mut my_claims = get_correct_claim(id);
+        my_claims.sub = "wrong user".to_string();
+        let token = gen_token(my_claims, None, &service.jwt_secret);
+        let response = get_authenticate_response(id, &token, &service);
+        assert!(!response.accept);
+        let error = validate_token(id, &service.jwt_secret, &token);
+        assert!(error.is_err());
+        match *error.unwrap_err().kind() {
+            jsonwebtoken::errors::ErrorKind::InvalidSubject => (),
+            _ => panic!("wrong error type"),
+        }
+    }
+
+    pub fn test_wrong_secret() {
+        let id = "test_authenticate_id";
+        let service = get_mock_service();
+        let my_claims = get_correct_claim(id);
+        let token = gen_token(my_claims, None, b"bad secret");
+        let response = get_authenticate_response(id, &token, &service);
+        assert!(!response.accept);
+        let error = validate_token(id, &service.jwt_secret, &token);
+        assert!(error.is_err());
+        match *error.unwrap_err().kind() {
+            jsonwebtoken::errors::ErrorKind::InvalidSignature => (),
+            _ => panic!("wrong error type"),
+        }
+    }
+
+    fn get_correct_claim(id: &str) -> Claims {
+        let now = SystemTime::now()
+            .duration_since(UNIX_EPOCH)
+            .unwrap()
+            .as_secs();
+        Claims {
+            sub: id.to_string(),
+            iss: ISSUER_NAME.to_string(),
+            exp: now + 24 * 60,
+        }
+    }
+
+    fn gen_token(claim: Claims, bad_alg: Option<jsonwebtoken::Algorithm>, 
secret: &[u8]) -> String {
+        let mut header = jsonwebtoken::Header::default();
+        header.alg = bad_alg.unwrap_or(JWT_ALG);
+        jsonwebtoken::encode(&header, &claim, secret).unwrap()
+    }
+
+    fn get_authenticate_response(
+        id: &str,
+        token: &str,
+        service: &TeaclaveAuthenticationInternalService,
+    ) -> UserAuthenticateResponse {
+        let credential = UserCredential {
+            id: id.to_string(),
+            token: token.to_string(),
+        };
+        let request = UserAuthenticateRequest { credential };
+        let request = Request::new(request);
+        service.user_authenticate(request).unwrap()
+    }
+
+    fn validate_token(
+        id: &str,
+        secret: &[u8],
+        token: &str,
+    ) -> jsonwebtoken::errors::Result<jsonwebtoken::TokenData<Claims>> {
+        let validation = jsonwebtoken::Validation {
+            iss: Some(ISSUER_NAME.to_string()),
+            sub: Some(id.to_string()),
+            algorithms: vec![JWT_ALG],
+            ..Default::default()
+        };
+        jsonwebtoken::decode::<crate::user_info::Claims>(token, secret, 
&validation)
+    }
+}
diff --git a/services/authentication/enclave/src/lib.rs 
b/services/authentication/enclave/src/lib.rs
index a57bc9b..7bfbcab 100644
--- a/services/authentication/enclave/src/lib.rs
+++ b/services/authentication/enclave/src/lib.rs
@@ -24,6 +24,7 @@ extern crate sgx_tstd as std;
 extern crate log;
 
 use anyhow::Result;
+use rand::RngCore;
 use std::prelude::v1::*;
 use std::sync::Arc;
 use std::thread;
@@ -34,19 +35,22 @@ use teaclave_ipc::proto::{
 };
 use teaclave_ipc::{handle_ecall, register_ecall_handler};
 use teaclave_proto::teaclave_authentication_service::{
-    TeaclaveAuthenticationRequest, TeaclaveAuthenticationResponse,
+    TeaclaveAuthenticationApiRequest, TeaclaveAuthenticationApiResponse,
+    TeaclaveAuthenticationInternalRequest, 
TeaclaveAuthenticationInternalResponse,
 };
 use teaclave_rpc::config::SgxTrustedTlsServerConfig;
 use teaclave_rpc::server::SgxTrustedTlsServer;
 use teaclave_service_enclave_utils::ServiceEnclave;
 
-mod service;
+mod api_service;
+mod internal_service;
 mod user_db;
 mod user_info;
 
-fn start_endpoint(
+fn start_internal_endpoint(
     listener: std::net::TcpListener,
     db_client: user_db::DbClient,
+    jwt_secret: Vec<u8>,
     attestation: Arc<RemoteAttestation>,
 ) {
     let config = SgxTrustedTlsServerConfig::new_without_verifier(
@@ -56,11 +60,45 @@ fn start_endpoint(
     .unwrap();
 
     let mut server = SgxTrustedTlsServer::<
-        TeaclaveAuthenticationResponse,
-        TeaclaveAuthenticationRequest,
+        TeaclaveAuthenticationInternalResponse,
+        TeaclaveAuthenticationInternalRequest,
     >::new(listener, &config);
 
-    let service = 
service::TeaclaveAuthenticationService::new(db_client).unwrap();
+    let service = internal_service::TeaclaveAuthenticationInternalService {
+        db_client,
+        jwt_secret,
+    };
+
+    match server.start(service) {
+        Ok(_) => (),
+        Err(e) => {
+            error!("Service exit, error: {}.", e);
+        }
+    }
+}
+
+fn start_api_endpoint(
+    listener: std::net::TcpListener,
+    db_client: user_db::DbClient,
+    jwt_secret: Vec<u8>,
+    attestation: Arc<RemoteAttestation>,
+) {
+    let config = SgxTrustedTlsServerConfig::new_without_verifier(
+        &attestation.cert,
+        &attestation.private_key,
+    )
+    .unwrap();
+
+    let mut server = SgxTrustedTlsServer::<
+        TeaclaveAuthenticationApiResponse,
+        TeaclaveAuthenticationApiRequest,
+    >::new(listener, &config);
+
+    let service = api_service::TeaclaveAuthenticationApiService {
+        db_client,
+        jwt_secret,
+    };
+
     match server.start(service) {
         Ok(_) => (),
         Err(e) => {
@@ -79,16 +117,20 @@ fn handle_start_service(args: &StartServiceInput) -> 
Result<StartServiceOutput>
         RemoteAttestation::generate_and_endorse(&ias_config.ias_key, 
&ias_config.ias_spid).unwrap(),
     );
     let database = user_db::Database::open()?;
+    let mut api_jwt_secret = vec![0; user_info::JWT_SECRET_LEN];
+    let mut rng = rand::thread_rng();
+    rng.fill_bytes(&mut api_jwt_secret);
+    let internal_jwt_secret = api_jwt_secret.to_owned();
 
     let attestation_ref = attestation.clone();
     let client = database.get_client();
     let api_endpoint_thread_handler = thread::spawn(move || {
-        start_endpoint(api_listener, client, attestation_ref);
+        start_api_endpoint(api_listener, client, api_jwt_secret, 
attestation_ref);
     });
 
     let client = database.get_client();
     let internal_endpoint_thread_handler = thread::spawn(move || {
-        start_endpoint(internal_listener, client, attestation);
+        start_internal_endpoint(internal_listener, client, 
internal_jwt_secret, attestation);
     });
 
     api_endpoint_thread_handler.join().unwrap();
@@ -123,9 +165,14 @@ pub mod tests {
 
     pub fn run_tests() -> bool {
         run_tests!(
-            service::tests::test_user_login,
-            service::tests::test_user_authenticate,
-            service::tests::test_user_register,
+            api_service::tests::test_user_login,
+            api_service::tests::test_user_register,
+            internal_service::tests::test_user_authenticate,
+            internal_service::tests::test_invalid_algorithm,
+            internal_service::tests::test_invalid_issuer,
+            internal_service::tests::test_expired_token,
+            internal_service::tests::test_invalid_user,
+            internal_service::tests::test_wrong_secret,
         )
     }
 }
diff --git a/services/authentication/enclave/src/service.rs 
b/services/authentication/enclave/src/service.rs
deleted file mode 100644
index a0abbe5..0000000
--- a/services/authentication/enclave/src/service.rs
+++ /dev/null
@@ -1,282 +0,0 @@
-use crate::user_db::{DbClient, DbError};
-use crate::user_info::{UserInfo, JWT_SECRET_LEN};
-use rand::RngCore;
-use std::prelude::v1::*;
-use std::time::{Duration, SystemTime, UNIX_EPOCH};
-use std::untrusted::time::SystemTimeEx;
-use teaclave_proto::teaclave_authentication_service::{
-    TeaclaveAuthentication, UserAuthenticateRequest, UserAuthenticateResponse, 
UserLoginRequest,
-    UserLoginResponse, UserRegisterRequest, UserRegisterResponse,
-};
-use teaclave_rpc::Request;
-use teaclave_service_enclave_utils::teaclave_service;
-use teaclave_types::{TeaclaveServiceResponseError, 
TeaclaveServiceResponseResult};
-use thiserror::Error;
-
-#[derive(Error, Debug)]
-enum TeaclaveAuthenticationError {
-    #[error("permission denied")]
-    PermissionDenied,
-    #[error("invalid userid")]
-    InvalidUserId,
-    #[error("invalid password")]
-    InvalidPassword,
-    #[error("service unavailable")]
-    ServiceUnavailable,
-}
-
-impl From<TeaclaveAuthenticationError> for TeaclaveServiceResponseError {
-    fn from(error: TeaclaveAuthenticationError) -> Self {
-        TeaclaveServiceResponseError::RequestError(error.to_string())
-    }
-}
-
-#[teaclave_service(
-    teaclave_authentication_service,
-    TeaclaveAuthentication,
-    TeaclaveAuthenticationError
-)]
-#[derive(Clone)]
-pub(crate) struct TeaclaveAuthenticationService {
-    db_client: DbClient,
-    jwt_secret: Vec<u8>,
-}
-
-impl TeaclaveAuthenticationService {
-    pub(crate) fn new(db_client: DbClient) -> anyhow::Result<Self> {
-        let mut jwt_secret = vec![0; JWT_SECRET_LEN];
-        let mut rng = rand::thread_rng();
-        rng.fill_bytes(&mut jwt_secret);
-        Ok(Self {
-            db_client,
-            jwt_secret,
-        })
-    }
-}
-
-impl TeaclaveAuthentication for TeaclaveAuthenticationService {
-    fn user_register(
-        &self,
-        request: Request<UserRegisterRequest>,
-    ) -> TeaclaveServiceResponseResult<UserRegisterResponse> {
-        let request = request.message;
-        if request.id.is_empty() {
-            return Err(TeaclaveAuthenticationError::InvalidUserId.into());
-        }
-        if self.db_client.get_user(&request.id).is_ok() {
-            return Err(TeaclaveAuthenticationError::InvalidUserId.into());
-        }
-        let new_user = UserInfo::new(&request.id, &request.password);
-        match self.db_client.create_user(&new_user) {
-            Ok(_) => Ok(UserRegisterResponse {}),
-            Err(DbError::UserExist) => 
Err(TeaclaveAuthenticationError::InvalidUserId.into()),
-            Err(_) => 
Err(TeaclaveAuthenticationError::ServiceUnavailable.into()),
-        }
-    }
-
-    fn user_login(
-        &self,
-        request: Request<UserLoginRequest>,
-    ) -> TeaclaveServiceResponseResult<UserLoginResponse> {
-        let request = request.message;
-        if request.id.is_empty() {
-            return Err(TeaclaveAuthenticationError::InvalidUserId.into());
-        }
-        if request.password.is_empty() {
-            return Err(TeaclaveAuthenticationError::InvalidPassword.into());
-        }
-        let user = self
-            .db_client
-            .get_user(&request.id)
-            .map_err(|_| TeaclaveAuthenticationError::PermissionDenied)?;
-        if !user.verify_password(&request.password) {
-            Err(TeaclaveAuthenticationError::PermissionDenied.into())
-        } else {
-            let now = SystemTime::now()
-                .duration_since(UNIX_EPOCH)
-                .map_err(|_| TeaclaveAuthenticationError::ServiceUnavailable)?;
-            let exp = (now + Duration::from_secs(24 * 60)).as_secs();
-            match user.get_token(exp, &self.jwt_secret) {
-                Ok(token) => Ok(UserLoginResponse { token }),
-                Err(_) => 
Err(TeaclaveAuthenticationError::ServiceUnavailable.into()),
-            }
-        }
-    }
-
-    fn user_authenticate(
-        &self,
-        request: Request<UserAuthenticateRequest>,
-    ) -> TeaclaveServiceResponseResult<UserAuthenticateResponse> {
-        let request = request.message;
-        if request.credential.id.is_empty() || 
request.credential.token.is_empty() {
-            return Ok(UserAuthenticateResponse { accept: false });
-        }
-        let user: UserInfo = match 
self.db_client.get_user(&request.credential.id) {
-            Ok(value) => value,
-            Err(_) => return Ok(UserAuthenticateResponse { accept: false }),
-        };
-        Ok(UserAuthenticateResponse {
-            accept: user.validate_token(&self.jwt_secret, 
&request.credential.token),
-        })
-    }
-}
-
-#[cfg(feature = "enclave_unit_test")]
-pub mod tests {
-    use super::*;
-    use crate::user_db::*;
-    use crate::user_info::*;
-    use std::vec;
-    use teaclave_proto::teaclave_common::UserCredential;
-
-    fn get_mock_service() -> TeaclaveAuthenticationService {
-        let database = Database::open().unwrap();
-        TeaclaveAuthenticationService::new(database.get_client()).unwrap()
-    }
-
-    pub fn test_user_register() {
-        let request = UserRegisterRequest {
-            id: "test_register_id".to_string(),
-            password: "test_password".to_string(),
-        };
-        let request = Request::new(request);
-        let service = get_mock_service();
-        assert!(service.user_register(request).is_ok());
-    }
-
-    pub fn test_user_login() {
-        let service = get_mock_service();
-        let request = UserRegisterRequest {
-            id: "test_login_id".to_string(),
-            password: "test_password".to_string(),
-        };
-        let request = Request::new(request);
-        assert!(service.user_register(request).is_ok());
-        let request = UserLoginRequest {
-            id: "test_login_id".to_string(),
-            password: "test_password".to_string(),
-        };
-        let request = Request::new(request);
-        assert!(service.user_login(request).is_ok());
-
-        info!(
-            "saved user_info: {:?}",
-            service.db_client.get_user("test_login_id").unwrap()
-        );
-        let request = UserLoginRequest {
-            id: "test_login_id".to_string(),
-            password: "test_password1".to_string(),
-        };
-        let request = Request::new(request);
-        assert!(service.user_login(request).is_err());
-    }
-
-    pub fn test_user_authenticate() {
-        let id = "test_authenticate_id";
-        let service = get_mock_service();
-        let request = UserRegisterRequest {
-            id: id.to_string(),
-            password: "test_password".to_string(),
-        };
-        let request = Request::new(request);
-        assert!(service.user_register(request).is_ok());
-
-        let request = UserLoginRequest {
-            id: id.to_string(),
-            password: "test_password".to_string(),
-        };
-        let request = Request::new(request);
-        let token = service.user_login(request).unwrap().token;
-        info!("login token: {}", token);
-        dump_token(&service.jwt_secret, &token);
-
-        let response = get_authenticate_response(id, &token, &service);
-        assert!(response.accept);
-
-        info!("test wrong algorithm");
-        let my_claims = get_correct_claim();
-        let token = gen_token(
-            my_claims,
-            Some(jsonwebtoken::Algorithm::HS256),
-            &service.jwt_secret,
-        );
-        dump_token(&service.jwt_secret, &token);
-        let response = get_authenticate_response(id, &token, &service);
-        assert!(!response.accept);
-
-        info!("test wrong issuer");
-        let mut my_claims = get_correct_claim();
-        my_claims.iss = "wrong issuer".to_string();
-        let token = gen_token(my_claims, None, &service.jwt_secret);
-        dump_token(&service.jwt_secret, &token);
-        let response = get_authenticate_response(id, &token, &service);
-        assert!(!response.accept);
-
-        info!("test wrong user");
-        let mut my_claims = get_correct_claim();
-        my_claims.sub = "wrong user".to_string();
-        let token = gen_token(my_claims, None, &service.jwt_secret);
-        dump_token(&service.jwt_secret, &token);
-        let response = get_authenticate_response(id, &token, &service);
-        assert!(!response.accept);
-
-        info!("test expired token");
-        let mut my_claims = get_correct_claim();
-        my_claims.exp -= 24 * 60 + 1;
-        let token = gen_token(my_claims, None, &service.jwt_secret);
-        dump_token(&service.jwt_secret, &token);
-        let response = get_authenticate_response(id, &token, &service);
-        assert!(!response.accept);
-
-        info!("test wrong secret");
-        let my_claims = get_correct_claim();
-        let token = gen_token(my_claims, None, b"bad secret");
-        dump_token(&service.jwt_secret, &token);
-        let response = get_authenticate_response(id, &token, &service);
-        assert!(!response.accept);
-    }
-
-    fn get_correct_claim() -> Claims {
-        let now = SystemTime::now()
-            .duration_since(UNIX_EPOCH)
-            .unwrap()
-            .as_secs();
-        Claims {
-            sub: "test_authenticate_id".to_string(),
-            iss: ISSUER_NAME.to_string(),
-            exp: now + 24 * 60,
-        }
-    }
-
-    fn gen_token(claim: Claims, bad_alg: Option<jsonwebtoken::Algorithm>, 
secret: &[u8]) -> String {
-        let mut header = jsonwebtoken::Header::default();
-        header.alg = bad_alg.unwrap_or(JWT_ALG);
-        jsonwebtoken::encode(&header, &claim, secret).unwrap()
-    }
-
-    fn get_authenticate_response(
-        id: &str,
-        token: &str,
-        service: &TeaclaveAuthenticationService,
-    ) -> UserAuthenticateResponse {
-        let credential = UserCredential {
-            id: id.to_string(),
-            token: token.to_string(),
-        };
-        let request = UserAuthenticateRequest { credential };
-        let request = Request::new(request);
-        service.user_authenticate(request).unwrap()
-    }
-
-    fn dump_token(secret: &[u8], token: &str) {
-        let validation = jsonwebtoken::Validation {
-            iss: Some(ISSUER_NAME.to_string()),
-            sub: Some("test_authenticate_id".to_string()),
-            algorithms: vec![JWT_ALG],
-            ..Default::default()
-        };
-        let token_data =
-            jsonwebtoken::decode::<crate::user_info::Claims>(token, secret, 
&validation);
-        info!("token {:?}", token_data);
-    }
-}
diff --git a/services/authentication/enclave/src/user_db.rs 
b/services/authentication/enclave/src/user_db.rs
index 7ff422a..c0f79a8 100644
--- a/services/authentication/enclave/src/user_db.rs
+++ b/services/authentication/enclave/src/user_db.rs
@@ -99,7 +99,7 @@ impl Database {
                 let call: DBCall = match receiver.recv() {
                     Ok(req) => req,
                     Err(e) => {
-                        error!("mspc receive error: {}", e);
+                        info!("mspc receive error: {}", e);
                         break;
                     }
                 };
@@ -120,7 +120,7 @@ impl Database {
                 };
                 match sender.send(response) {
                     Ok(_) => (),
-                    Err(e) => error!("mpsc send error: {}", e),
+                    Err(e) => info!("mpsc send error: {}", e),
                 }
             }
         });
diff --git a/services/frontend/enclave/src/service.rs 
b/services/frontend/enclave/src/service.rs
index 983e0b8..b5fb700 100644
--- a/services/frontend/enclave/src/service.rs
+++ b/services/frontend/enclave/src/service.rs
@@ -1,7 +1,7 @@
 use std::prelude::v1::*;
 use std::sync::{Arc, SgxMutex as Mutex};
 use teaclave_config::RuntimeConfig;
-use 
teaclave_proto::teaclave_authentication_service::TeaclaveAuthenticationClient;
+use 
teaclave_proto::teaclave_authentication_service::TeaclaveAuthenticationInternalClient;
 use teaclave_proto::teaclave_authentication_service::UserAuthenticateRequest;
 use teaclave_proto::teaclave_common::UserCredential;
 use teaclave_proto::teaclave_frontend_service::{
@@ -29,7 +29,7 @@ impl From<TeaclaveFrontendError> for 
TeaclaveServiceResponseError {
 #[teaclave_service(teaclave_frontend_service, TeaclaveFrontend, 
TeaclaveFrontendError)]
 #[derive(Clone)]
 pub(crate) struct TeaclaveFrontendService {
-    authentication_client: Arc<Mutex<TeaclaveAuthenticationClient>>,
+    authentication_client: Arc<Mutex<TeaclaveAuthenticationInternalClient>>,
 }
 
 impl TeaclaveFrontendService {
@@ -37,7 +37,7 @@ impl TeaclaveFrontendService {
         let channel = 
Endpoint::new(&config.internal_endpoints.authentication.advertised_address)
             .connect()
             .unwrap();
-        let client = TeaclaveAuthenticationClient::new(channel).unwrap();
+        let client = 
TeaclaveAuthenticationInternalClient::new(channel).unwrap();
         Self {
             authentication_client: Arc::new(Mutex::new(client)),
         }
diff --git a/services/proto/proto_gen/templates/proto.j2 
b/services/proto/proto_gen/templates/proto.j2
index 8980405..665ac76 100644
--- a/services/proto/proto_gen/templates/proto.j2
+++ b/services/proto/proto_gen/templates/proto.j2
@@ -1,10 +1,3 @@
-use anyhow;
-use teaclave_types;
-use teaclave_rpc;
-use core::convert::TryFrom;
-use teaclave_types::TeaclaveServiceResponseError;
-use std::prelude::v1::*;
-
 #[derive(Clone, serde::Serialize, serde::Deserialize, Debug)]
 #[serde(tag = "request", rename_all = "snake_case")]
 pub enum {{ service.proto_name }}Request {
@@ -27,11 +20,13 @@ pub trait {{ service.proto_name }} {
     {%- endfor %}
 
     fn dispatch(&self, request: teaclave_rpc::Request<{{ service.proto_name 
}}Request>) -> teaclave_types::TeaclaveServiceResponseResult<{{ 
service.proto_name }}Response> {
+         use core::convert::TryFrom;
+         use std::string::ToString;
          match request.message {
              {%- for m in service.methods %}
              {{ service.proto_name }}Request::{{ m.proto_name }}(r) => {
                  let r = crate::{{ proto_impl_mod_name }}::{{ m.input_type 
}}::try_from(r)
-                     .map_err(|_| 
TeaclaveServiceResponseError::InternalError("internal".to_string()))?;
+                     .map_err(|_| 
teaclave_types::TeaclaveServiceResponseError::InternalError("internal".to_string()))?;
                  let r = teaclave_rpc::Request {
                      metadata: request.metadata,
                      message: r,
@@ -66,13 +61,16 @@ impl {{ service.proto_name }}Client {
             {{ service.proto_name }}Request,
             {{ service.proto_name }}Response
         >,
-        metadata: std::collections::HashMap<String, String>,
+        metadata: std::collections::HashMap<std::string::String, 
std::string::String>,
     ) -> anyhow::Result<Self> {
         Ok(Self { channel, metadata })
     }
 
     {%- for m in service.methods %}
     pub fn {{ m.name }}<T: Into<{{ m.input_type }}>>(&mut self, request: T) -> 
teaclave_types::TeaclaveServiceResponseResult<{{ m.output_type }}> {
+        {%- if service.methods.len() > 1 %}
+        use std::string::ToString;
+        {%- endif %}
         let request = {{ service.proto_name }}Request::{{ m.proto_name 
}}(request.into());
         let request = teaclave_rpc::Request {
             metadata: self.metadata.clone(),
@@ -83,7 +81,7 @@ impl {{ service.proto_name }}Client {
             Ok({{ service.proto_name }}Response::{{ m.proto_name }}(response)) 
=> Ok(response),
             Err(e) => Err(e),
             {%- if service.methods.len() > 1 %}
-            _ => 
Err(TeaclaveServiceResponseError::InternalError("internal".to_string())),
+            _ => 
Err(teaclave_types::TeaclaveServiceResponseError::InternalError("internal".to_string())),
             {%- endif %}
         }
     }
diff --git a/services/proto/src/proto/teaclave_authentication_service.proto 
b/services/proto/src/proto/teaclave_authentication_service.proto
index 12b7edf..bf483c6 100644
--- a/services/proto/src/proto/teaclave_authentication_service.proto
+++ b/services/proto/src/proto/teaclave_authentication_service.proto
@@ -27,8 +27,11 @@ message UserAuthenticateResponse {
   bool accept = 1;
 }
 
-service TeaclaveAuthentication {
+service TeaclaveAuthenticationApi {
   rpc UserRegister(UserRegisterRequest) returns (UserRegisterResponse);
   rpc UserLogin (UserLoginRequest) returns (UserLoginResponse);
-  rpc UserAuthenticate (UserAuthenticateRequest) returns 
(UserAuthenticateResponse);
 }
+
+service TeaclaveAuthenticationInternal {
+  rpc UserAuthenticate (UserAuthenticateRequest) returns 
(UserAuthenticateResponse);
+}
\ No newline at end of file
diff --git a/services/proto/src/teaclave_authentication_service.rs 
b/services/proto/src/teaclave_authentication_service.rs
index 71db70e..7409c98 100644
--- a/services/proto/src/teaclave_authentication_service.rs
+++ b/services/proto/src/teaclave_authentication_service.rs
@@ -5,10 +5,14 @@ use serde::{Deserialize, Serialize};
 
 use crate::teaclave_authentication_service_proto as proto;
 use crate::teaclave_common;
-pub use proto::TeaclaveAuthentication;
-pub use proto::TeaclaveAuthenticationClient;
-pub use proto::TeaclaveAuthenticationRequest;
-pub use proto::TeaclaveAuthenticationResponse;
+pub use proto::TeaclaveAuthenticationApi;
+pub use proto::TeaclaveAuthenticationApiClient;
+pub use proto::TeaclaveAuthenticationApiRequest;
+pub use proto::TeaclaveAuthenticationApiResponse;
+pub use proto::TeaclaveAuthenticationInternal;
+pub use proto::TeaclaveAuthenticationInternalClient;
+pub use proto::TeaclaveAuthenticationInternalRequest;
+pub use proto::TeaclaveAuthenticationInternalResponse;
 
 #[derive(Serialize, Deserialize, Debug)]
 pub struct UserRegisterRequest {
diff --git 
a/tests/functional_tests/enclave/src/teaclave_authentication_service.rs 
b/tests/functional_tests/enclave/src/teaclave_authentication_service.rs
index 61887b8..fc39059 100644
--- a/tests/functional_tests/enclave/src/teaclave_authentication_service.rs
+++ b/tests/functional_tests/enclave/src/teaclave_authentication_service.rs
@@ -21,7 +21,7 @@ pub fn run_tests() -> bool {
     )
 }
 
-fn test_login_success() {
+fn get_api_client() -> TeaclaveAuthenticationApiClient {
     let runtime_config = 
RuntimeConfig::from_toml("runtime.config.toml").expect("runtime");
     let enclave_info =
         
EnclaveInfo::from_bytes(&runtime_config.audit.enclave_info_bytes.as_ref().unwrap());
@@ -38,7 +38,36 @@ fn test_login_success() {
         .config(config)
         .connect()
         .unwrap();
-    let mut client = TeaclaveAuthenticationClient::new(channel).unwrap();
+    TeaclaveAuthenticationApiClient::new(channel).unwrap()
+}
+
+fn get_internal_client() -> TeaclaveAuthenticationInternalClient {
+    let runtime_config = 
RuntimeConfig::from_toml("runtime.config.toml").expect("runtime");
+    let enclave_info =
+        
EnclaveInfo::from_bytes(&runtime_config.audit.enclave_info_bytes.as_ref().unwrap());
+    let enclave_attr = enclave_info
+        .get_enclave_attr("teaclave_authentication_service")
+        .expect("authentication");
+    let config = 
SgxTrustedTlsClientConfig::new_with_attestation_report_verifier(
+        vec![enclave_attr],
+        BUILD_CONFIG.ias_root_ca_cert,
+        verifier::universal_quote_verifier,
+    );
+
+    let channel = Endpoint::new(
+        &runtime_config
+            .internal_endpoints
+            .authentication
+            .advertised_address,
+    )
+    .config(config)
+    .connect()
+    .unwrap();
+    TeaclaveAuthenticationInternalClient::new(channel).unwrap()
+}
+
+fn test_login_success() {
+    let mut client = get_api_client();
     let request = UserRegisterRequest {
         id: "test_login_id1".to_string(),
         password: "test_password".to_string(),
@@ -56,8 +85,7 @@ fn test_login_success() {
 }
 
 fn test_login_fail() {
-    let channel = Endpoint::new("localhost:7776").connect().unwrap();
-    let mut client = TeaclaveAuthenticationClient::new(channel).unwrap();
+    let mut client = get_api_client();
     let request = UserRegisterRequest {
         id: "test_login_id2".to_string(),
         password: "test_password".to_string(),
@@ -75,60 +103,54 @@ fn test_login_fail() {
 }
 
 fn test_authenticate_success() {
-    let channel = Endpoint::new("localhost:17776").connect().unwrap();
-    let mut client = TeaclaveAuthenticationClient::new(channel).unwrap();
+    let mut api_client = get_api_client();
+    let mut internal_client = get_internal_client();
     let request = UserRegisterRequest {
         id: "test_authenticate_id1".to_string(),
         password: "test_password".to_string(),
     };
-    let response_result = client.user_register(request);
+    let response_result = api_client.user_register(request);
     assert!(response_result.is_ok());
 
     let request = UserLoginRequest {
         id: "test_authenticate_id1".to_string(),
         password: "test_password".to_string(),
     };
-    let response_result = client.user_login(request);
+    let response_result = api_client.user_login(request);
     assert!(response_result.is_ok());
     let credential = UserCredential {
         id: "test_authenticate_id1".to_string(),
         token: response_result.unwrap().token,
     };
     let request = UserAuthenticateRequest { credential };
-    let response_result = client.user_authenticate(request);
+    let response_result = internal_client.user_authenticate(request);
     info!("{:?}", response_result);
     assert!(response_result.unwrap().accept);
 }
 
 fn test_authenticate_fail() {
-    let channel = Endpoint::new("localhost:17776").connect().unwrap();
-    let mut client = TeaclaveAuthenticationClient::new(channel).unwrap();
+    let mut api_client = get_api_client();
+    let mut internal_client = get_internal_client();
+
     let request = UserRegisterRequest {
         id: "test_authenticate_id2".to_string(),
         password: "test_password".to_string(),
     };
-    let response_result = client.user_register(request);
+    let response_result = api_client.user_register(request);
     assert!(response_result.is_ok());
 
-    let request = UserLoginRequest {
-        id: "test_authenticate_id2".to_string(),
-        password: "test_password".to_string(),
-    };
-    let response_result = client.user_login(request);
-    assert!(response_result.is_ok());
     let credential = UserCredential {
         id: "test_authenticate_id2".to_string(),
         token: "wrong_token".to_string(),
     };
     let request = UserAuthenticateRequest { credential };
-    let response_result = client.user_authenticate(request);
+    let response_result = internal_client.user_authenticate(request);
     info!("{:?}", response_result);
     assert!(!response_result.unwrap().accept);
 }
 
 fn test_register_success() {
-    let channel = Endpoint::new("localhost:7776").connect().unwrap();
-    let mut client = TeaclaveAuthenticationClient::new(channel).unwrap();
+    let mut client = get_api_client();
     let request = UserRegisterRequest {
         id: "test_register_id1".to_string(),
         password: "test_password".to_string(),
@@ -139,8 +161,7 @@ fn test_register_success() {
 }
 
 fn test_register_fail() {
-    let channel = Endpoint::new("localhost:7776").connect().unwrap();
-    let mut client = TeaclaveAuthenticationClient::new(channel).unwrap();
+    let mut client = get_api_client();
     let request = UserRegisterRequest {
         id: "test_register_id2".to_string(),
         password: "test_password".to_string(),
@@ -149,7 +170,7 @@ fn test_register_fail() {
     assert!(response_result.is_ok());
     let request = UserRegisterRequest {
         id: "test_register_id2".to_string(),
-        password: "test_password".to_string(),
+        password: "test_password2".to_string(),
     };
     let response_result = client.user_register(request);
     info!("{:?}", response_result);


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to