AUTH [username] password Redis supports two forms: - `AUTH password` — authenticates with default username "nodedb" - `AUTH username password` — authenticates with explicit username On success, updates `session.tenant_id` from the authenticated identity.
(cmd: &RespCommand, session: &mut RespSession, state: &SharedState)
| 101 | /// |
| 102 | /// On success, updates `session.tenant_id` from the authenticated identity. |
| 103 | fn handle_auth(cmd: &RespCommand, session: &mut RespSession, state: &SharedState) -> RespValue { |
| 104 | let (username, password) = match cmd.argc() { |
| 105 | 1 => ("nodedb", cmd.arg_str(0).unwrap_or("")), |
| 106 | 2 => ( |
| 107 | cmd.arg_str(0).unwrap_or("nodedb"), |
| 108 | cmd.arg_str(1).unwrap_or(""), |
| 109 | ), |
| 110 | _ => return RespValue::err("ERR wrong number of arguments for 'auth' command"), |
| 111 | }; |
| 112 | |
| 113 | // Validate credentials using the same path as native/pgwire auth. |
| 114 | state.credentials.check_lockout(username).ok(); |
| 115 | |
| 116 | match state |
| 117 | .credentials |
| 118 | .verify_password_with_status(username, password) |
| 119 | { |
| 120 | PasswordVerification::Verified(_) => {} |
| 121 | PasswordVerification::Rejected(reason) => { |
| 122 | // Only a genuine credential failure counts toward the lockout |
| 123 | // counter. A policy rejection (expired / must-change password, |
| 124 | // inactive account) or an internal error must not. |
| 125 | if reason == AuthRejection::BadCredential { |
| 126 | let emitter = ArcAuditEmitter(std::sync::Arc::clone(&state.audit)); |
| 127 | state |
| 128 | .credentials |
| 129 | .record_login_failure(username, None, &emitter); |
| 130 | } |
| 131 | state.auth_metrics.record_auth_failure("resp_password"); |
| 132 | return RespValue::err("WRONGPASS invalid username-password pair"); |
| 133 | } |
| 134 | } |
| 135 | |
| 136 | state.credentials.record_login_success(username); |
| 137 | |
| 138 | // Resolve identity to get tenant_id. |
| 139 | match state.credentials.to_identity( |
| 140 | username, |
| 141 | crate::control::security::identity::AuthMethod::CleartextPassword, |
| 142 | ) { |
| 143 | Some(identity) => { |
| 144 | session.tenant_id = identity.tenant_id; |
| 145 | state.auth_metrics.record_auth_success("resp_password"); |
| 146 | RespValue::ok() |
| 147 | } |
| 148 | None => RespValue::err("ERR user not found after authentication"), |
| 149 | } |
| 150 | } |
| 151 | |
| 152 | // --------------------------------------------------------------------------- |
| 153 | // TTL commands |
no test coverage detected