1use std::fmt;
8use std::sync::Arc;
9
10use sipx_sip::Request;
11use sipx_ua::identity::{
12 AuthenticationError, AuthenticationService, Authority, CredentialFetcher, VerificationFailure,
13 VerificationService,
14};
15
16trait SignCall: Send + Sync {
17 fn sign(&self, request: &mut Request) -> Result<(), AuthenticationError>;
18}
19
20struct SelectedAuthentication<A, N> {
21 service: AuthenticationService<A>,
22 now: N,
23}
24
25impl<A, N> SignCall for SelectedAuthentication<A, N>
26where
27 A: Authority + Send + Sync,
28 N: Fn() -> i64 + Send + Sync,
29{
30 fn sign(&self, request: &mut Request) -> Result<(), AuthenticationError> {
31 self.service.sign(request, (self.now)())
32 }
33}
34
35#[derive(Clone)]
41pub struct OutboundIdentityPolicy {
42 signer: Arc<dyn SignCall>,
43}
44
45impl OutboundIdentityPolicy {
46 #[must_use]
48 pub fn new<A, N>(service: AuthenticationService<A>, now: N) -> Self
49 where
50 A: Authority + Send + Sync + 'static,
51 N: Fn() -> i64 + Send + Sync + 'static,
52 {
53 Self {
54 signer: Arc::new(SelectedAuthentication { service, now }),
55 }
56 }
57
58 pub(crate) fn sign(&self, request: &mut Request) -> Result<(), AuthenticationError> {
59 self.signer.sign(request)
60 }
61}
62
63impl fmt::Debug for OutboundIdentityPolicy {
64 fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
65 formatter
66 .debug_struct("OutboundIdentityPolicy")
67 .finish_non_exhaustive()
68 }
69}
70
71trait VerifyCall: Send + Sync {
72 fn verify(&mut self, request: &Request) -> Result<(), VerificationFailure>;
73}
74
75struct SelectedVerification<S, N> {
76 service: VerificationService<S>,
77 now: N,
78 required: bool,
79}
80
81impl<S, N> VerifyCall for SelectedVerification<S, N>
82where
83 S: CredentialFetcher + Send + Sync,
84 N: Fn() -> i64 + Send + Sync,
85{
86 fn verify(&mut self, request: &Request) -> Result<(), VerificationFailure> {
87 self.service
88 .verify(request, (self.now)(), self.required)
89 .map(|_| ())
90 }
91}
92
93pub struct InboundIdentityPolicy {
100 verifier: Box<dyn VerifyCall>,
101}
102
103impl InboundIdentityPolicy {
104 #[must_use]
106 pub fn new<S, N>(service: VerificationService<S>, required: bool, now: N) -> Self
107 where
108 S: CredentialFetcher + Send + Sync + 'static,
109 N: Fn() -> i64 + Send + Sync + 'static,
110 {
111 Self {
112 verifier: Box::new(SelectedVerification {
113 service,
114 now,
115 required,
116 }),
117 }
118 }
119
120 pub(crate) fn verify(&mut self, request: &Request) -> Result<(), VerificationFailure> {
121 self.verifier.verify(request)
122 }
123}
124
125impl fmt::Debug for InboundIdentityPolicy {
126 fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
127 formatter
128 .debug_struct("InboundIdentityPolicy")
129 .finish_non_exhaustive()
130 }
131}