1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
use super::ApplicationName;
use super::Authenticate;
use crate::front::listener::ConnectionMetadata;
use log::error;
use parsec_interface::operations::list_authenticators;
use parsec_interface::requests::request::RequestAuth;
use parsec_interface::requests::AuthType;
use parsec_interface::requests::{ResponseStatus, Result};
use parsec_interface::secrecy::ExposeSecret;
use std::str;
#[derive(Copy, Clone, Debug)]
pub struct DirectAuthenticator;
impl Authenticate for DirectAuthenticator {
fn describe(&self) -> Result<list_authenticators::AuthenticatorInfo> {
Ok(list_authenticators::AuthenticatorInfo {
description: String::from(
"Directly parses the authentication field as a UTF-8 string and uses that as the \
application identity. Should be used for testing only.",
),
version_maj: 0,
version_min: 1,
version_rev: 0,
id: AuthType::Direct,
})
}
fn authenticate(
&self,
auth: &RequestAuth,
_: Option<ConnectionMetadata>,
) -> Result<ApplicationName> {
if auth.buffer.expose_secret().is_empty() {
error!("The direct authenticator does not expect empty authentication values.");
Err(ResponseStatus::AuthenticationError)
} else {
match str::from_utf8(auth.buffer.expose_secret()) {
Ok(str) => Ok(ApplicationName(String::from(str))),
Err(_) => {
error!("Error parsing the authentication value as a UTF-8 string.");
Err(ResponseStatus::AuthenticationError)
}
}
}
}
}
#[cfg(test)]
mod test {
use super::super::Authenticate;
use super::DirectAuthenticator;
use parsec_interface::requests::request::RequestAuth;
use parsec_interface::requests::ResponseStatus;
#[test]
fn successful_authentication() {
let authenticator = DirectAuthenticator {};
let app_name = "app_name".to_string();
let req_auth = RequestAuth::new(app_name.clone().into_bytes());
let conn_metadata = None;
let auth_name = authenticator
.authenticate(&req_auth, conn_metadata)
.expect("Failed to authenticate");
assert_eq!(auth_name.get_name(), app_name);
}
#[test]
fn failed_authentication() {
let authenticator = DirectAuthenticator {};
let conn_metadata = None;
let status = authenticator
.authenticate(&RequestAuth::new(vec![0xff; 5]), conn_metadata)
.expect_err("Authentication should have failed");
assert_eq!(status, ResponseStatus::AuthenticationError);
}
#[test]
fn empty_auth() {
let authenticator = DirectAuthenticator {};
let conn_metadata = None;
let status = authenticator
.authenticate(&RequestAuth::new(Vec::new()), conn_metadata)
.expect_err("Empty auth should have failed");
assert_eq!(status, ResponseStatus::AuthenticationError);
}
}