tiberius/client/config/
jdbc.rs

1use super::{ConfigString, ServerDefinition};
2use crate::error::Error;
3use connection_string::JdbcString;
4use std::str::FromStr;
5
6pub(crate) struct JdbcConfig {
7    config: JdbcString,
8}
9
10impl FromStr for JdbcConfig {
11    type Err = Error;
12
13    fn from_str(s: &str) -> crate::Result<Self> {
14        let config = s.parse()?;
15        Ok(Self { config })
16    }
17}
18
19impl ConfigString for JdbcConfig {
20    fn dict(&self) -> &std::collections::HashMap<String, String> {
21        self.config.properties()
22    }
23
24    fn server(&self) -> crate::Result<ServerDefinition> {
25        let def = ServerDefinition {
26            host: self.config.server_name().map(|s| s.to_string()),
27            port: self.config.port(),
28            instance: self.config.instance_name().map(|s| s.to_string()),
29        };
30
31        Ok(def)
32    }
33}
34
35#[cfg(test)]
36mod tests {
37    use super::*;
38    use crate::client::AuthMethod;
39
40    #[cfg(any(
41        feature = "rustls",
42        feature = "native-tls",
43        feature = "vendored-openssl"
44    ))]
45    use crate::EncryptionLevel;
46
47    #[test]
48    fn server_parsing_no_browser() -> crate::Result<()> {
49        let test_str = "jdbc:sqlserver://my-server.com:4200";
50        let jdbc: JdbcConfig = test_str.parse()?;
51        let server = jdbc.server()?;
52
53        assert_eq!(Some("my-server.com".to_string()), server.host);
54        assert_eq!(Some(4200), server.port);
55        assert_eq!(None, server.instance);
56
57        Ok(())
58    }
59
60    #[test]
61    fn server_parsing_no_jdbc_no_browser() -> crate::Result<()> {
62        let test_str = "jdbc:sqlserver://my-server.com:4200";
63        let jdbc: JdbcConfig = test_str.parse()?;
64        let server = jdbc.server()?;
65
66        assert_eq!(Some("my-server.com".to_string()), server.host);
67        assert_eq!(Some(4200), server.port);
68        assert_eq!(None, server.instance);
69
70        Ok(())
71    }
72
73    #[test]
74    fn server_parsing_with_browser() -> crate::Result<()> {
75        let test_str = "jdbc:sqlserver://my-server.com\\TIBERIUS";
76        let jdbc: JdbcConfig = test_str.parse()?;
77        let server = jdbc.server()?;
78
79        assert_eq!(Some("my-server.com".to_string()), server.host);
80        assert_eq!(None, server.port);
81        assert_eq!(Some("TIBERIUS".to_string()), server.instance);
82
83        Ok(())
84    }
85
86    #[test]
87    fn server_parsing_with_browser_and_port() -> crate::Result<()> {
88        let test_str = "jdbc:sqlserver://my-server.com\\TIBERIUS:666";
89        let jdbc: JdbcConfig = test_str.parse()?;
90        let server = jdbc.server()?;
91
92        assert_eq!(Some("my-server.com".to_string()), server.host);
93        assert_eq!(Some(666), server.port);
94        assert_eq!(Some("TIBERIUS".to_string()), server.instance);
95
96        Ok(())
97    }
98
99    #[test]
100    fn database_parsing() -> crate::Result<()> {
101        let test_str = "jdbc:sqlserver://myserver.com:4200;database=Foo";
102        let jdbc: JdbcConfig = test_str.parse()?;
103
104        assert_eq!(Some("Foo".to_string()), jdbc.database());
105
106        let test_str = "jdbc:sqlserver://myserver.com:4200;databaseName=Foo";
107        let jdbc: JdbcConfig = test_str.parse()?;
108
109        assert_eq!(Some("Foo".to_string()), jdbc.database());
110
111        let test_str = "jdbc:sqlserver://myserver.com:4200;Initial Catalog=Foo";
112        let jdbc: JdbcConfig = test_str.parse()?;
113
114        assert_eq!(Some("Foo".to_string()), jdbc.database());
115
116        Ok(())
117    }
118
119    #[test]
120    fn trust_cert_parsing_true() -> crate::Result<()> {
121        let test_str = "jdbc:sqlserver://my-server.com:4200;TrustServerCertificate=true;";
122        let jdbc: JdbcConfig = test_str.parse()?;
123
124        assert!(jdbc.trust_cert()?);
125
126        Ok(())
127    }
128
129    #[test]
130    fn trust_cert_parsing_false() -> crate::Result<()> {
131        let test_str = "jdbc:sqlserver://my-server.com:4200;TrustServerCertificate=false;";
132        let jdbc: JdbcConfig = test_str.parse()?;
133
134        assert!(!jdbc.trust_cert()?);
135
136        Ok(())
137    }
138
139    #[test]
140    fn trust_cert_parsing_yes() -> crate::Result<()> {
141        let test_str = "jdbc:sqlserver://my-server.com:4200;TrustServerCertificate=yes;";
142        let jdbc: JdbcConfig = test_str.parse()?;
143
144        assert!(jdbc.trust_cert()?);
145
146        Ok(())
147    }
148
149    #[test]
150    fn trust_cert_parsing_no() -> crate::Result<()> {
151        let test_str = "jdbc:sqlserver://my-server.com:4200;TrustServerCertificate=no;";
152        let jdbc: JdbcConfig = test_str.parse()?;
153
154        assert!(!jdbc.trust_cert()?);
155
156        Ok(())
157    }
158
159    #[test]
160    fn trust_cert_parsing_missing() -> crate::Result<()> {
161        let test_str = "jdbc:sqlserver://my-server.com:4200;";
162        let jdbc: JdbcConfig = test_str.parse()?;
163
164        assert!(!jdbc.trust_cert()?);
165
166        Ok(())
167    }
168
169    #[test]
170    fn trust_cert_parsing_faulty() -> crate::Result<()> {
171        let test_str = "jdbc:sqlserver://my-server.com:4200;TrustServerCertificate=musti;";
172        let jdbc: JdbcConfig = test_str.parse()?;
173
174        assert!(jdbc.trust_cert().is_err());
175
176        Ok(())
177    }
178
179    #[test]
180    fn trust_cert_ca_parsing_ok() -> crate::Result<()> {
181        let test_str = "jdbc:sqlserver://my-server.com:4200;TrustServerCertificateCA=someca.crt;";
182        let ado: JdbcConfig = test_str.parse()?;
183
184        assert_eq!(Some("someca.crt".to_string()), ado.trust_cert_ca());
185
186        Ok(())
187    }
188
189    #[test]
190    fn parsing_sql_server_authentication() -> crate::Result<()> {
191        let test_str = "jdbc:sqlserver://my-server.com:4200;User ID=Musti;pwd=Naukio;";
192        let jdbc: JdbcConfig = test_str.parse()?;
193
194        assert_eq!(
195            AuthMethod::sql_server("Musti", "Naukio"),
196            jdbc.authentication()?
197        );
198
199        Ok(())
200    }
201
202    #[test]
203    #[cfg(windows)]
204    fn parsing_sspi_authentication() -> crate::Result<()> {
205        let test_str = "jdbc:sqlserver://my-server.com:4200;IntegratedSecurity=SSPI;";
206        let jdbc: JdbcConfig = test_str.parse()?;
207
208        assert_eq!(AuthMethod::Integrated, jdbc.authentication()?);
209
210        Ok(())
211    }
212
213    #[test]
214    #[cfg(all(feature = "integrated-auth-gssapi", unix))]
215    fn parsing_sspi_authentication() -> crate::Result<()> {
216        let test_str = "jdbc:sqlserver://my-server.com:4200;IntegratedSecurity=true;";
217        let jdbc: JdbcConfig = test_str.parse()?;
218
219        assert_eq!(AuthMethod::Integrated, jdbc.authentication()?);
220
221        Ok(())
222    }
223
224    #[test]
225    #[cfg(windows)]
226    fn parsing_windows_authentication() -> crate::Result<()> {
227        let test_str =
228            "jdbc:sqlserver://my-server.com:4200;uid=Musti;pwd=Naukio;IntegratedSecurity=SSPI;";
229        let jdbc: JdbcConfig = test_str.parse()?;
230
231        assert_eq!(
232            AuthMethod::windows("Musti", "Naukio"),
233            jdbc.authentication()?
234        );
235
236        Ok(())
237    }
238
239    #[test]
240    fn parsing_database() -> crate::Result<()> {
241        let test_str = "jdbc:sqlserver://my-server.com:4200;database=Cats;";
242        let jdbc: JdbcConfig = test_str.parse()?;
243
244        assert_eq!(Some("Cats".to_string()), jdbc.database());
245
246        Ok(())
247    }
248
249    #[test]
250    fn parsing_login_credentials_escaping() -> crate::Result<()> {
251        let test_str = "jdbc:sqlserver://my-server.com:4200;User ID=musti;Password={abc;}}45}";
252        let jdbc: JdbcConfig = test_str.parse()?;
253
254        assert_eq!(
255            AuthMethod::sql_server("musti", "abc;}45}"),
256            jdbc.authentication()?
257        );
258
259        Ok(())
260    }
261
262    #[test]
263    #[cfg(any(
264        feature = "rustls",
265        feature = "native-tls",
266        feature = "vendored-openssl"
267    ))]
268    fn encryption_parsing_on() -> crate::Result<()> {
269        let test_str = "jdbc:sqlserver://my-server.com:4200;encrypt=true;";
270        let jdbc: JdbcConfig = test_str.parse()?;
271
272        assert_eq!(EncryptionLevel::Required, jdbc.encrypt()?);
273
274        Ok(())
275    }
276
277    #[test]
278    #[cfg(any(
279        feature = "rustls",
280        feature = "native-tls",
281        feature = "vendored-openssl"
282    ))]
283    fn encryption_parsing_off() -> crate::Result<()> {
284        let test_str = "jdbc:sqlserver://my-server.com:4200;encrypt=false;";
285        let jdbc: JdbcConfig = test_str.parse()?;
286
287        assert_eq!(EncryptionLevel::Off, jdbc.encrypt()?);
288
289        Ok(())
290    }
291
292    #[test]
293    #[cfg(any(
294        feature = "rustls",
295        feature = "native-tls",
296        feature = "vendored-openssl"
297    ))]
298    fn encryption_parsing_plaintext() -> crate::Result<()> {
299        let test_str = "jdbc:sqlserver://my-server.com:4200;encrypt=DANGER_PLAINTEXT;";
300        let jdbc: JdbcConfig = test_str.parse()?;
301
302        assert_eq!(EncryptionLevel::NotSupported, jdbc.encrypt()?);
303
304        Ok(())
305    }
306
307    #[test]
308    #[cfg(any(
309        feature = "rustls",
310        feature = "native-tls",
311        feature = "vendored-openssl"
312    ))]
313    fn encryption_parsing_missing() -> crate::Result<()> {
314        let test_str = "jdbc:sqlserver://my-server.com:4200;";
315        let jdbc: JdbcConfig = test_str.parse()?;
316
317        assert_eq!(EncryptionLevel::Off, jdbc.encrypt()?);
318
319        Ok(())
320    }
321
322    #[test]
323    fn application_name_parsing() -> crate::Result<()> {
324        let test_str = "jdbc:sqlserver://my-server.com:4200;Application Name=meow";
325        let jdbc: JdbcConfig = test_str.parse()?;
326
327        assert_eq!(Some("meow".into()), jdbc.application_name());
328
329        let test_str = "jdbc:sqlserver://my-server.com:4200;ApplicationName=meow";
330        let jdbc: JdbcConfig = test_str.parse()?;
331
332        assert_eq!(Some("meow".into()), jdbc.application_name());
333
334        Ok(())
335    }
336}