parsec_interface/operations_protobuf/
convert_list_authenticators.rs

1// Copyright 2019 Contributors to the Parsec project.
2// SPDX-License-Identifier: Apache-2.0
3use super::generated_ops::list_authenticators::{
4    AuthenticatorInfo as AuthenticatorInfoProto, Operation as OperationProto, Result as ResultProto,
5};
6use crate::operations::list_authenticators::{AuthenticatorInfo, Operation, Result};
7use crate::requests::{AuthType, ResponseStatus};
8use num::FromPrimitive;
9use std::convert::{TryFrom, TryInto};
10
11impl TryFrom<OperationProto> for Operation {
12    type Error = ResponseStatus;
13
14    fn try_from(_proto_op: OperationProto) -> std::result::Result<Self, Self::Error> {
15        Ok(Operation {})
16    }
17}
18
19impl TryFrom<Operation> for OperationProto {
20    type Error = ResponseStatus;
21
22    fn try_from(_op: Operation) -> std::result::Result<Self, Self::Error> {
23        Ok(Default::default())
24    }
25}
26
27impl TryFrom<AuthenticatorInfoProto> for AuthenticatorInfo {
28    type Error = ResponseStatus;
29
30    fn try_from(proto_info: AuthenticatorInfoProto) -> std::result::Result<Self, Self::Error> {
31        let id: AuthType = match FromPrimitive::from_u32(proto_info.id) {
32            Some(id) => id,
33            None => return Err(ResponseStatus::AuthenticatorDoesNotExist),
34        };
35
36        Ok(AuthenticatorInfo {
37            description: proto_info.description,
38            version_maj: proto_info.version_maj,
39            version_min: proto_info.version_min,
40            version_rev: proto_info.version_rev,
41            id,
42        })
43    }
44}
45
46impl TryFrom<AuthenticatorInfo> for AuthenticatorInfoProto {
47    type Error = ResponseStatus;
48
49    fn try_from(info: AuthenticatorInfo) -> std::result::Result<Self, Self::Error> {
50        Ok(AuthenticatorInfoProto {
51            description: info.description,
52            version_maj: info.version_maj,
53            version_min: info.version_min,
54            version_rev: info.version_rev,
55            id: info.id as u32,
56        })
57    }
58}
59
60impl TryFrom<ResultProto> for Result {
61    type Error = ResponseStatus;
62
63    fn try_from(proto_op: ResultProto) -> std::result::Result<Self, Self::Error> {
64        let mut authenticators: Vec<AuthenticatorInfo> = Vec::new();
65        for authenticator in proto_op.authenticators {
66            authenticators.push(authenticator.try_into()?);
67        }
68
69        Ok(Result { authenticators })
70    }
71}
72
73impl TryFrom<Result> for ResultProto {
74    type Error = ResponseStatus;
75
76    fn try_from(op: Result) -> std::result::Result<Self, Self::Error> {
77        let mut authenticators: Vec<AuthenticatorInfoProto> = Vec::new();
78        for authenticator in op.authenticators {
79            authenticators.push(authenticator.try_into()?);
80        }
81
82        Ok(ResultProto { authenticators })
83    }
84}
85
86#[cfg(test)]
87mod test {
88    // Operation <-> Proto conversions are not tested since they're too simple
89    use super::super::generated_ops::list_authenticators::{
90        AuthenticatorInfo as AuthenticatorInfoProto, Result as ResultProto,
91    };
92    use super::super::{Convert, ProtobufConverter};
93    use crate::operations::list_authenticators::{AuthenticatorInfo, Operation, Result};
94    use crate::operations::{NativeOperation, NativeResult};
95    use crate::requests::{request::RequestBody, response::ResponseBody, AuthType, Opcode};
96    use std::convert::TryInto;
97
98    static CONVERTER: ProtobufConverter = ProtobufConverter {};
99
100    #[test]
101    fn proto_to_resp() {
102        let mut proto: ResultProto = Default::default();
103        let authenticator_info = AuthenticatorInfoProto {
104            description: String::from("authenticator description"),
105            version_maj: 0,
106            version_min: 1,
107            version_rev: 0,
108            id: AuthType::Direct as u32,
109        };
110        proto.authenticators.push(authenticator_info);
111        let resp: Result = proto.try_into().unwrap();
112
113        assert_eq!(resp.authenticators.len(), 1);
114        assert_eq!(
115            resp.authenticators[0].description,
116            "authenticator description"
117        );
118        assert_eq!(resp.authenticators[0].version_maj, 0);
119        assert_eq!(resp.authenticators[0].version_min, 1);
120        assert_eq!(resp.authenticators[0].version_rev, 0);
121        assert_eq!(resp.authenticators[0].id, AuthType::Direct);
122    }
123
124    #[test]
125    fn resp_to_proto() {
126        let mut resp: Result = Result {
127            authenticators: Vec::new(),
128        };
129        let authenticator_info = AuthenticatorInfo {
130            description: String::from("authenticator description"),
131            version_maj: 0,
132            version_min: 1,
133            version_rev: 0,
134            id: AuthType::Direct,
135        };
136        resp.authenticators.push(authenticator_info);
137
138        let proto: ResultProto = resp.try_into().unwrap();
139        assert_eq!(proto.authenticators.len(), 1);
140        assert_eq!(
141            proto.authenticators[0].description,
142            "authenticator description"
143        );
144        assert_eq!(proto.authenticators[0].version_maj, 0);
145        assert_eq!(proto.authenticators[0].version_min, 1);
146        assert_eq!(proto.authenticators[0].version_rev, 0);
147        assert_eq!(proto.authenticators[0].id, AuthType::Direct as u32);
148    }
149
150    #[test]
151    fn list_authenticators_req_to_native() {
152        let req_body = RequestBody::from_bytes(Vec::new());
153        assert!(CONVERTER
154            .body_to_operation(req_body, Opcode::ListAuthenticators)
155            .is_ok());
156    }
157
158    #[test]
159    fn op_list_authenticators_from_native() {
160        let list_authenticators = Operation {};
161        let body = CONVERTER
162            .operation_to_body(NativeOperation::ListAuthenticators(list_authenticators))
163            .expect("Failed to convert request");
164        assert!(body.is_empty());
165    }
166
167    #[test]
168    fn op_list_authenticators_e2e() {
169        let list_authenticators = Operation {};
170        let req_body = CONVERTER
171            .operation_to_body(NativeOperation::ListAuthenticators(list_authenticators))
172            .expect("Failed to convert request");
173
174        assert!(CONVERTER
175            .body_to_operation(req_body, Opcode::ListAuthenticators)
176            .is_ok());
177    }
178
179    #[test]
180    fn req_from_native_mangled_body() {
181        let req_body =
182            RequestBody::from_bytes(vec![0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88]);
183
184        assert!(CONVERTER
185            .body_to_operation(req_body, Opcode::ListAuthenticators)
186            .is_err());
187    }
188
189    #[test]
190    fn list_authenticators_body_to_native() {
191        let resp_body = ResponseBody::from_bytes(Vec::new());
192        assert!(CONVERTER
193            .body_to_result(resp_body, Opcode::ListAuthenticators)
194            .is_ok());
195    }
196
197    #[test]
198    fn result_list_authenticators_from_native() {
199        let mut list_authenticators = Result {
200            authenticators: Vec::new(),
201        };
202        let authenticator_info = AuthenticatorInfo {
203            description: String::from("authenticator description"),
204            version_maj: 0,
205            version_min: 1,
206            version_rev: 0,
207            id: AuthType::Direct,
208        };
209        list_authenticators.authenticators.push(authenticator_info);
210
211        let body = CONVERTER
212            .result_to_body(NativeResult::ListAuthenticators(list_authenticators))
213            .expect("Failed to convert response");
214        assert!(!body.is_empty());
215    }
216
217    #[test]
218    fn list_authenticators_result_e2e() {
219        let mut list_authenticators = Result {
220            authenticators: Vec::new(),
221        };
222        let authenticator_info = AuthenticatorInfo {
223            description: String::from("authenticator description"),
224            version_maj: 0,
225            version_min: 1,
226            version_rev: 0,
227            id: AuthType::Direct,
228        };
229        list_authenticators.authenticators.push(authenticator_info);
230
231        let body = CONVERTER
232            .result_to_body(NativeResult::ListAuthenticators(list_authenticators))
233            .expect("Failed to convert response");
234        assert!(!body.is_empty());
235
236        let result = CONVERTER
237            .body_to_result(body, Opcode::ListAuthenticators)
238            .expect("Failed to convert back to result");
239
240        match result {
241            NativeResult::ListAuthenticators(result) => {
242                assert_eq!(result.authenticators.len(), 1);
243            }
244            _ => panic!("Expected list_authenticators"),
245        }
246    }
247
248    #[test]
249    fn resp_from_native_mangled_body() {
250        let resp_body =
251            ResponseBody::from_bytes(vec![0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88]);
252        assert!(CONVERTER
253            .body_to_result(resp_body, Opcode::ListAuthenticators)
254            .is_err());
255    }
256}