opcua_client/
identity_token.rs1use std::{path::Path, sync::Arc};
2
3use async_trait::async_trait;
4use opcua_crypto::{CertificateStore, PrivateKey, X509};
5use opcua_types::{ByteString, Error, StatusCode};
6
7#[async_trait]
8pub trait IssuedTokenSource: Send + Sync {
11 async fn get_issued_token(&self) -> Result<ByteString, Error>;
14}
15
16#[async_trait]
17impl IssuedTokenSource for ByteString {
18 async fn get_issued_token(&self) -> Result<ByteString, Error> {
19 Ok(self.clone())
20 }
21}
22
23#[derive(Clone)]
25pub struct IssuedTokenWrapper(pub(crate) Arc<dyn IssuedTokenSource>);
26
27impl IssuedTokenWrapper {
28 pub fn new(token_source: Arc<dyn IssuedTokenSource>) -> Self {
30 Self(token_source)
31 }
32
33 pub fn new_source(token_source: impl IssuedTokenSource + 'static) -> Self {
35 Self(Arc::new(token_source))
36 }
37}
38
39impl std::fmt::Debug for IssuedTokenWrapper {
40 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
41 f.debug_tuple("IssuedTokenSource").finish()
42 }
43}
44
45#[derive(Clone)]
46pub struct Password(pub String);
49
50impl Password {
51 pub fn new(password: impl Into<String>) -> Self {
53 Password(password.into())
54 }
55}
56
57impl<T> From<T> for Password
58where
59 T: Into<String>,
60{
61 fn from(value: T) -> Self {
62 Password(value.into())
63 }
64}
65
66impl std::fmt::Debug for Password {
67 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
68 f.debug_tuple("Password").field(&"*****").finish()
69 }
70}
71
72#[derive(Debug, Clone)]
73pub enum IdentityToken {
75 Anonymous,
77 UserName(String, Password),
79 X509(Box<X509>, Box<PrivateKey>),
81 IssuedToken(IssuedTokenWrapper),
83}
84
85impl IdentityToken {
86 pub fn new_anonymous() -> Self {
88 IdentityToken::Anonymous
89 }
90 pub fn new_user_name(user_name: impl Into<String>, password: impl Into<Password>) -> Self {
92 IdentityToken::UserName(user_name.into(), password.into())
93 }
94
95 pub fn new_x509(cert: X509, private_key: PrivateKey) -> Self {
97 IdentityToken::X509(Box::new(cert), Box::new(private_key))
98 }
99
100 pub fn new_x509_path(
102 cert_path: impl AsRef<Path>,
103 key_path: impl AsRef<Path>,
104 ) -> Result<Self, Error> {
105 let cert = CertificateStore::read_cert(cert_path.as_ref())
106 .map_err(|e| Error::new(StatusCode::Bad, e))?;
107 let private_key = CertificateStore::read_pkey(key_path.as_ref())
108 .map_err(|e| Error::new(StatusCode::Bad, e))?;
109 Ok(IdentityToken::X509(Box::new(cert), Box::new(private_key)))
110 }
111
112 pub fn new_issued_token(token_source: impl IssuedTokenSource + 'static) -> Self {
114 IdentityToken::IssuedToken(IssuedTokenWrapper::new_source(token_source))
115 }
116
117 pub fn new_issued_token_arc(token_source: Arc<dyn IssuedTokenSource>) -> Self {
119 IdentityToken::IssuedToken(IssuedTokenWrapper::new(token_source))
120 }
121}