Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Issue #293 Unit tests demonstrating that BATCH mode redis client does not properly authenticate #292

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 52 additions & 0 deletions src/test/scala/com/redis/PipelineSpec.scala
Original file line number Diff line number Diff line change
Expand Up @@ -364,3 +364,55 @@ class PipelineSpec extends AnyFunSpec
}
}
}

class SecureBatchedPipelineSpec extends AnyFunSpec
with Matchers
with IntSpec
with Inside {

override protected lazy val r: RedisClient =
new RedisClient(redisContainerHost, redisContainerPort)

override val redisPassword = Some("antirez")

private def shutdown(client: RedisClient) {
client.disconnect
client.close()
}

describe("a redis client in batch mode connecting to a password-protected redis instance") {
it("should be able to connect to the instance") {
val client = new RedisClient(redisContainerHost, redisContainerPort, secret = redisPassword,
batch = RedisClient.BATCH)

noException should be thrownBy {
val res = client.batchedPipeline(List(() => { client.ping }))
res.get should contain only ("PONG")
}

shutdown(client)
}

it("should be rejected when it is not initialized with a password") {
val client = new RedisClient(redisContainerHost, redisContainerPort, secret = None,
batch = RedisClient.BATCH)

an[Exception] shouldBe thrownBy {
client.batchedPipeline(List(() => { client.ping }))
}

shutdown(client)
}

it("should be rejected when it is initialized with an incorrect password") {
val client = new RedisClient(redisContainerHost, redisContainerPort, secret = Some("WRONG"),
batch = RedisClient.BATCH)

an[Exception] shouldBe thrownBy {
client.batchedPipeline(List(() => { client.ping }))
}

shutdown(client)
}
}
}
47 changes: 45 additions & 2 deletions src/test/scala/com/redis/PoolSpec.scala
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,13 @@ import org.scalatest.matchers.should.Matchers
import scala.concurrent._
import scala.concurrent.duration._

class PoolSpec extends AnyFunSpec
abstract class BasePoolSpec extends AnyFunSpec
with Matchers
with BeforeAndAfterEach
with RedisDocker {

implicit lazy val clients: RedisClientPool = new RedisClientPool(redisContainerHost, redisContainerPort)
implicit lazy val clients: RedisClientPool =
new RedisClientPool(redisContainerHost, redisContainerPort, secret = redisPassword)

override protected def beforeEach(): Unit = {
super.beforeEach()
Expand All @@ -32,6 +33,10 @@ class PoolSpec extends AnyFunSpec
clients.close()
super.afterAll()
}
}

trait PoolLoadTesting {
self: BasePoolSpec =>

def lp(msgs: List[String]) = {
clients.withClient {
Expand Down Expand Up @@ -63,6 +68,9 @@ class PoolSpec extends AnyFunSpec
}
}
}
}

class PoolSpec extends BasePoolSpec with PoolLoadTesting {

describe("pool test") {
it("should distribute work amongst the clients") {
Expand Down Expand Up @@ -127,3 +135,38 @@ class PoolSpec extends AnyFunSpec
}
}
}

class SecurePoolSpec extends BasePoolSpec {

override val redisPassword = Option("mayonaise")

describe("redis pools with authentication") {
it("should be able to connect as normal") {
val response = clients.withClient { client =>
client.ping
}
response should equal(Some("PONG"))
}
}

private def shutdown(client: RedisClient) = {
client.disconnect
client.close()
}

// sanity check that the password set in the whisk docker container is working
describe("ad-hoc clients connecting to a secure redis server") {
it("should be rejected for no password") {
val client = new RedisClient(redisContainerHost, redisContainerPort)
an[Exception] shouldBe thrownBy(client.ping)
shutdown(client)
}

it("should be rejected for wrong password") {
val client = new RedisClient(redisContainerHost, redisContainerPort, secret = Some("WRONG"))
an[Exception] shouldBe thrownBy(client.ping)
shutdown(client)
}
}
}

6 changes: 5 additions & 1 deletion src/test/scala/com/redis/common/RedisDocker.scala
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,12 @@ trait RedisContainer extends DockerKit with DockerTestKit with DockerKitDockerJa

protected val redisContainerHost: String = "localhost"
protected val redisPort: Int = 6379
protected val redisPassword: Option[String] = None

protected def baseContainer(name: Option[String]) = DockerContainer("redis:latest", name=name)
// just password supported for now
private def args = redisPassword.map(password => Seq("--requirepass", password))

protected def baseContainer(name: Option[String]) = DockerContainer("redis:latest", name=name, command=args)

protected def createContainer(name: Option[String] = Some(RandomStringUtils.randomAlphabetic(10)),
ports: Map[Int, Int] = Map.empty): DockerContainer = {
Expand Down