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
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
/*
*
* * Copyright (c) 2025 Couchbase, Inc.
* *
* * Licensed under the Apache License, Version 2.0 (the "License");
* * you may not use this file except in compliance with the License.
* * You may obtain a copy of the License at
* *
* * http://www.apache.org/licenses/LICENSE-2.0
* *
* * Unless required by applicable law or agreed to in writing, software
* * distributed under the License is distributed on an "AS IS" BASIS,
* * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* * See the License for the specific language governing permissions and
* * limitations under the License.
*
*/
use crate::memdx::auth_mechanism::AuthMechanism;
use crate::memdx::dispatcher::Dispatcher;
use crate::memdx::error::Result;
use crate::memdx::op_auth_saslauto::Credentials;
use crate::memdx::op_auth_sasloauthbearer::{OpsSASLOAuthBearer, SASLOAuthBearerOptions};
use crate::memdx::op_auth_saslplain::{OpSASLPlainEncoder, OpsSASLAuthPlain, SASLAuthPlainOptions};
use crate::memdx::op_auth_saslscram::{OpSASLScramEncoder, OpsSASLAuthScram, SASLAuthScramOptions};
use crate::scram;
use hmac::Hmac;
use sha1::Sha1;
use sha2::{Sha256, Sha512};
use tokio::time::Instant;
#[derive(Clone, Debug, Eq, PartialEq, Ord, PartialOrd, Hash)]
pub struct SASLAuthByNameOptions {
pub credentials: Credentials,
pub auth_mechanism: AuthMechanism,
pub deadline: Instant,
}
pub trait OpSASLAuthByNameEncoder: OpSASLScramEncoder + OpSASLPlainEncoder {}
#[derive(Clone, Debug, Eq, PartialEq, Ord, PartialOrd, Hash)]
pub struct OpsSASLAuthByName {}
impl OpsSASLAuthByName {
pub async fn sasl_auth_by_name<E, D>(
&self,
encoder: &E,
dispatcher: &D,
opts: SASLAuthByNameOptions,
) -> Result<()>
where
E: OpSASLAuthByNameEncoder,
D: Dispatcher,
{
match opts.auth_mechanism {
AuthMechanism::Plain => {
let (username, password) = opts.credentials.user_pass()?;
OpsSASLAuthPlain {}
.sasl_auth_plain(
encoder,
dispatcher,
SASLAuthPlainOptions::new(
username.to_string(),
password.to_string(),
opts.deadline,
),
)
.await
}
AuthMechanism::ScramSha1 => {
let (username, password) = opts.credentials.user_pass()?;
OpsSASLAuthScram {}
.sasl_auth_scram(
encoder,
dispatcher,
scram::Client::<Hmac<Sha1>, Sha1>::new(
username.to_string(),
password.to_string(),
None,
),
SASLAuthScramOptions::new(opts.deadline),
)
.await
}
AuthMechanism::ScramSha256 => {
let (username, password) = opts.credentials.user_pass()?;
OpsSASLAuthScram {}
.sasl_auth_scram(
encoder,
dispatcher,
scram::Client::<Hmac<Sha256>, Sha256>::new(
username.to_string(),
password.to_string(),
None,
),
SASLAuthScramOptions::new(opts.deadline),
)
.await
}
AuthMechanism::ScramSha512 => {
let (username, password) = opts.credentials.user_pass()?;
OpsSASLAuthScram {}
.sasl_auth_scram(
encoder,
dispatcher,
scram::Client::<Hmac<Sha512>, Sha512>::new(
username.to_string(),
password.to_string(),
None,
),
SASLAuthScramOptions::new(opts.deadline),
)
.await
}
AuthMechanism::OAuthBearer => {
let token = opts.credentials.jwt()?;
OpsSASLOAuthBearer {}
.sasl_auth_oauth_bearer(
encoder,
dispatcher,
SASLOAuthBearerOptions::new(token.to_string(), opts.deadline),
)
.await
}
}
}
}