Skip to content

Commit b578e67

Browse files
committed
refactor: 🚚 Rename a lot of stuff ot be more concise
1 parent 0e7a59a commit b578e67

File tree

5 files changed

+87
-91
lines changed

5 files changed

+87
-91
lines changed

test-certs/src/configuration/certificates.rs

Lines changed: 47 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ use serde::{Deserialize, Serialize};
99
pub struct CertificateRoot {
1010
/// All certificates
1111
#[serde(flatten)]
12-
pub certificates: HashMap<String, CertificateTypes>,
12+
pub certificates: HashMap<String, CertificateType>,
1313
}
1414

1515
/// The certificate authority to sign other certificates.
@@ -21,7 +21,7 @@ pub struct CertificateAuthorityConfiguration {
2121

2222
/// Certificates that are signed by this CA.
2323
#[serde(skip_serializing_if = "HashMap::is_empty")]
24-
pub certificates: HashMap<String, CertificateTypes>,
24+
pub certificates: HashMap<String, CertificateType>,
2525
}
2626

2727
/// A certificate used for client authentication.
@@ -43,7 +43,7 @@ pub struct ServerConfiguration {
4343
/// All kinds of different certificates.
4444
#[derive(Debug, Serialize, Deserialize, PartialEq, Eq)]
4545
#[serde(tag = "type", rename_all = "lowercase")]
46-
pub enum CertificateTypes {
46+
pub enum CertificateType {
4747
/// A certificate that acts as a Certificate Authority.
4848
#[serde(alias = "ca")]
4949
CertificateAuthority(CertificateAuthorityConfiguration),
@@ -55,34 +55,34 @@ pub enum CertificateTypes {
5555
Server(ServerConfiguration),
5656
}
5757

58-
impl CertificateTypes {
59-
/// Should the private key be exported or not
58+
/// Is used to provide a reference to an empty HashMap.
59+
/// The [`LazyLock`] is required as a HashMap::new is not usable in const expressions.
60+
static NO_CERTIFICATES: LazyLock<HashMap<String, CertificateType>> = LazyLock::new(HashMap::new);
61+
62+
impl CertificateType {
63+
/// Should the private key be exported or not.
6064
pub fn export_key(&self) -> bool {
6165
match self {
62-
CertificateTypes::CertificateAuthority(certificate_authority) => {
66+
CertificateType::CertificateAuthority(certificate_authority) => {
6367
certificate_authority.export_key
6468
}
65-
CertificateTypes::Client(client) => client.export_key,
66-
CertificateTypes::Server(server) => server.export_key,
69+
CertificateType::Client(client) => client.export_key,
70+
CertificateType::Server(server) => server.export_key,
6771
}
6872
}
6973

7074
/// Certificates issued by this certificate.
71-
pub fn certificates(&self) -> &HashMap<String, CertificateTypes> {
75+
pub fn certificates(&self) -> &HashMap<String, CertificateType> {
7276
match self {
73-
CertificateTypes::CertificateAuthority(certificate_authority) => {
77+
CertificateType::CertificateAuthority(certificate_authority) => {
7478
&certificate_authority.certificates
7579
}
76-
CertificateTypes::Client(_client) => &NO_CERTIFICATES,
77-
CertificateTypes::Server(_server) => &NO_CERTIFICATES,
80+
CertificateType::Client(_client) => &NO_CERTIFICATES,
81+
CertificateType::Server(_server) => &NO_CERTIFICATES,
7882
}
7983
}
8084
}
8185

82-
/// Is used to provide a reference to an empty HashMap.
83-
/// The [`LazyLock`] is required as a HashMap::new is not usable in const expressions.
84-
static NO_CERTIFICATES: LazyLock<HashMap<String, CertificateTypes>> = LazyLock::new(HashMap::new);
85-
8686
impl Default for ClientConfiguration {
8787
fn default() -> Self {
8888
Self { export_key: true }
@@ -100,47 +100,41 @@ impl Default for ServerConfiguration {
100100
pub mod fixtures {
101101
use super::*;
102102

103-
/// Creates a certificate authority and a server and client certificated that are issued by it.
104-
pub fn certificate_ca_with_client() -> CertificateRoot {
103+
/// Provides a [`CertificateRoot`] with a ca certificate that issues one client certificate.
104+
pub fn ca_with_client_certificates() -> CertificateRoot {
105105
let certs = CertificateRoot {
106-
certificates: HashMap::from([("ca".to_string(), ca_with_client())]),
106+
certificates: HashMap::from([("ca".to_string(), ca_with_client_certificate_type())]),
107107
};
108108
certs
109109
}
110110

111-
/// Creates a certificate of type ca with a client cert.
112-
pub fn ca_with_client() -> CertificateTypes {
113-
CertificateTypes::CertificateAuthority(CertificateAuthorityConfiguration {
114-
certificates: HashMap::from([(
115-
"client".to_string(),
116-
CertificateTypes::Client(ClientConfiguration::default()),
117-
)]),
111+
/// Provides a [`CertificateType`] that is a ca certificate that issues one client certificate.
112+
pub fn ca_with_client_certificate_type() -> CertificateType {
113+
CertificateType::CertificateAuthority(CertificateAuthorityConfiguration {
114+
certificates: HashMap::from([("client".to_string(), client_certificate_type())]),
118115
..Default::default()
119116
})
120117
}
121118

122-
/// Creates a client certificate.
123-
pub fn certificate_client() -> CertificateRoot {
119+
/// Provides a [`CertificateRoot`] with only a client certificate.
120+
pub fn single_client_certificate() -> CertificateRoot {
124121
let certs = CertificateRoot {
125-
certificates: HashMap::from([(
126-
"client".to_string(),
127-
CertificateTypes::Client(ClientConfiguration::default()),
128-
)]),
122+
certificates: HashMap::from([("client".to_string(), client_certificate_type())]),
129123
};
130124
certs
131125
}
132126

133-
/// Creates a certificate of type client.
134-
pub fn client() -> CertificateTypes {
135-
CertificateTypes::Client(ClientConfiguration::default())
127+
/// Provides a [`CertificateType`] that is a client certificate.
128+
pub fn client_certificate_type() -> CertificateType {
129+
CertificateType::Client(ClientConfiguration::default())
136130
}
137131

138-
/// Creates a certificate authority without any other certificates.
139-
pub fn certificate_ca() -> CertificateRoot {
132+
/// Provides a [`CertificateRoot`] with only one ca certificate.
133+
pub fn single_ca_certificate() -> CertificateRoot {
140134
let certs = CertificateRoot {
141135
certificates: HashMap::from([(
142136
"ca".to_string(),
143-
CertificateTypes::CertificateAuthority(CertificateAuthorityConfiguration::default()),
137+
CertificateType::CertificateAuthority(CertificateAuthorityConfiguration::default()),
144138
)]),
145139
};
146140
certs
@@ -150,13 +144,13 @@ pub mod fixtures {
150144
#[cfg(test)]
151145
mod tests {
152146
use super::*;
153-
use fixtures::certificate_ca_with_client;
147+
use fixtures::ca_with_client_certificates;
154148
use serde_json::json;
155149

156-
fn get_ca(cert: &CertificateTypes) -> &CertificateAuthorityConfiguration {
157-
assert!(matches!(cert, CertificateTypes::CertificateAuthority(_)));
150+
fn get_ca(cert: &CertificateType) -> &CertificateAuthorityConfiguration {
151+
assert!(matches!(cert, CertificateType::CertificateAuthority(_)));
158152
let ca = match cert {
159-
CertificateTypes::CertificateAuthority(certificate_authority) => certificate_authority,
153+
CertificateType::CertificateAuthority(certificate_authority) => certificate_authority,
160154
_ => panic!("expected ca certificate"),
161155
};
162156
ca
@@ -171,9 +165,9 @@ mod tests {
171165
"type": "ca",
172166
});
173167

174-
let ca: CertificateTypes = serde_json::from_value(json).unwrap();
168+
let ca: CertificateType = serde_json::from_value(json).unwrap();
175169

176-
assert!(matches!(ca, CertificateTypes::CertificateAuthority(_)))
170+
assert!(matches!(ca, CertificateType::CertificateAuthority(_)))
177171
}
178172

179173
#[test]
@@ -183,7 +177,7 @@ mod tests {
183177
"bambu": "solala"
184178
});
185179

186-
let result: Result<CertificateTypes, _> = serde_json::from_value(json);
180+
let result: Result<CertificateType, _> = serde_json::from_value(json);
187181

188182
assert!(result.is_err())
189183
}
@@ -209,7 +203,7 @@ mod tests {
209203
}
210204
});
211205

212-
let ca: CertificateTypes = serde_json::from_value(json).unwrap();
206+
let ca: CertificateType = serde_json::from_value(json).unwrap();
213207
let ca = get_ca(&ca);
214208
let intermediate_ca = ca.certificates.get("intermediate_ca").unwrap();
215209
let intermediate_ca = get_ca(intermediate_ca);
@@ -219,7 +213,7 @@ mod tests {
219213

220214
#[test]
221215
fn should_serde_roundtrip() {
222-
let certs = certificate_ca_with_client();
216+
let certs = ca_with_client_certificates();
223217

224218
let serialized = serde_json::to_string(&certs).unwrap();
225219
let deserialized: CertificateRoot = serde_json::from_str(&serialized).unwrap();
@@ -236,7 +230,7 @@ mod tests {
236230
let certificates = CertificateRoot {
237231
certificates: HashMap::from([(
238232
"my-ca".to_string(),
239-
CertificateTypes::CertificateAuthority(CertificateAuthorityConfiguration {
233+
CertificateType::CertificateAuthority(CertificateAuthorityConfiguration {
240234
certificates: HashMap::new(),
241235
export_key: false,
242236
}),
@@ -258,23 +252,23 @@ mod tests {
258252
fn should_deserialize_ca() {
259253
let yaml = r#"type: ca"#;
260254

261-
let ca: CertificateTypes = serde_yaml::from_str(yaml).unwrap();
255+
let ca: CertificateType = serde_yaml::from_str(yaml).unwrap();
262256

263-
assert!(matches!(ca, CertificateTypes::CertificateAuthority(_)))
257+
assert!(matches!(ca, CertificateType::CertificateAuthority(_)))
264258
}
265259

266260
#[test]
267261
fn should_deserialize_certificateauthority() {
268262
let yaml = r#"type: certificateauthority"#;
269263

270-
let ca: CertificateTypes = serde_yaml::from_str(yaml).unwrap();
264+
let ca: CertificateType = serde_yaml::from_str(yaml).unwrap();
271265

272-
assert!(matches!(ca, CertificateTypes::CertificateAuthority(_)))
266+
assert!(matches!(ca, CertificateType::CertificateAuthority(_)))
273267
}
274268

275269
#[test]
276270
fn should_serde_roundtrip() {
277-
let certs = certificate_ca_with_client();
271+
let certs = ca_with_client_certificates();
278272

279273
let serialized = serde_yaml::to_string(&certs).unwrap();
280274
let deserialized: CertificateRoot = serde_yaml::from_str(&serialized).unwrap();

test-certs/src/configuration/mod.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,9 @@ pub mod certificates;
99
#[derive(Parser, Debug)]
1010
#[command(version, about, long_about = None)]
1111
pub struct Args {
12-
/// Configuration file that contains the certificate generation definition.
13-
#[arg(short, long, default_value = "./certificate_generation.yaml")]
14-
pub configuration: PathBuf,
12+
/// The input file that contains the certificate generation configuration.
13+
#[arg(short, long, default_value = "./certificates.yaml")]
14+
pub input: PathBuf,
1515

1616
/// Folder where all generated certificates will be saved.
1717
#[arg(short, long = "out-dir", default_value = "./certificates.d/")]
@@ -47,10 +47,10 @@ mod tests {
4747
#[test]
4848
fn should_parse_args() {
4949
let args =
50-
Args::try_parse_from(&["", "--configuration", "./file.yaml", "--out-dir", "./certs", "json"])
50+
Args::try_parse_from(&["", "--input", "./file.yaml", "--out-dir", "./certs", "json"])
5151
.unwrap();
5252

53-
assert_eq!(args.configuration.display().to_string(), "./file.yaml");
53+
assert_eq!(args.input.display().to_string(), "./file.yaml");
5454
assert_eq!(args.format.to_string(), "json");
5555
assert_eq!(args.outdir.display().to_string(), "./certs");
5656
}

test-certs/src/lib.rs

Lines changed: 21 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66

77
use std::{fmt::Debug, io::Write, path::PathBuf};
88

9-
use configuration::certificates::CertificateTypes;
9+
use configuration::certificates::CertificateType;
1010
use rcgen::{
1111
BasicConstraints, CertificateParams, DistinguishedName, DnType, IsCa, KeyPair, KeyUsagePurpose,
1212
};
@@ -21,20 +21,19 @@ pub enum Error {
2121
FailedToCreateCertificate(#[from] rcgen::Error),
2222

2323
/// Error to write the certificate to disk
24-
#[error("Could not write certificate to '{0}'")]
25-
FailedToWriteCertificate(PathBuf),
24+
#[error("Could not write certificate")]
25+
FailedToWriteCertificate(std::io::Error),
2626

27-
/// Error to write the certificate key to disk
28-
#[error("Could not write certificate key to '{0}'")]
29-
FailedToWriteKey(PathBuf),
27+
/// Error to write the certificate key to disk
28+
#[error("Could not write certificate key")]
29+
FailedToWriteKey(std::io::Error),
3030

3131
/// Multiple errors that occurred while working with certificates
3232
#[error("Multiple errors occurred")]
3333
ErrorCollection(Vec<Error>),
3434
}
3535

3636
/// A pair of a certificate and the corresponding private key.
37-
#[allow(unused, reason = "Initial draft therefore values are not used yet")]
3837
pub struct Certificate {
3938
certificate: rcgen::Certificate,
4039
key: KeyPair,
@@ -44,32 +43,28 @@ pub struct Certificate {
4443

4544
impl Certificate {
4645
/// Write the certificate and the key if marked for export to the specified folder.
47-
///
48-
/// This fails if the folder is not accessible.
4946
pub fn write(&self, directory: &PathBuf) -> Result<(), Error> {
5047
let cert_file = directory.join(format!("{}.pem", &self.name));
5148

52-
let mut cert = std::fs::File::create(&cert_file)
53-
.map_err(|_| Error::FailedToWriteCertificate(cert_file.clone()))?;
49+
let mut cert =
50+
std::fs::File::create(&cert_file).map_err(Error::FailedToWriteCertificate)?;
5451
cert.write_fmt(format_args!("{}", self.certificate.pem()))
55-
.map_err(|_| Error::FailedToWriteCertificate(cert_file))?;
52+
.map_err(Error::FailedToWriteCertificate)?;
5653

5754
if self.export_key {
5855
let key_file = directory.join(format!("{}.key", &self.name));
59-
let mut key = std::fs::File::create(&key_file)
60-
.map_err(|_| Error::FailedToWriteCertificate(key_file.clone()))?;
56+
let mut key = std::fs::File::create(&key_file).map_err(Error::FailedToWriteKey)?;
6157
key.write_fmt(format_args!("{}", self.key.serialize_pem()))
62-
.map_err(|_| Error::FailedToWriteCertificate(key_file))?;
58+
.map_err(Error::FailedToWriteKey)?;
6359
}
6460
Ok(())
6561
}
6662
}
6763

64+
65+
6866
/// Generates all certificates that are present in the configuration file.
69-
///
70-
/// Each certificate chain is evaluated from the specified root certificate.
71-
/// If one certificate in the chain could not be created the corresponding
72-
/// error is reported and the chain will not be generated.
67+
// TODO: Make builder and return errors and certificates at the same time, maybe with an Iterator?
7368
pub fn generate(
7469
certificate_config: configuration::certificates::CertificateRoot,
7570
) -> Result<Vec<Certificate>, Error> {
@@ -98,7 +93,7 @@ pub fn generate(
9893
/// Generates the certificate and all certificates issued by this one.
9994
fn generate_certificates(
10095
name: &str,
101-
config: &CertificateTypes,
96+
config: &CertificateType,
10297
issuer: Option<&Certificate>,
10398
) -> Result<Vec<Certificate>, Error> {
10499
let mut result = vec![];
@@ -116,7 +111,7 @@ fn generate_certificates(
116111
/// Create the actual certificate and private key.
117112
fn create_certificate(
118113
name: &str,
119-
certificate_config: &CertificateTypes,
114+
certificate_config: &CertificateType,
120115
issuer: Option<&Certificate>,
121116
) -> Result<Certificate, Error> {
122117
let key = KeyPair::generate()?;
@@ -161,15 +156,15 @@ fn issuer_params(common_name: &str) -> CertificateParams {
161156
#[cfg(test)]
162157
mod test {
163158
use configuration::certificates::fixtures::{
164-
ca_with_client, certificate_ca_with_client, client,
159+
ca_with_client_certificate_type, ca_with_client_certificates, client_certificate_type,
165160
};
166161
use testdir::testdir;
167162

168163
use super::*;
169164

170165
#[test]
171166
fn should_create_certificates() {
172-
let certificate_config = certificate_ca_with_client();
167+
let certificate_config = ca_with_client_certificates();
173168
let certificates = generate(certificate_config).unwrap();
174169
assert_eq!(
175170
certificates.len(),
@@ -180,15 +175,15 @@ mod test {
180175

181176
#[test]
182177
fn should_create_certificate() {
183-
let config = client();
178+
let config = client_certificate_type();
184179
let result = create_certificate("test", &config, None);
185180

186181
assert!(result.is_ok())
187182
}
188183

189184
#[test]
190185
fn should_generate_certificates() {
191-
let config = ca_with_client();
186+
let config = ca_with_client_certificate_type();
192187
let result = generate_certificates("my-ca", &config, None);
193188

194189
assert!(result.is_ok())
@@ -197,7 +192,7 @@ mod test {
197192
#[test]
198193
fn should_write_certificate_to_file() {
199194
let dir = testdir!();
200-
let config = client();
195+
let config = client_certificate_type();
201196
let certificates = generate_certificates("my-client", &config, None).unwrap();
202197
let certificate = certificates.first().unwrap();
203198

0 commit comments

Comments
 (0)