Skip to content

Commit 7d65d4e

Browse files
avifeneshjhpung
andauthored
Feature/replace credes (#2651)
* arrange typos and clean code Signed-off-by: avifenesh <[email protected]> * Add support for re-authentication on NOAUTH error Signed-off-by: avifenesh <[email protected]> * Add integration tests for password replacement in Redis connections Signed-off-by: avifenesh <[email protected]> * Implement password replacement functionality in Client and StandaloneClient Signed-off-by: avifenesh <[email protected]> * Add ReplaceConnectionPassword message to protobuf for password reset functionality Signed-off-by: avifenesh <[email protected]> * Add replace_connection_password method to manage connection password updates Signed-off-by: avifenesh <[email protected]> * Update CHANGELOG.md to include support for replacing connection configured password Signed-off-by: avifenesh <[email protected]> * Node: add repalceConnectionPassword method to manage connection password updates Signed-off-by: jhpung <[email protected]> Signed-off-by: avifenesh <[email protected]> --------- Signed-off-by: avifenesh <[email protected]> Signed-off-by: jhpung <[email protected]> Co-authored-by: jhpung <[email protected]>
1 parent 664cc8e commit 7d65d4e

File tree

23 files changed

+1098
-129
lines changed

23 files changed

+1098
-129
lines changed

.github/workflows/python.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,7 @@ jobs:
115115
working-directory: ./python
116116
run: |
117117
source .env/bin/activate
118+
pip install -r dev_requirements.txt
118119
cd python/tests/
119120
pytest --asyncio-mode=auto --html=pytest_report.html --self-contained-html
120121
@@ -177,6 +178,7 @@ jobs:
177178
working-directory: ./python
178179
run: |
179180
source .env/bin/activate
181+
pip install -r dev_requirements.txt
180182
cd python/tests/
181183
pytest --asyncio-mode=auto -k test_pubsub --html=pytest_report.html --self-contained-html
182184

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
#### Changes
2+
* Node, Python: Adding support for replacing connection configured password ([#2651](https://github.com/valkey-io/valkey-glide/pull/2651))
23
* Node: Add FT._ALIASLIST command([#2652](https://github.com/valkey-io/valkey-glide/pull/2652))
34
* Python: Python: `FT._ALIASLIST` command added([#2638](https://github.com/valkey-io/valkey-glide/pull/2638))
45
* Node: alias commands added: FT.ALIASADD, FT.ALIADDEL, FT.ALIASUPDATE([#2596](https://github.com/valkey-io/valkey-glide/pull/2596))

glide-core/redis-rs/redis/Cargo.toml

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ repository = "https://github.com/redis-rs/redis-rs"
88
documentation = "https://docs.rs/redis"
99
license = "BSD-3-Clause"
1010
edition = "2021"
11-
rust-version = "1.65"
11+
rust-version = "1.67"
1212
readme = "../README.md"
1313

1414
[package.metadata.docs.rs]
@@ -47,7 +47,6 @@ pin-project-lite = { version = "0.2", optional = true }
4747
tokio-util = { version = "0.7", optional = true }
4848
tokio = { version = "1", features = ["rt", "net", "time", "sync"] }
4949
socket2 = { version = "0.5", features = ["all"], optional = true }
50-
fast-math = { version = "0.1.1", optional = true }
5150
dispose = { version = "0.5.0", optional = true }
5251

5352
# Only needed for the connection manager
@@ -67,7 +66,7 @@ dashmap = { version = "6.0", optional = true }
6766
async-trait = { version = "0.1.24", optional = true }
6867

6968
# Only needed for tokio support
70-
tokio-retry2 = {version = "0.5", features = ["jitter"], optional = true}
69+
tokio-retry2 = { version = "0.5", features = ["jitter"], optional = true }
7170

7271
# Only needed for native tls
7372
native-tls = { version = "0.2", optional = true }
@@ -125,7 +124,6 @@ aio = [
125124
"tokio-util/codec",
126125
"combine/tokio",
127126
"async-trait",
128-
"fast-math",
129127
"dispose",
130128
]
131129
geospatial = []

glide-core/redis-rs/redis/src/aio/multiplexed_connection.rs

Lines changed: 109 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,9 @@ use std::time::Duration;
3131
#[cfg(feature = "tokio-comp")]
3232
use tokio_util::codec::Decoder;
3333

34+
// Default connection timeout in ms
35+
const DEFAULT_CONNECTION_ATTEMPT_TIMEOUT: Duration = Duration::from_millis(250);
36+
3437
// Senders which the result of a single request are sent through
3538
type PipelineOutput = oneshot::Sender<RedisResult<Value>>;
3639

@@ -76,7 +79,7 @@ struct PipelineMessage<S> {
7679
/// interface provided by `Pipeline` an easy interface of request to response, hiding the `Stream`
7780
/// and `Sink`.
7881
#[derive(Clone)]
79-
struct Pipeline<SinkItem> {
82+
pub(crate) struct Pipeline<SinkItem> {
8083
sender: mpsc::Sender<PipelineMessage<SinkItem>>,
8184
push_manager: Arc<ArcSwap<PushManager>>,
8285
is_stream_closed: Arc<AtomicBool>,
@@ -399,6 +402,7 @@ where
399402
self.push_manager.store(Arc::new(push_manager));
400403
}
401404

405+
/// Checks if the pipeline is closed.
402406
pub fn is_closed(&self) -> bool {
403407
self.is_stream_closed.load(Ordering::Relaxed)
404408
}
@@ -413,6 +417,7 @@ pub struct MultiplexedConnection {
413417
response_timeout: Duration,
414418
protocol: ProtocolVersion,
415419
push_manager: PushManager,
420+
password: Option<String>,
416421
}
417422

418423
impl Debug for MultiplexedConnection {
@@ -455,35 +460,28 @@ impl MultiplexedConnection {
455460
where
456461
C: Unpin + AsyncRead + AsyncWrite + Send + 'static,
457462
{
458-
fn boxed(
459-
f: impl Future<Output = ()> + Send + 'static,
460-
) -> Pin<Box<dyn Future<Output = ()> + Send>> {
461-
Box::pin(f)
462-
}
463-
464-
#[cfg(not(feature = "tokio-comp"))]
465-
compile_error!("tokio-comp feature is required for aio feature");
466-
467-
let redis_connection_info = &connection_info.redis;
468463
let codec = ValueCodec::default()
469464
.framed(stream)
470465
.and_then(|msg| async move { msg });
471466
let (mut pipeline, driver) =
472467
Pipeline::new(codec, glide_connection_options.disconnect_notifier);
473-
let driver = boxed(driver);
468+
let driver = Box::pin(driver);
474469
let pm = PushManager::default();
475470
if let Some(sender) = glide_connection_options.push_sender {
476471
pm.replace_sender(sender);
477472
}
478473

479474
pipeline.set_push_manager(pm.clone()).await;
480-
let mut con = MultiplexedConnection {
481-
pipeline,
482-
db: connection_info.redis.db,
483-
response_timeout,
484-
push_manager: pm,
485-
protocol: redis_connection_info.protocol,
486-
};
475+
476+
let mut con = MultiplexedConnection::builder(pipeline)
477+
.with_db(connection_info.redis.db)
478+
.with_response_timeout(response_timeout)
479+
.with_push_manager(pm)
480+
.with_protocol(connection_info.redis.protocol)
481+
.with_password(connection_info.redis.password.clone())
482+
.build()
483+
.await?;
484+
487485
let driver = {
488486
let auth = setup_connection(&connection_info.redis, &mut con);
489487

@@ -502,6 +500,7 @@ impl MultiplexedConnection {
502500
}
503501
}
504502
};
503+
505504
Ok((con, driver))
506505
}
507506

@@ -575,6 +574,97 @@ impl MultiplexedConnection {
575574
self.push_manager = push_manager.clone();
576575
self.pipeline.set_push_manager(push_manager).await;
577576
}
577+
578+
/// Replace the password used to authenticate with the server.
579+
/// If `None` is provided, the password will be removed.
580+
pub async fn update_connection_password(
581+
&mut self,
582+
password: Option<String>,
583+
) -> RedisResult<Value> {
584+
self.password = password;
585+
Ok(Value::Okay)
586+
}
587+
588+
/// Creates a new `MultiplexedConnectionBuilder` for constructing a `MultiplexedConnection`.
589+
pub(crate) fn builder(pipeline: Pipeline<Vec<u8>>) -> MultiplexedConnectionBuilder {
590+
MultiplexedConnectionBuilder::new(pipeline)
591+
}
592+
}
593+
594+
/// A builder for creating `MultiplexedConnection` instances.
595+
pub struct MultiplexedConnectionBuilder {
596+
pipeline: Pipeline<Vec<u8>>,
597+
db: Option<i64>,
598+
response_timeout: Option<Duration>,
599+
push_manager: Option<PushManager>,
600+
protocol: Option<ProtocolVersion>,
601+
password: Option<String>,
602+
}
603+
604+
impl MultiplexedConnectionBuilder {
605+
/// Creates a new builder with the required pipeline
606+
pub(crate) fn new(pipeline: Pipeline<Vec<u8>>) -> Self {
607+
Self {
608+
pipeline,
609+
db: None,
610+
response_timeout: None,
611+
push_manager: None,
612+
protocol: None,
613+
password: None,
614+
}
615+
}
616+
617+
/// Sets the database index for the `MultiplexedConnectionBuilder`.
618+
pub fn with_db(mut self, db: i64) -> Self {
619+
self.db = Some(db);
620+
self
621+
}
622+
623+
/// Sets the response timeout for the `MultiplexedConnectionBuilder`.
624+
pub fn with_response_timeout(mut self, timeout: Duration) -> Self {
625+
self.response_timeout = Some(timeout);
626+
self
627+
}
628+
629+
/// Sets the push manager for the `MultiplexedConnectionBuilder`.
630+
pub fn with_push_manager(mut self, push_manager: PushManager) -> Self {
631+
self.push_manager = Some(push_manager);
632+
self
633+
}
634+
635+
/// Sets the protocol version for the `MultiplexedConnectionBuilder`.
636+
pub fn with_protocol(mut self, protocol: ProtocolVersion) -> Self {
637+
self.protocol = Some(protocol);
638+
self
639+
}
640+
641+
/// Sets the password for the `MultiplexedConnectionBuilder`.
642+
pub fn with_password(mut self, password: Option<String>) -> Self {
643+
self.password = password;
644+
self
645+
}
646+
647+
/// Builds and returns a new `MultiplexedConnection` instance using the configured settings.
648+
pub async fn build(self) -> RedisResult<MultiplexedConnection> {
649+
let db = self.db.unwrap_or_default();
650+
let response_timeout = self
651+
.response_timeout
652+
.unwrap_or(DEFAULT_CONNECTION_ATTEMPT_TIMEOUT);
653+
let push_manager = self.push_manager.unwrap_or_default();
654+
let protocol = self.protocol.unwrap_or_default();
655+
let password = self.password;
656+
657+
let con = MultiplexedConnection {
658+
pipeline: self.pipeline,
659+
db,
660+
response_timeout,
661+
push_manager,
662+
protocol,
663+
password,
664+
};
665+
666+
Ok(con)
667+
}
578668
}
579669

580670
impl ConnectionLike for MultiplexedConnection {

glide-core/redis-rs/redis/src/cluster.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -306,7 +306,7 @@ where
306306

307307
/// Returns the connection status.
308308
///
309-
/// The connection is open until any `read_response` call recieved an
309+
/// The connection is open until any `read_response` call received an
310310
/// invalid response from the server (most likely a closed or dropped
311311
/// connection, otherwise a Redis protocol error). When using unix
312312
/// sockets the connection is open until writing a command failed with a
@@ -808,7 +808,7 @@ where
808808
self.refresh_slots()?;
809809

810810
// Given that there are commands that need to be retried, it means something in the cluster
811-
// topology changed. Execute each command seperately to take advantage of the existing
811+
// topology changed. Execute each command separately to take advantage of the existing
812812
// retry logic that handles these cases.
813813
for retry_idx in to_retry {
814814
let cmd = &cmds[retry_idx];

0 commit comments

Comments
 (0)